def AddCurveToScene(self, shp, edge_color, deflection): """ shp is either a TopoDS_Wire or a TopodS_Edge. """ if is_edge(shp): pnts = discretize_edge(shp, deflection) elif is_wire(shp): pnts = discretize_wire(shp, deflection) np_edge_vertices = np.array(pnts, dtype=np.float32) np_edge_indices = np.arange(np_edge_vertices.shape[0], dtype=np.uint32) edge_geometry = BufferGeometry( attributes={ 'position': BufferAttribute(np_edge_vertices), 'index': BufferAttribute(np_edge_indices) }) edge_material = LineBasicMaterial(color=edge_color, linewidth=1) # and to the dict of shapes, to have a mapping between meshes and shapes edge_id = "%s" % uuid.uuid4().hex self._shapes[edge_id] = shp edge_line = Line(geometry=edge_geometry, material=edge_material, name=edge_id) # and to the dict of shapes, to have a mapping between meshes and shapes edge_id = "%s" % uuid.uuid4().hex self._shapes[edge_id] = shp return edge_line
def DisplayShape(self, shape, vertex_shader=None, fragment_shader=None, 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=2., mesh_quality=1.): """ Adds a shape to the rendering buffer. This class computes the x3d file """ # if the shape is an edge or a wire, use the related functions if is_edge(shape): print("X3D exporter, discretize an edge") pnts = discretize_edge(shape) edge_hash = "edg%s" % uuid.uuid4().hex line_set = ExportEdgeToILS(pnts) x3dfile_content = indexed_lineset_to_x3d_string([line_set], ils_id=edge_hash) edge_full_path = os.path.join(self._path, edge_hash + '.x3d') with open(edge_full_path, "w") as edge_file: edge_file.write(x3dfile_content) # store this edge hash self._x3d_edges[edge_hash] = [color, line_width] return self._x3d_shapes, self._x3d_edges elif is_wire(shape): print("X3D exporter, discretize a wire") pnts = discretize_wire(shape) wire_hash = "wir%s" % uuid.uuid4().hex line_set = ExportEdgeToILS(pnts) x3dfile_content = indexed_lineset_to_x3d_string([line_set], ils_id=wire_hash) wire_full_path = os.path.join(self._path, wire_hash + '.x3d') with open(wire_full_path, "w") as wire_file: wire_file.write(x3dfile_content) # store this edge hash self._x3d_edges[wire_hash] = [color, line_width] return self._x3d_shapes, self._x3d_edges shape_uuid = uuid.uuid4().hex shape_hash = "shp%s" % shape_uuid x3d_exporter = X3DExporter(shape, vertex_shader, fragment_shader, export_edges, color, specular_color, shininess, transparency, line_color, line_width, mesh_quality) x3d_exporter.compute() x3d_filename = os.path.join(self._path, "%s.x3d" % shape_hash) # the x3d filename is computed from the shape hash shape_id = len(self._x3d_shapes) x3d_exporter.write_to_file(x3d_filename, shape_id) ## TODO : orientation and translation # get shape translation and orientation # trans = shape.Location().Transformation().TranslationPart().Coord() # vector # v = gp_Vec() # angle = shape.Location().Transformation().GetRotation().GetVectorAndAngle(v) # ori = (v.X(), v.Y(), v.Z(), angle) # angles # fill the shape dictionnary with shape hash, translation and orientation # self._x3d_shapes[shape_hash] = [trans, ori] self._x3d_shapes[shape_hash] = [export_edges, color, specular_color, shininess, transparency, line_color, line_width] return self._x3d_shapes, self._x3d_edges
def collect_dumpable_shapes(self, shape): if shape.ShapeType() == TopAbs_EDGE: points = [] try: points = discretize_edge(shape, 0.25) except: points = [] else: debug("Discretize done !") return points debug("edge: %s/%s"%(str(shape), self.describe_edge(shape))) it = TopoDS_Iterator(shape) points = [] while it.More(): shp = it.Value() brt = BRep_Tool() debug("vertex: %s"%(str(shp),)) pnt = brt.Pnt(topods_Vertex(shp)) points.append((pnt.X(), pnt.Y(), pnt.Z())) it.Next() return points else: lines = [] it = TopoDS_Iterator(shape) while it.More(): shp = it.Value() lines.append(self.collect_dumpable_shapes(shp)) it.Next() return lines
def DisplayShape(self, shape, vertex_shader=None, fragment_shader=None, 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=2., mesh_quality=1.): """ Adds a shape to the rendering buffer. This class computes the x3d file """ # if the shape is an edge or a wire, use the related functions if is_edge(shape): print("X3D exporter, discretize an edge") pnts = discretize_edge(shape) edge_hash = "edg%s" % uuid.uuid4().hex line_set = export_edge_to_indexed_lineset(pnts) x3dfile_content = indexed_lineset_to_x3d_string([line_set], ils_id=edge_hash) edge_full_path = os.path.join(self._path, edge_hash + '.x3d') with open(edge_full_path, "w") as edge_file: edge_file.write(x3dfile_content) # store this edge hash self._x3d_edges[edge_hash] = [color, line_width] return self._x3d_shapes, self._x3d_edges if is_wire(shape): print("X3D exporter, discretize a wire") pnts = discretize_wire(shape) wire_hash = "wir%s" % uuid.uuid4().hex line_set = export_edge_to_indexed_lineset(pnts) x3dfile_content = indexed_lineset_to_x3d_string([line_set], ils_id=wire_hash) wire_full_path = os.path.join(self._path, wire_hash + '.x3d') with open(wire_full_path, "w") as wire_file: wire_file.write(x3dfile_content) # store this edge hash self._x3d_edges[wire_hash] = [color, line_width] return self._x3d_shapes, self._x3d_edges shape_uuid = uuid.uuid4().hex shape_hash = "shp%s" % shape_uuid x3d_exporter = X3DExporter(shape, vertex_shader, fragment_shader, export_edges, color, specular_color, shininess, transparency, line_color, line_width, mesh_quality) x3d_exporter.compute() x3d_filename = os.path.join(self._path, "%s.x3d" % shape_hash) # the x3d filename is computed from the shape hash shape_id = len(self._x3d_shapes) x3d_exporter.write_to_file(x3d_filename, shape_id) self._x3d_shapes[shape_hash] = [ export_edges, color, specular_color, shininess, transparency, line_color, line_width ] return self._x3d_shapes, self._x3d_edges
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 _edge_to_svg_polyline(self, topods_edge,scale=1): """ Returns a svgwrite.Path for the edge, and the 2d bounding box """ unit = self.UNIT tol = self.TOL points_3d = discretize_edge(topods_edge, tol) points_2d = [] box2d = Bnd_Box2d() for point in points_3d: # we tak only the first 2 coordinates (x and y, leave z) x_p = point[0] y_p = - point[1] box2d.Add(gp_Pnt2d(x_p, y_p)) points_2d.append((x_p, y_p)) return svgwrite.shapes.Polyline(points_2d, fill="none", class_='vectorEffectClass'), box2d
def AddCurveToScene(self, shp, color): """ shp is either a TopoDS_Wire or a TopodS_Edge. """ if is_edge(shp): pnts = discretize_edge(shp) elif is_wire(shp): pnts = discretize_wire(shp) np_edge_vertices = np.array(pnts, dtype=np.float32) np_edge_indices = np.arange(np_edge_vertices.shape[0], dtype=np.uint32) edge_geometry = BufferGeometry(attributes={ 'position': BufferAttribute(np_edge_vertices), 'index' : BufferAttribute(np_edge_indices) }) edge_material = LineBasicMaterial(color=color, linewidth=1) edge_lines = Line(geometry=edge_geometry, material=edge_material) # Add geometries to pickable or non pickable objects self._displayed_pickable_objects.add(edge_lines)
def AddCurveToScene(self, shp, color): """ shp is either a TopoDS_Wire or a TopodS_Edge. """ if is_edge(shp): pnts = discretize_edge(shp) elif is_wire(shp): pnts = discretize_wire(shp) np_edge_vertices = np.array(pnts, dtype=np.float32) np_edge_indices = np.arange(np_edge_vertices.shape[0], dtype=np.uint32) edge_geometry = BufferGeometry(attributes={ 'position': BufferAttribute(np_edge_vertices), 'index' : BufferAttribute(np_edge_indices) }) edge_material = LineBasicMaterial(color=color, linewidth=2, fog=True) edge_lines = LineSegments(geometry=edge_geometry, material=edge_material) # Add geometries to pickable or non pickable objects self._displayed_pickable_objects.add(edge_lines)
def edge_to_svg_polyline(topods_edge, tol=0.1, unit="mm"): """Returns a svgwrite.Path for the edge, and the 2d bounding box""" unit_factor = 1 # by default if unit == "mm": unit_factor = 1 elif unit == "m": unit_factor = 1e3 points_3d = discretize_edge(topods_edge, tol) points_2d = [] box2d = Bnd_Box2d() for point in points_3d: # we tak only the first 2 coordinates (x and y, leave z) x_p = -point[0] * unit_factor y_p = point[1] * unit_factor box2d.Add(gp_Pnt2d(x_p, y_p)) points_2d.append((x_p, y_p)) return svgwrite.shapes.Polyline(points_2d, fill="none"), box2d
def test_discretize_edge(self): tor = BRepPrimAPI_MakeTorus(50, 20).Shape() topo = TopologyExplorer(tor) for edge in topo.edges(): pnts = discretize_edge(edge) self.assertTrue(pnts)
def Write(self, path): from bcad.binterpreter.scl_context import SCLProjection p = SCLProjection(None) p.hlr_project(self.shapes) shapes = [] for c in p.children: if c.shape != None: dump_topology_to_string(c.shape.get_shape()) shapes.append(c.shape.get_shape()) lines = [] for s in shapes: lines.extend(self.collect_dumpable_shapes(s)) #debug("Lines: %s"%(str(lines),)) ctr = 0 for l in lines: #debug ("l: %s"%(str(l),)) if len(l)>1: s = l[0][:2] for p in l[1:]: e = p[:2] self.msp.add_line(s, e) s = e # e = l[1][:2] # self.doc.saveas(path) return for s in shapes: exp = TopExp_Explorer() exp.Init(s, TopAbs_EDGE) while exp.More(): edge = exp.Value() if not is_edge(edge): warning("Is not an edge.") if exp.Value().IsNull(): warning("TopoDS_Edge is null") curve_adaptor = BRepAdaptor_Curve(edge) first = curve_adaptor.FirstParameter() last = curve_adaptor.LastParameter() geom_curve = curve_adaptor.Curve() #edges.append(exp.Current()) # first = topexp.FirstVertex(exp.Value()) # last = topexp.LastVertex(exp.Value()) # # Take geometrical information from vertices. # pnt_first = BRep_Tool.Pnt(first) # pnt_last = BRep_Tool.Pnt(last) # a, b = BRep_Tool.Curve(exp.Value()) exp.Next() if (geom_curve.GetType() == GeomAbs_Line): debug("Is line") elif (geom_curve.GetType() == GeomAbs_Circle): debug("Is circle") elif (geom_curve.GetType() == GeomAbs_Ellipse): debug("Is ellipse") elif (geom_curve.GetType() == GeomAbs_Hyperbola): debug("Is hyperbola") elif (geom_curve.GetType() == GeomAbs_Parabola): debug("Is parabola") elif (geom_curve.GetType() == GeomAbs_BezierCurve): debug("Is bezier") elif (geom_curve.GetType() == GeomAbs_BSplineCurve): debug("Is bspline") elif (geom_curve.GetType() == GeomAbs_OffsetCurve): debug("Is offset") elif (geom_curve.GetType() == GeomAbs_OtherCurve): #debug("Is other") continue #self.msp.add_line() pts = discretize_edge(edge) debug("Curve[%i]: %s / %s"%(ctr, str(geom_curve.GetType()),str(edge))) ctr+=1
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=2., 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 = Tesselator(shape) tess.Compute(compute_edges=export_edges, mesh_quality=mesh_quality, uv_coords=False, 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[hash] = [(0, 0, 0), line_width] return self._3js_shapes, self._3js_edges
def _render_shape(self, shape_index, shape=None, edges=None, vertices=None, mesh_color=None, edge_color=None, vertex_color=None, render_edges=False, edge_width=1, vertex_width=5, deflection=0.05, transparent=False, opacity=1.0): edge_list = None edge_lines = None points = None shape_mesh = None if shape is not None: if mesh_color is None: mesh_color = self.default_mesh_color if edge_color is None: edge_color = self.default_edge_color if vertex_color is None: vertex_color = self.default_edge_color # same as edge_color # BEGIN copy # The next lines are copied with light modifications from # https://github.com/tpaviot/pythonocc-core/blob/master/src/Display/WebGl/jupyter_renderer.py # first, compute the tesselation tess = Tesselator(shape) tess.Compute(uv_coords=False, compute_edges=render_edges, mesh_quality=self.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') # compute normals np_normals = np.array(tess.GetNormalsAsTuple(), dtype='float32').reshape(-1, 3) if np_normals.shape != np_vertices.shape: raise AssertionError("Wrong number of normals/shapes") # build a BufferGeometry instance shape_geometry = BufferGeometry( attributes={ 'position': BufferAttribute(np_vertices), 'index': BufferAttribute(np_faces), 'normal': BufferAttribute(np_normals) }) shp_material = self._material(mesh_color, transparent=True, opacity=opacity) shape_mesh = Mesh(geometry=shape_geometry, material=shp_material, name="mesh_%d" % shape_index) if render_edges: edge_list = list( map( lambda i_edge: [ tess.GetEdgeVertex(i_edge, i_vert) for i_vert in range( tess.ObjEdgeGetVertexCount(i_edge)) ], range(tess.ObjGetEdgeCount()))) # END copy if vertices is not None: vertices_list = [] for vertex in vertices: p = BRep_Tool.Pnt(vertex) vertices_list.append((p.X(), p.Y(), p.Z())) vertices_list = np.array(vertices_list, dtype=np.float32) attributes = { "position": BufferAttribute(vertices_list, normalized=False) } mat = PointsMaterial(color=vertex_color, sizeAttenuation=False, size=vertex_width) geom = BufferGeometry(attributes=attributes) points = Points(geometry=geom, material=mat) if edges is not None: edge_list = [discretize_edge(edge, deflection) for edge in edges] if edge_list is not None: edge_list = _flatten(list(map(_explode, edge_list))) lines = LineSegmentsGeometry(positions=edge_list) mat = LineMaterial(linewidth=edge_width, color=edge_color) edge_lines = LineSegments2(lines, mat, name="edges_%d" % shape_index) if shape_mesh is not None or edge_lines is not None or points is not None: index_mapping = {"mesh": None, "edges": None, "shape": shape_index} if shape_mesh is not None: ind = len(self.pickable_objects.children) self.pickable_objects.add(shape_mesh) index_mapping["mesh"] = ind if edge_lines is not None: ind = len(self.pickable_objects.children) self.pickable_objects.add(edge_lines) index_mapping["edges"] = ind if points is not None: ind = len(self.pickable_objects.children) self.pickable_objects.add(points) index_mapping["mesh"] = ind self.pick_mapping.append(index_mapping)
def to_lineset(edge): return ExportEdgeToILS(discretize_edge(edge.toOCC()))
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