상속: IMgaComponentEx, IGMEVersionInfo
예제 #1
0
        public void ImportCADModel(string CADpath = null)
        {
            string cadFilename = "";

            this.Logger = new CyPhyGUIs.GMELogger(CurrentProj, this.GetType().Name);
            using (this.Logger)
            {
                //The CAT module will perform these steps, in this order:
                //  - Check that the user has Creo (so that the extraction will be successful)
                //      - Implementation Suggestion: The extraction utility may have special flag to have it indicates if all the dependencies are met

                //  - Display a dialog box to let the user choose their Creo model file
                bool cad_file_chosen         = false;
                bool test_copy_and_path_only = false;
                if (string.IsNullOrWhiteSpace(CADpath))
                {
                    cad_file_chosen = get_cad_file(out cadFilename);
                }
                else
                {
                    test_copy_and_path_only = true;
                    cadFilename             = CADpath;
                    if (File.Exists(cadFilename))
                    {
                        cad_file_chosen = true;
                    }
                    else
                    {
                        this.Logger.WriteError("Invalid CAD file path passed in: " + CADpath);
                    }
                }

                //  - Run the extractor on the Creo model file
                #region Run the Extractor

                bool   extractor_ran_success = test_copy_and_path_only;
                string tempXMLfile           = Path.GetTempFileName();
                this.Logger.WriteDebug("Temporary XML file created: " + tempXMLfile);

                if (cad_file_chosen && !test_copy_and_path_only)
                {
                    try
                    {
                        // assemble the arg string
                        // first the input CAD file
                        // include quotation marks to handle paths with white spaces
                        string argstring = "ExtractACM-XMLfromCreoModels -c \"";
                        argstring += cadFilename;
                        argstring += "\"";

                        // add the XML output file name
                        argstring += " -x \"";
                        argstring += tempXMLfile;
                        argstring += "\"";

                        // Debug only: pause before exit, graphics mode.
                        //argstring += " -p -g";

                        Process firstProc = new Process();

                        string path = Path.Combine(META.VersionInfo.MetaPath, "bin\\CAD\\Creo\\bin\\CADCreoParametricCreateAssembly.exe");
                        if (!File.Exists(path))
                        {
                            this.Logger.WriteError(String.Format("Cannot find '{0}'", path));
                            throw new Exception("CADCreoParametricCreateAssembly.exe not found.");
                        }

                        firstProc.StartInfo.FileName               = path;
                        firstProc.StartInfo.Arguments              = argstring;
                        firstProc.StartInfo.CreateNoWindow         = true;
                        firstProc.StartInfo.UseShellExecute        = false;
                        firstProc.StartInfo.RedirectStandardOutput = true;
                        firstProc.StartInfo.RedirectStandardError  = true;
                        firstProc.StartInfo.RedirectStandardInput  = true;

                        int           streamsClosed    = 0;
                        StringBuilder exeConsoleOutput = new StringBuilder();

                        DataReceivedEventHandler handler = (sender, e) =>
                        {
                            lock (Logger)
                            {
                                if (e.Data == null)
                                {
                                    streamsClosed += 1;
                                    if (streamsClosed == 2)
                                    {
                                    }
                                    return;
                                }
                                Logger.WriteDebug(e.Data);
                                exeConsoleOutput.AppendLine(e.Data);
                            }
                        };
                        firstProc.OutputDataReceived += handler;
                        firstProc.ErrorDataReceived  += handler;
                        firstProc.EnableRaisingEvents = true;
                        bool             showProgressBar        = sender != null && sender is IWin32Window;
                        bool             done                   = false;
                        Object           doneSyncObject         = new object();
                        GUIs.CADProgress progress               = null;
                        EventHandler     closeDialogWithSuccess = (e, o) =>
                        {
                            lock (doneSyncObject)
                            {
                                if (done == false)
                                {
                                    progress.BeginInvoke((Action)(() =>
                                    {
                                        done = true;
                                        progress.DialogResult = DialogResult.OK;
                                        progress.Close();
                                    }));
                                }
                            }
                        };
                        if (showProgressBar)
                        {
                            progress          = new GUIs.CADProgress();
                            firstProc.Exited += closeDialogWithSuccess;
                        }
                        IntPtr job = JobObjectPinvoke.CreateKillOnCloseJob();
                        firstProc.Exited += (s, o) =>
                        {
                            if (job != JobObjectPinvoke.INVALID_HANDLE_VALUE)
                            {
                                JobObjectPinvoke.CloseHandle(job);
                            }
                            if (progress != null && progress.DialogResult == DialogResult.Cancel)
                            {
                                File.Delete(tempXMLfile);
                            }
                        };

                        this.Logger.WriteDebug("Calling CADCreoParametricCreateAssembly.exe with argument string: " + argstring);

                        firstProc.Start();
                        JobObjectPinvoke.AssignProcessToJobObject(firstProc, job);
                        firstProc.StandardInput.Close();
                        firstProc.BeginOutputReadLine();
                        firstProc.BeginErrorReadLine();

                        if (showProgressBar)
                        {
                            progress.FormClosing += (e, o) =>
                            {
                                lock (doneSyncObject)
                                {
                                    firstProc.Exited -= closeDialogWithSuccess;
                                    done              = true;
                                }
                            };
                            var result = progress.ShowDialog((IWin32Window)sender);
                            if (result == DialogResult.Cancel)
                            {
                                cleanup(null, true);
                                return;
                            }
                        }
                        else
                        {
                            firstProc.WaitForExit();
                        }

                        this.Logger.WriteDebug("CADCreoParametricCreateAssembly.exe ExtractACM-XMLfromCreoModels has completed.");

                        if (firstProc.ExitCode == 0)
                        {
                            extractor_ran_success = true;
                        }
                        else
                        {
                            this.Logger.WriteDebug("CADCreoParametricCreateAssembly.exe ExtractACM-XMLfromCreoModels returned error code " + firstProc.ExitCode.ToString());
                            // Warn with last non-empty line, it should contain a useful error message
                            Regex lastLine = new Regex("[\\n^]([^\\n]+)(\\n|\\s)*$", RegexOptions.Singleline);
                            var   match    = lastLine.Match(exeConsoleOutput.ToString());
                            if (match != null && match.Success)
                            {
                                this.Logger.WriteWarning(match.Groups[1].Value);
                            }
                            throw new Exception("Extract executable returned error code " + firstProc.ExitCode.ToString() + ". Detailed log at " + this.Logger.LogFilenames.FirstOrDefault());
                        }
                    }
                    catch (Exception ex)
                    {
                        this.Logger.WriteError("An error occurred running Creo parametric: " + ex.Message + " - Extraction Failed. Insure you can access the Creo license server");
                        cleanup(tempXMLfile, true);
                        return;
                    }
                }
                #endregion

                //  - Use a function from CyPhy2ComponentModel to convert the extractor's XML format into a CyPhy model fragment
                #region Convert_to_XML
                // used in creating the resource object below
                CyPhy.CADModel ProcessedCADModel = null;

                if (extractor_ran_success && !test_copy_and_path_only)
                {
                    this.Logger.WriteDebug("About to call DeserializeAvmComponentXml...");
                    StreamReader  streamReader = new StreamReader(tempXMLfile);
                    avm.Component ac_import    = CyPhyComponentImporter.CyPhyComponentImporterInterpreter.DeserializeAvmComponentXml(streamReader);
                    streamReader.Close();
                    this.Logger.WriteDebug("... finished DeserializeAvmComponentXml call.");

                    foreach (var cadmodel in ac_import.DomainModel.Where(dm => dm is avm.cad.CADModel)
                             .Cast <avm.cad.CADModel>())
                    {
                        var rf = CyPhyClasses.RootFolder.GetRootFolder(CurrentProj);

                        AVM2CyPhyML.CyPhyMLComponentBuilder newComponent = new AVM2CyPhyML.CyPhyMLComponentBuilder(rf);
                        ProcessedCADModel      = newComponent.process(cadmodel, (CyPhy.Component)GetCurrentDesignElement());
                        ProcessedCADModel.Name = Path.GetFileName(AVM2CyPhyML.CyPhyMLComponentBuilder.GetCreoFileWithoutVersion(cadFilename));
                    }

                    // find the largest current Y value so our new elements are added below the existing design elements
                    foreach (var child in GetCurrentDesignElement().AllChildren)
                    {
                        foreach (MgaPart item in (child.Impl as MgaFCO).Parts)
                        {
                            int    read_x, read_y;
                            string read_str;
                            item.GetGmeAttrs(out read_str, out read_x, out read_y);
                            greatest_current_y = (read_y > greatest_current_y) ? read_y : greatest_current_y;
                        }
                    }

                    // layout CAD model to the "south" of existing elements
                    foreach (MgaPart item in (ProcessedCADModel.Impl as MgaFCO).Parts)
                    {
                        item.SetGmeAttrs(null, CAD_MODEL_START_X, greatest_current_y + CAD_MODEL_START_Y);
                    }

                    // Extend it's properties out to the component level.
                    this.CADModuleImportExtension(ProcessedCADModel);
                }
                else if (test_copy_and_path_only)
                {
                    ProcessedCADModel      = CyPhyClasses.CADModel.Create((CyPhy.Component)GetCurrentDesignElement());
                    ProcessedCADModel.Name = Path.GetFileName(AVM2CyPhyML.CyPhyMLComponentBuilder.GetCreoFileWithoutVersion(CADpath));
                }

                #endregion

                //  - Copy the Creo Model files into the component's backend folder
                //      - Note: The solution includes a function that can find this folder using the project.manifest.json file.
                //      - For nice organization, create them in a subfolder called "CAD"
                // create avmproj
                #region Copy files to backend folder

                // used in creating the resource object below
                string PathforComp = null;

                var importedCADFiles = new List <String>();
                if (extractor_ran_success)
                {
                    try
                    {
                        // create the destination path
                        PathforComp = META.ComponentLibraryManager.EnsureComponentFolder((CyPhy.Component)GetCurrentDesignElement());
                        PathforComp = ((CyPhy.Component)GetCurrentDesignElement()).GetDirectoryPath(ComponentLibraryManager.PathConvention.ABSOLUTE);

                        string finalPathName = Path.Combine(PathforComp, "CAD");

                        Directory.CreateDirectory(finalPathName);

                        // determine if one part file or all part and assembly files need to be copied
                        string cpsrcfile = System.IO.Path.GetFileName(cadFilename);

                        // copy the selected file
                        string cadFileCopyPath = System.IO.Path.Combine(finalPathName, cpsrcfile);
                        if (Path.GetFullPath(cadFilename) != Path.GetFullPath(cadFileCopyPath))
                        {
                            System.IO.File.Copy(cadFilename, cadFileCopyPath, true);
                        }

                        // Set "primary" file as the first in the list.
                        importedCADFiles.Add(Path.Combine("CAD", Path.GetFileName(cadFileCopyPath)));

                        if (fileISasm(cpsrcfile) && !test_copy_and_path_only)
                        {
                            // get a string of the XML contents
                            this.Logger.WriteDebug("About to read contents of XML file using class XmlDocument: " + tempXMLfile);

                            XmlDocument doc = new XmlDocument();
                            doc.Load(tempXMLfile);
                            string xmlcontents = doc.InnerXml;

                            // mine down to the Resource dependencies
                            using (XmlReader reader = XmlReader.Create(new StringReader(xmlcontents)))
                            {
                                // iterate through each file listed in the resourcedependency section
                                while (reader.ReadToFollowing("ResourceDependency") == true)
                                {
                                    string res_path = reader.GetAttribute("Path");
                                    this.Logger.WriteDebug("Copying this file: " + res_path);

                                    // CAD files end in .1 .2 etc. Pick the latest ones
                                    var allFiles = Directory.EnumerateFiles(Path.GetDirectoryName(res_path), "*prt." /*n.b. literal dot*/ + "*")
                                                   .Concat(Directory.EnumerateFiles(Path.GetDirectoryName(res_path), "*asm.*"))
                                                   .Select(Path.GetFileName)
                                                   .Select(filename => new { basename = filename.Substring(0, filename.LastIndexOf('.')), version = filename.Substring(filename.LastIndexOf('.') + 1) })
                                                   .Where(p => { int val; return(Int32.TryParse(p.version, out val)); })
                                                   .OrderByDescending(p => Int32.Parse(p.version))
                                                   .ToArray();
                                    foreach (var basename in allFiles.Select(p => p.basename).Distinct())
                                    {
                                        var latest = allFiles.Where(p => p.basename == basename).FirstOrDefault();
                                        if (latest != null)
                                        {
                                            string latestFilename = latest.basename + "." + latest.version;
                                            // Need to limit this down to just the filename in question
                                            // The XML file changes the name to all caps, so compare apples to apples
                                            if (latestFilename.ToUpperInvariant().StartsWith(Path.GetFileName(res_path).ToUpperInvariant()))
                                            {
                                                string destpathandname = Path.Combine(finalPathName, latestFilename);
                                                if (!importedCADFiles.Contains(Path.Combine("CAD", Path.GetFileName(destpathandname))))
                                                {
                                                    importedCADFiles.Add(Path.Combine("CAD", Path.GetFileName(destpathandname)));
                                                }
                                                var sourcepathandname = Path.Combine(Path.GetDirectoryName(res_path), latestFilename);
                                                if (Path.GetFullPath(sourcepathandname) != Path.GetFullPath(destpathandname))
                                                {
                                                    File.Copy(sourcepathandname, destpathandname, true);
                                                }
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception err_create_proj)
                    {
                        this.Logger.WriteError("Error creating AVM project: " + err_create_proj.Message, " - Extraction Failed. Possible ComponentManagement issue.");
                        cleanup(tempXMLfile, true);
                        return;
                    }
                }
                #endregion

                //  - Create Resource objects in the CyPhy Component model that point to these Creo Model files
                //      - Note: The "paths" of these should be the relative path from that component's root folder
                if (extractor_ran_success)
                {
                    foreach (var cadFile in importedCADFiles)
                    {
                        CyPhy.Resource ResourceObj = CyPhyClasses.Resource.Create((CyPhy.Component)GetCurrentDesignElement());
                        ResourceObj.Attributes.ID    = Guid.NewGuid().ToString("B");
                        ResourceObj.Attributes.Path  = AVM2CyPhyML.CyPhyMLComponentBuilder.GetCreoFileWithoutVersion(cadFile);
                        ResourceObj.Attributes.Notes = "CAD Model Import tool added this resource object for the imported CAD file";
                        ResourceObj.Name             = Path.GetFileName(AVM2CyPhyML.CyPhyMLComponentBuilder.GetCreoFileWithoutVersion(cadFile));

                        // layout Resource just to the side of the CAD model
                        foreach (MgaPart item in (ResourceObj.Impl as MgaFCO).Parts)
                        {
                            item.SetGmeAttrs(null, RESOURCE_START_X, greatest_current_y + RESOURCE_START_Y);
                        }

                        // The "primary" CAD model is the first one -- associate it with the CyPhy CADModel object
                        if (importedCADFiles.IndexOf(cadFile) == 0)
                        {
                            //  - Create a UsesResource association between the CyPhy CADModel object and the Resource object that represents the top-level Creo Model file.
                            CyPhyClasses.UsesResource.Connect(ResourceObj, ProcessedCADModel, null, null, (CyPhy.Component)GetCurrentDesignElement());
                        }
                    }
                }

                // throw in an ACM file for the current state of the component.
                if (extractor_ran_success && !test_copy_and_path_only)
                {
                    var    exporter = new CyPhyComponentExporter.CyPhyComponentExporterInterpreter();
                    String acmPath  = Path.Combine(PathforComp, GetCurrentDesignElement().Name + ".component.acm");
                    CyPhyComponentExporterInterpreter.ExportToDirectory((CyPhy.Component)GetCurrentDesignElement(), Path.GetDirectoryName(acmPath));
                }

                // Clean up
                cleanup(tempXMLfile, (extractor_ran_success && !test_copy_and_path_only));
            }
        }
예제 #2
0
        public void ImportCyberModel(string Cyberpath = null)
        {
            string CyberFilename = "";

            this.Logger = new CyPhyGUIs.GMELogger(CurrentProj, this.GetType().Name);

            //  - Display a dialog box to let the user choose their Cyber model file
            bool Cyber_file_chosen = false;

            //bool test_copy_and_path_only = false;
            if (string.IsNullOrWhiteSpace(Cyberpath))
            {
                Cyber_file_chosen = get_Cyber_file(out CyberFilename);
            }
            else
            {
                //test_copy_and_path_only = true;
                CyberFilename = Cyberpath;
                if (File.Exists(CyberFilename))
                {
                    Cyber_file_chosen = true;
                }
                else
                {
                    this.Logger.WriteError("Invalid Cyber file path passed in: " + Cyberpath);
                }
            }

            //  - Run the extractor on the Creo model file
            #region Run the Extractor

            List <string> componentList = new List <string>();
            IMgaProject   project       = (IMgaProject)Activator.CreateInstance(Type.GetTypeFromProgID("Mga.MgaProject"));
            string        compName;
            project.OpenEx("MGA=" + CyberFilename, "CyberComposition", null);
            try
            {
                project.BeginTransactionInNewTerr();
                IMgaFCO currentObj;
                try
                {
                    IMgaFolder  currentFolder = (IMgaFolder)project.RootFolder;
                    IMgaFolders cFolders      = currentFolder.ChildFolders;
                    foreach (IMgaFolder f in cFolders)
                    {
                        if (f.MetaFolder.Name == "Components")
                        {
                            IMgaFCOs objects = f.ChildFCOs;
                            foreach (IMgaFCO o in objects)
                            {
                                componentList.Add("/" + f.Name + "/" + o.Name);
                            }
                        }
                    }
                }
                finally
                {
                    project.CommitTransaction();
                }


                // Adapted from ModelicaImporter.cs
                string result = "";
                using (CyberComponentPicker cyberpicker = new CyberComponentPicker(componentList))
                {
                    var dialogResult = cyberpicker.ShowDialog();
                    if (dialogResult != System.Windows.Forms.DialogResult.OK)
                    {
                        this.Logger.WriteInfo("Modelica import was cancelled by the user.");
                        return;
                    }

                    result = cyberpicker.compResult;
                }

                var halves = result.Split('/');
                compName = halves[1];

                project.BeginTransactionInNewTerr();
                try
                {
                    currentObj = (IMgaFCO)project.RootFolder.ObjectByPath[result];
                }
                finally
                {
                    project.CommitTransaction();
                }

                IMgaComponentEx comp = (IMgaComponentEx)Activator.CreateInstance(Type.GetTypeFromProgID("MGA.Interpreter.CyberComponentExporter"));
                comp.Initialize((MgaProject)project);
                comp.InvokeEx((MgaProject)project, (MgaFCO)currentObj, null, 128);

                project.Save();
            }
            finally
            {
                project.Close(true);
            }

            #endregion

            //  - Use a function from CyPhy2ComponentModel to convert the extractor's XML format into a CyPhy model fragment
            #region Convert_to_XML
            // used in creating the resource object below
            CyPhy.CyberModel ProcessedCyberModel = null;

            if (true)
            {
                this.Logger.WriteDebug("About to call DeserializeAvmComponentXml...");
                StreamReader  streamReader = new StreamReader(compName + ".component.acm");
                avm.Component ac_import    = CyPhyComponentImporter.CyPhyComponentImporterInterpreter.DeserializeAvmComponentXml(streamReader);
                streamReader.Close();
                this.Logger.WriteDebug("... finished DeserializeAvmComponentXml call.");

                foreach (avm.cyber.CyberModel Cybermodel in ac_import.DomainModel.Where(dm => dm is avm.cyber.CyberModel)
                         .Cast <avm.cyber.CyberModel>())
                {
                    var rf = CyPhyClasses.RootFolder.GetRootFolder(CurrentProj);

                    Dictionary <string, CyPhy.Component> avmidComponentMap = new Dictionary <string, CyPhy.Component>();
                    AVM2CyPhyML.CyPhyMLComponentBuilder  newComponent      = new AVM2CyPhyML.CyPhyMLComponentBuilder(rf);
                    ProcessedCyberModel      = newComponent.process(Cybermodel, GetCurrentComp());
                    ProcessedCyberModel.Name = Path.GetFileNameWithoutExtension(CyberFilename);
                }

                // find the largest current Y value so our new elements are added below the existing design elements
                foreach (var child in GetCurrentComp().AllChildren)
                {
                    foreach (MgaPart item in (child.Impl as MgaFCO).Parts)
                    {
                        int    read_x, read_y;
                        string read_str;
                        item.GetGmeAttrs(out read_str, out read_x, out read_y);
                        greatest_current_y = (read_y > greatest_current_y) ? read_y : greatest_current_y;
                    }
                }

                // layout Cyber model to the "south" of existing elements
                foreach (MgaPart item in (ProcessedCyberModel.Impl as MgaFCO).Parts)
                {
                    item.SetGmeAttrs(null, Cyber_MODEL_START_X, greatest_current_y + Cyber_MODEL_START_Y);
                }

                // Extend it's properties out to the component level.
                this.CyberModuleImportExtension(ProcessedCyberModel);
            }

            #endregion

            //  - Copy the Cyber Model files into the component's backend folder
            //      - Note: The solution includes a function that can find this folder using the project.manifest.json file.
            //      - For nice organization, create them in a subfolder called "Cyber"
            // create avmproj
            #region Copy files to backend folder

            // used in creating the resource object below
            string PathforComp = null;

            var importedCyberFiles = new List <String>();
            if (true)
            {
                try
                {
                    // create the destination path
                    PathforComp = GetCurrentComp().GetDirectoryPath(ComponentLibraryManager.PathConvention.ABSOLUTE);

                    string finalPathName = Path.Combine(PathforComp, "Cyber");

                    Directory.CreateDirectory(finalPathName);

                    // determine if one part file or all part and assembly files need to be copied
                    string cpsrcfile = System.IO.Path.GetFileName(CyberFilename);

                    // copy the selected file
                    string CyberFileCopyPath = System.IO.Path.Combine(finalPathName, cpsrcfile);
                    System.IO.File.Copy(CyberFilename, CyberFileCopyPath, true);

                    // Set "primary" file as the first in the list.
                    importedCyberFiles.Add(Path.Combine("Cyber", Path.GetFileName(CyberFileCopyPath)));

                    if (true)
                    {
                        // get a string of the XML contents
                        this.Logger.WriteDebug("About to read contents of XML file using class XmlDocument: " + compName + ".component.acm");

                        XmlDocument doc = new XmlDocument();
                        doc.Load(compName + ".component.acm");
                        string xmlcontents = doc.InnerXml;

                        // mine down to the Resource dependencies
                        using (XmlReader reader = XmlReader.Create(new StringReader(xmlcontents)))
                        {
                            // iterate through each file listed in the resourcedependency section
                            while (reader.ReadToFollowing("ResourceDependency") == true)
                            {
                                string res_name = reader.GetAttribute("Name");
                                string res_path = reader.GetAttribute("Path");
                                this.Logger.WriteDebug("Copying this file: " + res_path + "\\" + res_name);

                                // Cyber files end in .1 .2 etc. Pick the latest ones
                                var allFiles = Directory.EnumerateFiles(Path.GetDirectoryName(res_path), "*mga." /*n.b. literal dot*/ + "*")
                                               .Select(Path.GetFileName)
                                               .Select(filename => new { basename = filename.Substring(0, filename.LastIndexOf('.')), version = filename.Substring(filename.LastIndexOf('.') + 1) })
                                               .Where(p => { int val; return(Int32.TryParse(p.version, out val)); })
                                               .OrderByDescending(p => Int32.Parse(p.version))
                                               .ToArray();
                                foreach (var basename in allFiles.Select(p => p.basename).Distinct())
                                {
                                    var latest = allFiles.Where(p => p.basename == basename).FirstOrDefault();
                                    if (latest != null)
                                    {
                                        string latestFilename = latest.basename + "." + latest.version;
                                        // Need to limit this down to just the filename in question
                                        // The XML file changes the name to all caps, so compare apples to apples
                                        if (latestFilename.ToUpper().StartsWith(res_name.ToUpper()))
                                        {
                                            string destpathandname = Path.Combine(finalPathName, latestFilename);
                                            if (!importedCyberFiles.Contains(Path.Combine("Cyber", Path.GetFileName(destpathandname))))
                                            {
                                                importedCyberFiles.Add(Path.Combine("Cyber", Path.GetFileName(destpathandname)));
                                            }
                                            File.Copy(Path.Combine(Path.GetDirectoryName(res_path), latestFilename), destpathandname, true);
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception err_create_proj)
                {
                    this.Logger.WriteError("Error creating AVM project: " + err_create_proj.Message, " - Extraction Failed. Possible ComponentManagement issue.");
                    //cleanup(tempXMLfile, true);
                    return;
                }
            }
            #endregion

            //  - Create Resource objects in the CyPhy Component model that point to these Cyber Model files
            //      - Note: The "paths" of these should be the relative path from that component's root folder
            if (true)
            {
                foreach (var CyberFile in importedCyberFiles)
                {
                    CyPhy.Resource ResourceObj = CyPhyClasses.Resource.Create(GetCurrentComp());
                    ResourceObj.Attributes.ID    = Guid.NewGuid().ToString("B");
                    ResourceObj.Attributes.Path  = CyberFile;
                    ResourceObj.Attributes.Notes = "Cyber Model Import tool added this resource object for the imported Cyber file";
                    ResourceObj.Name             = Path.GetFileName(CyberFile);

                    // layout Resource just to the side of the Cyber model
                    foreach (MgaPart item in (ResourceObj.Impl as MgaFCO).Parts)
                    {
                        item.SetGmeAttrs(null, RESOURCE_START_X, greatest_current_y + RESOURCE_START_Y);
                    }

                    // The "primary" Cyber model is the first one -- associate it with the CyPhy CyberModel object
                    if (importedCyberFiles.IndexOf(CyberFile) == 0)
                    {
                        //  - Create a UsesResource association between the CyPhy CyberModel object and the Resource object that represents the top-level Creo Model file.
                        CyPhyClasses.UsesResource.Connect(ResourceObj, ProcessedCyberModel, null, null, GetCurrentComp());
                    }
                }
            }

            // throw in an ACM file for the current state of the component.
            if (true)
            {
                var    exporter = new CyPhyComponentExporter.CyPhyComponentExporterInterpreter();
                String acmPath  = Path.Combine(PathforComp, GetCurrentComp().Name + ".component.acm");
                CyPhyComponentExporterInterpreter.ExportToFile(GetCurrentComp(), Path.GetDirectoryName(acmPath));
            }

            // Clean up
            //cleanup(tempXMLfile, true);
        }
        public void ImportCyberModel(string Cyberpath = null)
        {
            string CyberFilename = "";
            this.Logger = new CyPhyGUIs.GMELogger(CurrentProj, this.GetType().Name);

            //  - Display a dialog box to let the user choose their Cyber model file
            bool Cyber_file_chosen = false;
            //bool test_copy_and_path_only = false;
            if (string.IsNullOrWhiteSpace(Cyberpath))
            {
                Cyber_file_chosen = get_Cyber_file(out CyberFilename);
            }
            else
            {
                //test_copy_and_path_only = true;
                CyberFilename = Cyberpath;
                if (File.Exists(CyberFilename))
                {
                    Cyber_file_chosen = true;
                }
                else
                {
                    this.Logger.WriteError("Invalid Cyber file path passed in: " + Cyberpath);
                }
            }

            //  - Run the extractor on the Creo model file
            #region Run the Extractor

            List<string> componentList = new List<string>();
            IMgaProject project = (IMgaProject)Activator.CreateInstance(Type.GetTypeFromProgID("Mga.MgaProject"));
            string compName;
            project.OpenEx("MGA=" + CyberFilename, "CyberComposition", null);
            try
            {
                project.BeginTransactionInNewTerr();
                IMgaFCO currentObj;
                try
                {
                    IMgaFolder currentFolder = (IMgaFolder)project.RootFolder;
                    IMgaFolders cFolders = currentFolder.ChildFolders;
                    foreach (IMgaFolder f in cFolders)
                    {
                        if (f.MetaFolder.Name == "Components")
                        {
                            IMgaFCOs objects = f.ChildFCOs;
                            foreach (IMgaFCO o in objects)
                            {
                                componentList.Add("/" + f.Name + "/" + o.Name);
                            }
                        }
                    }  
                }
                finally
                {
                    project.CommitTransaction();
                }


                // Adapted from ModelicaImporter.cs 
                string result = "";
                using (CyberComponentPicker cyberpicker = new CyberComponentPicker(componentList))
                {
                    var dialogResult = cyberpicker.ShowDialog();
                    if (dialogResult != System.Windows.Forms.DialogResult.OK)
                    {
                        this.Logger.WriteInfo("Modelica import was cancelled by the user.");
                        return;
                    }

                    result = cyberpicker.compResult;
                }

                var halves = result.Split('/');
                compName = halves[1];

                project.BeginTransactionInNewTerr();
                try
                {
                    currentObj = (IMgaFCO)project.RootFolder.ObjectByPath[result];
                }
                finally
                {
                    project.CommitTransaction();
                }

                IMgaComponentEx comp = (IMgaComponentEx)Activator.CreateInstance(Type.GetTypeFromProgID("MGA.Interpreter.CyberComponentExporter"));
                comp.Initialize((MgaProject)project);
                comp.InvokeEx((MgaProject)project, (MgaFCO)currentObj, null, 128);

                project.Save();
            }
            finally
            {
                project.Close(true);
            }
 
            #endregion

            //  - Use a function from CyPhy2ComponentModel to convert the extractor's XML format into a CyPhy model fragment
            #region Convert_to_XML
            // used in creating the resource object below
            CyPhy.CyberModel ProcessedCyberModel = null;

            if (true)
            {
                this.Logger.WriteDebug("About to call DeserializeAvmComponentXml...");
                StreamReader streamReader = new StreamReader(compName + ".component.acm");
                avm.Component ac_import = CyPhyComponentImporter.CyPhyComponentImporterInterpreter.DeserializeAvmComponentXml(streamReader);
                streamReader.Close();
                this.Logger.WriteDebug("... finished DeserializeAvmComponentXml call.");

                foreach (avm.cyber.CyberModel Cybermodel in ac_import.DomainModel.Where(dm => dm is avm.cyber.CyberModel)
                                                                          .Cast<avm.cyber.CyberModel>())
                {
                    var rf = CyPhyClasses.RootFolder.GetRootFolder(CurrentProj);

                    Dictionary<string, CyPhy.Component> avmidComponentMap = new Dictionary<string, CyPhy.Component>();
                    AVM2CyPhyML.CyPhyMLComponentBuilder newComponent = new AVM2CyPhyML.CyPhyMLComponentBuilder(rf);
                    ProcessedCyberModel = newComponent.process(Cybermodel, GetCurrentComp());
                    ProcessedCyberModel.Name = Path.GetFileNameWithoutExtension(CyberFilename);
                }

                // find the largest current Y value so our new elements are added below the existing design elements
                foreach (var child in GetCurrentComp().AllChildren)
                {
                    foreach (MgaPart item in (child.Impl as MgaFCO).Parts)
                    {
                        int read_x, read_y;
                        string read_str;
                        item.GetGmeAttrs(out read_str, out read_x, out read_y);
                        greatest_current_y = (read_y > greatest_current_y) ? read_y : greatest_current_y;
                    }
                }

                // layout Cyber model to the "south" of existing elements
                foreach (MgaPart item in (ProcessedCyberModel.Impl as MgaFCO).Parts)
                {
                    item.SetGmeAttrs(null, Cyber_MODEL_START_X, greatest_current_y + Cyber_MODEL_START_Y);
                }

                // Extend it's properties out to the component level.
                this.CyberModuleImportExtension(ProcessedCyberModel);
            }

            #endregion

            //  - Copy the Cyber Model files into the component's backend folder
            //      - Note: The solution includes a function that can find this folder using the project.manifest.json file.
            //      - For nice organization, create them in a subfolder called "Cyber"
            // create avmproj
            #region Copy files to backend folder

            // used in creating the resource object below
            string PathforComp = null;

            var importedCyberFiles = new List<String>();
            if (true)
            {
                try
                {
                    // create the destination path
                    PathforComp = GetCurrentComp().GetDirectoryPath(ComponentLibraryManager.PathConvention.ABSOLUTE);
                    
                    string finalPathName = Path.Combine(PathforComp, "Cyber");

                    Directory.CreateDirectory(finalPathName);

                    // determine if one part file or all part and assembly files need to be copied
                    string cpsrcfile = System.IO.Path.GetFileName(CyberFilename);

                    // copy the selected file
                    string CyberFileCopyPath = System.IO.Path.Combine(finalPathName, cpsrcfile);
                    System.IO.File.Copy(CyberFilename, CyberFileCopyPath, true);

                    // Set "primary" file as the first in the list.
                    importedCyberFiles.Add(Path.Combine("Cyber", Path.GetFileName(CyberFileCopyPath)));

                    if (true)
                    {
                        // get a string of the XML contents
                        this.Logger.WriteDebug("About to read contents of XML file using class XmlDocument: " + compName + ".component.acm");

                        XmlDocument doc = new XmlDocument();
                        doc.Load(compName + ".component.acm");
                        string xmlcontents = doc.InnerXml;

                        // mine down to the Resource dependencies
                        using (XmlReader reader = XmlReader.Create(new StringReader(xmlcontents)))
                        {
                            // iterate through each file listed in the resourcedependency section
                            while (reader.ReadToFollowing("ResourceDependency") == true)
                            {
                                string res_name = reader.GetAttribute("Name");
                                string res_path = reader.GetAttribute("Path");
                                this.Logger.WriteDebug("Copying this file: " + res_path + "\\" + res_name);

                                // Cyber files end in .1 .2 etc. Pick the latest ones
                                var allFiles = Directory.EnumerateFiles(Path.GetDirectoryName(res_path), "*mga." /*n.b. literal dot*/ + "*")
                                    .Select(Path.GetFileName)
                                    .Select(filename => new { basename = filename.Substring(0, filename.LastIndexOf('.')), version = filename.Substring(filename.LastIndexOf('.') + 1) })
                                    .Where(p => { int val; return Int32.TryParse(p.version, out val); })
                                    .OrderByDescending(p => Int32.Parse(p.version))
                                    .ToArray();
                                foreach (var basename in allFiles.Select(p => p.basename).Distinct())
                                {
                                    var latest = allFiles.Where(p => p.basename == basename).FirstOrDefault();
                                    if (latest != null)
                                    {
                                        string latestFilename = latest.basename + "." + latest.version;
                                        // Need to limit this down to just the filename in question
                                        // The XML file changes the name to all caps, so compare apples to apples
                                        if (latestFilename.ToUpper().StartsWith(res_name.ToUpper()))
                                        {
                                            string destpathandname = Path.Combine(finalPathName, latestFilename);
                                            if (!importedCyberFiles.Contains(Path.Combine("Cyber", Path.GetFileName(destpathandname))))
                                            {
                                                importedCyberFiles.Add(Path.Combine("Cyber", Path.GetFileName(destpathandname)));
                                            }
                                            File.Copy(Path.Combine(Path.GetDirectoryName(res_path), latestFilename), destpathandname, true);
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception err_create_proj)
                {
                    this.Logger.WriteError("Error creating AVM project: " + err_create_proj.Message, " - Extraction Failed. Possible ComponentManagement issue.");
                    //cleanup(tempXMLfile, true);
                    return;
                }
            }
            #endregion

            //  - Create Resource objects in the CyPhy Component model that point to these Cyber Model files
            //      - Note: The "paths" of these should be the relative path from that component's root folder
            if (true)
            {
                foreach (var CyberFile in importedCyberFiles)
                {

                    CyPhy.Resource ResourceObj = CyPhyClasses.Resource.Create(GetCurrentComp());
                    ResourceObj.Attributes.ID = Guid.NewGuid().ToString("B");
                    ResourceObj.Attributes.Path = CyberFile;
                    ResourceObj.Attributes.Notes = "Cyber Model Import tool added this resource object for the imported Cyber file";
                    ResourceObj.Name = Path.GetFileName(CyberFile);

                    // layout Resource just to the side of the Cyber model
                    foreach (MgaPart item in (ResourceObj.Impl as MgaFCO).Parts)
                    {
                        item.SetGmeAttrs(null, RESOURCE_START_X, greatest_current_y + RESOURCE_START_Y);
                    }

                    // The "primary" Cyber model is the first one -- associate it with the CyPhy CyberModel object
                    if (importedCyberFiles.IndexOf(CyberFile) == 0)
                    {
                        //  - Create a UsesResource association between the CyPhy CyberModel object and the Resource object that represents the top-level Creo Model file.
                        CyPhyClasses.UsesResource.Connect(ResourceObj, ProcessedCyberModel, null, null, GetCurrentComp());
                    }
                }
            }

            // throw in an ACM file for the current state of the component.
            if (true)
            {
                var exporter = new CyPhyComponentExporter.CyPhyComponentExporterInterpreter();
                String acmPath = Path.Combine(PathforComp,GetCurrentComp().Name + ".component.acm");
                CyPhyComponentExporterInterpreter.ExportToFile(GetCurrentComp(), Path.GetDirectoryName(acmPath));
            }

            // Clean up
            //cleanup(tempXMLfile, true);
        }
예제 #4
0
        public void ImportCADModel(string CADpath = null)
        {
            string cadFilename = "";
            this.Logger = new CyPhyGUIs.GMELogger(CurrentProj, this.GetType().Name);

            //The CAT module will perform these steps, in this order:
            //  - Check that the user has Creo (so that the extraction will be successful)
            //      - Implementation Suggestion: The extraction utility may have special flag to have it indicates if all the dependencies are met
            bool creo_installed = this.CREO_present();

            //  - Display a dialog box to let the user choose their Creo model file
            bool cad_file_chosen = false;
            bool test_copy_and_path_only = false;
            if (string.IsNullOrWhiteSpace(CADpath))
            {
                cad_file_chosen = get_cad_file(out cadFilename);
            }
            else
            {
                test_copy_and_path_only = true;
                cadFilename = CADpath;
                if (File.Exists(cadFilename))
                {
                    cad_file_chosen = true;
                }
                else
                {
                    this.Logger.WriteError("Invalid CAD file path passed in: " + CADpath);
                }
            }

            //  - Run the extractor on the Creo model file
            #region Run the Extractor

            bool extractor_ran_success = test_copy_and_path_only;
            string tempXMLfile = Path.GetTempFileName(); 
            this.Logger.WriteDebug("Temporary XML file created: " + tempXMLfile);

            if (creo_installed && cad_file_chosen && !test_copy_and_path_only)
            {
                try
                {
                    // assemble the arg string
                    // first the input CAD file
                    // include quotation marks to handle paths with white spaces
                    string argstring = "-c \"";
                    argstring += cadFilename;
                    argstring += "\"";

                    // add the XML output file name
                    argstring += " -x ";
                    argstring += tempXMLfile;

                    // Debug only: pause before exit, graphics mode.
                    //argstring += " -p -g";

                    Process firstProc = new Process();

                    // NOTE: Process class does not expand environment variables, do it manually
                    string temp = Environment.GetEnvironmentVariable("PROE_ISIS_EXTENSIONS");
                    if (temp == null)
                    {
                        this.Logger.WriteError("Please set the PROE_ISIS_EXTENSIONS environment variable");
                        cleanup(tempXMLfile, true);
                        return;
                    }
                    string path = Path.Combine(temp, "bin\\ExtractACM-XMLfromCreoModels.exe");
                    if (!File.Exists(path))
                    {
                        this.Logger.WriteError("Cannot find ExtractACM-XMLfromCreoModels.exe - Check if CAD Assembler was built and files installed to PROE_ISIS_EXTENSIONS");
                        throw new Exception("ExtractACM-XMLfromCreoModels.exe not found.");
                    }

                    firstProc.StartInfo.FileName = path;
                    firstProc.StartInfo.Arguments = argstring;
                    this.Logger.WriteDebug("Calling ExtractACM-XMLfromCreoModels.exe with argument string: " + argstring);

                    firstProc.EnableRaisingEvents = true;

                    firstProc.Start();

                    firstProc.WaitForExit();

                    this.Logger.WriteDebug("ExtractACM-XMLfromCreoModels.exe has completed.");

                    if (firstProc.ExitCode == 0)
                    {
                        extractor_ran_success = true;
                    }
                    else
                    {
                        this.Logger.WriteDebug("ExtractACM-XMLfromCreoModels.exe returned error code " + firstProc.ExitCode.ToString());
                        throw new Exception("Extract executable returned error code " + firstProc.ExitCode.ToString());
                    }
                }
                catch (Exception ex)
                {
                    this.Logger.WriteError("An error occurred running Creo parametric: " + ex.Message + " - Extraction Failed. Insure you can access the Creo license server");
                    cleanup(tempXMLfile, true);
                    return;
                }
            }
            #endregion

            //  - Use a function from CyPhy2ComponentModel to convert the extractor's XML format into a CyPhy model fragment
            #region Convert_to_XML
            // used in creating the resource object below
            CyPhy.CADModel ProcessedCADModel = null;

            if (extractor_ran_success  && !test_copy_and_path_only)
            {
                this.Logger.WriteDebug("About to call DeserializeAvmComponentXml...");
                StreamReader streamReader = new StreamReader(tempXMLfile);
                avm.Component ac_import = CyPhyComponentImporter.CyPhyComponentImporterInterpreter.DeserializeAvmComponentXml(streamReader);
                streamReader.Close();
                this.Logger.WriteDebug("... finished DeserializeAvmComponentXml call.");

                foreach (var cadmodel in ac_import.DomainModel.Where(dm => dm is avm.cad.CADModel)
                                                                          .Cast<avm.cad.CADModel>())
                {
                    var rf = CyPhyClasses.RootFolder.GetRootFolder(CurrentProj);

                    Dictionary<string, CyPhy.Component> avmidComponentMap = new Dictionary<string, CyPhy.Component>();
                    AVM2CyPhyML.CyPhyMLComponentBuilder newComponent = new AVM2CyPhyML.CyPhyMLComponentBuilder(rf);
                    ProcessedCADModel = newComponent.process(cadmodel, GetCurrentComp());
                    ProcessedCADModel.Name = Path.GetFileNameWithoutExtension(cadFilename);
                }

                // find the largest current Y value so our new elements are added below the existing design elements
                foreach (var child in GetCurrentComp().AllChildren)
                {
                    foreach (MgaPart item in (child.Impl as MgaFCO).Parts)
                    {
                        int read_x, read_y;
                        string read_str;
                        item.GetGmeAttrs(out read_str, out read_x, out read_y);
                        greatest_current_y = (read_y > greatest_current_y) ? read_y : greatest_current_y;
                    }
                }

                // layout CAD model to the "south" of existing elements
                foreach (MgaPart item in (ProcessedCADModel.Impl as MgaFCO).Parts)
                {
                    item.SetGmeAttrs(null, CAD_MODEL_START_X, greatest_current_y + CAD_MODEL_START_Y);
                }

                // Extend it's properties out to the component level.
                this.CADModuleImportExtension(ProcessedCADModel);
            }
            else if (test_copy_and_path_only)
            {
                ProcessedCADModel = CyPhyClasses.CADModel.Create(GetCurrentComp());
                ProcessedCADModel.Name = Path.GetFileNameWithoutExtension(CADpath);
            }

            #endregion

            //  - Copy the Creo Model files into the component's backend folder
            //      - Note: The solution includes a function that can find this folder using the project.manifest.json file.
            //      - For nice organization, create them in a subfolder called "CAD"
            // create avmproj
            #region Copy files to backend folder

            // used in creating the resource object below
            string PathforComp = null;

            var importedCADFiles = new List<String>();
            if (extractor_ran_success)
            {
                try
                {
                    // create the destination path
                    PathforComp = META.ComponentLibraryManager.EnsureComponentFolder(GetCurrentComp());
                    PathforComp = GetCurrentComp().GetDirectoryPath(ComponentLibraryManager.PathConvention.ABSOLUTE);
                    
                    string finalPathName = Path.Combine(PathforComp, "CAD");

                    Directory.CreateDirectory(finalPathName);

                    // determine if one part file or all part and assembly files need to be copied
                    string cpsrcfile = System.IO.Path.GetFileName(cadFilename);

                    // copy the selected file
                    string cadFileCopyPath = System.IO.Path.Combine(finalPathName, cpsrcfile);
                    System.IO.File.Copy(cadFilename, cadFileCopyPath, true);

                    // Set "primary" file as the first in the list.
                    importedCADFiles.Add(Path.Combine("CAD", Path.GetFileName(cadFileCopyPath)));

                    if (fileISasm(cpsrcfile) && !test_copy_and_path_only)
                    {
                        // get a string of the XML contents
                        this.Logger.WriteDebug("About to read contents of XML file using class XmlDocument: " + tempXMLfile);

                        XmlDocument doc = new XmlDocument();
                        doc.Load(tempXMLfile);
                        string xmlcontents = doc.InnerXml;

                        // mine down to the Resource dependencies
                        using (XmlReader reader = XmlReader.Create(new StringReader(xmlcontents)))
                        {
                            // iterate through each file listed in the resourcedependency section
                            while (reader.ReadToFollowing("ResourceDependency") == true)
                            {
                                string res_name = reader.GetAttribute("Name");
                                string res_path = reader.GetAttribute("Path");
                                this.Logger.WriteDebug("Copying this file: " + res_path + "\\" + res_name);

                                // CAD files end in .1 .2 etc. Pick the latest ones
                                var allFiles = Directory.EnumerateFiles(Path.GetDirectoryName(res_path), "*prt." /*n.b. literal dot*/ + "*")
                                    .Concat(Directory.EnumerateFiles(Path.GetDirectoryName(res_path), "*asm.*"))
                                    .Select(Path.GetFileName)
                                    .Select(filename => new { basename = filename.Substring(0, filename.LastIndexOf('.')), version = filename.Substring(filename.LastIndexOf('.') + 1) })
                                    .Where(p => { int val; return Int32.TryParse(p.version, out val); })
                                    .OrderByDescending(p => Int32.Parse(p.version))
                                    .ToArray();
                                foreach (var basename in allFiles.Select(p => p.basename).Distinct())
                                {
                                    var latest = allFiles.Where(p => p.basename == basename).FirstOrDefault();
                                    if (latest != null)
                                    {
                                        string latestFilename = latest.basename + "." + latest.version;
                                        // Need to limit this down to just the filename in question
                                        // The XML file changes the name to all caps, so compare apples to apples
                                        if (latestFilename.ToUpper().StartsWith(res_name.ToUpper()))
                                        {
                                            string destpathandname = Path.Combine(finalPathName, latestFilename);
                                            if (!importedCADFiles.Contains(Path.Combine("CAD", Path.GetFileName(destpathandname))))
                                            {
                                                importedCADFiles.Add(Path.Combine("CAD", Path.GetFileName(destpathandname)));
                                            }
                                            File.Copy(Path.Combine(Path.GetDirectoryName(res_path), latestFilename), destpathandname, true);
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception err_create_proj)
                {
                    this.Logger.WriteError("Error creating AVM project: " + err_create_proj.Message, " - Extraction Failed. Possible ComponentManagement issue.");
                    cleanup(tempXMLfile, true);
                    return;
                }
            }
            #endregion

            //  - Create Resource objects in the CyPhy Component model that point to these Creo Model files
            //      - Note: The "paths" of these should be the relative path from that component's root folder
            if (extractor_ran_success)
            {
                foreach (var cadFile in importedCADFiles)
                {

                    CyPhy.Resource ResourceObj = CyPhyClasses.Resource.Create(GetCurrentComp());
                    ResourceObj.Attributes.ID = Guid.NewGuid().ToString("B");
                    ResourceObj.Attributes.Path = cadFile;
                    ResourceObj.Attributes.Notes = "CAD Model Import tool added this resource object for the imported CAD file";
                    ResourceObj.Name = Path.GetFileName(cadFile);

                    // layout Resource just to the side of the CAD model
                    foreach (MgaPart item in (ResourceObj.Impl as MgaFCO).Parts)
                    {
                        item.SetGmeAttrs(null, RESOURCE_START_X, greatest_current_y + RESOURCE_START_Y);
                    }

                    // The "primary" CAD model is the first one -- associate it with the CyPhy CADModel object
                    if (importedCADFiles.IndexOf(cadFile) == 0)
                    {
                        //  - Create a UsesResource association between the CyPhy CADModel object and the Resource object that represents the top-level Creo Model file.
                        CyPhyClasses.UsesResource.Connect(ResourceObj, ProcessedCADModel, null, null, GetCurrentComp());
                    }
                }
            }

            // throw in an ACM file for the current state of the component.
            if (extractor_ran_success && !test_copy_and_path_only)
            {
                var exporter = new CyPhyComponentExporter.CyPhyComponentExporterInterpreter();
                String acmPath = Path.Combine(PathforComp,GetCurrentComp().Name + ".component.acm");
                CyPhyComponentExporterInterpreter.ExportToFile(GetCurrentComp(), Path.GetDirectoryName(acmPath));
            }

            // Clean up
            cleanup(tempXMLfile, (extractor_ran_success && !test_copy_and_path_only));
        }