예제 #1
0
def axes(max_dist, axis_rad=0.25, axis_color='yellow'):
    """
    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
    axis_rad : float
                radius of cylinder representing each axis (default: 0.25)
    axis_color : color
                color the axes are drawn in (default: 'yellow')

    Returns
    -------
    Xaxis, Yaxis, Zaxis : pythreejs.Mesh*3
            Three pythreejs Mesh objects representing the x, y, and z axes.
    """
    Xaxis = p3j.Mesh(geometry=p3j.CylinderBufferGeometry(radiusTop=axis_rad, radiusBottom=axis_rad, 
                                                height=max_dist, 
                                                radiusSegments=12, 
                                                heightSegments=1, 
                                                openEnded=False, 
                                                thetaStart=0, thetaLength=2*np.pi), 
                material=p3j.MeshBasicMaterial(color=axis_color),
                position=[max_dist/2, 0, 0])
    Xaxis.rotateZ(np.pi/2)
    
    Yaxis = p3j.Mesh(geometry=p3j.CylinderBufferGeometry(radiusTop=axis_rad, radiusBottom=axis_rad, 
                                                height=max_dist, 
                                                radiusSegments=12, 
                                                heightSegments=1, 
                                                openEnded=False, 
                                                thetaStart=0, thetaLength=2*np.pi), 
                material=p3j.MeshBasicMaterial(color=axis_color),
                position=[0, max_dist/2, 0])
    
    Zaxis = p3j.Mesh(geometry=p3j.CylinderBufferGeometry(radiusTop=axis_rad, radiusBottom=axis_rad, 
                                                height=max_dist, 
                                                radiusSegments=12, 
                                                heightSegments=1, 
                                                openEnded=False, 
                                                thetaStart=0, thetaLength=2*np.pi), 
                material=p3j.MeshBasicMaterial(color=axis_color),
                position=[0, 0, max_dist/2])
    Zaxis.rotateX(np.pi/2)

    return Xaxis, Yaxis, Zaxis
예제 #2
0
    def _ipython_display_(self):
        # This needs to actually display, which is not the same as returning a display.
        cam = pythreejs.PerspectiveCamera(
            position=[25, 35, 100],
            fov=20,
            children=[pythreejs.AmbientLight()],
        )
        children = [cam, pythreejs.AmbientLight(color="#dddddd")]
        material = pythreejs.MeshBasicMaterial(color="#ff0000",
                                               vertexColors="VertexColors",
                                               side="DoubleSide")
        for model in self.components:
            mesh = pythreejs.Mesh(geometry=model.geometry,
                                  material=material,
                                  position=[0, 0, 0])
            children.append(mesh)

        scene = pythreejs.Scene(children=children)

        rendererCube = pythreejs.Renderer(
            camera=cam,
            background="white",
            background_opacity=1,
            scene=scene,
            controls=[pythreejs.OrbitControls(controlling=cam)],
            width=800,
            height=800,
        )

        return rendererCube
예제 #3
0
    def add_view_frustum():
        position = np.array(lm_camera_params['eye'])
        center = np.array(lm_camera_params['center'])
        up = np.array(lm_camera_params['up'])
        aspect = lm_camera_params['aspect']
        fov = math.radians(lm_camera_params['vfov'])

        M = lookat_matrix(position, center, up)
        z = 5
        half_fov = fov * .5
        y = math.tan(half_fov) * z
        x = aspect * y

        p = list(position)
        p1 = list(position + np.dot(M, [-x, -y, -z]))
        p2 = list(position + np.dot(M, [x, -y, -z]))
        p3 = list(position + np.dot(M, [x, y, -z]))
        p4 = list(position + np.dot(M, [-x, y, -z]))

        # Add mesh
        geom = three.Geometry(
            vertices=[p, p1, p2, p, p2, p3, p, p3, p4, p, p4, p1])
        mat = three.MeshBasicMaterial(color='#00ff00',
                                      wireframe=True,
                                      side='DoubleSide')
        mesh = three.Line(geometry=geom, material=mat)
        scene.add(mesh)
