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)); } }
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); }
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)); }