def import_into_gmsh_use_nativepointer(obj, geom_repr: str, model: gmsh.model) -> List[tuple]: from OCC.Extend.TopologyUtils import TopologyExplorer from ada import PrimBox ents = [] if geom_repr == ElemType.SOLID: geom = obj.solid t = TopologyExplorer(geom) geom_iter = t.solids() elif geom_repr == ElemType.SHELL: geom = obj.shell if type(obj) not in (PrimBox, ) else obj.geom t = TopologyExplorer(geom) geom_iter = t.faces() else: geom = obj.line t = TopologyExplorer(geom) geom_iter = t.edges() for shp in geom_iter: ents += model.occ.importShapesNativePointer(int(shp.this)) if len(ents) == 0: raise ValueError("No entities found") return ents
def import_as_multiple_shapes(event=None): compound = read_step_file( os.path.join('..', 'assets', 'models', 'as1_pe_203.stp')) t = TopologyExplorer(compound) display.EraseAll() for solid in t.solids(): color = Quantity_Color(random.random(), random.random(), random.random(), Quantity_TOC_RGB) display.DisplayColoredShape(solid, color) display.FitAll()
def parse_shape(self): assert self.shape_type is "Compound" self.config['shape'] = self.shape_type self.config['data'] = [] s_id = 1 t = TopologyExplorer(self.shape) for subshape in t.solids(): print(s_id) solid = Solid(subshape, "Solid", s_id) solid.parse_shape() self.config['data'].append(solid.config) s_id = s_id + 1
def move_to_box(iname, cname, wname, visualize=False): """Move foam to periodic box. Works on BREP files. Information about physical volumes is lost. Args: iname (str): input filename cname (str): output filename with cells wname (str): output filename with walls visualize (bool): show picture of foam morphology in box if True """ cells = TopoDS_Shape() builder = BRep_Builder() breptools_Read(cells, iname, builder) texp = TopologyExplorer(cells) solids = list(texp.solids()) cells = TopoDS_Compound() builder.MakeCompound(cells) box = BRepPrimAPI_MakeBox(gp_Pnt(1, -1, -1), 3, 3, 3).Shape() vec = gp_Vec(-1, 0, 0) solids = slice_and_move(solids, box, vec) box = BRepPrimAPI_MakeBox(gp_Pnt(-3, -1, -1), 3, 3, 3).Shape() vec = gp_Vec(1, 0, 0) solids = slice_and_move(solids, box, vec) box = BRepPrimAPI_MakeBox(gp_Pnt(-1, 1, -1), 3, 3, 3).Shape() vec = gp_Vec(0, -1, 0) solids = slice_and_move(solids, box, vec) box = BRepPrimAPI_MakeBox(gp_Pnt(-1, -3, -1), 3, 3, 3).Shape() vec = gp_Vec(0, 1, 0) solids = slice_and_move(solids, box, vec) box = BRepPrimAPI_MakeBox(gp_Pnt(-1, -1, 1), 3, 3, 3).Shape() vec = gp_Vec(0, 0, -1) solids = slice_and_move(solids, box, vec) box = BRepPrimAPI_MakeBox(gp_Pnt(-1, -1, -3), 3, 3, 3).Shape() vec = gp_Vec(0, 0, 1) solids = slice_and_move(solids, box, vec) create_compound(solids, cells, builder) breptools_Write(cells, cname) if visualize: display, start_display, _, _ = init_display() display.DisplayShape(cells, update=True) start_display() box = BRepPrimAPI_MakeBox(gp_Pnt(0, 0, 0), 1, 1, 1).Shape() walls = BRepAlgoAPI_Cut(box, cells).Shape() breptools_Write(walls, wname) if visualize: display, start_display, _, _ = init_display() display.DisplayShape(walls, update=True) start_display()
def importStep(self): if (self.display): self.display.EraseAll() assembly = readStepFile(self.path + self.name) os.system("mkdir " + self.folder) write_stl_file( assembly, self.folder + "/assembly_" + self.name.split('.')[0] + ".stl") topoDS_Assembly = TopologyExplorer(assembly) self.exportCompounds(topoDS_Assembly) for compound in topoDS_Assembly.solids(): color = Quantity_Color(random.random(), random.random(), random.random(), Quantity_TOC_RGB) if (self.display): self.display.DisplayColoredShape(compound, color) if (self.display): self.display.FitAll() configFile = open('config.json', "w") json.dump(self.dataStruct, configFile) print("end")
def slice_and_move(obj, box, vec): """Cut, move, and join and object One object is cut by another object. Sliced part is moved by a vector. Moved part is joined with non-moved part. Args: obj (Solid): object to be cut box (Solid): object used for cutting vec (gp_Vec): vector defining the offset """ print('Solids before slicing: {}'.format(len(obj))) newsol = [] for solid in obj: cut = BRepAlgoAPI_Cut(solid, box).Shape() comm = BRepAlgoAPI_Common(solid, box).Shape() comm = translate_topods_from_vector(comm, vec) newsol.append(cut) texp = TopologyExplorer(comm) if list(texp.solids()): newsol.append(comm) print('Solids after slicing: {}'.format(len(newsol))) return newsol
def read_file(self): """Build tree = treelib.Tree() to facilitate displaying the CAD model and constructing the tree view showing the assembly/component relationships. 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") tmodel = TreeModel("STEP") self.shape_tool = tmodel.shape_tool self.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(self.filename) if status == IFSelect_RetDone: logger.info("Transfer doc to STEPCAFControl_Reader") step_reader.Transfer(tmodel.doc) labels = TDF_LabelSequence() self.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 = self.getName(rootlabel) logger.info('Name of root label: %s', name) isAssy = self.shape_tool.IsAssembly(rootlabel) 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. # there is no need to examine other labels at root explicitly. topLoc = TopLoc_Location() topLoc = self.shape_tool.GetLocation(rootlabel) self.assyLocStack.append(topLoc) entry = rootlabel.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 = self.shape_tool.GetComponents(rootlabel, topComps, subchilds) logger.debug("Is Assembly? %s", isAssy) logger.debug("Number of components: %s", topComps.Length()) logger.debug("Is Reference? %s", self.shape_tool.IsReference(rootlabel)) if topComps.Length(): self.findComponents(rootlabel, 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 = self.shape_tool.IsAssembly(label) logger.debug("Label %i is assembly?: %s", j+1, isAssy) shape = self.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 tmodel.doc # <class 'OCC.Core.TDocStd.TDocStd_Document'>
def extract_subshapes(shp_): t = TopologyExplorer(shp_) return list(t.solids())
print(" * single thread runtime: %.2fs" % delta_single) print(" * multi thread runtime: %.2fs" % delta_multi) print(" * muti/single=%.2f%%" % (delta_multi / delta_single * 100)) # TEST 2 : other step, with a loop over each subshape print("TEST 2 ===") shp3 = read_step_file( os.path.join('..', 'examples', 'models', 'RC_Buggy_2_front_suspension.stp')) shp4 = read_step_file( os.path.join('..', 'examples', 'models', 'RC_Buggy_2_front_suspension.stp')) topo1 = TopologyExplorer(shp3) t4 = time.monotonic() for solid in topo1.solids(): o = Tesselator(solid) o.Compute(parallel=False, mesh_quality=0.5) t5 = time.monotonic() delta_single = t5 - t4 topo2 = TopologyExplorer(shp4) t6 = time.monotonic() for solid in topo2.solids(): o = Tesselator(solid) o.Compute(parallel=True, mesh_quality=0.5) t7 = time.monotonic() delta_multi = t7 - t6 print("Test 2 Results:") print(" * single thread runtime: %.2fs" % delta_single)
t3 = time.monotonic() delta_multi = t3 - t2 print("Test 1 Results:") print(" * single thread runtime: %.2fs" % delta_single) print(" * multi thread runtime: %.2fs" % delta_multi) print(" * muti/single=%.2f%%" % (delta_multi / delta_single * 100)) # TEST 2 : other step, with a loop over each subshape print("TEST 2 ===") shp3 = read_step_file(step_file) shp4 = read_step_file(step_file) topo1 = TopologyExplorer(shp3) t4 = time.monotonic() for solid in topo1.solids(): o = Tesselator(solid) o.Compute(parallel=False, mesh_quality=0.5) t5 = time.monotonic() delta_single = t5-t4 topo2 = TopologyExplorer(shp4) t6 = time.monotonic() for solid in topo2.solids(): o = Tesselator(solid) o.Compute(parallel=True, mesh_quality=0.5) t7 = time.monotonic() delta_multi = t7 - t6 print("Test 2 Results:") print(" * single thread runtime: %.2fs" % delta_single)
# In[ ]: from OCC.Display.WebGl.jupyter_renderer import JupyterRenderer, format_color from OCC.Extend.TopologyUtils import TopologyExplorer from OCC.Extend.DataExchange import read_step_file # In[ ]: shp = read_step_file( os.path.join('..', 'assets', 'models', 'RC_Buggy_2_front_suspension.stp')) # In[ ]: my_renderer = JupyterRenderer(size=(700, 700)) # In[ ]: # loop over subshapes so that each subshape is meshed/displayed t = TopologyExplorer(shp) for solid in t.solids(): # random colors, just for fun random_color = format_color(randint(0, 255), randint(0, 255), randint(0, 255)) my_renderer.DisplayShape(solid, shape_color=random_color, render_edges=True) # In[ ]: my_renderer.Display()
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