예제 #4
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
예제 #5
0
def OldStarMesh(temp=Te_Sun, rad=1,  scale=(1, 1, 1), pos=[0, 0, 0]):
    """
    This function creates a pythreejs object that represents a star using
    a texture based on public domain STEREO Heliographic map made with
    images taken of the Sun on Dec. 30, 2011.  Image downloaded from
       https://stereo.gsfc.nasa.gov/360blog/
    and had its brightness and resolution rescaled.

    Parameters
    ----------
    temp : float
            temperature of star in Kelvin (default 5777)
    rad : float
            radius of the star in system units (default 1)
    scale : tuple
             pythreejs scale in each dimension as tuple (default (1, 1, 1) )
    pos : list
           three-dimensional position as list (default [0, 0, 0] )

    Returns
    -------
    star : pythreejs.Mesh
              a spherical pythreejs Mesh object representing a star
    """

    # Check is position is a list
    if isinstance(pos, list):
        # Check if this is a list of 3 items
        if (len(pos) != 3):
            raise TypeError('pos passed to StarMesh must be list of 3 numbers')
        # Check that all the items in the list are numbers
        for this_pos in pos:
            try:
                i = float(this_pos)
            except ValueError:
                raise TypeError('ValueError: pos contains list item that is not a number.')
    else:
        raise TypeError('pos passed to StarMesh must be list of 3 numbers')

    # Check is scale is a tuple
    if isinstance(scale, tuple):
        if (len(scale) != 3):
            raise TypeError('scale passed to StarMesh must be tuple of 3 numbers')
    else:
        raise TypeError('scale must be a tuple')

    # Define color and texture of star surface
    hexcolor = tc.rgb2hex(tc.temp2rgb(float(temp)))[0]
    StarTexture = p3j.ImageTexture(imageUri='images/sun_surface.jpg')

    # Create sphere using MeshBasicMaterial (which is unaffected by lighting)
    StarSurface = p3j.MeshBasicMaterial(color=hexcolor, map=StarTexture)

    StarGeom = p3j.SphereBufferGeometry(radius=rad, widthSegments=32,
                                        heightSegments=16)
    return p3j.Mesh(geometry=StarGeom, material=StarSurface,
                    position=pos, scale=scale)
예제 #6
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
예제 #7
0
    def mesh(self):
        import numpy as np
        import pythreejs as js

        wireframe = self.view_data.get('wireframe', False)

        def triangles(polygon):
            points = polygon.points
            return [(points[0], points[ix], points[ix + 1])
                    for ix in range(1, len(polygon.points) - 1)]

        def _ba(vs):
            points = np.array(vs, dtype=np.float32)
            return js.BufferAttribute(array=points, normalized=False)

        vertices = [
            list(p.xyz) for polygon in self.polygons
            for t in triangles(polygon)
            for p in t
        ]
        normals = [
            list(polygon.plane.normal.xyz) for polygon in self.polygons
            for t in triangles(polygon)
            for p in t
        ]

        geometry = js.BufferGeometry(
            attributes={
                'position': _ba(vertices),
                'normal': _ba(normals)
            },
        )

        if not wireframe:
            color = self.view_data.get('color', 'white')
            material = material=js.MeshLambertMaterial(color=color)
            opacity = self.view_data.get('opacity')
            if opacity is not None:
                material.opacity = opacity
                material.transparent = True
            return js.Mesh(geometry, material)
        else:
            color = self.view_data.get('color', '#00ff00')
            material = js.MeshBasicMaterial(color=color, wireframe=True)
            return js.Mesh(geometry, material)
예제 #8
0
def display_portal(th_scene, portal):
    """Display portal."""
    def portal_vertices(portal):
        p1 = np.array(portal[0])
        p2 = np.array(portal[1])
        p4 = np.array(portal[2])
        p3 = p1 + (p2 - p1) + (p4 - p1)
        return [p1, p2, p3, p1, p3, p4]

    ps_attr = three.BufferAttribute(array=portal_vertices(portal),
                                    normalized=False)
    geom = three.BufferGeometry(attributes={'position': ps_attr})
    mat = three.MeshBasicMaterial(color='#ff0000',
                                  transparent=True,
                                  opacity=0.1,
                                  side='DoubleSide')
    mesh = three.Mesh(geometry=geom, material=mat)
    th_scene.add(mesh)
예제 #9
0
    def add_lm_scene_mesh():
        # Default material
        mat_default = three.MeshBasicMaterial(color='#000000',
                                              wireframe=True,
                                              transparent=True,
                                              opacity=0.2,
                                              depthTest=False)

        # Convert lm mesh
        def traverse_func(node, trans):
            # Underlying mesh
            mesh = node.primitive.mesh
            if mesh is None:
                return

            # Iterate through all triangles
            vs = []

            def process_triangle(face_index, tri):
                vs.append(list(tri.p1.p))
                vs.append(list(tri.p2.p))
                vs.append(list(tri.p3.p))

            mesh.foreach_triangle(process_triangle)

            # Create geometry
            ps_attr = three.BufferAttribute(array=vs, normalized=False)
            geom = three.BufferGeometry(attributes={'position': ps_attr})

            # Create mesh
            mesh = three.Mesh(geometry=geom, material=mat_default)
            mesh.matrixAutoUpdate = False
            mesh.matrix = trans.T.flatten().tolist()
            scene.add(mesh)

        lm_scene.traverse_primitive_nodes(traverse_func)
