// META-2043 Extend CAD CAT module to create component-level Parameters for CAD Model's Parameters void CADModuleImportExtension(CyPhy.CADModel ProcessedCADModel) { // When the user imports a CAD Model, the current implementation creates a CyPhy CADModel object. After this point: int numComponentParams = 0; foreach (CyPhy.CADParameter parm in ProcessedCADModel.Children.CADParameterCollection) { // - For each CADParameter object, create a corresponding Property object under the parent Component. // - Give the Property the same name CyPhy.Property newprop = CyPhyClasses.Property.Create(GetCurrentComp()); newprop.Name = parm.Name; if (!String.IsNullOrWhiteSpace(parm.Attributes.Value)) { newprop.Attributes.Value = parm.Attributes.Value; } // - Create a CADParameterPortMap connection from the Property to the CADParameter CyPhy.CADParameterPortMap ppmap = CyPhyClasses.CADParameterPortMap.Connect(newprop, parm); ppmap.Name = parm.Name; // - Perform some layout "niceification" on the resulting objects. foreach (MgaPart item in (newprop.Impl as MgaFCO).Parts) { item.SetGmeAttrs(null, PARAMETER_START_X, greatest_current_y + PARAMETER_START_Y + (numComponentParams * PARAMETER_ADJUST_Y)); } numComponentParams++; } }
public static String GetResourceID(CyPhyML.CADModel cadModel) { // Starting with the DomainModel object, we'll find a Resource object to which it has a relation. // Then we'll return the path of that Resource object. List <CyPhyML.Resource> l_Resources = new List <CyPhyML.Resource>(); foreach (CyPhyML.UsesResource ur in cadModel.DstConnections.UsesResourceCollection) { l_Resources.Add(ur.DstEnds.Resource); } foreach (CyPhyML.UsesResource ur in cadModel.SrcConnections.UsesResourceCollection) { l_Resources.Add(ur.SrcEnds.Resource); } // If no Resources found, return false. // If at least one Resource was found, return the path of the first. if (l_Resources.Count == 0) { return(""); } else { return(l_Resources.FirstOrDefault().Attributes.ID); } }
public static CyPhyML.CADDatum FindDatum(CyPhyML.CADModel cadmodel, string name) { foreach (var datum in cadmodel.Children.CADDatumCollection) { if (datum.Attributes.DatumName.ToLower() == name.ToLower()) { return(datum); } } return(null); }
private void AddCadModelToComponent(CyPhy.CAD2EDATransform xform, CyPhy.CADModel cadModel, CyPhy.Component component, AbstractClasses.Component rtn) { string cadPath; bool retVal = cadModel.TryGetResourcePath(out cadPath, ComponentLibraryManager.PathConvention.REL_TO_PROJ_ROOT); if (retVal == false) { logger.WriteError("Unable to get CADModel's associated resource file path for component {0}", component.Name); } if (cadModel.Attributes.FileFormat == CyPhyClasses.CADModel.AttributesClass.FileFormat_enum.AP_203 || cadModel.Attributes.FileFormat == CyPhyClasses.CADModel.AttributesClass.FileFormat_enum.AP_214) { rtn.cadModels.Add(new AbstractClasses.STEPModel() { path = cadPath, rotationVector = new XYZTuple <Double, Double, Double>(xform.Attributes.RotationX, xform.Attributes.RotationY, xform.Attributes.RotationZ), translationVector = new XYZTuple <Double, Double, Double>(xform.Attributes.TranslationX, xform.Attributes.TranslationY, xform.Attributes.TranslationZ), scalingVector = new XYZTuple <Double, Double, Double>(xform.Attributes.ScaleX, xform.Attributes.ScaleY, xform.Attributes.ScaleZ), }); } else if (cadModel.Attributes.FileFormat == CyPhyClasses.CADModel.AttributesClass.FileFormat_enum.STL) { rtn.cadModels.Add(new AbstractClasses.STLModel() { path = cadPath, rotationVector = new XYZTuple <Double, Double, Double>(xform.Attributes.RotationX, xform.Attributes.RotationY, xform.Attributes.RotationZ), translationVector = new XYZTuple <Double, Double, Double>(xform.Attributes.TranslationX, xform.Attributes.TranslationY, xform.Attributes.TranslationZ), scalingVector = new XYZTuple <Double, Double, Double>(xform.Attributes.ScaleX, xform.Attributes.ScaleY, xform.Attributes.ScaleZ), }); } else { logger.WriteError("Visualizer currently only supports STP & STL files. Component {0} has an " + "EDAModel connected to a non-STEP/STL formatted CADModel.", component.Name); } }
public void PopulateStructuralInterface(CyPhy.CADModel cadmodel) { if (CyPhyImpl is CyPhy.Connector) { PopulateStructuralInterface(CyPhyImpl as CyPhy.Connector, cadmodel); } else if (CyPhyImpl is CyPhy.CADDatum) { PopulateStructuralInterface(CyPhyImpl as CyPhy.CADDatum, cadmodel); } }
public void PopulateStructuralInterface(CyPhy.CADDatum datum, CyPhy.CADModel acadmodel) { // META-947: Creates a virtual connector Dictionary <string, DataRep.Datum> featuremap = new Dictionary <string, DataRep.Datum>(); FindMatchingDatums(datum, acadmodel, featuremap); this.DatumList = featuremap; this.DegreeFreedom = GetDegreesOfFreedom(); }
private bool CheckComponent(CyPhy.Component cyphycomp) { bool status = true; string comppath = cyphycomp.Path; CyPhy.CADModel cadmodel = cyphycomp.Children.CADModelCollection.FirstOrDefault(x => x.Attributes.FileFormat.ToString() == cadFormat); if (cadmodel == null || cadmodel.Attributes.FileFormat.ToString() != cadFormat) { Logger.Instance.AddLogMessage("Component is missing CADModel object, it will be excluded from assembly xml: [" + comppath + "]", Severity.Normal); return(false); } return(status); }
private void FindMatchingSolidModelingFeatures(CyPhy.CADDatum datum, CyPhy.CADModel acadmodel) { // META-947: Creates a virtual connector DataRep.StructuralInterfaceConstraint sirep = new StructuralInterfaceConstraint(datum, this.Id, this.DisplayID); sirep.PopulateStructuralInterface(acadmodel); if (sirep.DatumList.Count > 0) { StructuralInterfaceNodes[datum.ID] = sirep; } }
private void CreatePointCoordinatesList(CyPhy.Component component) { CyPhy.CADModel cadmodel = component.Children.CADModelCollection.FirstOrDefault(x => x.Attributes.FileFormat.ToString() == "Creo"); if (cadmodel == null) { return; } string componentID = component.ID; string cadmodelID = cadmodel.ID; /* * var conns = component.Children.PortCompositionCollection * .Where(x => x.SrcEnd.Kind == "Point" && x.DstEnd.Kind == "Point") * .Cast<IMgaSimpleConnection>() * .Where(x => (x.Src.ParentModel.ID == componentID || x.Src.ParentModel.ID == cadmodelID) && (x.Dst.ParentModel.ID == componentID || x.Dst.ParentModel.ID == cadmodelID)); */ foreach (var p in cadmodel.Children.PointCollection) { MgaFCO pointFCO = p.Impl as MgaFCO; var connPt = pointFCO.PartOfConns .Cast <IMgaConnPoint>() .Select(x => x.Owner) .Cast <IMgaSimpleConnection>() .Where(x => ((x.Src.ID == pointFCO.ID) && (x.Dst.ParentModel.ID == componentID)) || ((x.Dst.ID == pointFCO.ID) && (x.Src.ParentModel.ID == componentID))); if (connPt.Count() > 0) { CyPhy.Point point = CyPhyClasses.Point.Cast(pointFCO); if (point != null) { TestBenchModel.TBComputation computation = new TestBenchModel.TBComputation() { ComponentID = DisplayID, ComputationType = TestBenchModel.TBComputation.Type.POINTCOORDINATES, Details = point.Attributes.DatumName, MetricID = DisplayID + ":" + point.Attributes.DatumName, RequestedValueType = "Vector" }; this.PointCoordinatesList.Add(computation); } } } }
private void FindMatchingSolidModelingFeatures(CyPhy.Connector a, CyPhy.CADModel acadmodel) { // META-947: Connector instead of StructuralInterface // [1] Connectors can be nested so find all cad datums within a connector recursively // [2] Find connected datums // Skip Connector without any Datum Ports DataRep.StructuralInterfaceConstraint sirep = new StructuralInterfaceConstraint(a, this.Id, this.DisplayID); sirep.PopulateStructuralInterface(acadmodel); if (sirep.DatumList.Count > 0) { StructuralInterfaceNodes[a.ID] = sirep; } }
// META-2043 Extend CAD CAT module to create component-level Parameters for CAD Model's Parameters void CADModuleImportExtension(CyPhy.CADModel ProcessedCADModel) { // When the user imports a CAD Model, the current implementation creates a CyPhy CADModel object. After this point: int numComponentParams = 0; foreach (CyPhy.CADParameter parm in ProcessedCADModel.Children.CADParameterCollection) { // - For each CADParameter object, create a corresponding Property object under the parent Component. // - Give the Property the same name CyPhy.Property newprop = CyPhyClasses.Property.Create((CyPhy.Component)GetCurrentDesignElement()); newprop.Name = parm.Name; if (!String.IsNullOrWhiteSpace(parm.Attributes.Value)) { newprop.Attributes.Value = parm.Attributes.Value; } if (String.IsNullOrWhiteSpace(parm.Attributes.Unit) == false) { if (map == null) { map = new CyPhyUnitMap(); map._cyPhyMLRootFolder = CyPhyClasses.RootFolder.GetRootFolder(ProcessedCADModel.Impl.Project); map.init(true); } CyPhy.unit unit; if (map._unitSymbolCyPhyMLUnitMap.TryGetValue(parm.Attributes.Unit, out unit)) { newprop.Referred.unit = unit; } } // - Create a CADParameterPortMap connection from the Property to the CADParameter CyPhy.CADParameterPortMap ppmap = CyPhyClasses.CADParameterPortMap.Connect(newprop, parm); ppmap.Name = parm.Name; // - Perform some layout "niceification" on the resulting objects. foreach (MgaPart item in (newprop.Impl as MgaFCO).Parts) { item.SetGmeAttrs(null, PARAMETER_START_X, greatest_current_y + PARAMETER_START_Y + (numComponentParams * PARAMETER_ADJUST_Y)); } numComponentParams++; } }
public void PopulateStructuralInterface(CyPhy.Connector a, CyPhy.CADModel acadmodel) { // META-947: Connector instead of StructuralInterface // [1] Connectors can be nested so find all cad datums within a connector recursively // [2] Find connected datums // Skip Connector without any Datum Ports // Limitref datums won't be considered part of the connection List <CyPhy.CADDatum> CadDatum_List = new List <CyPhy.CADDatum>(); List <CyPhy.CADDatum> LimitRefDatum_List = new List <CyPhy.CADDatum>(); FindCadDatumsInConnector(a, CadDatum_List, LimitRefDatum_List); Dictionary <string, DataRep.Datum> featuremap = new Dictionary <string, DataRep.Datum>(); Dictionary <string, DataRep.Datum> limitrefmap = new Dictionary <string, DataRep.Datum>(); foreach (CyPhy.CADDatum item in CadDatum_List) { FindMatchingDatums(item, acadmodel, featuremap); } foreach (CyPhy.CADDatum item in LimitRefDatum_List) { FindMatchingDatums(item, acadmodel, limitrefmap); } this.DatumList = featuremap; this.DegreeFreedom = GetDegreesOfFreedom(); SetupJoint(CadDatum_List, LimitRefDatum_List, limitrefmap); SetupAdjoiningTreatment(); foreach (var intfgeom in a.SrcConnections.InterfaceGeometryCollection.Union(a.DstConnections.InterfaceGeometryCollection)) { var geom = (intfgeom.SrcEnds.GeometryTypes == null) ? intfgeom.DstEnds.GeometryTypes : intfgeom.SrcEnds.GeometryTypes; if (geom != null) { Geometry.Add(CADGeometry.CreateGeometry(geom)); } } }
private void ParseAraTemplateComponent(CyPhy.Component component, AbstractClasses.AraTemplateComponent rtn) { // 1) Check only one CADModel (must be STEP) // 2) Grab CADModel resource (path to stock STEP file) // 3) Grab parameters in CADModel // 1 IEnumerable <CyPhy.CADModel> cadModels = component.Children.CADModelCollection; if (cadModels.Count() == 0 || cadModels.Count() > 1) { logger.WriteError("Ara template component {0} must have one and only one CADModel.", component.Name); } CyPhy.CADModel cadModel = cadModels.First(); if (cadModel.Attributes.FileFormat != CyPhyClasses.CADModel.AttributesClass.FileFormat_enum.AP_203 && cadModel.Attributes.FileFormat != CyPhyClasses.CADModel.AttributesClass.FileFormat_enum.AP_214) { logger.WriteError("Ara template component {0} points to a non-STEP formatted component. Template " + "components must reference a STEP file only.", component.Name); } // 2 string cadPath; bool retVal = cadModel.TryGetResourcePath(out cadPath, ComponentLibraryManager.PathConvention.REL_TO_PROJ_ROOT); if (retVal == false) { logger.WriteError("Unable to get CADModel's associated resource file path for component {0}", component.Name); } rtn.cadModels.Add(new AbstractClasses.STEPModel() { path = Path.Combine("..", "..", cadPath) }); // 3 rtn.parameters = new List <string>(); foreach (var param in cadModel.Children.CADParameterCollection) { rtn.parameters.Add(param.Name); } }
private AbstractClasses.Component ParseCyPhyComponent(CyPhy.Component component) { string classification = component.Attributes.Classifications.ToString(); if (String.Compare(classification, "ara_template") == 0 || String.Compare(classification, "template.ara_module_template") == 0) { // Stock module present for component replacement. AbstractClasses.AraTemplateComponent template = new AbstractClasses.AraTemplateComponent() { name = component.Attributes.InstanceGUID, classification = classification }; ParseAraTemplateComponent(component, template); return(template); } AbstractClasses.Component rtn = new AbstractClasses.Component() { // MOT-656 Switch to using component GUID as map key. Each component guaranteed to have a GUID, no need to check. name = component.Attributes.InstanceGUID, classification = classification }; // Check for only one EDAModel IEnumerable <CyPhy.EDAModel> edas = component.Children.EDAModelCollection; if (edas.Count() > 1) { logger.WriteError("Multiple EDAModels found for component {0}. Component should " + "only have one EDAModel.", component.Name); return(null); } IEnumerable <CyPhy.CAD2EDATransform> xforms = component.Children.CAD2EDATransformCollection; if (xforms.Count() == 0) { if (edas.Count() == 0) { logger.WriteInfo("Skipping component {0}, no EDAModel or CAD2EDATransform objects found.", component.Name); } else { logger.WriteWarning("EDAModel found for component {0} with no CAD2EDATransform, will generate " + "placeholder in visualizer based on EDAModel dimensions.", component.Name); CyPhy.EDAModel edaModel = edas.First(); } } else { // At this point you know all transforms point to the same EDAModel. The language also only // allows for one transform connection per CAD model, so you know there are no duplicate // transforms. foreach (var xform in xforms) { CyPhy.CADModel cadModel = xform.SrcEnds.CADModel; AddCadModelToComponent(xform, cadModel, component, rtn); } } return(rtn); }
private bool FindMatchingDatums(CyPhy.CADDatum datum, CyPhy.CADModel cadmodel, Dictionary <string, DataRep.Datum> featuremap) { string cadmodel_id = cadmodel.ID; string alignment = "ALIGN"; string orientation = "NONE"; if (datum.Kind == "Surface") { alignment = (datum as CyPhy.Surface).Attributes.Alignment.ToString(); if (alignment == "MATE") { Logger.Instance.AddLogMessage("MATE alignment is used on surface: " + datum.ToHyperLink() + ". This construct is obsolete, please set up the connection as ALIGN.", Severity.Warning); } } CadDatumTraversal traversal = new CadDatumTraversal(datum, cadmodel_id); if (traversal.datumFound.Count > 0) { if (traversal.datumFound.Count > 1) { Logger.Instance.AddLogMessage("Connector datum connected to multiple datums in the same CADModel [" + datum.Path + "]", Severity.Error); return(true); // Error } // META-3232 /* * DataRep.Datum datumRep = new DataRep.Datum(traversal.datumFound.First().Attributes.DatumName, * datum.Kind, * this.ParentInstanceGUID, guide); */ bool guide = datum.Attributes.DefinitionNotes.Contains("GUIDE"); if (guide) { Logger.Instance.AddLogMessage("Datum is using old guide format. Please use the attribute 'IsGuide'. [" + datum.Path + "]", Severity.Error); return(true); // Error } guide |= datum.Attributes.IsGuide; DataRep.Datum datumRep = new DataRep.Datum(traversal.datumFound.First(), this.ParentInstanceGUID, guide); if (datum.Kind == "Surface") { if (traversal.ReverseMap) { orientation = "SIDE_B"; } else { orientation = "SIDE_A"; } } if (datum.Kind == "CoordinateSystem") { alignment = "CSYS"; } datumRep.Alignment = alignment; datumRep.Orientation = orientation; if (!featuremap.ContainsKey(datum.Name)) { featuremap[datum.Name] = datumRep; } } return(false); }
private Edit CreateComponentEditMessage(string instanceId, CyPhyML.Component component, CyPhyML.CADModel cadModel) { string cadModelRelativePath = ""; if (false == cadModel.TryGetResourcePath(out cadModelRelativePath) || cadModelRelativePath == "") { // TODO log //return null; } var message = new Edit() { editMode = MetaLinkProtobuf.Edit.EditMode.POST, guid = Guid.NewGuid().ToString(), //sequence = 0, }; message.origin.Add(GMEOrigin); message.topic.Add(instanceId); edu.vanderbilt.isis.meta.Action action = new edu.vanderbilt.isis.meta.Action(); message.actions.Add(action); action.actionMode = MetaLinkProtobuf.Action.ActionMode.UPDATE_CAD_COMPONENT; action.subjectID = component.Attributes.AVMID; action.environment.Add(new edu.vanderbilt.isis.meta.Environment() { name = SearchPathStr, }); AddSearchPathToEnvironment(component, action.environment[0]); if (cadModelRelativePath.Length != 0) { action.payload = new Payload(); CADComponentType cadComponent = new CADComponentType() { AvmComponentID = component.Attributes.AVMID, CADModelID = CyphyMetaLinkUtils.GetResourceID(cadModel), // Using CADModelID to transport this information (the resource id) Name = Path.GetFileNameWithoutExtension(cadModelRelativePath), // the partial creo file name (less .prt or .asm) Type = (Path.GetExtension(cadModelRelativePath).EndsWith(".prt") || Path.GetExtension(cadModelRelativePath).EndsWith(".PRT")) ? "PART" : "ASSEMBLY" }; foreach (var connector in component.Children.ConnectorCollection) { cadComponent.Connectors.Add(new ConnectorType() { ID = connector.Guid.ToString(), DisplayName = connector.Name }); } foreach (var datum in cadModel.Children.CADDatumCollection) { cadComponent.Datums.Add(new ConnectorDatumType() { ID = datum.Attributes.DatumName, DisplayName = datum.Name }); } action.payload.components.Add(cadComponent); } return(message); }
// 8/16/13 private void TraverseComponentAssemblyForComponentExport(ComponentIndex compindex, CyPhy.ComponentAssembly componentasm, string OutputDirectory, string ProjectDirectory) { foreach (CyPhy.ComponentRef cref in componentasm.Children.ComponentRefCollection) { throw new Exception("Model not fully elaborated, contains ComponentRef [" + cref.Path + "]"); } foreach (CyPhy.ComponentAssembly cainst in componentasm.Children.ComponentAssemblyCollection) { TraverseComponentAssemblyForComponentExport(compindex, cainst, OutputDirectory, ProjectDirectory); } foreach (CyPhy.Component cint in componentasm.Children.ComponentCollection) { var console = GMEConsole.CreateFromProject(cint.Impl.Project); string comp_inst_loc = cint.Attributes.InstanceGUID; //Component Instance char[] charsToTrim = { '{', '}' }; string ACMDir = Path.Combine(OutputDirectory, "ComponentACMs"); //create folder for component acm's if (!Directory.Exists(ACMDir)) { Directory.CreateDirectory(ACMDir); } string avmid = cint.Attributes.AVMID; string newACMComponentFileLocation; char[] charsToTrim1 = { '{', '}' }; string RandACMFileName = System.IO.Path.GetRandomFileName() + ".component.acm"; newACMComponentFileLocation = Path.Combine(ACMDir, RandACMFileName); String classification = ""; try { // First, try to copy the original ACM file, if found. // If not, then export a new one. CAD model must be present. string originalACMFilePath = ""; if (META.ComponentLibraryManager.TryGetOriginalACMFilePath(cint, out originalACMFilePath, META.ComponentLibraryManager.PathConvention.ABSOLUTE, ProjectDirectory: ProjectDirectory)) { File.Copy(originalACMFilePath, newACMComponentFileLocation); classification = cint.Attributes.Classifications.Split('\n').FirstOrDefault(); } else { const string cadFormat = "Creo"; CyPhy.CADModel cadmodel = cint.Children.CADModelCollection.FirstOrDefault(x => x.Attributes.FileFormat.ToString() == cadFormat); if (cadmodel == null || cadmodel.Attributes.FileFormat.ToString() != cadFormat) { console.Warning.WriteLine("Skipping component export for {0}. No original ACM file found and no CAD model present in component.", Safeify(cint.Name)); continue; } else { var avmComponentModel = CyPhyML2AVM.AVMComponentBuilder.CyPhyML2AVM(cint); SerializeAvmComponent(avmComponentModel, newACMComponentFileLocation); classification = avmComponentModel.Classifications.FirstOrDefault(); } } } catch (Exception ex) { //var console = GMEConsole.CreateFromProject(cint.Impl.Project); console.Warning.WriteLine("Unable to find original ACM file or export a new one for {0}. Reason: {1} Moving to next component.", Safeify(cint.Name), Safeify(ex.Message)); continue; } System.Uri acm = new Uri(newACMComponentFileLocation); System.Uri acm_folder = new Uri(ACMDir); string relative_path = Uri.UnescapeDataString(acm_folder.MakeRelativeUri(acm).ToString()); compindex.AddMember(cint.Name, cint.Attributes.AVMID, cint.Attributes.InstanceGUID, relative_path, classification); //add component to index compindex.Serialize(); compindex.SerializeToFile(Path.Combine(OutputDirectory, "component_index.json")); } }
public void RenameCADFile(string CADpath = null, string NewName = null) { string StartingCadFilename = ""; string CadFilenamePath = ""; string cad_extension = ""; string RenamedCadFilename = ""; this.Logger = new CyPhyGUIs.GMELogger(CurrentProj, this.GetType().Name); // Get the file name desirous of changing #region get_name // - Display a dialog box to let the user choose their Creo model file bool cad_file_chosen = false; bool test_mode_only = false; if (string.IsNullOrWhiteSpace(CADpath)) { cad_file_chosen = get_cad_file(out StartingCadFilename); } else { test_mode_only = true; StartingCadFilename = CADpath.Replace("/", "\\"); if (File.Exists(StartingCadFilename)) { cad_file_chosen = true; } else { if (!test_mode_only) { this.Logger.WriteError("Invalid CAD file path passed in: " + CADpath); } } } #endregion // check chosen file constraints #region check_constraints if (cad_file_chosen) { // - file chosen is in the component folder structure string must_be_in_dir = ((CyPhy.Component)GetCurrentDesignElement()).GetDirectoryPath(ComponentLibraryManager.PathConvention.ABSOLUTE).Replace("/", "\\"); if (!StartingCadFilename.Contains(must_be_in_dir)) { if (!test_mode_only) { this.Logger.WriteError("File to rename must reside in current component's folder:" + must_be_in_dir); } //cleanup cleanup(false); return; } // - file chosen is a CREO .prt or .asm file if (!(StartingCadFilename.Contains(".prt") || StartingCadFilename.Contains(".asm"))) { if (!test_mode_only) { this.Logger.WriteError("File to rename must be a CAD .prt or .asm file only"); } //cleanup cleanup(false); return; } } #endregion // Get new desired name #region get_new_name if (cad_file_chosen) { string new_file_name = ""; if (test_mode_only) { new_file_name = NewName; } else { new_file_name = GetNewFilename(); } if (!String.IsNullOrEmpty(new_file_name)) { // massage new name CadFilenamePath = Path.GetDirectoryName(StartingCadFilename); // - strip off the CREO version extension string just_the_name = Path.GetFileNameWithoutExtension(new_file_name); // - retain the original extension type (.prt or .asm) cad_extension = FileExtensionType(StartingCadFilename); // construct the new file name RenamedCadFilename = Path.Combine(CadFilenamePath, just_the_name) + cad_extension + ".1"; // - verify chosen name does not alreay exist if (File.Exists(RenamedCadFilename)) { if (!test_mode_only) { this.Logger.WriteError("Chosen new filename already exists: ", RenamedCadFilename); } //cleanup cleanup(false); return; } } else { if (!test_mode_only) { this.Logger.WriteError("Chosen new filename is invalid or null: ", RenamedCadFilename); } //cleanup cleanup(false); return; } } #endregion // change model and resource names and path to match new name if (cad_file_chosen) { // Step 1 - Look for a Resource object that has a "Path" attribute that matches the "old path". //- Does the file path chosen match the "Path" attribute of a Resource? // - If not, quit. CyPhy.Resource ResourceObj = null; var resourcePath = ComponentLibraryManager.MakeRelativePath( ((CyPhy.Component)GetCurrentDesignElement()).GetDirectoryPath(ComponentLibraryManager.PathConvention.ABSOLUTE), AVM2CyPhyML.CyPhyMLComponentBuilder.GetCreoFileWithoutVersion(StartingCadFilename)); // n.b. current dir doesn't matter, we just want to canonicalize .. . / et al resourcePath = Path.GetFullPath(resourcePath); try { ResourceObj = GetCurrentDesignElement().Children.ResourceCollection .Where(p => Path.GetFullPath(AVM2CyPhyML.CyPhyMLComponentBuilder.GetCreoFileWithoutVersion(p.Attributes.Path)) == resourcePath).First(); } catch (InvalidOperationException ex) { if (!test_mode_only) { this.Logger.WriteError("No resource found with that CAD file path", ComponentLibraryManager.MakeRelativePath( ((CyPhy.Component)GetCurrentDesignElement()).GetDirectoryPath(ComponentLibraryManager.PathConvention.ABSOLUTE), StartingCadFilename), ex.Message); } cleanup(false); return; } // Step 2 - Check if the Resource is attached to a CADModel. // - If not, quit. bool ResourceConnected2Model = true; // first check if Resource is Source, Model is Destination try { ResourceConnected2Model = ResourceObj.DstConnections.UsesResourceCollection.Where(c => c.DstEnds.CADModel != null).Any(); } catch (Exception ex) { ResourceConnected2Model = false; if (!test_mode_only) { this.Logger.WriteError("No connection from this Resource to a CAD model", ex.Message); } } // check opposite direction if connection not found if (!ResourceConnected2Model) { // next check if Resource is Destination, Model is Source try { ResourceConnected2Model = ResourceObj.SrcConnections.UsesResourceCollection.Where(c => c.SrcEnds.CADModel != null).Any(); ResourceConnected2Model = true; } catch (Exception ex) { if (!test_mode_only) { this.Logger.WriteError("No connection from this Resource to a CAD model", ex.Message); } cleanup(true); return; } } // Step 3 - rename the file in the folder try { //TODO commented out for debug File.Move(StartingCadFilename, RenamedCadFilename); } catch (Exception ex) { // the rename failed. bail out this.Logger.WriteError("Error renaming CAD file:", Path.GetFileName(StartingCadFilename), ex.Message); cleanup(true); return; } // Step 4 - Change that "Path" attribute to the new name. // change the resource name and path // Path name needs to be relative to component folder string new_path = ComponentLibraryManager.MakeRelativePath(((CyPhy.Component)GetCurrentDesignElement()).GetDirectoryPath(ComponentLibraryManager.PathConvention.ABSOLUTE), AVM2CyPhyML.CyPhyMLComponentBuilder.GetCreoFileWithoutVersion(RenamedCadFilename)); ResourceObj.Attributes.Path = new_path; // Step 5 - If the Resource name happens to be the filename, change it too. if (AVM2CyPhyML.CyPhyMLComponentBuilder.GetCreoFileWithoutVersion(ResourceObj.Name) == Path.GetFileName(AVM2CyPhyML.CyPhyMLComponentBuilder.GetCreoFileWithoutVersion(StartingCadFilename))) { ResourceObj.Name = Path.GetFileName(AVM2CyPhyML.CyPhyMLComponentBuilder.GetCreoFileWithoutVersion(RenamedCadFilename)); } // Step 6 - If the CAD Model name happens to be the filename, change it too. // change the model name CyPhy.CADModel ModelObj = null; bool ModelObjExists = true; var modelObjName = AVM2CyPhyML.CyPhyMLComponentBuilder.GetCreoFileWithoutVersion(Path.GetFileName(StartingCadFilename)); try { // FIXME: check that it is connected to ResourceObj ModelObj = GetCurrentDesignElement().Children.CADModelCollection.Where(p => p.Name == modelObjName).First(); } // check if ModelObj exists catch (InvalidOperationException) { ModelObjExists = false; if (!test_mode_only) { // this doesn't matter, don't confuse the user // this.Logger.WriteWarning("Cannot rename CADModel, because there is no CADModel named '{0}'", modelObjName, ex.Message); } } if (ModelObjExists) { ModelObj.Name = AVM2CyPhyML.CyPhyMLComponentBuilder.GetCreoFileWithoutVersion(Path.GetFileName(RenamedCadFilename)); } } //cleanup cleanup(cad_file_chosen && !test_mode_only); return; }
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)); } }
private void CreateStructuralInterfaceEquivalent(CyPhy.Component cyphycomp) { CyPhy.CADModel cadmodel = cyphycomp.Children.CADModelCollection.FirstOrDefault(x => x.Attributes.FileFormat.ToString() == "Creo"); if (cadmodel != null) { string uri; cadmodel.TryGetResourcePath(out uri); char[] start = new char[] { '/', '\\' }; if (!String.IsNullOrEmpty(uri)) { uri = uri.TrimStart(start); string absPath; cadmodel.TryGetResourcePath(out absPath, ComponentLibraryManager.PathConvention.ABSOLUTE); var hyperlink = cyphycomp.ToHyperLink(Traceability); missingFile = Task.Run(() => CheckFileExists(hyperlink, uri, absPath)); // META-1382 //ModelName = UtilityHelpers.CleanString2(Path.GetFileNameWithoutExtension(uri)); ModelName = Path.GetFileName(uri); List <string> tokens_2 = ModelName.Split('.').ToList <string>(); int index = tokens_2.FindIndex(x => x.ToUpper() == "PRT"); if (index != -1) { ModelType = "Part"; ModelName = string.Join("", tokens_2.GetRange(0, index).ToArray()); } else { index = tokens_2.FindIndex(x => x.ToUpper() == "ASM"); if (index != -1) { ModelType = "Assembly"; ModelName = string.Join("", tokens_2.GetRange(0, index).ToArray()); } } // It shouldn't be an empty string if (ModelType.Length == 0) { ModelType = "Part"; } } else { Logger.Instance.AddLogMessage("CADModel Resource Path information unavailable for component [" + cyphycomp.Path + "," + DisplayID + "]!", Severity.Warning); } ModelURI = uri.Length > 0 ? Path.GetDirectoryName(uri) : ""; //ModelType = cadmodel.Attributes.FileType.ToString(); foreach (var param in cadmodel.Children.CADParameterCollection) { CADParameter acadparam = new CADParameter(param); CadParameters.Add(acadparam); } // META-947: Connector replaced StructuralInterface // Not dealing with nested Connectors right now. // foreach (var item in cyphycomp.Children.StructuralInterfaceCollection) foreach (CyPhy.Connector item in cyphycomp.Children.ConnectorCollection) { FindMatchingSolidModelingFeatures(item, cadmodel); } foreach (CyPhy.CADDatum item in cyphycomp.Children.CADDatumCollection) { // only Coordinate System is supported if (item is CyPhy.CoordinateSystem) { FindMatchingSolidModelingFeatures(item, cadmodel); } //else // Logger.Instance.AddLogMessage("Only CoordinateSystem datums outside of a Connector are supported, other datum types not supported.", Severity.Warning); } // Materials if (cyphycomp.Children.MaterialRefCollection.Any()) { CyPhy.MaterialRef matRef = cyphycomp.Children.MaterialRefCollection.First(); CyPhy.Material material = matRef.Referred.Material; if (material != null) { this.MaterialName = material.Attributes.Name; } } } }