def test_tesselate_box(self): """1st test : tesselation of a box""" a_box = BRepPrimAPI_MakeBox(10, 20, 30).Shape() tess = ShapeTesselator(a_box) tess.Compute() self.assertEqual(tess.ObjGetTriangleCount(), 12) self.assertEqual(tess.ObjGetNormalCount(), 24)
def test_tesselate_torus_with_edges(self): """2st test : tesselation of a torus""" a_torus = BRepPrimAPI_MakeTorus(10, 4).Shape() tess = ShapeTesselator(a_torus) tess.Compute(compute_edges=True) self.assertGreater(tess.ObjGetTriangleCount(), 100) self.assertGreater(tess.ObjGetNormalCount(), 100)
def upload_model(): if request.method == "POST": if request.files: model = request.files["model"] modelfile = os.path.join(app.config["MODEL_UPLOADS"], model.filename) model.save(modelfile) filename, file_extension = os.path.splitext(model.filename) #big_shp = read_step_file(modelfile) step_reader = STEPControl_Reader() status = step_reader.ReadFile(modelfile) if status == IFSelect_RetDone: ok = step_reader.TransferRoots() _nbs = step_reader.NbShapes() big_shp = step_reader.Shape() tess = ShapeTesselator(big_shp) tess.Compute(compute_edges=False, mesh_quality=0.5) jsonfile = filename + ".json" with open(os.path.join(app.config["MODEL_UPLOADS"], jsonfile), "w") as text_file: json_shape = tess.ExportShapeToThreejsJSONString(filename) json_shape = json_shape.replace("data\\", "data/") json_shape = json_shape.replace("\\step_postprocessed\\", "/step_postprocessed/") text_file.write(json_shape) else: raise Exception("error could not read step file") return redirect(url_for('modelview', modelname=jsonfile)) return render_template("public/upload.html")
def test_export_to_x3d(self): """3rd test : export a sphere to X3D file format""" a_sphere = BRepPrimAPI_MakeSphere(10.0).Shape() tess = ShapeTesselator(a_sphere) tess.Compute() tess.ExportShapeToX3D(os.path.join("test_io", "sphere.x3d")) self.assertTrue(os.path.exists(os.path.join("test_io", "sphere.x3d")))
def test_tesselate_twice(self): """ calling Compte() many times should no raise an exception """ another_torus = BRepPrimAPI_MakeTorus(10, 4).Shape() torus_tess = ShapeTesselator(another_torus) torus_tess.Compute() torus_tess.Compute()
def test_export_to_x3d_TriangleSet(self): """ 3rd test : export a sphere to an X3D TriangleSet triangle mesh """ a_sphere = BRepPrimAPI_MakeBox(10., 10., 10.).Shape() tess = ShapeTesselator(a_sphere) tess.Compute() ifs = tess.ExportShapeToX3DIndexedFaceSet() self.assertTrue(ifs.startswith("<TriangleSet")) self.assertTrue("0 10 0" in ifs) # a vertex self.assertTrue("0 0 1" in ifs) # a normal
def test_export_to_x3d_TriangleSet(self): """3rd test : export a sphere to an X3D TriangleSet triangle mesh""" a_sphere = BRepPrimAPI_MakeBox(10.0, 10.0, 10.0).Shape() sphere_tess = ShapeTesselator(a_sphere) sphere_tess.Compute() sphere_triangle_set_string = sphere_tess.ExportShapeToX3DTriangleSet() self.assertTrue(sphere_triangle_set_string.startswith("<TriangleSet")) self.assertTrue("0 10 0" in sphere_triangle_set_string) # a vertex self.assertTrue("0 0 1" in sphere_triangle_set_string) # a normal
def test_tesselate_STEP_file(self): """loads a step file, tesselate. The as1_pe_203 contains free edges""" stp_file = os.path.join(os.path.join("test_io", "as1_pe_203.stp")) stp_file_shape = read_step_file(stp_file) stp_file_tesselator = ShapeTesselator(stp_file_shape) # free edges have been excluded, then should work as expected stp_file_tesselator.Compute(compute_edges=True)
def test_x3d_file_is_valid_xml(self): """use ElementTree to parse X3D output""" another_torus = BRepPrimAPI_MakeTorus(10, 4).Shape() torus_tess = ShapeTesselator(another_torus) torus_tess.Compute() output_x3d_filename = os.path.join("test_io", "torus.x3d") torus_tess.ExportShapeToX3D(output_x3d_filename) self.assertTrue(os.path.exists(output_x3d_filename)) with open(output_x3d_filename, "r") as x3d_file: x3d_content = x3d_file.read() ET.fromstring(x3d_content) # raise an exception if not valid xml
def test_export_to_3js_JSON(self): a_box = BRepPrimAPI_MakeBox(10, 20, 30).Shape() tess = ShapeTesselator(a_box) tess.Compute() # get the JSON string JSON_str = tess.ExportShapeToThreejsJSONString("myshapeid") # check the python JSON parser can decode the string # i.e. the JSON string is well formed dico = json.loads(JSON_str) # after that, check that the number of vertices is ok self.assertEqual(len(dico["data"]["attributes"]["position"]["array"]), 36 * 3)
def exportThreeJS(filePath, shape): tess = ShapeTesselator(shape) tess.Compute(compute_edges=False, mesh_quality=1.) json_shape = tess.ExportShapeToThreejsJSONString(filePath) json_shape = json_shape.replace('data\\', 'data/') json_shape = json_shape.replace('\\step_postprocessed\\', '/step_postprocessed/') return json_shape
def drawShape(self, shape, color=(0.65, 0.65, 0.7), transparency=0., line_width=1., ): # if the shape is an edge or a wire, use the related functions shininess=0.9 specular_color=(0.2, 0.2, 0.2) shape_precision, wire_precision = self.precision if is_edge(shape): print("discretize an edge") pnts = discretize_edge(shape, wire_precision) edge_hash = "exp_%s_edge" % str(self.shapeNum).zfill(3) self.shapeNum += 1 str_to_write = export_edgedata_to_json(edge_hash, pnts) edge_full_path = os.path.join(self._path, edge_hash + '.json') with open(edge_full_path, "w") as edge_file: edge_file.write(str_to_write) # store this edge hash self.stringList.append("\tzdeskXCurve(slidePath+'%s.json', %s, %g);\n" % (edge_hash, color_to_hex(color), line_width)) print("%s, %i segments" % (edge_hash ,len(pnts)-1)) elif is_wire(shape): print("discretize a wire") pnts = discretize_wire(shape, wire_precision) wire_hash = "exp_%s_wire" % str(self.shapeNum).zfill(3) self.shapeNum += 1 str_to_write = export_edgedata_to_json(wire_hash, pnts) wire_full_path = os.path.join(self._path, wire_hash + '.json') with open(wire_full_path, "w") as wire_file: wire_file.write(str_to_write) # store this edge hash self.stringList.append("\tzdeskXCurve(slidePath+'%s.json', %s, %g);\n" % (wire_hash, color_to_hex(color), line_width)) print("%s, %i segments" % (wire_hash ,len(pnts)-1)) else: #solid or shell print("tesselate a shape") shape_uuid = uuid.uuid4().hex shape_hash = "exp_%s_shape" % str(self.shapeNum).zfill(3) self.shapeNum += 1 # tesselate tess = ShapeTesselator(shape) tess.Compute(compute_edges=False, mesh_quality=shape_precision, parallel=True) # export to 3JS shape_full_path = os.path.join(self._path, shape_hash + '.json') with open(shape_full_path, 'w') as json_file: json_file.write(tess.ExportShapeToThreejsJSONString(shape_uuid)) self.stringList.append("\tzdeskXShape(slidePath+'%s.json', %s, %s, %g, %g);\n" % (shape_hash, color_to_hex(color), color_to_hex(specular_color), shininess, 1 - transparency)) print("%s, %i triangles\n" % (shape_hash, tess.ObjGetTriangleCount()))
def exportFaces(self, topoDS_Assembly, topoDS_Compound, index): folder = self.folder + "/compound" + str(index) + "_faces" os.system("mkdir " + folder) # outFile = open(folder + "/faces.x3d", "w") self.dataStruct["compounds"].append("compound" + str(index) + "_faces") # self.printStart(outFile) for index, TopAbs_face in enumerate( topoDS_Assembly.faces_from_solids(topoDS_Compound)): color = Quantity_Color(random.random(), random.random(), random.random(), Quantity_TOC_RGB) tesselator = ShapeTesselator(TopAbs_face) tesselator.Compute(True) write_stl_file(TopAbs_face, folder + "/faces_" + str(index) + ".stl")
def draw_shape_mpl(shape): """ Draw a TopoDS_Shape with matplotlib """ tess = ShapeTesselator(shape) tess.Compute() triangles = [] edges = [] # get the triangles triangle_count = tess.ObjGetTriangleCount() for i_triangle in range(0, triangle_count): i1, i2, i3 = tess.GetTriangleIndex(i_triangle) triangles.append( [tess.GetVertex(i1), tess.GetVertex(i2), tess.GetVertex(i3)]) # get the edges edge_count = tess.ObjGetEdgeCount() for i_edge in range(0, edge_count): vertex_count = tess.ObjEdgeGetVertexCount(i_edge) edge = [] for i_vertex in range(0, vertex_count): vertex = tess.GetEdgeVertex(i_edge, i_vertex) edge.append(vertex) edges.append(edge) # plot it fig = plt.figure() ax = Axes3D(fig) ax.add_collection3d(Poly3DCollection(triangles, linewidths=0.2, alpha=0.5)) ax.add_collection3d(Line3DCollection(edges, colors='w', linewidths=1.0)) ax.get_xaxis().set_visible(True) ax.get_yaxis().set_visible(True) ax.set_autoscale_on(True) plt.show()
def occ_shape_to_faces( shape: "TopoDS_Shape", quality=1.0, render_edges=False, parallel=True ) -> Tuple[np.ndarray, np.ndarray, np.ndarray, Union[None, np.ndarray]]: from OCC.Core.Tesselator import ShapeTesselator # first, compute the tesselation try: tess = ShapeTesselator(shape) except RuntimeError as e: raise UnableToCreateTesselationFromSolidOCCGeom(e) tess.Compute(compute_edges=render_edges, mesh_quality=quality, parallel=parallel) # get vertices and normals vertices_position = tess.GetVerticesPositionAsTuple() number_of_triangles = tess.ObjGetTriangleCount() number_of_vertices = len(vertices_position) # number of vertices should be a multiple of 3 if number_of_vertices % 3 != 0: raise AssertionError("Wrong number of vertices") if number_of_triangles * 9 != number_of_vertices: raise AssertionError("Wrong number of triangles") # then we build the vertex and faces collections as numpy ndarrays np_vertices = np.array(vertices_position, dtype="float32").reshape( int(number_of_vertices / 3), 3) # Note: np_faces is just [0, 1, 2, 3, 4, 5, ...], thus arange is used np_faces = np.arange(np_vertices.shape[0], dtype="uint32") np_normals = np.array(tess.GetNormalsAsTuple(), dtype="float32").reshape(-1, 3) edges = np.array( map( lambda i_edge: [ tess.GetEdgeVertex(i_edge, i_vert) for i_vert in range(tess.ObjEdgeGetVertexCount(i_edge)) ], range(tess.ObjGetEdgeCount()), )) return np_vertices, np_faces, np_normals, edges
def test_tesselate_torus_with_bad_quality(self): """2st test : tesselation of a torus""" a_torus = BRepPrimAPI_MakeTorus(10, 4).Shape() tess = ShapeTesselator(a_torus) tess.Compute(mesh_quality=40.0) # since mesh quality is much lower, we should count less vertices and # triangles self.assertGreater(tess.ObjGetTriangleCount(), 10) self.assertLess(tess.ObjGetTriangleCount(), 100) self.assertGreater(tess.ObjGetNormalCount(), 10) self.assertLess(tess.ObjGetNormalCount(), 100)
def exportCompounds(self, topoDS_Assembly, writeFaces=False): self.dataStruct["path"] = self.path + self.folder # outFile = open(folder + "/assembly_" + self.name.split('.')[0] +".x3d", "w") self.dataStruct["assemblyFile"] = "assembly_" + self.name.split( '.')[0] + ".x3d" self.dataStruct["compounds"] = [] # self.printStart(outFile) for index, topoDS_compound in enumerate(topoDS_Assembly.solids()): color = Quantity_Color(random.random(), random.random(), random.random(), Quantity_TOC_RGB) tesselator = ShapeTesselator(topoDS_compound) tesselator.Compute(True) ouputString = tesselator.ExportShapeToX3DIndexedFaceSet() write_stl_file( topoDS_compound, self.folder + "/compound_" + str(index) + "_" + self.name.split('.')[0] + ".stl") # self.exportObj(coords) # normals = ouputString.split("<Normal vector='")[1].split(" '></Normal>")[0].split(" ") # normals = [float(item) for item in normals] # print(len(normals)) # self.printHeader(outFile) # print(ouputString, file = outFile) # self.printFooter(outFile) self.exportFaces(topoDS_Assembly, topoDS_compound, index)
def to_tesselation(self): """Convert the surface to a triangle mesh. Returns ------- :class:`~compas.datastructures.Mesh` """ from OCC.Core.Tesselator import ShapeTesselator tess = ShapeTesselator(self.occ_shape) tess.Compute() vertices = [] triangles = [] for i in range(tess.ObjGetVertexCount()): vertices.append(tess.GetVertex(i)) for i in range(tess.ObjGetTriangleCount()): triangles.append(tess.GetTriangleIndex(i)) return Mesh.from_vertices_and_faces(vertices, triangles)
def to_tesselation(self) -> Mesh: """Create a tesselation of the shape for visualisation. Returns ------- :class:`~compas.datastructures.Mesh` """ tesselation = ShapeTesselator(self.shape) tesselation.Compute() vertices = [ tesselation.GetVertex(i) for i in range(tesselation.ObjGetVertexCount()) ] triangles = [ tesselation.GetTriangleIndex(i) for i in range(tesselation.ObjGetTriangleCount()) ] return Mesh.from_vertices_and_faces(vertices, triangles)
def compute(self): shape_tesselator = ShapeTesselator(self._shape) shape_tesselator.Compute(compute_edges=self._export_edges, mesh_quality=self._mesh_quality, parallel=True) self._triangle_sets.append( shape_tesselator.ExportShapeToX3DTriangleSet()) # then process edges if self._export_edges: # get number of edges nbr_edges = shape_tesselator.ObjGetEdgeCount() for i_edge in range(nbr_edges): edge_point_set = [] nbr_vertices = shape_tesselator.ObjEdgeGetVertexCount(i_edge) for i_vert in range(nbr_vertices): edge_point_set.append( shape_tesselator.GetEdgeVertex(i_edge, i_vert)) ils = export_edge_to_indexed_lineset(edge_point_set) self._line_sets.append(ils)
def to_three_json(assembly: "Assembly", output_file_path): from OCC.Core.Tesselator import ShapeTesselator quality = 1.0 render_edges = False parallel = True total_json = [] for p in assembly.parts.values(): for obj in p.get_all_physical_objects(): geom = obj.solid tess = ShapeTesselator(geom) tess.Compute(compute_edges=render_edges, mesh_quality=quality, parallel=parallel) res = tess.ExportShapeToThreejsJSONString(obj.name) total_json.append(res) output = { "metadata": { "version": 4.3, "type": "Object", "generator": "ObjectExporter" }, "textures": [], "images": [], "geometries": [{ "uuid": "0A8F2988-626F-411C-BD6A-AC656C4E6878", "type": "BufferGeometry", "data": { "attributes": { "position": { "itemSize": 3, "type": "Float32Array", "array": [1, 1, 0, 1, -1, 0, -1, -1, 0, -1, 1, 0], "normalized": False, }, "normal": { "itemSize": 3, "type": "Float32Array", "array": [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], "normalized": False, }, "uv": { "itemSize": 2, "type": "Float32Array", "array": [1, 1, 1, 0, 0, 0, 0, 1], "normalized": False, }, }, # // type of index must be Uint8Array or Uint16Array. # // # vertices thus cannot exceed 255 or 65535 respectively. # // The current parser is able to read the index array # // if it is nested in the attributes object, but such # // syntax is no longer encouraged. "index": { "type": "Uint16Array", "array": [0, 1, 2, 0, 2, 3] }, "boundingSphere": { "center": [0, 0, 0], "radius": 1 }, }, }], "materials": [], "object": { "uuid": "378FAA8D-0888-4249-8701-92D1C1F37C51", "type": "Scene", "matrix": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], "children": [{ "uuid": "E7B44C44-DD75-4C29-B571-21AD6AEF0CA9", "name": "SharedVertexTest", "type": "Mesh", "geometry": "0A8F2988-626F-411C-BD6A-AC656C4E6878", "matrix": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], }], }, } output_file_path = pathlib.Path(output_file_path) os.makedirs(output_file_path.parent, exist_ok=True) with open(output_file_path, "w") as f: json.dump(output, f, indent=4)
def ConvertShape( self, shape, export_edges=False, color=(0.65, 0.65, 0.7), specular_color=(0.2, 0.2, 0.2), shininess=0.9, transparency=0.0, line_color=(0, 0.0, 0.0), line_width=1.0, point_size=1.0, mesh_quality=1.0, ): # if the shape is an edge or a wire, use the related functions color = color_to_hex(color) specular_color = color_to_hex(specular_color) if is_edge(shape): print("discretize an edge") pnts = discretize_edge(shape) edge_hash = "edg%s" % uuid.uuid4().hex shape_content = export_edgedata_to_json(edge_hash, pnts) # store this edge hash self._3js_edges[edge_hash] = [color, line_width, shape_content] return self._3js_shapes, self._3js_edges, self._3js_vertex elif is_wire(shape): print("discretize a wire") pnts = discretize_wire(shape) wire_hash = "wir%s" % uuid.uuid4().hex shape_content = export_edgedata_to_json(wire_hash, pnts) # store this edge hash self._3js_edges[wire_hash] = [color, line_width, shape_content] return self._3js_shapes, self._3js_edges, self._3js_vertex # if shape is array of gp_Pnt elif isinstance(shape, list) and isinstance(shape[0], gp_Pnt): print("storage points") vertices_list = [] # will be passed to javascript BB = BRep_Builder() compound = TopoDS_Compound() BB.MakeCompound(compound) for vertex in shape: vertext_to_add = BRepBuilderAPI_MakeVertex(vertex).Shape() BB.Add(compound, vertext_to_add) vertices_list.append([vertex.X(), vertex.Y(), vertex.Z()]) points_hash = "pnt%s" % uuid.uuid4().hex # store this vertex hash. Note: TopoDS_Compound did not save now self._3js_vertex[points_hash] = [color, point_size, vertices_list] return self._3js_shapes, self._3js_edges, self._3js_vertex # convert as TopoDS_Shape shape_uuid = uuid.uuid4().hex shape_hash = "shp%s" % shape_uuid # tesselate tess = ShapeTesselator(shape) tess.Compute(compute_edges=export_edges, mesh_quality=mesh_quality, parallel=True) # update spinning cursor sys.stdout.write("\r%s mesh shape %s, %i triangles " % (next( self.spinning_cursor), shape_hash, tess.ObjGetTriangleCount())) sys.stdout.flush() # export to 3JS # generate the mesh shape_content = tess.ExportShapeToThreejsJSONString(shape_uuid) # add this shape to the shape dict, sotres everything related to it self._3js_shapes[shape_hash] = [ export_edges, color, specular_color, shininess, transparency, line_color, line_width, shape_content, ] # draw edges if necessary if export_edges: # export each edge to a single json # get number of edges nbr_edges = tess.ObjGetEdgeCount() for i_edge in range(nbr_edges): # after that, the file can be appended edge_content = "" edge_point_set = [] nbr_vertices = tess.ObjEdgeGetVertexCount(i_edge) for i_vert in range(nbr_vertices): edge_point_set.append(tess.GetEdgeVertex(i_edge, i_vert)) # write to file edge_hash = "edg%s" % uuid.uuid4().hex edge_content += export_edgedata_to_json( edge_hash, edge_point_set) # store this edge hash, with black color self._3js_edges[edge_hash] = [ color_to_hex((0, 0, 0)), line_width, edge_content, ] return self._3js_shapes, self._3js_edges, self._3js_vertex
##along with pythonOCC. If not, see <http://www.gnu.org/licenses/>. from OCC.Core.Tesselator import ShapeTesselator from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox try: import numpy as np HAVE_NUMPY = True except ImportError: HAVE_NUMPY = False # create the shape box_s = BRepPrimAPI_MakeBox(10, 20, 30).Shape() # compute the tessellation tess = ShapeTesselator(box_s) tess.Compute() # get vertices vertices_position = tess.GetVerticesPositionAsTuple() number_of_triangles = tess.ObjGetTriangleCount() number_of_vertices = len(vertices_position) # number of vertices should be a multiple of 3 if number_of_vertices % 3 != 0: raise AssertionError("wrong number of vertices returned by the teselator") if number_of_triangles * 9 != number_of_vertices: raise AssertionError("wrong number of triangles returned by the teselator") # get normals
def AddShapeToScene( self, shp, shape_color=None, # the default render_edges=False, edge_color=None, vertex_color=None, quality=1.0, transparency=False, opacity=1.0, ): # first, compute the tesselation tess = ShapeTesselator(shp) tess.Compute(compute_edges=render_edges, mesh_quality=quality, parallel=True) # get vertices and normals vertices_position = tess.GetVerticesPositionAsTuple() number_of_triangles = tess.ObjGetTriangleCount() number_of_vertices = len(vertices_position) # number of vertices should be a multiple of 3 if number_of_vertices % 3 != 0: raise AssertionError("Wrong number of vertices") if number_of_triangles * 9 != number_of_vertices: raise AssertionError("Wrong number of triangles") # then we build the vertex and faces collections as numpy ndarrays np_vertices = np.array(vertices_position, dtype="float32").reshape( int(number_of_vertices / 3), 3) # Note: np_faces is just [0, 1, 2, 3, 4, 5, ...], thus arange is used np_faces = np.arange(np_vertices.shape[0], dtype="uint32") # set geometry properties buffer_geometry_properties = { "position": BufferAttribute(np_vertices), "index": BufferAttribute(np_faces), } if self._compute_normals_mode == NORMAL.SERVER_SIDE: # get the normal list, converts to a numpy ndarray. This should not raise # any issue, since normals have been computed by the server, and are available # as a list of floats np_normals = np.array(tess.GetNormalsAsTuple(), dtype="float32").reshape(-1, 3) # quick check if np_normals.shape != np_vertices.shape: raise AssertionError("Wrong number of normals/shapes") buffer_geometry_properties["normal"] = BufferAttribute(np_normals) # build a BufferGeometry instance shape_geometry = BufferGeometry(attributes=buffer_geometry_properties) # if the client has to render normals, add the related js instructions if self._compute_normals_mode == NORMAL.CLIENT_SIDE: shape_geometry.exec_three_obj_method("computeVertexNormals") # then a default material shp_material = self._material(shape_color, transparent=transparency, opacity=opacity) # and to the dict of shapes, to have a mapping between meshes and shapes mesh_id = "%s" % uuid.uuid4().hex self._shapes[mesh_id] = shp # finally create the mesh shape_mesh = Mesh(geometry=shape_geometry, material=shp_material, name=mesh_id) # edge rendering, if set to True if render_edges: edges = list( map( lambda i_edge: [ tess.GetEdgeVertex(i_edge, i_vert) for i_vert in range(tess.ObjEdgeGetVertexCount(i_edge)) ], range(tess.ObjGetEdgeCount()), )) edge_list = _flatten(list(map(_explode, edges))) lines = LineSegmentsGeometry(positions=edge_list) mat = LineMaterial(linewidth=1, color=edge_color) edge_lines = LineSegments2(lines, mat, name=mesh_id) self._displayed_non_pickable_objects.add(edge_lines) return shape_mesh
for u, v in tubemesh.face_halfedges(face): edge = BRepBuilderAPI_MakeEdge(gp_Pnt(*points[u]), gp_Pnt(*points[v])).Edge() brep.Add(edge, GeomAbs_C0, True) brep.Build() face = BRepBuilderAPI_MakeFace(brep.Face()).Face() builder.Add(shell, face) # ============================================================================== # Tesselation # ============================================================================== tess = ShapeTesselator(shell) tess.Compute() vertices = [] triangles = [] for i in range(tess.ObjGetVertexCount()): xyz = tess.GetVertex(i) vertices.append(xyz) for i in range(tess.ObjGetTriangleCount()): a, b, c = tess.GetTriangleIndex(i) triangles.append([a, b, c]) mesh = Mesh.from_vertices_and_faces(vertices, triangles)
def parse_shape(self, geometry): # compute the tessellation tess = ShapeTesselator(geometry) tess.Compute(compute_edges=True) # tess.Compute(compute_edges=False, mesh_quality=1.0, parallel=True) # get the vertices vertices = [] vertex_count = tess.ObjGetVertexCount() for i_vertex in range(0, vertex_count): i1, i2, i3 = tess.GetVertex(i_vertex) vertices.append(i1) vertices.append(i2) vertices.append(i3) # get the normals normals = [] normals_count = tess.ObjGetNormalCount() for i_normal in range(0, normals_count): i1, i2, i3 = tess.GetNormal(i_normal) normals.append(i1) normals.append(i2) normals.append(i3) # get the triangles triangles = [] triangle_count = tess.ObjGetTriangleCount() for i_triangle in range(0, triangle_count): i1, i2, i3 = tess.GetTriangleIndex(i_triangle) triangles.append(i1) triangles.append(i2) triangles.append(i3) # get the edges edges = [] edge_count = tess.ObjGetEdgeCount() for i_edge in range(0, edge_count): vertex_count = tess.ObjEdgeGetVertexCount(i_edge) # edge = [] for i_vertex in range(0, vertex_count): vertex = tess.GetEdgeVertex(i_edge, i_vertex) # edge.append(vertex) # edges.append(i_vertex) edges.append(vertex[0]) edges.append(vertex[1]) edges.append(vertex[2]) # edges.append(edge) return vertices, normals, triangles, edges
def DisplayShape(self, shape, export_edges=False, color=(0.65, 0.65, 0.7), specular_color=(0.2, 0.2, 0.2), shininess=0.9, transparency=0., line_color=(0, 0., 0.), line_width=1., mesh_quality=1.): # if the shape is an edge or a wire, use the related functions if is_edge(shape): print("discretize an edge") pnts = discretize_edge(shape) edge_hash = "edg%s" % uuid.uuid4().hex str_to_write = export_edgedata_to_json(edge_hash, pnts) edge_full_path = os.path.join(self._path, edge_hash + '.json') with open(edge_full_path, "w") as edge_file: edge_file.write(str_to_write) # store this edge hash self._3js_edges[edge_hash] = [color, line_width] return self._3js_shapes, self._3js_edges elif is_wire(shape): print("discretize a wire") pnts = discretize_wire(shape) wire_hash = "wir%s" % uuid.uuid4().hex str_to_write = export_edgedata_to_json(wire_hash, pnts) wire_full_path = os.path.join(self._path, wire_hash + '.json') with open(wire_full_path, "w") as wire_file: wire_file.write(str_to_write) # store this edge hash self._3js_edges[wire_hash] = [color, line_width] return self._3js_shapes, self._3js_edges shape_uuid = uuid.uuid4().hex shape_hash = "shp%s" % shape_uuid # tesselate tess = ShapeTesselator(shape) tess.Compute(compute_edges=export_edges, mesh_quality=mesh_quality, parallel=True) # update spinning cursor sys.stdout.write("\r%s mesh shape %s, %i triangles " % (next( self.spinning_cursor), shape_hash, tess.ObjGetTriangleCount())) sys.stdout.flush() # export to 3JS shape_full_path = os.path.join(self._path, shape_hash + '.json') # add this shape to the shape dict, sotres everything related to it self._3js_shapes[shape_hash] = [ export_edges, color, specular_color, shininess, transparency, line_color, line_width ] # generate the mesh #tess.ExportShapeToThreejs(shape_hash, shape_full_path) # and also to JSON with open(shape_full_path, 'w') as json_file: json_file.write(tess.ExportShapeToThreejsJSONString(shape_uuid)) # draw edges if necessary if export_edges: # export each edge to a single json # get number of edges nbr_edges = tess.ObjGetEdgeCount() for i_edge in range(nbr_edges): # after that, the file can be appended str_to_write = '' edge_point_set = [] nbr_vertices = tess.ObjEdgeGetVertexCount(i_edge) for i_vert in range(nbr_vertices): edge_point_set.append(tess.GetEdgeVertex(i_edge, i_vert)) # write to file edge_hash = "edg%s" % uuid.uuid4().hex str_to_write += export_edgedata_to_json( edge_hash, edge_point_set) # create the file edge_full_path = os.path.join(self._path, edge_hash + '.json') with open(edge_full_path, "w") as edge_file: edge_file.write(str_to_write) # store this edge hash, with black color self._3js_edges[edge_hash] = [(0, 0, 0), line_width] return self._3js_shapes, self._3js_edges
from OCC.Core.Tesselator import ShapeTesselator from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox from compas.datastructures import Mesh from compas_view2.app import App box = BRepPrimAPI_MakeBox(1, 1, 1).Shape() tess = ShapeTesselator(box) tess.Compute(compute_edges=True) vertices = [] triangles = [] edges = [] for i in range(tess.ObjGetVertexCount()): xyz = tess.GetVertex(i) vertices.append(xyz) for i in range(tess.ObjGetTriangleCount()): a, b, c = tess.GetTriangleIndex(i) triangles.append([a, b, c]) for i in range(tess.ObjGetEdgeCount()): edge = [] for j in range(tess.ObjEdgeGetVertexCount(i)): edge.append(j) edges.append(edge) print(vertices) print(triangles)