예제 #10
0
def StarMesh(temp=Te_Sun, rad=1, scale=(1, 1, 1), pos=[0, 0, 0]):
    """
    This function creates a pythreejs object that represents a star using
    a set of nested spheres that are partly transparent to simulate limb
    darkening.

    Parameters
    ----------
    temp : float
            temperature of star in Kelvin (default 5777)
    rad : float
            radius of the star in system units (default 1)
    scale : tuple
             pythreejs scale in each dimension as tuple (default (1, 1, 1) )
    pos : list
           three-dimensional position as list (default [0, 0, 0] )

    Returns
    -------
    star : pythreejs.Mesh
              a spherical pythreejs Mesh object representing a star
    """

    # Check is position is a list
    if isinstance(pos, list):
        # Check if this is a list of 3 items
        if (len(pos) != 3):
            raise TypeError('pos passed to StarMesh must be list of 3 numbers')
        # Check that all the items in the list are numbers
        for this_pos in pos:
            try:
                i = float(this_pos)
            except ValueError:
                raise TypeError(
                    'ValueError: pos contains list item that is not a number.')
    else:
        raise TypeError('pos passed to StarMesh must be list of 3 numbers')

    # Check is scale is a tuple
    if isinstance(scale, tuple):
        if (len(scale) != 3):
            raise TypeError(
                'scale passed to StarMesh must be tuple of 3 numbers')
    else:
        raise TypeError('scale must be a tuple')

    # Define color of star surface
    hexcolor = tc.rgb2hex(tc.temp2rgb(float(temp)))[0]

    # Number of transparent layers to use to build star
    layers = 20

    # Radial scaling
    drad = 0.97

    # Starting resolution
    N_azi, N_pol = 32, 16

    # Layer opacity
    tau = 0.4

    # Radii to use
    radii = rad * drad**np.array(range(layers - 1, -1, -1))

    # 3D object to represent star
    star = p3j.Object3D()

    # Build the object from inside out
    for i in range(layers):
        # Tweak number of vertices in sphere up for the outer surface sphere
        if (i > (layers - 2)):
            N_azi *= 2
            N_pol *= 2

        geom = p3j.SphereBufferGeometry(radius=radii[i],
                                        widthSegments=N_azi,
                                        heightSegments=N_pol,
                                        renderOrder=-i)

        material = p3j.MeshBasicMaterial(color=hexcolor,
                                         transparent=True,
                                         opacity=tau)
        star.add(p3j.Mesh(geom, material))

    # Set the position and scale of this mesh
    star.position = pos
    star.scale = scale

    return star
