def parse_doc(self): """Generate new part_dict & label_dict. part_dict (dict of dicts) is used primarily for 3D display part_dict = {uid: {'shape': , 'name': , 'color': , 'loc': }} label_dict (dict of dicts) is used primarily for tree view display label_dict = {uid: {'entry': , 'name': , 'parent_uid': , 'ref_entry': , 'is_assy': }} """ # Initialize dictionaries & list self._share_dict = {'0:1:1': 0} # {entry: ser_nbr} self.part_dict = {} self.label_dict = {} # Temporary use during unpacking self.parent_uid_stack = [] # uid of parent (topmost first) self.assy_entry_stack = ['0:1:1'] # [entries of containing assemblies] self.assy_loc_stack = [] # applicable <TopLoc_Location> locations shape_tool = XCAFDoc_DocumentTool_ShapeTool(self.doc.Main()) color_tool = XCAFDoc_DocumentTool_ColorTool(self.doc.Main()) # Find root label of self.doc labels = TDF_LabelSequence() shape_tool.GetShapes(labels) root_label = labels.Value(1) # First label at root nbr = labels.Length() # number of labels at root logger.debug('Number of labels at doc root : %i', nbr) # Get root label information # The first label at root holds an assembly, it is the Top Assy. # Through this label, the entire assembly is accessible. # There is no need to explicitly examine other labels at root. root_name = root_label.GetLabelName() root_entry = root_label.EntryDumpToString() root_uid = self.get_uid_from_entry(root_entry) loc = shape_tool.GetLocation(root_label) # <TopLoc_Location> self.assy_loc_stack.append(loc) self.assy_entry_stack.append(root_entry) self.label_dict = { root_uid: { 'entry': root_entry, 'name': root_name, 'parent_uid': None, 'ref_entry': None, 'is_assy': True } } self.parent_uid_stack.append(root_uid) top_comps = TDF_LabelSequence() # Components of Top Assy subchilds = False is_assy = shape_tool.GetComponents(root_label, top_comps, subchilds) if top_comps.Length(): # if is_assy: logger.debug("") logger.debug("Parsing components of label entry %s)", root_entry) self.parse_components(top_comps, shape_tool, color_tool) else: print("Something is wrong.")
def read_file(self): """Build self.tree (treelib.Tree()) containing CAD data read from a step file. Each node of self.tree contains the following: (Name, UID, ParentUID, {Data}) where the Data keys are: 'a' (isAssy?), 'l' (TopLoc_Location), 'c' (Quantity_Color), 's' (TopoDS_Shape) """ logger.info("Reading STEP file") doc = TDocStd_Document(TCollection_ExtendedString("STEP")) # Create the application app = XCAFApp_Application_GetApplication() app.NewDocument(TCollection_ExtendedString("MDTV-CAF"), doc) # Get root shapes shape_tool = XCAFDoc_DocumentTool_ShapeTool(doc.Main()) shape_tool.SetAutoNaming(True) self.color_tool = XCAFDoc_DocumentTool_ColorTool(doc.Main()) layer_tool = XCAFDoc_DocumentTool_LayerTool(doc.Main()) l_materials = XCAFDoc_DocumentTool_MaterialTool(doc.Main()) step_reader = STEPCAFControl_Reader() step_reader.SetColorMode(True) step_reader.SetLayerMode(True) step_reader.SetNameMode(True) step_reader.SetMatMode(True) status = step_reader.ReadFile(self.filename) if status == IFSelect_RetDone: logger.info("Transfer doc to STEPCAFControl_Reader") step_reader.Transfer(doc) # Test round trip by writing doc back to another file. logger.info("Doing a 'short-circuit' Round Trip test") doctype = type(doc) # <class 'OCC.Core.TDocStd.TDocStd_Document'> logger.info(f"Writing {doctype} back to another STEP file") self.testRTStep(doc) # Save doc to file (for educational purposes) (not working yet) logger.debug("Saving doc to file") savefilename = TCollection_ExtendedString('../doc.txt') app.SaveAs(doc, savefilename) labels = TDF_LabelSequence() color_labels = TDF_LabelSequence() shape_tool.GetShapes(labels) self.shape_tool = shape_tool logger.info('Number of labels at root : %i' % labels.Length()) try: label = labels.Value(1) # First label at root except RuntimeError: return name = self.getName(label) logger.info('Name of root label: %s' % name) isAssy = shape_tool.IsAssembly(label) logger.info("First label at root holds an assembly? %s" % isAssy) if isAssy: # If first label at root holds an assembly, it is the Top Assembly. # Through this label, the entire assembly is accessible. # No need to examine other labels at root explicitly. topLoc = TopLoc_Location() topLoc = shape_tool.GetLocation(label) self.assyLocStack.append(topLoc) entry = label.EntryDumpToString() logger.debug("Entry: %s" % entry) logger.debug("Top assy name: %s" % name) # Create root node for top assy newAssyUID = self.getNewUID() self.tree.create_node(name, newAssyUID, None, { 'a': True, 'l': None, 'c': None, 's': None }) self.assyUidStack.append(newAssyUID) topComps = TDF_LabelSequence() # Components of Top Assy subchilds = False isAssy = shape_tool.GetComponents(label, topComps, subchilds) logger.debug("Is Assembly? %s" % isAssy) logger.debug("Number of components: %s" % topComps.Length()) logger.debug("Is Reference? %s" % shape_tool.IsReference(label)) if topComps.Length(): self.findComponents(label, topComps) else: # Labels at root can hold solids or compounds (which are 'crude' assemblies) # Either way, we will need to create a root node in self.tree newAssyUID = self.getNewUID() self.tree.create_node(os.path.basename(self.filename), newAssyUID, None, { 'a': True, 'l': None, 'c': None, 's': None }) self.assyUidStack = [newAssyUID] for j in range(labels.Length()): label = labels.Value(j + 1) name = self.getName(label) isAssy = shape_tool.IsAssembly(label) logger.debug("Label %i is assembly?: %s" % (j + 1, isAssy)) shape = shape_tool.GetShape(label) color = self.getColor(shape) isSimpleShape = self.shape_tool.IsSimpleShape(label) logger.debug("Is Simple Shape? %s" % isSimpleShape) shapeType = shape.ShapeType() logger.debug("The shape type is: %i" % shapeType) if shapeType == 0: logger.debug( "The shape type is OCC.Core.TopAbs.TopAbs_COMPOUND") topo = TopologyExplorer(shape) #topo = aocutils.topology.Topo(shape) logger.debug("Nb of compounds : %i" % topo.number_of_compounds()) logger.debug("Nb of solids : %i" % topo.number_of_solids()) logger.debug("Nb of shells : %i" % topo.number_of_shells()) newAssyUID = self.getNewUID() for i, solid in enumerate(topo.solids()): name = "P%s" % str(i + 1) self.tree.create_node(name, self.getNewUID(), self.assyUidStack[-1], { 'a': False, 'l': None, 'c': color, 's': solid }) elif shapeType == 2: logger.debug( "The shape type is OCC.Core.TopAbs.TopAbs_SOLID") self.tree.create_node(name, self.getNewUID(), self.assyUidStack[-1], { 'a': False, 'l': None, 'c': color, 's': shape }) elif shapeType == 3: logger.debug( "The shape type is OCC.Core.TopAbs.TopAbs_SHELL") self.tree.create_node(name, self.getNewUID(), self.assyUidStack[-1], { 'a': False, 'l': None, 'c': color, 's': shape }) return True