def __add_line_geometry(self, lines, shading, obj=None): lines = lines.astype("float32", copy=False) mi = np.min(lines, axis=0) ma = np.max(lines, axis=0) geometry = p3s.BufferGeometry( attributes={ 'position': p3s.BufferAttribute(lines, normalized=False) }) material = p3s.LineBasicMaterial(linewidth=shading["line_width"], color=shading["line_color"]) #, vertexColors='VertexColors'), lines = p3s.LineSegments(geometry=geometry, material=material) #type='LinePieces') line_obj = { "geometry": geometry, "mesh": lines, "material": material, "max": ma, "min": mi, "type": "Lines", "wireframe": None } if obj: return self.__add_object(line_obj, obj), line_obj else: return self.__add_object(line_obj)
def ghostMaterial(self, origMaterial, solidColor): name = self._mangledNameForMaterial(True, origMaterial) if name not in self.materials: args = {'transparent': True, 'opacity': 0.25} args.update( self._colorTexArgs( *self._extractMaterialDescriptors(origMaterial), solidColor)) if (self.isLineMesh): self.materials[name] = pythreejs.LineBasicMaterial( **args, **self.commonArgs) elif (self.isPointCloud): self.materials[name] = pythreejs.PointsMaterial( **args, **self.commonArgs, size=5, sizeAttenuation=False) else: self.materials[name] = pythreejs.MeshLambertMaterial( **args, **self.commonArgs) else: # Update the existing ghost material's color (if a solid color is used) useVertexColors, textureMapDataTex = self._extractMaterialDescriptors( origMaterial) if (useVertexColors == False) and (textureMapDataTex is None): self.materials[name].color = solidColor return self.materials[name]
def _grid_views_default(self): # This needs to generate the geometries and access the materials grid_views = [] cmap = mcm.get_cmap("inferno") for level in range(self.ds.max_level + 1): # We truncate at half of the colormap so that we just get a slight # linear progression color = mcolors.to_hex( cmap(self.cmap_truncate * level / self.ds.max_level)) # Corners is shaped like 8, 3, NGrids this_level = self.ds.index.grid_levels[:, 0] == level corners = np.rollaxis(self.ds.index.grid_corners[:, :, this_level], 2).astype("float32") indices = (((np.arange(corners.shape[0]) * 8)[:, None] + _CORNER_INDICES[None, :]).ravel().astype("uint32")) corners.shape = (corners.size // 3, 3) geometry = pythreejs.BufferGeometry(attributes=dict( position=pythreejs.BufferAttribute(array=corners, normalized=False), index=pythreejs.BufferAttribute(array=indices, normalized=False), )) material = pythreejs.LineBasicMaterial(color=color, linewidth=1, linecap="round", linejoin="round") segments = pythreejs.LineSegments(geometry=geometry, material=material) grid_views.append(segments) return grid_views
def mesh(self, colors={}): import pythreejs as js import numpy as np lines = [] line_colors = [] red = [1, 0, 0] green = [0, 1, 0] exterior = self.project(exterior=True) interior = self.project(exterior=False) for color, polygons in zip([green, red], [exterior, interior]): for polygon in polygons: for segment in polygon.segments(): lines.extend([segment.p1, segment.p2]) line_colors.extend([color, color]) lines = np.array(lines, dtype=np.float32) line_colors = np.array(line_colors, dtype=np.float32) geometry = js.BufferGeometry(attributes={ 'position': js.BufferAttribute(lines, normalized=False), 'color': js.BufferAttribute(line_colors, normalized=False), }, ) material = js.LineBasicMaterial(vertexColors='VertexColors', linewidth=1) return js.LineSegments(geometry, material)
def edge_lines(sheet, coords, **draw_specs): spec = sheet_spec() spec.update(**draw_specs) up_srce = sheet.upcast_srce(sheet.vert_df[sheet.coords]) up_trgt = sheet.upcast_trgt(sheet.vert_df[sheet.coords]) vertices = np.hstack([up_srce.values, up_trgt.values]) vertices = vertices.reshape(vertices.shape[0] * 2, 3) colors = spec['vert']['color'] if isinstance(colors, str): colors = [colors for v in vertices] else: colors = np.asarray(colors) if (colors.shape == (sheet.Nv, 3)) or (colors.shape == (sheet.Nv, 4)): sheet.vert_df['hex_c'] = [mpl_colors.rgb2hex(c) for c in colors] srce_c = sheet.upcast_srce(sheet.vert_df['hex_c']) trgt_c = sheet.upcast_trgt(sheet.vert_df['hex_c']) colors = np.vstack([srce_c.values, trgt_c.values]).T.reshape(vertices.shape[0]) colors = list(colors) else: raise ValueError linesgeom = py3js.PlainGeometry(vertices=[list(v) for v in vertices], colors=colors) return py3js.Line(geometry=linesgeom, material=py3js.LineBasicMaterial( linewidth=spec['edge']['width'], vertexColors='VertexColors'), type='LinePieces')
def xyplane(max_dist, grid_space): """ Generates and returns two pythreejs items: a mesh of a flat surface and a SurfaceGrid object, both representing the xy plane. NOTE: max_dist will be rounded UP to next grid_space position (e.g. if yoru submit a max_width of 38 but a grid_space of 5, the max_width will be silently rounded up to 40 to allow an integer number of grids). Keyword arguments: max_dist (float): Maximum extent of grid from origin in each dimension grid_space (float): The grid spacing in system units. Parameters ---------- max_dist : float maximum extent of grid from origin in each dimension grid_space : float the grid spacing in system units. Returns ------- surface : pythreejs.Mesh a pythreejs Mesh object representing the xy plane. surf_grid : pythreejs.SurfaceGrid a pythreejs SurfaceGrid object for the grid on the xy plane. """ # Determine the gridsize to use, adding one additional step if necessary x_steps = int(np.ceil(max_dist / grid_space)) xmax = x_steps * grid_space # Number of vertices (subtract one for number of boxes shown) nx, ny = (2 * x_steps + 1, 2 * x_steps + 1) x = np.linspace(-xmax, xmax, nx) y = np.linspace(-xmax, xmax, ny) xx, yy = np.meshgrid(x, y) z = 0 * xx + 0 * yy # Generate the 3D surface and surface grid to return surf_g = p3j.SurfaceGeometry(z=list(z[::-1].flat), width=2 * xmax, height=2 * xmax, width_segments=nx - 1, height_segments=ny - 1) surface_material = p3j.MeshBasicMaterial(color='darkslategrey', transparent=True, opacity=0.5) surf = p3j.Mesh(geometry=surf_g, material=surface_material) grid_material = p3j.LineBasicMaterial(color='grey') # To avoid overlap, lift grid slightly above the plane scaling # by size of grid surfgrid = p3j.SurfaceGrid(geometry=surf_g, material=grid_material, position=[0, 0, 1e-2 * max_dist]) return surf, surfgrid
def __initialize_wireframe(self): edges_material = three.LineBasicMaterial(color='#686868', linewidth=1, depthTest=True, opacity=.2, transparent=True) wireframe = self.__get_wireframe_from_boundary() return three.LineSegments(wireframe, material=edges_material)
def display_path(th_scene, vs, **kwargs): """Display path.""" geom = three.Geometry(vertices=vs) mat_line = three.LineBasicMaterial(**kwargs) line = three.Line(geometry=geom, material=mat_line) th_scene.add(line) mat_points = three.PointsMaterial(**kwargs) points = three.Points(geometry=geom, material=mat_points) th_scene.add(points)
def lines_children(origins, targets, color="blue"): material = p3js.LineBasicMaterial(color=color, linewidth=4) scene_children = [] # For each 24 joint for origin, target in zip(origins, targets): geometry = p3js.Geometry(vertices=np.array([origin, target]).tolist()) line = p3js.Line(geometry, material) scene_children.append(line) return scene_children
def material(self, useVertexColors, textureMapDataTex = None): name = self._mangledMaterialName(False, useVertexColors, textureMapDataTex) if name not in self.materials: if (self.isLineMesh): args = self._colorTexArgs(useVertexColors, textureMapDataTex, 'black') self.materials[name] = pythreejs.LineBasicMaterial(**args, **self.commonArgs) else: args = self._colorTexArgs(useVertexColors, textureMapDataTex, 'lightgray') self.materials[name] = pythreejs.MeshLambertMaterial(**args, **self.commonArgs) return self.materials[name]
def get_polylines_pythreejs(polylines): lines = [] for x in polylines: line_geometry = pythreejs.Geometry(vertices=x["vertices"]) line = pythreejs.Line( geometry=line_geometry, material=pythreejs.LineBasicMaterial(color=x["color"]), type='LinePieces') lines.append(line) return lines
def _create_mesh(geometry, color, wireframe, position): if wireframe: edges = p3.EdgesGeometry(geometry) mesh = p3.LineSegments(geometry=edges, material=p3.LineBasicMaterial(color=color)) else: material = p3.MeshBasicMaterial(color=color) mesh = p3.Mesh(geometry=geometry, material=material) mesh.position = tuple(position.value) return mesh
def _create_outline(self, axparams): """ Make a wireframe cube with tick labels """ box_geometry = p3.BoxBufferGeometry( axparams['x']["lims"][1] - axparams['x']["lims"][0], axparams['y']["lims"][1] - axparams['y']["lims"][0], axparams['z']["lims"][1] - axparams['z']["lims"][0]) edges = p3.EdgesGeometry(box_geometry) self.outline = p3.LineSegments( geometry=edges, material=p3.LineBasicMaterial(color='#000000'), position=axparams["centre"]) self.axticks = self._generate_axis_ticks_and_labels(axparams)
def render_wireframe(mesh, up_vector=(0, 1, 0)): geometry = build_geometry( mesh.triangles, mesh.positions, normals=getattr(mesh, "normals", None), colors=getattr(mesh, "colors", None), ) obj = three.LineSegments( geometry=three.WireframeGeometry(geometry), material=three.LineBasicMaterial(color="green"), position=[0, 0, 0], ) center = np.array(mesh.positions).reshape(-1, 3).mean(axis=0) offset = 8 * np.array(mesh.positions).reshape(-1, 3).std(axis=0) return render_scene(Scene(eye_pos=center + offset, obj_pos=center, obj=obj, up=up_vector))
def joint_children(joints3D, color="blue", links=None): material = p3js.LineBasicMaterial(color=color, linewidth=4) scene_children = [] # For each 24 joint if links is None: links = [ (0, 1, 2, 3, 4), (0, 5, 6, 7, 8), (0, 9, 10, 11, 12), (0, 13, 14, 15, 16), (0, 17, 18, 19, 20), ] for link in links: for j1, j2 in zip(link[0:-1], link[1:]): geometry = p3js.Geometry(vertices=joints3D[(j1, j2), :].tolist()) line = p3js.Line(geometry, material) scene_children.append(line) return scene_children
def ray2mesh(ray): rays = py3js.Group() w = ray.wavelength rc, gc, bc = wavelength2RGB(w) rc = int(255 * rc) gc = int(255 * gc) bc = int(255 * bc) material = py3js.LineBasicMaterial( color="#{:02X}{:02X}{:02X}".format(rc, gc, bc)) rl = ray2list(ray) for r in rl: geometry = py3js.Geometry() geometry.vertices = r line = py3js.Line(geometry, material) rays.add(line) return rays
def axes_1d(x, y, color="#000000", linewidth=1.5): N = len(x) pts = np.zeros([5, 3]) xmin = np.amin(x) xmax = np.amax(x) ymin = np.amin(y) ymax = np.amax(y) pts[:, 0] = x pts[:, 1] = y geometry = p3.BufferGeometry(attributes={ 'position': p3.BufferAttribute(array=pts), }) material = p3.LineBasicMaterial(color=color, linewidth=linewidth) line = p3.Line(geometry=geometry, material=material) width = 800 height = 500
def to_edge_mesh(surf, mapper, prop, use_edge_coloring=True, use_lines=False): """Convert a pyvista surface to a three.js edge mesh.""" # extract all edges from the surface. Should not use triangular # mesh here as mesh may contain more than triangular faces if use_lines: edges_mesh = surf edges = segment_poly_cells(surf) else: edges_mesh = surf.extract_all_edges() edges = edges_mesh.lines.reshape(-1, 3)[:, 1:] attr = { 'position': array_to_float_buffer(edges_mesh.points), 'index': cast_to_min_size(edges, surf.n_points), } # add in colors coloring = get_coloring(mapper, surf) if coloring != 'NoColors' and not use_edge_coloring: if mapper.GetScalarModeAsString() == 'UsePointData': edge_scalars = edges_mesh.point_data.active_scalars edge_colors = map_scalars(mapper, edge_scalars) attr['color'] = array_to_float_buffer(edge_colors) edge_geo = tjs.BufferGeometry(attributes=attr) mesh_attr = {} if coloring != 'NoColors': mesh_attr['vertexColors'] = coloring if use_edge_coloring: edge_color = prop.GetEdgeColor() else: edge_color = prop.GetColor() edge_mat = tjs.LineBasicMaterial(color=color_to_hex(edge_color), linewidth=prop.GetLineWidth(), opacity=prop.GetOpacity(), side='FrontSide', **mesh_attr) return tjs.LineSegments(edge_geo, edge_mat)
def ray2mesh(ray): rays = py3js.Group() if ray.draw_color is None: color = wavelength2RGB(ray.wavelength) else: color = colors.to_rgb(ray.draw_color) int_colors = [int(255 * c) for c in color] material = py3js.LineBasicMaterial(color="#{:02X}{:02X}{:02X}".format( *int_colors)) rl = ray2list(ray) for r in rl: geometry = py3js.Geometry() geometry.vertices = r line = py3js.Line(geometry, material) rays.add(line) return rays
def plot_1d(x, y, color="blue", linewidth=2, background="#DDDDDD"): if len(x) != len(y): raise RuntimeError("bad shape") N = len(x) dx = config.figure["width"] dy = config.figure["height"] xmin = np.amin(x) ymin = np.amin(y) scale_x = dx / (np.amax(x) - xmin) scale_y = dy / (np.amax(y) - ymin) pts = np.zeros([N, 3], dtype=np.float32) pts[:, 0] = (x - xmin) * scale_x pts[:, 1] = (y - ymin) * scale_y # arr = p3.BufferAttribute(array=pts) geometry = p3.BufferGeometry(attributes={ 'position': p3.BufferAttribute(array=pts), }) material = p3.LineBasicMaterial(color=color, linewidth=linewidth) line = p3.Line(geometry=geometry, material=material) # width = 800 # height= 500 # Create the threejs scene with ambient light and camera # camera = p3.PerspectiveCamera(position=[0.5*dx, 0.5*dy, 0], # aspect=dx / dy) camera = p3.OrthographicCamera(0, dx, dy, 0, 0.5 * dx, -0.5 * dx) return render(objects=line, camera=camera, background=background, enableRotate=False, width=dx, height=dy)
def create_outline(self): """ Make a wireframe cube with tick labels """ box_geometry = p3.BoxBufferGeometry( self.xminmax['x'][1] - self.xminmax['x'][0], self.xminmax['y'][1] - self.xminmax['y'][0], self.xminmax['z'][1] - self.xminmax['z'][0]) edges = p3.EdgesGeometry(box_geometry) outline = p3.LineSegments( geometry=edges, material=p3.LineBasicMaterial(color='#000000'), position=[ 0.5 * np.sum(self.xminmax['x']), 0.5 * np.sum(self.xminmax['y']), 0.5 * np.sum(self.xminmax['z']) ]) ticks_and_labels = self.generate_axis_ticks_and_labels() return outline, ticks_and_labels
def visualize(self, colors={}): from ..space import Vector import pythreejs as js import numpy as np prior = Motion(x=0, y=0, z=0, f=0) lines = [] line_colors = [] for parent, command in self.commands(): if isinstance(command, Motion): updated = prior.merge(command) pv = Vector(*prior.xyz) uv = Vector(*updated.xyz) delta = pv - uv start = (uv + pv) / 2 lines.extend([prior.xyz, updated.xyz]) a1 = delta.rotate(Vector(0, 0, 1), tau / 16) * 0.1 a2 = delta.rotate(Vector(0, 0, 1), -tau / 16) * 0.1 lines.extend( [start, (a1 + start).xyz, start, (a2 + start).xyz]) prior = updated color = getattr(parent, 'color', [0, 1, 0]) line_colors.extend([color, color]) line_colors.extend([color, color]) line_colors.extend([color, color]) lines = np.array(lines, dtype=np.float32) line_colors = np.array(line_colors, dtype=np.float32) geometry = js.BufferGeometry(attributes={ 'position': js.BufferAttribute(lines, normalized=False), 'color': js.BufferAttribute(line_colors, normalized=False), }, ) material = js.LineBasicMaterial(vertexColors='VertexColors', linewidth=1) return js.LineSegments(geometry, material)
def axes(max_dist): """ Generate X, Y, Z axes of length max_width in the form of a pythreejs Line object. Parameters ---------- max_dist : float maximum extent of grid from origin in each dimension Returns ------- axes : pythreejs.Line a pythreejs Line object representing the xyz axes. """ axes_geom = p3j.Geometry( vertices=[[0, 0, 0], [max_dist, 0, 0], [0, 0, 0], [0, max_dist, 0], [0, 0, 0], [0, 0, max_dist]], colors=['white', 'white', 'white', 'white', 'white', 'white']) return p3j.Line(geometry=axes_geom, material=p3j.LineBasicMaterial( linewidth=1, vertexColors='VertexColors'))
def _get_grids(self, obj_vertices): extents = self._get_extents(obj_vertices) grid_verts = [] deltas = [extent[1] - extent[0] for extent in extents] max_extent = max(deltas) space1 = 10.0**pymath.floor( pymath.log(max_extent) / pymath.log(10.0) - 0.5) space2 = 2 * 10.0**pymath.floor( pymath.log(max_extent / 2.0) / pymath.log(10.0) - 0.5) space = space2 if max_extent / space2 < 5: space = space1 N = int(pymath.floor(max_extent / space + 2.0)) grid_cols = [] axis_cols = ['#ff3333', '#33ff33', '#3333ff'] ends = [] for axis1 in range(3): start = pymath.floor(extents[axis1][0] / space) * space ends.append(start + space * N) for axis2 in range(3): axis3 = [x for x in [0, 1, 2] if x not in [axis1, axis2]][0] if axis1 == axis2: continue delta = extents[axis1][1] - extents[axis1][0] start2 = pymath.floor(extents[axis2][0] / space) * space end2 = start2 + (N - 1) * space verts = self._get_grid_lines(axis1, start, space, N, axis2, start2, end2) grid_verts.extend(verts) grid_cols.extend([axis_cols[axis3] for vert in verts]) # now draw the X,Y,Z labels: char_width = max_extent * 0.05 char_lines = [] # X: char_lines_x = [] char_lines_x.append([[0.0, 0.0], [1.0, 1.0]]) char_lines_x.append([[0.0, 1.0], [1.0, 0.0]]) char_lines.append(char_lines_x) # Y: char_lines_y = [] char_lines_y.append([[0.5, 0.0], [0.5, 0.5]]) char_lines_y.append([[0.5, 0.5], [0.0, 1.0]]) char_lines_y.append([[0.5, 0.5], [1.0, 1.0]]) char_lines.append(char_lines_y) # Z: char_lines_z = [] char_lines_z.append([[1.0, 1.0], [0.0, 1.0]]) char_lines_z.append([[0.0, 1.0], [1.0, 0.0]]) char_lines_z.append([[1.0, 0.0], [0.0, 0.0]]) char_lines.append(char_lines_z) for iaxis in range(3): ax1 = [0, 1, 2][iaxis] ax2 = [2, 2, 1][iaxis] char_lns = char_lines[iaxis] segs = [[[0, 0], [ends[iaxis] + char_width, 0]], [[ends[iaxis] + char_width, 0], [ends[iaxis] + 0.5 * char_width, 0.5 * char_width]], [[ends[iaxis] + char_width, 0], [ends[iaxis] + 0.5 * char_width, -0.5 * char_width]]] for seg in segs: for pt in seg: pt3 = [0, 0, 0] pt3[ax1] += pt[0] pt3[ax2] += pt[1] grid_verts.append(pt3) grid_cols.append('#000000') for seg in char_lns: for pt in seg: pt3 = [0, 0, 0] pt3[iaxis] += ends[iaxis] + 2 * char_width pt3[ax1] += pt[0] * char_width pt3[ax2] += 1.2 * (pt[1] - 0.5) * char_width grid_verts.append(pt3) grid_cols.append('#000000') lines_geom = pjs.Geometry(vertices=grid_verts, colors=grid_cols) lines = pjs.LineSegments(geometry=lines_geom, material=pjs.LineBasicMaterial( linewidth=self.grid_lines_width, transparent=True, opacity=0.5, dashSize=10, gapSize=10, vertexColors='VertexColors'), type='LinePieces') return lines, space
def _render_obj(self, rendered_obj, **kw): obj_geometry = pjs.BufferGeometry(attributes=dict( position=pjs.BufferAttribute(rendered_obj.plot_verts), color=pjs.BufferAttribute(rendered_obj.base_cols), normal=pjs.BufferAttribute( rendered_obj.face_normals.astype('float32')))) vertices = rendered_obj.vertices # Create a mesh. Note that the material need to be told to use the vertex colors. my_object_mesh = pjs.Mesh( geometry=obj_geometry, material=pjs.MeshLambertMaterial(vertexColors='VertexColors'), position=[0, 0, 0], ) line_material = pjs.LineBasicMaterial(color='#ffffff', transparent=True, opacity=0.3, linewidth=1.0) my_object_wireframe_mesh = pjs.LineSegments( geometry=obj_geometry, material=line_material, position=[0, 0, 0], ) n_vert = vertices.shape[0] center = vertices.mean(axis=0) extents = self._get_extents(vertices) max_delta = np.max(extents[:, 1] - extents[:, 0]) camPos = [center[i] + 4 * max_delta for i in range(3)] light_pos = [center[i] + (i + 3) * max_delta for i in range(3)] # Set up a scene and render it: camera = pjs.PerspectiveCamera(position=camPos, fov=20, children=[ pjs.DirectionalLight( color='#ffffff', position=light_pos, intensity=0.5) ]) camera.up = (0, 0, 1) v = [0.0, 0.0, 0.0] if n_vert > 0: v = vertices[0].tolist() select_point_geom = pjs.SphereGeometry(radius=1.0) select_point_mesh = pjs.Mesh( select_point_geom, material=pjs.MeshBasicMaterial(color=SELECTED_VERTEX_COLOR), position=v, scale=(0.0, 0.0, 0.0)) #select_edge_mesh = pjs.ArrowHelper(dir=pjs.Vector3(1.0, 0.0, 0.0), origin=pjs.Vector3(0.0, 0.0, 0.0), length=1.0, # hex=SELECTED_EDGE_COLOR_INT, headLength=0.1, headWidth=0.05) arrow_cyl_mesh = pjs.Mesh(geometry=pjs.SphereGeometry(radius=0.01), material=pjs.MeshLambertMaterial()) arrow_head_mesh = pjs.Mesh(geometry=pjs.SphereGeometry(radius=0.001), material=pjs.MeshLambertMaterial()) scene_things = [ my_object_mesh, my_object_wireframe_mesh, select_point_mesh, arrow_cyl_mesh, arrow_head_mesh, camera, pjs.AmbientLight(color='#888888') ] if self.draw_grids: grids, space = self._get_grids(vertices) scene_things.append(grids) scene = pjs.Scene(children=scene_things, background=BACKGROUND_COLOR) click_picker = pjs.Picker(controlling=my_object_mesh, event='dblclick') out = Output() top_msg = HTML() def on_dblclick(change): if change['name'] == 'point': try: point = np.array(change['new']) face = click_picker.faceIndex face_points = rendered_obj.face_verts[face] face_vecs = face_points - np.roll(face_points, 1, axis=0) edge_lens = np.sqrt((face_vecs**2).sum(axis=1)) point_vecs = face_points - point[np.newaxis, :] point_dists = (point_vecs**2).sum(axis=1) min_point = np.argmin(point_dists) v1s = point_vecs.copy() v2s = np.roll(v1s, -1, axis=0) edge_mids = 0.5 * (v2s + v1s) edge_mid_dists = (edge_mids**2).sum(axis=1) min_edge_point = np.argmin(edge_mid_dists) edge_start = min_edge_point edge = face * 3 + edge_start close_vert = rendered_obj.face_verts[face, min_point] edge_start_vert = rendered_obj.face_verts[face, edge_start] edge_end_vert = rendered_obj.face_verts[face, (edge_start + 1) % 3] vertex = face * 3 + min_point radius = min( [edge_lens.max() * 0.02, 0.1 * edge_lens.min()]) edge_head_length = radius * 4 edge_head_width = radius * 2 select_point_mesh.scale = (radius, radius, radius) top_msg.value = '<font color="{}">selected face: {}</font>, <font color="{}">edge: {}</font>, <font color="{}"> vertex: {}</font>'.format( SELECTED_FACE_COLOR, face, SELECTED_EDGE_COLOR, edge, SELECTED_VERTEX_COLOR, vertex) newcols = rendered_obj.base_cols.copy() newcols[face * 3:(face + 1) * 3] = np.array( SELECTED_FACE_RGB, dtype='float32') select_point_mesh.position = close_vert.tolist() obj_geometry.attributes['color'].array = newcols with out: make_arrow(arrow_cyl_mesh, arrow_head_mesh, edge_start_vert, edge_end_vert, radius / 2, radius, radius * 3, SELECTED_EDGE_COLOR) except: with out: print(traceback.format_exc()) click_picker.observe(on_dblclick, names=['point']) renderer_obj = pjs.Renderer( camera=camera, background='#cccc88', background_opacity=0, scene=scene, controls=[pjs.OrbitControls(controlling=camera), click_picker], width=self.width, height=self.height) display_things = [top_msg, renderer_obj, out] if self.draw_grids: s = """ <svg width="{}" height="30"> <rect width="20" height="20" x="{}" y="0" style="fill:none;stroke-width:1;stroke:rgb(0,255,0)" /> <text x="{}" y="15">={:.1f}</text> Sorry, your browser does not support inline SVG. </svg>""".format(self.width, self.width // 2, self.width // 2 + 25, space) display_things.append(HTML(s)) display(VBox(display_things))
def add_mesh(self, v, f, c=None, uv=None, shading={}, texture_data=None): sh = self.__get_shading(shading) mesh_obj = {} #it is a tet if v.shape[1] == 3 and f.shape[1] == 4: f_tmp = np.ndarray([f.shape[0]*4, 3], dtype=f.dtype) for i in range(f.shape[0]): f_tmp[i*4+0] = np.array([f[i][1], f[i][0], f[i][2]]) f_tmp[i*4+1] = np.array([f[i][0], f[i][1], f[i][3]]) f_tmp[i*4+2] = np.array([f[i][1], f[i][2], f[i][3]]) f_tmp[i*4+3] = np.array([f[i][2], f[i][0], f[i][3]]) f = f_tmp if v.shape[1] == 2: v = np.append(v, np.zeros([v.shape[0], 1]), 1) # Type adjustment vertices v = v.astype("float32", copy=False) # Color setup colors, coloring = self.__get_colors(v, f, c, sh) # Type adjustment faces and colors c = colors.astype("float32", copy=False) # Material and geometry setup ba_dict = {"color": p3s.BufferAttribute(c)} if coloring == "FaceColors": verts = np.zeros((f.shape[0]*3, 3), dtype="float32") for ii in range(f.shape[0]): #print(ii*3, f[ii]) verts[ii*3] = v[f[ii,0]] verts[ii*3+1] = v[f[ii,1]] verts[ii*3+2] = v[f[ii,2]] v = verts else: f = f.astype("uint32", copy=False).ravel() ba_dict["index"] = p3s.BufferAttribute(f, normalized=False) ba_dict["position"] = p3s.BufferAttribute(v, normalized=False) if type(uv) != type(None): uv = (uv - np.min(uv)) / (np.max(uv) - np.min(uv)) if texture_data is None: texture_data = gen_checkers(20, 20) tex = p3s.DataTexture(data=texture_data, format="RGBFormat", type="FloatType") material = p3s.MeshStandardMaterial(map=tex, reflectivity=sh["reflectivity"], side=sh["side"], roughness=sh["roughness"], metalness=sh["metalness"], flatShading=sh["flat"], polygonOffset=True, polygonOffsetFactor= 1, polygonOffsetUnits=5) ba_dict["uv"] = p3s.BufferAttribute(uv.astype("float32", copy=False)) else: material = p3s.MeshStandardMaterial(vertexColors=coloring, reflectivity=sh["reflectivity"], side=sh["side"], roughness=sh["roughness"], metalness=sh["metalness"], flatShading=sh["flat"], polygonOffset=True, polygonOffsetFactor= 1, polygonOffsetUnits=5) geometry = p3s.BufferGeometry(attributes=ba_dict) if coloring == "VertexColors": geometry.exec_three_obj_method('computeVertexNormals') else: geometry.exec_three_obj_method('computeFaceNormals') # Mesh setup mesh = p3s.Mesh(geometry=geometry, material=material) # Wireframe setup mesh_obj["wireframe"] = None if sh["wireframe"]: wf_geometry = p3s.WireframeGeometry(mesh.geometry) # WireframeGeometry wf_material = p3s.LineBasicMaterial(color=sh["wire_color"], linewidth=sh["wire_width"]) wireframe = p3s.LineSegments(wf_geometry, wf_material) mesh.add(wireframe) mesh_obj["wireframe"] = wireframe # Bounding box setup if sh["bbox"]: v_box, f_box = self.__get_bbox(v) _, bbox = self.add_edges(v_box, f_box, sh, mesh) mesh_obj["bbox"] = [bbox, v_box, f_box] # Object setup mesh_obj["max"] = np.max(v, axis=0) mesh_obj["min"] = np.min(v, axis=0) mesh_obj["geometry"] = geometry mesh_obj["mesh"] = mesh mesh_obj["material"] = material mesh_obj["type"] = "Mesh" mesh_obj["shading"] = sh mesh_obj["coloring"] = coloring mesh_obj["arrays"] = [v, f, c] # TODO replays with proper storage or remove if not needed return self.__add_object(mesh_obj)