예제 #11
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))
예제 #12
0
def to_surf_mesh(actor, surf, mapper, prop, add_attr={}):
    """Convert a pyvista surface to a buffer geometry.

    General Notes
    -------------

    * THREE.BufferGeometry expects position and index attributes
      representing a triangulated mesh points and face indices or just
      a position array representing individual faces of a mesh.
    * The normals attribute is needed for physically based rendering,
      but not for the other mesh types.
    * Colors must be a RGB array with one value per point.

    Shading Notes
    -------------
    To match VTK, the following materials are used to match VTK's shading:

    * MeshPhysicalMaterial when physically based rendering is enabled
    * MeshPhongMaterial when physically based rendering is disabled,
      but lighting is enabled.
    * MeshBasicMaterial when lighting is disabled.

    """
    # convert to an all-triangular surface
    if surf.is_all_triangles():
        trimesh = surf
    else:
        trimesh = surf.triangulate()

    position = array_to_float_buffer(trimesh.points)

    # convert to minimum index type
    face_ind = trimesh.faces.reshape(-1, 4)[:, 1:]
    index = cast_to_min_size(face_ind, trimesh.n_points)
    attr = {
        'position': position,
        'index': index,
    }

    if prop.GetInterpolation():  # something other than flat shading
        attr['normal'] = buffer_normals(trimesh)

    # extract point/cell scalars for coloring
    colors = None
    scalar_mode = mapper.GetScalarModeAsString()
    if scalar_mode == 'UsePointData':
        colors = map_scalars(mapper, trimesh.point_data.active_scalars)
    elif scalar_mode == 'UseCellData':
        # special handling for RGBA
        if mapper.GetColorMode() == 2:
            scalars = trimesh.cell_data.active_scalars.repeat(3, axis=0)
            scalars = scalars.astype(np.float32, copy=False)
            colors = scalars[:, :3] / 255  # ignore alpha
        else:
            # must repeat for each triangle
            scalars = trimesh.cell_data.active_scalars.repeat(3)
            colors = map_scalars(mapper, scalars)

        position = array_to_float_buffer(trimesh.points[face_ind])
        attr = {'position': position}

    # add colors to the buffer geometry attributes
    if colors is not None:
        attr['color'] = array_to_float_buffer(colors)

    # texture coordinates
    t_coords = trimesh.active_t_coords
    if t_coords is not None:
        attr['uv'] = array_to_float_buffer(t_coords)

    # TODO: Convert PBR textures
    # base_color_texture = prop.GetTexture("albedoTex")
    # orm_texture = prop.GetTexture("materialTex")
    # anisotropy_texture = prop.GetTexture("anisotropyTex")
    # normal_texture = prop.GetTexture("normalTex")
    # emissive_texture = prop.GetTexture("emissiveTex")
    # coatnormal_texture = prop.GetTexture("coatNormalTex")
    if prop.GetNumberOfTextures():  # pragma: no cover
        warnings.warn(
            'pythreejs converter does not support PBR textures (yet).')

    # create base buffer geometry
    surf_geo = tjs.BufferGeometry(attributes=attr)

    # add texture to the surface buffer if available
    texture = actor.GetTexture()
    tjs_texture = None
    if texture is not None:
        wrapped_tex = pv.wrap(texture.GetInput())
        data = wrapped_tex.active_scalars
        dim = (wrapped_tex.dimensions[0], wrapped_tex.dimensions[1],
               data.shape[1])
        data = data.reshape(dim)
        fmt = "RGBFormat" if data.shape[1] == 3 else "RGBAFormat"

        # Create data texture and catch invalid warning
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore",
                                    message="Given trait value dtype")
            tjs_texture = tjs.DataTexture(data=data,
                                          format="RGBFormat",
                                          type="UnsignedByteType")

    # these attributes are always used regardless of the material
    shared_attr = {
        'vertexColors': get_coloring(mapper, trimesh),
        'wireframe': prop.GetRepresentation() == 1,
        'opacity': prop.GetOpacity(),
        'wireframeLinewidth': prop.GetLineWidth(),
        # 'side': 'DoubleSide'  # enabling seems to mess with textures
    }

    if colors is None:
        shared_attr['color'] = color_to_hex(prop.GetColor())

    if tjs_texture is not None:
        shared_attr['map'] = tjs_texture
    else:
        shared_attr['side'] = 'DoubleSide'

    if prop.GetOpacity() < 1.0:
        shared_attr['transparent'] = True

    if prop.GetInterpolation() == 3:  # using physically based rendering
        material = tjs.MeshPhysicalMaterial(flatShading=False,
                                            roughness=prop.GetRoughness(),
                                            metalness=prop.GetMetallic(),
                                            reflectivity=0,
                                            **shared_attr,
                                            **add_attr)
    elif prop.GetLighting():
        # specular disabled to fix lighting issues
        material = tjs.MeshPhongMaterial(
            shininess=0,
            flatShading=prop.GetInterpolation() == 0,
            specular=color_to_hex((0, 0, 0)),
            reflectivity=0,
            **shared_attr,
            **add_attr)
    else:  # no lighting
        material = tjs.MeshBasicMaterial(**shared_attr, **add_attr)

    return tjs.Mesh(geometry=surf_geo, material=material)
