def __init__(self, points, point_size=0.001, color='green'): geometry = BufferGeometry( attributes={ 'position': BufferAttribute(array=points.astype(np.float32)) }) material = PointsMaterial(size=point_size, color=color) Points.__init__(self, geometry=geometry, material=material)
def AddVerticesToScene(self, pnt_list, vertex_color, vertex_width=5): """ shp is a list of gp_Pnt """ vertices_list = [] # will be passed to pythreejs BB = BRep_Builder() compound = TopoDS_Compound() BB.MakeCompound(compound) for vertex in pnt_list: vertex_to_add = BRepBuilderAPI_MakeVertex(vertex).Shape() BB.Add(compound, vertex_to_add) vertices_list.append([vertex.X(), vertex.Y(), vertex.Z()]) # map the Points and the AIS_PointCloud # and to the dict of shapes, to have a mapping between meshes and shapes point_cloud_id = "%s" % uuid.uuid4().hex self._shapes[point_cloud_id] = compound vertices_list = np.array(vertices_list, dtype=np.float32) attributes = { "position": BufferAttribute(vertices_list, normalized=False) } mat = PointsMaterial(color=vertex_color, sizeAttenuation=True, size=vertex_width) geom = BufferGeometry(attributes=attributes) points = Points(geometry=geom, material=mat, name=point_cloud_id) return points
def vertices_to_mesh(name, vertices, vertex_color, vertex_width=5): """ :param name: :param vertices: :param vertex_color: RGB tuple (r, g, b) :param vertex_width: :return: :rtype: pythreejs.objects.Points_autogen.Points """ vertices = np.array(vertices, dtype=np.float32) attributes = {"position": BufferAttribute(vertices, normalized=False)} mat = PointsMaterial(color=format_color(*vertex_color), sizeAttenuation=False, size=vertex_width) geom = BufferGeometry(attributes=attributes) points = Points(geometry=geom, material=mat, name=name) return points
def DisplayMesh(self, part: "Part", edge_color=None, vertex_color=None, vertex_width=2): from OCC.Core.BRep import BRep_Builder from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeVertex from OCC.Core.gp import gp_Pnt from OCC.Core.TopoDS import TopoDS_Compound # edge_color = format_color(*part.colour) if edge_color is None else edge_color rgb = randint(0, 255), randint(0, 255), randint(0, 255) edge_color = format_color(*rgb) if edge_color is None else edge_color vertex_color = self._default_vertex_color if vertex_color is None else vertex_color pmesh_id = "%s" % uuid.uuid4().hex BB = BRep_Builder() compound = TopoDS_Compound() BB.MakeCompound(compound) vertices_list = [] def togp(n_): return gp_Pnt(float(n_[0]), float(n_[1]), float(n_[2])) for vertex in map(togp, part.fem.nodes): vertex_to_add = BRepBuilderAPI_MakeVertex(vertex).Shape() BB.Add(compound, vertex_to_add) vertices_list.append([vertex.X(), vertex.Y(), vertex.Z()]) attributes = { "position": BufferAttribute(vertices_list, normalized=False) } mat = PointsMaterial(color=vertex_color, sizeAttenuation=False, size=vertex_width) geom = BufferGeometry(attributes=attributes) points_geom = Points(geometry=geom, material=mat, name=pmesh_id) lmesh_id = "%s" % uuid.uuid4().hex edges_nodes = list( chain.from_iterable( filter( None, [get_vertices_from_elem(el) for el in part.fem.elements]))) np_edge_vertices = np.array(edges_nodes, dtype=np.float32) np_edge_indices = np.arange(np_edge_vertices.shape[0], dtype=np.uint32) vertex_col = tuple([x / 255 for x in rgb]) edge_geometry = BufferGeometry( attributes={ "position": BufferAttribute(np_edge_vertices), "index": BufferAttribute(np_edge_indices), "color": BufferAttribute( [vertex_col for n in np_edge_vertices]), }) edge_material = LineBasicMaterial(vertexColors="VertexColors", linewidth=5) edge_geom = LineSegments( geometry=edge_geometry, material=edge_material, type="LinePieces", name=lmesh_id, ) output = [points_geom, edge_geom] for elem in output: self._shapes[elem.name] = compound self._refs[elem.name] = part self._displayed_pickable_objects.add(elem) self._fem_sets_opts.options = ["None"] + [ f"{part.fem.name}.{s.name}" for s in filter( lambda x: "internal" not in x.metadata.keys(), part.fem.sets) ] self._fem_refs[part.fem.name] = (part.fem, edge_geometry)
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 _render_shape( self, shape=None, edges=None, vertices=None, mesh_color=None, edge_color=None, vertex_color=None, edge_width=1, vertex_width=5, transparent=False, opacity=1.0, ): edge_list = [] normals_list = [] edge_lines = [] normal_lines = [] points = None shape_mesh = None # edge_accuracy = None if shape is not None: # Compute the tesselation and build mesh with Timer(self.timeit, "", "build mesh:", 5): edge_list, normals_list = shape["edges"] shape_geometry = BufferGeometry( attributes={ "position": BufferAttribute(shape["vertices"]), "index": BufferAttribute(shape["triangles"]), "normal": BufferAttribute(shape["normals"]), } ) if mesh_color is None: mesh_color = self.default_mesh_color shp_material = material(mesh_color, transparent=transparent, opacity=opacity) shape_mesh = IndexedMesh(geometry=shape_geometry, material=shp_material) if vertices is not None: if vertex_color is None: vertex_color = self.default_edge_color # same as edge_color vertices_list = vertices attributes = {"position": BufferAttribute(vertices_list, normalized=False)} mat = PointsMaterial(color=vertex_color, sizeAttenuation=False, size=vertex_width) geom = BufferGeometry(attributes=attributes) points = IndexedPoints(geometry=geom, material=mat) if edges is not None: edge_list = edges if len(edge_list) > 0: if edge_color is None: edge_color = self.default_edge_color if isinstance(edge_color, (list, tuple)): if len(edge_list) != len(edge_color): print("warning: color list and edge list have different length, using first color for all edges") edge_color = edge_color[0] if isinstance(edge_color, (list, tuple)): lines = LineSegmentsGeometry( positions=edge_list, colors=[[Color(color).percentage] * 2 for color in edge_color], ) mat = LineMaterial(linewidth=edge_width, vertexColors="VertexColors") edge_lines = [IndexedLineSegments2(lines, mat)] else: lines = LineSegmentsGeometry(positions=edge_list) mat = LineMaterial( linewidth=edge_width, color=edge_color.web_color if isinstance(edge_color, Color) else edge_color ) edge_lines = [IndexedLineSegments2(lines, mat)] if len(normals_list) > 0: lines = LineSegmentsGeometry(positions=normals_list) mat = LineMaterial(linewidth=2, color="#9400d3") normal_lines = [IndexedLineSegments2(lines, mat)] return shape_mesh, edge_lines, normal_lines, points
def render_shape( self, shape=None, edges=None, vertices=None, mesh_color=None, edge_color=None, vertex_color=None, render_edges=True, render_shapes=True, edge_width=1, vertex_width=5, transparent=False, opacity=1.0, ): edge_list = None edge_lines = None points = None shape_mesh = None render_timer = Timer(self.timeit, "| | shape render time") 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 # Compute the tesselation and build mesh tesselation_timer = Timer(self.timeit, "| | | build mesh time") shape_geometry = RENDER_CACHE.tessellate(shape, self.quality, self.angular_tolerance, self.timeit) shp_material = material(mesh_color.web_color, transparent=transparent, opacity=opacity) # Do not cache building the mesh. Might lead to unpredictable results shape_mesh = IndexedMesh(geometry=shape_geometry, material=shp_material) tesselation_timer.stop() if render_edges: edges = get_edges(shape) # unset shape_mesh again if not render_shapes: shape_mesh = None if vertices is not None: vertices_list = [] for vertex in vertices: vertices_list.append(get_point(vertex)) vertices_list = np.array(vertices_list, dtype=np.float32) attributes = { "position": BufferAttribute(vertices_list, normalized=False) } mat = PointsMaterial(color=vertex_color.web_color, sizeAttenuation=False, size=vertex_width) geom = BufferGeometry(attributes=attributes) points = IndexedPoints(geometry=geom, material=mat) if edges is not None: discretize_timer = Timer(self.timeit, "| | | discretize time") edge_list = [ discretize_edge(edge, self.edge_accuracy) for edge in edges ] discretize_timer.stop() if edge_list is not None: discretize_timer = Timer(self.timeit, "| | | edge list") edge_list = flatten(list(map(explode, edge_list))) if isinstance(edge_color, (list, tuple)): if len(edge_list) != len(edge_color): print( "warning: color list and edge list have different length, using first color for all edges" ) edge_color = edge_color[0] if isinstance(edge_color, (list, tuple)): lines = LineSegmentsGeometry( positions=edge_list, colors=[[color.percentage] * 2 for color in edge_color], ) mat = LineMaterial(linewidth=edge_width, vertexColors="VertexColors") edge_lines = [IndexedLineSegments2(lines, mat)] else: lines = LineSegmentsGeometry(positions=edge_list) mat = LineMaterial(linewidth=edge_width, color=edge_color.web_color) edge_lines = [IndexedLineSegments2(lines, mat)] discretize_timer.stop() render_timer.stop() return shape_mesh, edge_lines, points
def DisplayMesh(self, part, edge_color=None, vertex_color=None, vertex_width=2): """ :param part: :param edge_color: :param vertex_color: :param vertex_width: :type part: ada.Part """ from itertools import chain from random import randint from OCC.Core.BRep import BRep_Builder from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeVertex from OCC.Core.gp import gp_Pnt from OCC.Core.TopoDS import TopoDS_Compound # edge_color = format_color(*part.colour) if edge_color is None else edge_color edge_color = (format_color(randint(0, 255), randint( 0, 255), randint(0, 255)) if edge_color is None else edge_color) vertex_color = self._default_vertex_color if vertex_color is None else vertex_color pmesh_id = "%s" % uuid.uuid4().hex BB = BRep_Builder() compound = TopoDS_Compound() BB.MakeCompound(compound) vertices_list = [] def togp(n_): return gp_Pnt(float(n_[0]), float(n_[1]), float(n_[2])) for vertex in map(togp, part.fem.nodes): vertex_to_add = BRepBuilderAPI_MakeVertex(vertex).Shape() BB.Add(compound, vertex_to_add) vertices_list.append([vertex.X(), vertex.Y(), vertex.Z()]) attributes = { "position": BufferAttribute(vertices_list, normalized=False) } mat = PointsMaterial(color=vertex_color, sizeAttenuation=False, size=vertex_width) geom = BufferGeometry(attributes=attributes) points_geom = Points(geometry=geom, material=mat, name=pmesh_id) def grab_nodes(el): """ :param el: :type el: ada.fem.Elem :return: """ if el.edges_seq is None: return None return [ part.fem.nodes.from_id(i).p for i in [el.nodes[e].id for ed_seq in el.edges_seq for e in ed_seq] ] lmesh_id = "%s" % uuid.uuid4().hex edges_nodes = list( chain.from_iterable( filter(None, map(grab_nodes, part.fem.elements)))) np_edge_vertices = np.array(edges_nodes, 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) edge_geom = LineSegments( geometry=edge_geometry, material=edge_material, type="LinePieces", name=lmesh_id, ) output = [points_geom, edge_geom] for elem in output: self._shapes[elem.name] = compound self._refs[elem.name] = part self._displayed_pickable_objects.add(elem) self._fem_sets_opts.options = ["None"] + [ s.name for s in filter( lambda x: "internal" not in x.metadata.keys(), part.fem.sets) ]
def __init__(self,*args, **kwargs): """ There are several options for arguments this this function. One positional array-like Figure#scatter(np.random.randint(0, 10, (10, 3))) Three positional list-likes Figure#scatter(xs, ys, zs) Three named list-likes Figure#scatter(xs=[1, 2], ys=[2, 3], zs=[10, 20]) Three positional column names and a dataframe Figure#scatter("x", "y", "depth", my_dataframe) Arguments: attenuate_size (False): Whether items further from the camera should appear smaller """ super().__init__(**kwargs) pts = None if len(args) == 1: if isinstance(args[0], (np.ndarray, Iterable)): pts = np.asarray(args[0], dtype=np.float32) if len(args) == 3 and isinstance(args[0], (list, np.ndarray)): pts = np.asarray([i for i in zip(args[0], args[1], args[2])],dtype=np.float32) if pts is None: raise ValueError("Unsupported arguments to scatter.") self._coords = pts color = kwargs.get("c") if "c" in kwargs else None if color is None: color = kwargs.get("color", None) if color is None: color = pts / pts.max() if len(color) != len(pts): color = [color for _ in pts] colors = ( BufferAttribute(array=color, dtype=np.float32) if color is not None else BufferAttribute(array=np.asarray(pts / pts.max(), dtype=np.float32)) ) geometry = BufferGeometry( attributes={ "position": BufferAttribute(array=np.asarray(pts, dtype=np.float32)), "color": colors, } ) tex = CIRCLE_MAP if kwargs.get("marker") in [".", "o", "circle"]: tex = CIRCLE_MAP elif kwargs.get("marker") in ["[]", "r", "q", "square"]: tex = None elif "map" in kwargs: tex = kwargs.get("map") material = PointsMaterial( vertexColors="VertexColors", size=kwargs.get("size", 5), sizeAttenuation=kwargs.get("attenuate_size", False), **({"map": tex} if tex else {}), ) p = Points(geometry=geometry, material=material) self._objects.append(p)
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, transparent=False, opacity=1.0, ): edge_list = None edge_lines = None points = None shape_mesh = None start_render_time = self._start_timer() 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 # Compute the tesselation start_tesselation_time = self._start_timer() np_vertices, np_triangles, np_normals = tessellate( shape, self.quality, self.angular_tolerance ) if np_normals.shape != np_vertices.shape: raise AssertionError("Wrong number of normals/shapes") self._stop_timer("tesselation time", start_tesselation_time) # build a BufferGeometry instance shape_geometry = BufferGeometry( attributes={ "position": BufferAttribute(np_vertices), "index": BufferAttribute(np_triangles.ravel()), "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: edges = get_edges(shape) if vertices is not None: vertices_list = [] for vertex in vertices: vertices_list.append(get_point(vertex)) 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: start_discretize_time = self._start_timer() edge_list = [discretize_edge(edge, self.edge_accuracy) for edge in edges] self._stop_timer("discretize time", start_discretize_time) 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) self._stop_timer("shape render time", start_render_time)