def find_components(self, comps): """Discover components from comps (LabelSequence) of an assembly. Components of an assembly are, by definition, references which refer to either a shape or another assembly. Components are essentially 'instances' of the referred shape or assembly, and carry a location vector specifing the location of the referred shape or assembly. """ for j in range(comps.Length()): c_label = comps.Value(j + 1) # component label <class 'TDF_Label'> c_name = c_label.GetLabelName() c_entry = c_label.EntryDumpToString() ref_label = TDF_Label() # label of referred shape (or assembly) is_ref = self.shape_tool.GetReferredShape(c_label, ref_label) if is_ref: # just in case all components are not references ref_entry = ref_label.EntryDumpToString() ref_name = ref_label.GetLabelName() indent = "\t" * self.indent self.output += f"{self.uid}{indent}[{c_entry}] {c_name}" self.output += f" => [{ref_entry}] {ref_name}\n" self.uid += 1 if self.shape_tool.IsAssembly(ref_label): self.indent += 1 ref_comps = TDF_LabelSequence() # Components of Assy subchilds = False _ = self.shape_tool.GetComponents(ref_label, ref_comps, subchilds) if ref_comps.Length(): self.find_components(ref_comps) self.indent -= 1
def parse_components(self, comps, shape_tool, color_tool): """Parse components from comps (LabelSequence). Components of an assembly are, by definition, references which refer to either a simple shape or a compound shape (an assembly). Components are essentially 'instances' of the referred shape or assembly and carry a location vector specifing the location of the referred shape or assembly.""" for j in range(comps.Length()): logger.debug("Assy_entry_stack: %s", self.assy_entry_stack) logger.debug("loop %i of %i", j + 1, comps.Length()) c_label = comps.Value(j + 1) # component label <class 'TDF_Label'> c_name = c_label.GetLabelName() c_entry = c_label.EntryDumpToString() c_uid = self.get_uid_from_entry(c_entry) c_shape = shape_tool.GetShape(c_label) logger.debug("Component number %i", j + 1) logger.debug("Component name: %s", c_name) logger.debug("Component entry: %s", c_entry) ref_label = TDF_Label() # label of referred shape (or assembly) is_ref = shape_tool.GetReferredShape(c_label, ref_label) if is_ref: # I think all components are references ref_name = ref_label.GetLabelName() ref_shape = shape_tool.GetShape(ref_label) ref_entry = ref_label.EntryDumpToString() self.label_dict[c_uid] = { 'entry': c_entry, 'name': c_name, 'parent_uid': self.parent_uid_stack[-1], 'ref_entry': ref_entry } if shape_tool.IsSimpleShape(ref_label): self.label_dict[c_uid].update({'is_assy': False}) temp_assy_loc_stack = list(self.assy_loc_stack) # Multiply locations in stack sequentially to a result if len(temp_assy_loc_stack) > 1: res_loc = temp_assy_loc_stack.pop(0) for loc in temp_assy_loc_stack: res_loc = res_loc.Multiplied(loc) c_shape.Move(res_loc) elif len(temp_assy_loc_stack) == 1: res_loc = temp_assy_loc_stack.pop() c_shape.Move(res_loc) else: res_loc = None # It is possible for this component to both specify a # location 'c_loc' and refer directly to a top level shape. # If this component *does* specify a location 'c_loc', # it will be applied to the referred shape without being # included in temp_assy_loc_stack. But in order to keep # track of the total location from the root shape to the # instance, it needs to be accounted for (by mutiplying # res_loc by it) before saving it to part_dict. c_loc = None c_loc = shape_tool.GetLocation(c_label) if c_loc: loc = res_loc.Multiplied(c_loc) color = Quantity_Color() color_tool.GetColor(ref_shape, XCAFDoc_ColorSurf, color) self.part_dict[c_uid] = { 'shape': c_shape, 'color': color, 'name': c_name, 'loc': loc } elif shape_tool.IsAssembly(ref_label): self.label_dict[c_uid].update({'is_assy': True}) logger.debug("Referred item is an Assembly") # Location vector is carried by component aLoc = TopLoc_Location() aLoc = shape_tool.GetLocation(c_label) self.assy_loc_stack.append(aLoc) self.assy_entry_stack.append(ref_entry) self.parent_uid_stack.append(c_uid) r_comps = TDF_LabelSequence() # Components of Assy subchilds = False isAssy = shape_tool.GetComponents(ref_label, r_comps, subchilds) logger.debug("Assy name: %s", ref_name) logger.debug("Is Assembly? %s", isAssy) logger.debug("Number of components: %s", r_comps.Length()) if r_comps.Length(): logger.debug("") logger.debug("Parsing components of label entry %s)", ref_entry) self.parse_components(r_comps, shape_tool, color_tool) else: print( f"I was wrong: All components are *not* references {c_uid}" ) self.assy_entry_stack.pop() self.assy_loc_stack.pop() self.parent_uid_stack.pop()