예제 #13
0
파일: plot_2d.py 프로젝트: sciview/sciview
def plot_2d(x, y, data, cmap="viridis", vmin=None, vmax=None):


    # if len(x) != len(y):
    #     raise RuntimeError("bad shape")

    N = data.size

    dx = config.figure["width"]
    dy = config.figure["height"]

    xe = centers_to_edges(x)
    ye = centers_to_edges(y)

    xmin = np.amin(xe)
    ymin = np.amin(ye)

    scale_x = dx / (np.amax(xe) - xmin)
    scale_y = dy / (np.amax(ye) - ymin)






    # # x_grid, y_grid = np.meshgrid((x - xmin) * scale_x, (y - ymin) * scale_y, indexing="ij")
    # y_grid, x_grid = np.meshgrid((y - ymin) * scale_y, (x - xmin) * scale_x, indexing="ij")

    # pixel_size_x = (xe[1] - xe[0]) * scale_x
    # pixel_size_y = (ye[1] - ye[0]) * scale_y

    # pts = np.zeros([N, 3], dtype=np.float32)
    # pts[:, 0] = x_grid.flatten()
    # pts[:, 1] = y_grid.flatten()






    # pts = p3.BufferAttribute(array=det_pos)

    scalar_map = get_cmap(data=None, cmap="viridis", log=False, vmin=None, vmax=None)
    colors = scalar_map.to_rgba(data).astype(np.float32)

    # colors = p3.BufferAttribute(
    #     array=scalar_map.to_rgba(data).astype(np.float32))

    nx = xe.shape[0] - 1
    ny = ye.shape[0] - 1
    npixels = nx * ny


    arr_x = np.zeros(2 * nx, dtype=np.float32)
    arr_x[::2] = xe[:-1]
    arr_x[1::2] = xe[1:]
    arr_y = np.zeros(2 * ny, dtype=np.float32)
    arr_y[::2] = ye[:-1]
    arr_y[1::2] = ye[1:]

    x_grid, y_grid = np.meshgrid((arr_x - xmin) * scale_x, (arr_y - ymin) * scale_y)
    # x_grid, y_grid = np.meshgrid(arr_x, arr_y)

    # print(arr_x.dtype)
    # print(x_grid.dtype, y_grid.dtype)
    # print(x_grid.ravel().dtype)
    vertices = np.array([x_grid.ravel(), y_grid.ravel(), np.zeros(x_grid.size, dtype=np.float32)]).T
    del x_grid, y_grid

    face_elem = np.array([[0, 1, nx*2], [1, nx*2+1, nx*2]], dtype=np.uint32)

    # faces = np.tile

    # self.vertices = np.tile(detector_shape, [self.ndets, 1]) + np.repeat(self.det_pos, self.nverts, axis=0)

    # faces = np.arange(self.nverts * self.ndets, dtype=np.uint)
    faces = np.tile(face_elem, [npixels, 1]) + \
            np.repeat(np.arange(0, npixels*2, 2, dtype=np.uint32), 2*3, axis=0).reshape(npixels*2, 3) + \
            np.repeat(np.arange(0, (nx*2)*ny, nx*2, dtype=np.uint32), (nx*2)*3, axis=0).reshape(npixels*2, 3)


    # faces = np.tile(detector_faces, [self.ndets, 1]) + np.repeat(
    #     np.arange(0, self.ndets*self.nverts, self.nverts, dtype=np.uint32), self.nfaces*3, axis=0).reshape(self.nfaces*self.ndets, 3)

    # vertexcolors = np.repeat(colors[:, :3], 4, axis=0).astype(np.float32)

    vertexcolors = np.zeros([2*nx, 2*ny, 3], dtype=np.float32)
    # print(np.shape(vertexcolors))
    # print(np.shape(vertexcolors[::2, ::2, :]))
    # print(np.shape(colors[:, :, :3]))
    vertexcolors[::2, ::2, :] = colors[:, :, :3]
    vertexcolors[1::2, 1::2, :] = colors[:, :, :3]
    vertexcolors[1::2, ::2, :] = colors[:, :, :3]
    vertexcolors[::2, 1::2, :] = colors[:, :, :3]
    # arr_y = np.zeros(2 * ny, dtype=np.float32)
    # arr_y[::2] = ye[:-1]
    # arr_y[1::2] = ye[1:]
    del colors

    # vertexcolors = np.zeros([npixels*2, 3], dtype=np.float32)

    # print(vertices.shape)
    # print(faces.shape)
    # print(vertexcolors.shape)
    # print(vertices.dtype)
    # print(faces.dtype)
    # print(vertexcolors.dtype)

    # print("vertices")
    # print(vertices)
    # print("faces")
    # print(faces)
    # print("colors")
    # print(vertexcolors)
    # print(colors)


    geometry = p3.BufferGeometry(attributes=dict(
        position=p3.BufferAttribute(vertices, normalized=False),
        index=p3.BufferAttribute(faces.ravel(), normalized=False),
        color=p3.BufferAttribute(vertexcolors.reshape(4*nx*ny, 3, order='F')),
    ))


    material = p3.MeshBasicMaterial(vertexColors='VertexColors')
    # material = p3.MeshBasicMaterial()

    # self.material = self.p3.MeshPhongMaterial(vertexColors='VertexColors',
    #                                           transparent=True)


    image = p3.Mesh(geometry=geometry, material=material)







    # geometry = p3.BufferGeometry(attributes={
    #     'position': p3.BufferAttribute(array=pts),
    #     'color': p3.BufferAttribute(
    #         array=scalar_map.to_rgba(data).astype(np.float32))
    # })
    # material = p3.PointsMaterial(vertexColors='VertexColors',
    #                                        size=pixel_size_x)
    #                                        # map=texture,
    #                                        # depthTest=False,
    #                                        # transparent=True)
    # image = p3.Points(geometry=geometry, material=material)





    # # 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.5*dx],
    #                                         aspect=dx / dy)
    # camera = p3.PerspectiveCamera(45, dx/dy, 1, 5000)
    camera = p3.OrthographicCamera(0, dx, dy, 0, 0.5*dx, -0.5*dx)

    return render(objects=image, camera=camera,
                  enableRotate=True, width=dx, height=dy)
