Exemple #1
0
    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]
Exemple #3
0
 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
Exemple #4
0
    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)
Exemple #5
0
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')
Exemple #6
0
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
Exemple #7
0
 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)
Exemple #8
0
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)
Exemple #9
0
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
Exemple #10
0
 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]
Exemple #11
0
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
Exemple #12
0
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
Exemple #13
0
    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)
Exemple #14
0
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))
Exemple #15
0
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
Exemple #16
0
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
Exemple #17
0
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)
Exemple #19
0
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
Exemple #20
0
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)
Exemple #21
0
    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
Exemple #22
0
    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)
Exemple #23
0
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'))
Exemple #24
0
    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
Exemple #25
0
    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))
Exemple #26
0
    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)