class ExportCAFMethod (object): def __init__(self, name="name", tol=1.0E-10): self.name = name self.step = STEPCAFControl_Writer() self.step.SetNameMode(True) self.h_doc = TDocStd_Document() self.x_app = XCAFApp_Application.GetApplication().GetObject() self.x_app.NewDocument( TCollection_ExtendedString("MDTV-CAF"), self.h_doc) self.doc = self.h_doc.GetObject() self.h_shape_tool = XCAFDoc_DocumentTool_ShapeTool(self.doc.Main()) self.shape_tool = self.h_shape_tool.GetObject() Interface_Static_SetCVal("write.step.schema", "AP214") def Add(self, shape, name="name"): """ STEPControl_AsIs translates an Open CASCADE shape to its highest possible STEP representation. STEPControl_ManifoldSolidBrep translates an Open CASCADE shape to a STEP manifold_solid_brep or brep_with_voids entity. STEPControl_FacetedBrep translates an Open CASCADE shape into a STEP faceted_brep entity. STEPControl_ShellBasedSurfaceModel translates an Open CASCADE shape into a STEP shell_based_surface_model entity. STEPControl_GeometricCurveSet translates an Open CASCADE shape into a STEP geometric_curve_set entity. """ label = self.shape_tool.AddShape(shape) self.step.Transfer(self.h_doc, STEPControl_AsIs) def Write(self, filename=None): if not filename: filename = self.name path, ext = os.path.splitext(filename) if not ext: ext = ".stp" status = self.step.Write(path + ext) assert(status == IFSelect_RetDone)
def test_write_step_file(self) -> None: """Exports a colored box into a STEP file""" ### initialisation doc = TDocStd_Document(TCollection_ExtendedString("pythonocc-doc")) self.assertTrue(doc is not None) # Get root assembly shape_tool = XCAFDoc_DocumentTool.ShapeTool(doc.Main()) colors = XCAFDoc_DocumentTool.ColorTool(doc.Main()) ### create the shape to export test_shape = BRepPrimAPI_MakeBox(100.0, 100.0, 100.0).Shape() ### add shape shp_label = shape_tool.AddShape(test_shape) ### set a color for this shape r = 1.0 g = b = 0.5 red_color = Quantity_Color(r, g, b, Quantity_TypeOfColor.Quantity_TOC_RGB) colors.SetColor(shp_label, red_color, XCAFDoc_ColorGen) # write file WS = XSControl_WorkSession() writer = STEPCAFControl_Writer(WS, False) writer.Transfer(doc, STEPControl_AsIs) status = writer.Write("./test_io/test_ocaf_generated.stp") self.assertTrue(status) self.assertTrue(os.path.isfile("./test_io/test_ocaf_generated.stp"))
def doc_linter(self, doc=None): """Clean self.doc by cycling through a STEP save/load cycle.""" if doc is None: doc = self.doc # Create a file object to save to fname = "deleteme.txt" # Initialize STEP exporter WS = XSControl_WorkSession() step_writer = STEPCAFControl_Writer(WS, False) # Transfer shapes and write file step_writer.Transfer(doc, STEPControl_AsIs) status = step_writer.Write(fname) assert status == IFSelect_RetDone # Create new TreeModel and read STEP data tmodel = TreeModel("DOC") shape_tool = tmodel.shape_tool color_tool = tmodel.color_tool step_reader = STEPCAFControl_Reader() step_reader.SetColorMode(True) step_reader.SetLayerMode(True) step_reader.SetNameMode(True) step_reader.SetMatMode(True) status = step_reader.ReadFile(fname) if status == IFSelect_RetDone: logger.info("Transfer doc to STEPCAFControl_Reader") step_reader.Transfer(tmodel.doc) os.remove(fname) return tmodel.doc
def test_write_step_file(self): ''' Exports a colored box into a STEP file ''' ### initialisation h_doc = Handle_TDocStd_Document() assert (h_doc.IsNull()) # Create the application app = XCAFApp_Application.GetApplication().GetObject() app.NewDocument(TCollection_ExtendedString("MDTV-CAF"), h_doc) # Get root assembly doc = h_doc.GetObject() h_shape_tool = XCAFDoc_DocumentTool_ShapeTool(doc.Main()) l_Colors = XCAFDoc_DocumentTool_ColorTool(doc.Main()) shape_tool = h_shape_tool.GetObject() colors = l_Colors.GetObject() ### create the shape to export test_shape = BRepPrimAPI_MakeBox(100., 100., 100.).Shape() ### add shape shp_label = shape_tool.AddShape(test_shape) ### set a color for this shape r = 1 g = b = 0.5 red_color = Quantity_Color(r, g, b, 0) colors.SetColor(shp_label, red_color, XCAFDoc_ColorGen) # write file WS = XSControl_WorkSession() writer = STEPCAFControl_Writer(WS.GetHandle(), False) writer.Transfer(h_doc, STEPControl_AsIs) status = writer.Write("./test_io/test_ocaf_generated.stp") assert status assert os.path.isfile("./test_io/test_ocaf_generated.stp")
def transfer_step(self, schema='AP203', units=None): """ Transfer the document in preparation for STEP export. :param str schema: Schema for STEP file ('AP203', or 'AP214'). :param units: Units to convert STEP file to. :type units: str or None :return: *True* if transferred, *False* otherwise. :rtype: bool """ self._step_writer = STEPCAFControl_Writer() self._step_writer.SetNameMode(True) self._step_writer.SetColorMode(True) Interface_Static.SetCVal('write.step.schema', schema) try: units = units_dict[units] except KeyError: units = Settings.units Interface_Static.SetCVal('write.step.unit', units) self._step_writer.Transfer(self._doc) tw = self._step_writer.ChangeWriter().WS().TransferWriter() self._step_fp = tw.FinderProcess() return True
def __init__(self, name="name", tol=1.0E-10): self.name = name self.step = STEPCAFControl_Writer() self.step.SetNameMode(True) self.doc = TDocStd_Document(TCollection_ExtendedString("")) self.x_app = XCAFApp_Application.GetApplication() self.x_app.NewDocument(TCollection_ExtendedString("MDTV-CAF"), self.doc) self.shape_tool = XCAFDoc_DocumentTool_ShapeTool(self.doc.Main()) Interface_Static_SetCVal("write.step.schema", "AP214") Interface_Static_SetCVal('write.step.unit', 'mm')
def testRTStep(self, doc): """A 'short-circuit' Round Trip test. Write doc back to step file.""" fname = "../testRoundTrip.stp" # initialize the STEP exporter step_writer = STEPCAFControl_Writer() # transfer shapes and write file step_writer.Transfer(doc) status = step_writer.Write(fname) assert (status == IFSelect_RetDone)
def saveStep(self): """Export self.doc to STEP file.""" prompt = 'Choose filename for step file.' fnametuple = QFileDialog.getSaveFileName( None, prompt, './', "STEP files (*.stp *.STP *.step)") fname, _ = fnametuple if not fname: print("Save step cancelled.") return # Reconstruct XCAFDoc related code from stepXD.StepImporter labels = TDF_LabelSequence() shape_tool = XCAFDoc_DocumentTool_ShapeTool(self.doc.Main()) shape_tool.GetShapes(labels) logger.info('Number of labels at root : %i', labels.Length()) try: rootlabel = labels.Value(1) # First label at root except RuntimeError: return name = rootlabel.GetLabelName() logger.info('Name of root label: %s', name) isAssy = shape_tool.IsAssembly(rootlabel) logger.info("First label at root holds an assembly? %s", isAssy) # Modify self.doc by adding active part to rootlabel. #Standard_Boolean expand = Standard_False; //default #TDF_Label aLabel = myAssembly->AddComponent (aShape [,expand]); newLabel = shape_tool.AddComponent(rootlabel, self.activePart, True) #set a name to newlabel (as a reminder using OCAF), use: #TCollection_ExtendedString aName ...; #// contains the desired name for this Label (ASCII) #TDataStd_Name::Set (aLabel, aName); newName = TCollection_ExtendedString( self._nameDict[self.activePartUID]) TDataStd_Name.Set(newLabel, newName) logger.info('Name of new part: %s', newName) #myAssembly->UpdateAssemblies(); shape_tool.UpdateAssemblies() # initialize the STEP exporter step_writer = STEPCAFControl_Writer() # transfer shapes and write file step_writer.Transfer(self.doc) status = step_writer.Write(fname) assert status == IFSelect_RetDone
def saveStepDoc(self): """Export self.doc to STEP file.""" prompt = 'Choose filename for step file.' fnametuple = QFileDialog.getSaveFileName( None, prompt, './', "STEP files (*.stp *.STP *.step)") fname, _ = fnametuple if not fname: print("Save step cancelled.") return # initialize STEP exporter WS = XSControl_WorkSession() step_writer = STEPCAFControl_Writer(WS, False) # transfer shapes and write file step_writer.Transfer(self.doc, STEPControl_AsIs) status = step_writer.Write(fname) assert status == IFSelect_RetDone
def write_file(self): r"""Write file""" work_session = XSControl_WorkSession() writer = STEPCAFControl_Writer(work_session.GetHandle(), False) transfer_status = writer.Transfer(self.h_doc, STEPControl_AsIs) if transfer_status != IFSelect_RetDone: msg = "An error occurred while transferring a shape " \ "to the STEP writer" logger.error(msg) raise StepShapeTransferException(msg) logger.info('Writing STEP file') write_status = writer.Write(self.filename) if write_status == IFSelect_RetDone: logger.info("STEP file write successful.") else: msg = "An error occurred while writing the STEP file" logger.error(msg) raise StepFileWriteException(msg)
def export_STEPFile_single(shape, filename, tol=1.0E-6): """ Exports a .stp file containing the input shapes Parameters ---------- shape : TopoDS_Shape filename : string The output filename """ step = STEPCAFControl_Writer() step.SetNameMode(True) step.SetPropsMode(True) h_doc = TDocStd_Document() x_app = XCAFApp_Application.GetApplication().GetObject() x_app.NewDocument(TCollection_ExtendedString("MDTV-CAF"), h_doc) doc = h_doc.GetObject() h_shape_tool = XCAFDoc_DocumentTool_ShapeTool(doc.Main()) shape_tool = h_shape_tool.GetObject() Interface_Static_SetCVal("write.step.schema", "AP214") # transfer shapes print(filename) shape_tool.AddShape(shape) step.Transfer(h_doc, STEPControl_AsIs) status = step.Write(filename) assert(status == IFSelect_RetDone)
def externalGeometryAssembly(self): # Create a TDoc holding the assembly of structure parts with external geometry. When assembled, write the STEP file # Initialize the writer shapes = [] step_writer = STEPCAFControl_Writer() step_writer.SetNameMode(True) step_writer.SetPropsMode(True) # create the handle to a document doc = TDocStd_Document(TCollection_ExtendedString("ocx-doc")) # Get root assembly shape_tool = XCAFDoc_DocumentTool_ShapeTool(doc.Main()) shape_tool.SetAutoNaming(False) l_colors = XCAFDoc_DocumentTool_ColorTool(doc.Main()) l_layers = XCAFDoc_DocumentTool_LayerTool(doc.Main()) l_materials = XCAFDoc_DocumentTool_MaterialTool(doc.Main()) aBuilder = BRep_Builder() # Loop over all Panels panelchildren = [] for panel in self.model.panels: OCXCommon.LogMessage(panel, self.logging) guid = self.model.getGUID(panel) children = self.model.getPanelChildren(guid) panelchildren = panelchildren + children # Build the Panel compound compound = TopoDS_Compound() aBuilder.MakeCompound(compound) label = shape_tool.AddShape(compound) pname = panel.get('name') tname = TDataStd_Name() tname.Set(TCollection_ExtendedString(pname)) label.AddAttribute(tname) for child in children: object = self.model.getObject(child) name = object.get('name') extg = ExternalGeometry(self.model, object, self.dict, self.logging) # Init the creator extg.readExtGeometry() # Read the Brep if extg.IsDone(): aBuilder.Add(compound, extg.Shape()) tname = TDataStd_Name() label = shape_tool.AddShape(extg.Shape()) tname.Set(TCollection_ExtendedString(name)) label.AddAttribute(tname) # Root brackets compound = TopoDS_Compound() aBuilder.MakeCompound(compound) label = shape_tool.AddShape(compound) tname = TDataStd_Name() tname.Set(TCollection_ExtendedString('Brackets')) label.AddAttribute(tname) for br in self.model.brackets: guid = self.model.getGUID(br) name = br.get('name') if guid not in panelchildren: extg = ExternalGeometry(self.model, br, self.dict, self.logging) # Init the creator extg.readExtGeometry() # Read the Brep if extg.IsDone(): aBuilder.Add(compound, extg.Shape()) tname = TDataStd_Name() label = shape_tool.AddShape(extg.Shape()) tname.Set(TCollection_ExtendedString(name)) label.AddAttribute(tname) # Root plates compound = TopoDS_Compound() aBuilder.MakeCompound(compound) label = shape_tool.AddShape(compound) tname = TDataStd_Name() tname.Set(TCollection_ExtendedString('Plates')) label.AddAttribute(tname) for pl in self.model.plates: guid = self.model.getGUID(pl) name = pl.get('name') if guid not in panelchildren: extg = ExternalGeometry(self.model, pl, self.dict, self.logging) # Init the creator extg.readExtGeometry() # Read the Brep if extg.IsDone(): aBuilder.Add(compound, extg.Shape()) tname = TDataStd_Name() label = shape_tool.AddShape(extg.Shape()) tname.Set(TCollection_ExtendedString(name)) label.AddAttribute(tname) # Root pillars compound = TopoDS_Compound() aBuilder.MakeCompound(compound) label = shape_tool.AddShape(compound) tname = TDataStd_Name() tname.Set(TCollection_ExtendedString('Pillars')) label.AddAttribute(tname) for pil in self.model.pillars: guid = self.model.getGUID(pil) name = pil.get('name') if guid not in panelchildren: extg = ExternalGeometry(self.model, pil, self.dict, self.logging) # Init the creator extg.readExtGeometry() # Read the Brep if extg.IsDone(): aBuilder.Add(compound, extg.Shape()) tname = TDataStd_Name() label = shape_tool.AddShape(extg.Shape()) tname.Set(TCollection_ExtendedString(name)) label.AddAttribute(tname) step_writer.Perform( doc, TCollection_AsciiString(self.model.ocxfile.stem + '.stp')) return
class XdeDocument(object): """ Wrapper class to work with Extended Data Exchange. :param bool binary: If *True*, the document will be saved in a binary format. If *False*, the document will be saved in an XML format. """ def __init__(self, binary=True): if binary: self._fmt = 'BinXCAF' self._ext = '.xbf' else: self._fmt = 'XmlXCAF' self._ext = '.xml' # Get application self._app = XCAFApp_Application.GetApplication() if binary: binxcafdrivers.DefineFormat(self._app) else: xmlxcafdrivers.DefineFormat(self._app) # Initialize document fmt = TCollection_ExtendedString(self._fmt) self._doc = TDocStd_Document(fmt) self._app.InitDocument(self._doc) # Exchange data self._shape = None self._step_writer = None self._step_fp = None self._init_tool() def _init_tool(self): self._tool = XCAFDoc_DocumentTool.ShapeTool(self._doc.Main()) @property def main_label(self): """ :return: The main label of the document. :rtype: afem.exchange.xde.XdeLabel """ return XdeLabel(self._doc.Main()) @property def shapes_label(self): """ :return: The shapes label of the document. :rtype: afem.exchange.xde.XdeLabel """ return XdeLabel(XCAFDoc_DocumentTool.ShapesLabel_(self._doc.Main())) def open(self, fn): """ Open a document. :param str fn: The filename. :return: *True* if opened, *False* if not. :rtype: bool """ if not fn.endswith(self._ext): fn += self._ext txt = TCollection_ExtendedString(fn) status, self._doc = self._app.Open(txt, self._doc) if status != PCDM_RS_OK: return False self._init_tool() return True def save_as(self, fn): """ Save the document. :param str fn: The filename. :return: *True* if sucessfully saved, *False* if not. :rtype: bool """ if not fn.endswith(self._ext): fn += self._ext txt = TCollection_ExtendedString(fn) status = self._app.SaveAs(self._doc, txt) return status == PCDM_SS_OK def close(self): """ Close the document. :return: None. """ self._doc.Close() def read_step(self, fn): """ Read and translate a STEP file. :param str fn: The filename. :return: The shapes label. :rtype: afem.exchange.xde.Label. :raise RuntimeError: If the file cannot be read. """ reader = STEPCAFControl_Reader() reader.SetNameMode(True) reader.SetColorMode(True) status = reader.Perform(fn, self._doc) if not status: raise RuntimeError("Error reading STEP file.") self._shape = Shape.wrap(reader.Reader().OneShape()) label = XCAFDoc_DocumentTool.ShapesLabel_(self._doc.Main()) return XdeLabel(label) def transfer_step(self, schema='AP203', units=None): """ Transfer the document in preparation for STEP export. :param str schema: Schema for STEP file ('AP203', or 'AP214'). :param units: Units to convert STEP file to. :type units: str or None :return: *True* if transferred, *False* otherwise. :rtype: bool """ self._step_writer = STEPCAFControl_Writer() self._step_writer.SetNameMode(True) self._step_writer.SetColorMode(True) Interface_Static.SetCVal('write.step.schema', schema) try: units = units_dict[units] except KeyError: units = Settings.units Interface_Static.SetCVal('write.step.unit', units) self._step_writer.Transfer(self._doc) tw = self._step_writer.ChangeWriter().WS().TransferWriter() self._step_fp = tw.FinderProcess() return True def set_shape_name(self, shape, name): """ Set the name of the STEP entity for the given shape. The shape(s) should be transferred before naming them. :param afem.topology.entities.Shape shape: The shape (or sub-shape). :param str name: The name. :return: *True* if name is set, *False* otherwise. :rtype: bool """ if self._step_writer is None: raise RuntimeError('Document has not been transferred.') item = stepconstruct.FindEntity(self._step_fp, shape.object) if not item: return False item.SetName(TCollection_HAsciiString(name)) return True def write_step(self, fn, schema='AP203', units=None): """ Write the document to a STEP file. :param str fn: The filename. :param str schema: Schema for STEP file ('AP203', or 'AP214'). :param units: Units to convert STEP file to. :type units: str or None :return: *True* if written successfully, *False* otherwise. """ if self._step_writer is None: self.transfer_step(schema, units) status = self._step_writer.Write(fn) return int(status) < int(IFSelect_RetError) def is_top_level(self, label): """ Check if label is top-level as opposed to a component of assembly or a sub-shape. :param afem.exchange.xde.XdeLabel label: The label :return: *True* if top-level, *False* otherwise. :rtype: bool """ return self._tool.IsTopLevel(label.object) def is_sub_shape(self, label, shape): """ Check if the shape is a sub-shape of the shape stored on the label. :param afem.exchange.xde.XdeLabel label: The label :param afem.topology.entities.Shape shape: The shape. :return: *True* if a sub-shape, *False* otherwise. :rtype: bool """ return self._tool.IsSubShape(label.object, shape.object) def find_shape(self, shape, find_instance=False): """ Find the label corresponding to the shape. This method searches only top-level shapes. :param afem.topology.entities.Shape shape: The shape. :param bool find_instance: If *False*, search for the non-located shape in an assembly. If *True*, search for the shape with the same location. :return: The shape label if found, *None* otherwise. :rtype: afem.exchange.xde.XdeLabel """ label = self._tool.FindShape(shape.object, find_instance) if not label: return None return XdeLabel(label) def new_shape(self): """ Create a new top-level label. :return: The label. :rtype: afem.exchange.xde.XdeLabel """ return XdeLabel(self._tool.NewShape()) def set_shape(self, label, shape): """ Set the shape of the top-level label. :param afem.exchange.xde.XdeLabel label: The label. :param afem.topology.entities.Shape shape: The shape. :return: None. """ self._tool.SetShape(label.object, shape.object) def add_shape(self, shape, name=None, make_assy=True): """ Add a new top-level shape. :param afem.topology.entities.Shape shape: The shape. :param str name: The label name. :param bool make_assy: If *True*, then treat compounds as assemblies. :return: The shape label. :rtype: afem.exchange.xde.XdeLabel """ label = XdeLabel(self._tool.AddShape(shape.object, make_assy)) if name is not None: label.set_name(name) return label def remove_shape(self, label, remove_completely=True): """ Remove a shape. :param afem.exchange.xde.XdeLabel label: The label. :param bool remove_completely: If *True*, removes all shapes. If *False*, only remove the shape with the same location. :return: *True* if removed, or *False* if not removed because it is not a free or top-level shape. :rtype: bool """ return self._tool.RemoveShape(label.object, remove_completely) def get_shapes(self): """ Get a list containing all top-level shapes. :return: List of top-level shapes. :rtype: list(afem.exchange.xde.XdeLabel) """ labels = TDF_LabelSequence() self._tool.GetShapes(labels) return [XdeLabel(label) for label in labels] def get_shape_by_name(self, name): """ Get a shape label by its name. This only applies to top-level shapes and will return the first match. :param str name: The name. :return: The label or *None* if not found. :rtype: afem.exchange.xde.XdeLabel or None """ for label in self.get_shapes(): if label.name == name: return label def find_subshape(self, label, shape): """ Find a label for the sub-shape stored on the given label. :param afem.exchange.xde.XdeLabel label: The label. :param afem.topology.entities.Shape shape: The sub-shape. :return: The sub-shape label if found, *None* otherwise. :rtype: afem.exchange.xde.XdeLabel or None """ sub_label = TDF_Label() status, sub_label = self._tool.FindSubShape(label.object, shape.object, sub_label) if not status: return None return XdeLabel(sub_label) def add_subshape(self, label, shape, name=None): """ Add a label for a sub-shape stored on the shape of the label. :param afem.exchange.xde.XdeLabel label: The label. :param afem.topology.entities.Shape shape: The sub-shape. :param str name: The name of the sub-shape label. :return: The sub-shape label. :rtype: afem.exchange.xde.XdeLabel """ label = XdeLabel(self._tool.AddSubShape(label.object, shape.object)) if name is None: return label label.set_name(name) return label def set_auto_naming(self, mode): """ Set the option to auto-name shape labels. This only applies to top-level shapes. :param bool mode: The mode. If *True*, added shapes are automatically named based on their type (e.g., "SOLID", "SHELL", etc.). :return: None. """ self._tool.SetAutoNaming_(mode)