예제 #14
0
def hand_obj_children(
    obj_verts=None,
    obj_faces=None,
    gt_obj_verts=None,
    gt_obj_faces=None,
    hand_verts=None,
    mano_faces_left=None,
    display_wireframe=False,
    inside_face_colors=True,
    hand_opacity=1,
    obj_opacity=0.2,
):
    """Args:
        obj_verts(numpy.ndarray): vertices of object
        hand_verts(numpy.ndarray): vertices of handect
        *_faces(numpy.ndarray): faces
    """

    scene_children = []
    if obj_verts is not None:
        geo_obj = p3js.Geometry(vertices=obj_verts.tolist(),
                                faces=obj_faces.tolist())
        geo_obj.exec_three_obj_method("computeFaceNormals")
        mat = p3js.MeshLambertMaterial(color="red",
                                       side="FrontSide",
                                       transparent=True)
        mat.opacity = obj_opacity  # obj_opacity
        surf_obj = p3js.Mesh(geometry=geo_obj, material=mat)
        if inside_face_colors:
            back_color = "#a91818"
        else:
            back_color = "red"
        mat_bak = p3js.MeshLambertMaterial(color=back_color,
                                           side="BackSide",
                                           transparent=True)
        mat_bak.opacity = obj_opacity
        surf_obj_back = p3js.Mesh(geometry=geo_obj, material=mat_bak)
        scene_children.append(surf_obj)
        scene_children.append(surf_obj_back)
        if display_wireframe:
            obj_edges = p3js.Mesh(
                geometry=geo_obj,
                material=p3js.MeshBasicMaterial(color="black", wireframe=True),
            )
            scene_children.append(obj_edges)
    if gt_obj_verts is not None:
        geo_obj = p3js.Geometry(vertices=gt_obj_verts.tolist(),
                                faces=gt_obj_faces.tolist())
        geo_obj.exec_three_obj_method("computeFaceNormals")
        mat = p3js.MeshLambertMaterial(color="orange",
                                       side="FrontSide",
                                       transparent=True)
        mat.opacity = obj_opacity
        surf_obj = p3js.Mesh(geometry=geo_obj, material=mat)
        mat_back = p3js.MeshLambertMaterial(color="#a91818",
                                            side="BackSide",
                                            transparent=True)
        mat_back.opacity = obj_opacity
        surf_obj_back = p3js.Mesh(geometry=geo_obj, material=mat_bak)
        scene_children.append(surf_obj)
        scene_children.append(surf_obj_back)
        if display_wireframe:
            obj_edges = p3js.Mesh(
                geometry=geo_obj,
                material=p3js.MeshBasicMaterial(color="black", wireframe=True),
            )
            scene_children.append(obj_edges)
    if hand_verts is not None:
        geo_hand = p3js.Geometry(vertices=hand_verts.tolist(),
                                 faces=mano_faces_left.tolist())
        geo_hand.exec_three_obj_method("computeFaceNormals")
        mat = p3js.MeshLambertMaterial(color="blue",
                                       side="FrontSide",
                                       transparent=True)
        mat.opacity = hand_opacity
        surf_hand = p3js.Mesh(geometry=geo_hand, material=mat)
        bak_mat = p3js.MeshLambertMaterial(color="blue",
                                           side="BackSide",
                                           transparent=True)
        bak_mat.opacity = hand_opacity
        surf_hand_bak = p3js.Mesh(geometry=geo_hand, material=bak_mat)

        scene_children.append(surf_hand)
        scene_children.append(surf_hand_bak)
        if display_wireframe:
            hand_edges = p3js.Mesh(
                geometry=geo_hand,
                material=p3js.MeshBasicMaterial(color="black", wireframe=True),
            )
            scene_children.append(hand_edges)

    return scene_children
예제 #15
0
normals = np.zeros(faces.shape)
normals += np.array([0, 1, 0])
geometry = THREE.BufferGeometry(
    attributes={
        'position':
        THREE.BufferAttribute(np.array(x0, dtype=np.float32),
                              normalized=False),
        'normal':
        THREE.BufferAttribute(np.array(normals, dtype=np.float32),
                              normalized=False),
        'index':
        THREE.BufferAttribute(np.array(faces.ravel(), dtype=np.uint16)),
    })
mesh = THREE.Mesh(
    geometry,
    THREE.MeshBasicMaterial(sice='DoubleSide', wireframe=True, color='red'))


# %%
def viewer_cloth(cloth):
    view_width = 800
    view_height = 600
    camera = THREE.PerspectiveCamera(position=[20, 5, 30],
                                     aspect=view_width / view_height)
    key_light = THREE.DirectionalLight(position=[10, 10, 10])
    ambient_light = THREE.AmbientLight()
    axes_helper = THREE.AxesHelper(0.5)

    scene = THREE.Scene()
    controller = THREE.OrbitControls(controlling=camera)
    renderer = THREE.Renderer(camera=camera,
예제 #16
0
 def allocateWireframeMaterial(self):
     return pythreejs.MeshBasicMaterial(color='black', side='DoubleSide', wireframe=True, morphTargets=True)
예제 #17
0
def generate_3js_render(
    element_groups,
    canvas_size,
    zoom,
    camera_fov=30,
    background_color="white",
    background_opacity=1.0,
    reuse_objects=False,
    use_atom_arrays=False,
    use_label_arrays=False,
):
    """Create a pythreejs scene of the elements.

    Regarding initialisation performance, see: https://github.com/jupyter-widgets/pythreejs/issues/154
    """
    import pythreejs as pjs

    key_elements = {}
    group_elements = pjs.Group()
    key_elements["group_elements"] = group_elements

    unique_atom_sets = {}
    for el in element_groups["atoms"]:
        element_hash = (
            ("radius", el.sradius),
            ("color", el.color),
            ("fill_opacity", el.fill_opacity),
            ("stroke_color", el.get("stroke_color", "black")),
            ("ghost", el.ghost),
        )
        unique_atom_sets.setdefault(element_hash, []).append(el)

    group_atoms = pjs.Group()
    group_ghosts = pjs.Group()

    atom_geometries = {}
    atom_materials = {}
    outline_materials = {}

    for el_hash, els in unique_atom_sets.items():
        el = els[0]
        data = dict(el_hash)

        if reuse_objects:
            atom_geometry = atom_geometries.setdefault(
                el.sradius,
                pjs.SphereBufferGeometry(radius=el.sradius,
                                         widthSegments=30,
                                         heightSegments=30),
            )
        else:
            atom_geometry = pjs.SphereBufferGeometry(radius=el.sradius,
                                                     widthSegments=30,
                                                     heightSegments=30)

        if reuse_objects:
            atom_material = atom_materials.setdefault(
                (el.color, el.fill_opacity),
                pjs.MeshLambertMaterial(color=el.color,
                                        transparent=True,
                                        opacity=el.fill_opacity),
            )
        else:
            atom_material = pjs.MeshLambertMaterial(color=el.color,
                                                    transparent=True,
                                                    opacity=el.fill_opacity)

        if use_atom_arrays:
            atom_mesh = pjs.Mesh(geometry=atom_geometry,
                                 material=atom_material)
            atom_array = pjs.CloneArray(
                original=atom_mesh,
                positions=[e.position.tolist() for e in els],
                merge=False,
            )
        else:
            atom_array = [
                pjs.Mesh(
                    geometry=atom_geometry,
                    material=atom_material,
                    position=e.position.tolist(),
                    name=e.info_string,
                ) for e in els
            ]

        data["geometry"] = atom_geometry
        data["material_body"] = atom_material

        if el.ghost:
            key_elements["group_ghosts"] = group_ghosts
            group_ghosts.add(atom_array)
        else:
            key_elements["group_atoms"] = group_atoms
            group_atoms.add(atom_array)

        if el.get("stroke_width", 1) > 0:
            if reuse_objects:
                outline_material = outline_materials.setdefault(
                    el.get("stroke_color", "black"),
                    pjs.MeshBasicMaterial(
                        color=el.get("stroke_color", "black"),
                        side="BackSide",
                        transparent=True,
                        opacity=el.get("stroke_opacity", 1.0),
                    ),
                )
            else:
                outline_material = pjs.MeshBasicMaterial(
                    color=el.get("stroke_color", "black"),
                    side="BackSide",
                    transparent=True,
                    opacity=el.get("stroke_opacity", 1.0),
                )
            # TODO use stroke width to dictate scale
            if use_atom_arrays:
                outline_mesh = pjs.Mesh(
                    geometry=atom_geometry,
                    material=outline_material,
                    scale=(1.05, 1.05, 1.05),
                )
                outline_array = pjs.CloneArray(
                    original=outline_mesh,
                    positions=[e.position.tolist() for e in els],
                    merge=False,
                )
            else:
                outline_array = [
                    pjs.Mesh(
                        geometry=atom_geometry,
                        material=outline_material,
                        position=e.position.tolist(),
                        scale=(1.05, 1.05, 1.05),
                    ) for e in els
                ]

            data["material_outline"] = outline_material

            if el.ghost:
                group_ghosts.add(outline_array)
            else:
                group_atoms.add(outline_array)

        key_elements.setdefault("atom_arrays", []).append(data)

    group_elements.add(group_atoms)
    group_elements.add(group_ghosts)

    group_labels = add_labels(element_groups, key_elements, use_label_arrays)
    group_elements.add(group_labels)

    if len(element_groups["cell_lines"]) > 0:
        cell_line_mat = pjs.LineMaterial(
            linewidth=1,
            color=element_groups["cell_lines"].group_properties["color"])
        cell_line_geo = pjs.LineSegmentsGeometry(positions=[
            el.position.tolist() for el in element_groups["cell_lines"]
        ])
        cell_lines = pjs.LineSegments2(geometry=cell_line_geo,
                                       material=cell_line_mat)
        key_elements["cell_lines"] = cell_lines
        group_elements.add(cell_lines)

    if len(element_groups["bond_lines"]) > 0:
        bond_line_mat = pjs.LineMaterial(
            linewidth=element_groups["bond_lines"].
            group_properties["stroke_width"],
            vertexColors="VertexColors",
        )
        bond_line_geo = pjs.LineSegmentsGeometry(
            positions=[
                el.position.tolist() for el in element_groups["bond_lines"]
            ],
            colors=[[Color(c).rgb for c in el.color]
                    for el in element_groups["bond_lines"]],
        )
        bond_lines = pjs.LineSegments2(geometry=bond_line_geo,
                                       material=bond_line_mat)
        key_elements["bond_lines"] = bond_lines
        group_elements.add(bond_lines)

    group_millers = pjs.Group()
    if len(element_groups["miller_lines"]) or len(
            element_groups["miller_planes"]):
        key_elements["group_millers"] = group_millers

    if len(element_groups["miller_lines"]) > 0:
        miller_line_mat = pjs.LineMaterial(
            linewidth=3,
            vertexColors="VertexColors"  # TODO use stroke_width
        )
        miller_line_geo = pjs.LineSegmentsGeometry(
            positions=[
                el.position.tolist() for el in element_groups["miller_lines"]
            ],
            colors=[[Color(el.stroke_color).rgb] * 2
                    for el in element_groups["miller_lines"]],
        )
        miller_lines = pjs.LineSegments2(geometry=miller_line_geo,
                                         material=miller_line_mat)
        group_millers.add(miller_lines)

    for el in element_groups["miller_planes"]:
        vertices = el.position.tolist()
        faces = [(
            0,
            1,
            2,
            triangle_normal(vertices[0], vertices[1], vertices[2]),
            "black",
            0,
        )]
        if len(vertices) == 4:
            faces.append((
                2,
                3,
                0,
                triangle_normal(vertices[2], vertices[3], vertices[0]),
                "black",
                0,
            ))
        elif len(vertices) != 3:
            raise NotImplementedError("polygons with more than 4 points")
        plane_geom = pjs.Geometry(vertices=vertices, faces=faces)
        plane_mat = pjs.MeshBasicMaterial(
            color=el.fill_color,
            transparent=True,
            opacity=el.fill_opacity,
            side="DoubleSide",
        )
        plane_mesh = pjs.Mesh(geometry=plane_geom, material=plane_mat)
        group_millers.add(plane_mesh)

    group_elements.add(group_millers)

    scene = pjs.Scene(background=None)
    scene.add([group_elements])

    view_width, view_height = canvas_size

    minp, maxp = element_groups.get_position_range()
    # compute a minimum camera distance, that is guaranteed to encapsulate all elements
    camera_dist = maxp[2] + sqrt(maxp[0]**2 + maxp[1]**2) / tan(
        radians(camera_fov / 2))

    camera = pjs.PerspectiveCamera(
        fov=camera_fov,
        position=[0, 0, camera_dist],
        aspect=view_width / view_height,
        zoom=zoom,
    )
    scene.add([camera])
    ambient_light = pjs.AmbientLight(color="lightgray")
    key_elements["ambient_light"] = ambient_light
    direct_light = pjs.DirectionalLight(position=(maxp * 2).tolist())
    key_elements["direct_light"] = direct_light
    scene.add([camera, ambient_light, direct_light])

    camera_control = pjs.OrbitControls(controlling=camera,
                                       screenSpacePanning=True)

    atom_picker = pjs.Picker(controlling=group_atoms, event="dblclick")
    key_elements["atom_picker"] = atom_picker
    material = pjs.SpriteMaterial(
        map=create_arrow_texture(right=False),
        transparent=True,
        depthWrite=False,
        depthTest=False,
    )
    atom_pointer = pjs.Sprite(material=material,
                              scale=(4, 3, 1),
                              visible=False)
    scene.add(atom_pointer)
    key_elements["atom_pointer"] = atom_pointer

    renderer = pjs.Renderer(
        camera=camera,
        scene=scene,
        controls=[camera_control, atom_picker],
        width=view_width,
        height=view_height,
        alpha=True,
        clearOpacity=background_opacity,
        clearColor=background_color,
    )
    return renderer, key_elements