def __init__(self):
        self.rotation = AffineTransform()

        # Generate some data to work with
        x,y,z,d = radar_example_data()
        print x.shape, y.shape, z.shape
        print d.shape, d.min(), d.max()

        verts, faces = mesh_from_quads(x,y,z)
        face_colors = np.empty((faces.shape[0], 4))
        face_colors[0::2,0] = d.flat
        face_colors[0::2,1] = d.flat
        face_colors[0::2,2] = d.flat
        face_colors[1::2,0] = d.flat
        face_colors[1::2,1] = d.flat
        face_colors[1::2,2] = d.flat
        face_colors[:,3] = 1.0 # transparency
        mdata = MeshData(vertices=verts, faces=faces, face_colors=face_colors)
        mesh = Mesh(meshdata=mdata)
        mesh.transform = vispy.scene.transforms.AffineTransform()
        mesh.transform.scale([1./10, 1./10, 1./10])
        
        vispy.scene.SceneCanvas.__init__(self, keys='interactive')

        self.size = (800, 800)
        self.show()
        view = self.central_widget.add_view()
        # view.set_camera('turntable', mode='ortho', up='z', distance=2)
        view.camera='turntable'
        view.camera.mode='ortho'
        view.camera.up='z'
        view.camera.distance=20
        view.add(mesh)
Exemple #2
0
def add_mesh_data_to_view(mdata,
                          view,
                          want_faces=True,
                          want_points=True,
                          want_lines=True,
                          transform=transforms.MatrixTransform()):
  color = mdata.get('color', 'g')
  if isinstance(color, str) and color == 'random': color = np.random.random(3).tolist()
  else: color = Color(color).rgb.tolist()

  res = Attributize()
  res.lines = []
  res.objs = []
  if want_lines and 'lines' in mdata:
    for polyline in mdata.lines:
      if isinstance(polyline, Attributize):
        width = polyline.get('width', 1)
        method = 'gl'
        if width > 1: method = 'gl'
        l = Line(
            pos=np.array(np.array(polyline.polyline)),
            antialias=True,
            method=method,
            color=np.array(polyline.colors),
            width=width,)
      else:
        l = Line(pos=np.array(np.array(polyline)), antialias=False, method='gl', color=color)
      l.transform = transform
      view.add(l)
      res.lines.append(l)
      res.objs.append(l)

  if want_points and mdata.get('points', None) is not None:
    scatter = Markers()
    #mdata.points = np.array((
    #    (10.928140, -51.417831, -213.253723),
    #    (0.000000, -46.719570, -205.607208),
    #    (0.000000, -53.499737, -215.031876),
    #    (0.000000, -69.314308, -223.780746),
    #    (0.000000, -89.549263, -170.910568),))
    #mdata.points = np.array(((-12.138942,-55.812309,-217.007050),(10.928140,-51.417831,-213.253723),(-7.289741,-43.585541,-200.506531)))
    points_color = mdata.get('points_color', color)
    points_size = mdata.get('points_size', 10)
    points = np.array(mdata.points)

    #print('PLOTTING ', points, points_size)
    if len(points) == 0: return
    scatter.set_data(points, edge_color=None, face_color=points_color, size=points_size)
    scatter.transform = transform
    view.add(scatter)
    res.objs.append(scatter)
    res.points = scatter

  if want_faces and 'mesh' in mdata:
    mesh = Mesh(meshdata=mdata.mesh, color=color + [0.7])
    mesh.transform = transform
    view.add(mesh)
    res.mesh = mesh
    res.objs.append(mesh)
  return res
Exemple #3
0
    def __init__(self):
        self.meshes = []
        self.rotation = AffineTransform()

        # Generate some data to work with
        global mdata
        mdata = create_sphere(20, 40, 1.0)

        # Mesh with pre-indexed vertices, uniform color
        self.meshes.append(Mesh(meshdata=mdata, color='r'))
        #mesh.transform = STTransform(scale=(1, 1, .001), translate=(400, 400))

        ## Mesh with pre-indexed vertices, per-face color
        ##   Because vertices are pre-indexed, we get a different color
        ##   every time a vertex is visited, resulting in sharp color
        ##   differences between edges.
        verts = mdata.vertices(indexed='faces')
        nf = verts.size//9
        fcolor = np.ones((nf, 3, 4), dtype=np.float32)
        fcolor[..., 0] = np.linspace(1, 0, nf)[:, np.newaxis]
        fcolor[..., 1] = np.random.normal(size=nf)[:, np.newaxis]
        fcolor[..., 2] = np.linspace(0, 1, nf)[:, np.newaxis]
        mesh = Mesh(vertices=verts, face_colors=fcolor)
        self.meshes.append(mesh)

        ## Mesh with unindexed vertices, per-vertex color
        ##   Because vertices are unindexed, we get the same color
        ##   every time a vertex is visited, resulting in no color differences
        ##   between edges.
        verts = mdata.vertices()
        faces = mdata.faces()
        nv = verts.size//3
        vcolor = np.ones((nv, 4), dtype=np.float32)
        vcolor[:, 0] = np.linspace(1, 0, nv)
        vcolor[:, 1] = np.random.normal(size=nv)
        vcolor[:, 2] = np.linspace(0, 1, nv)
        self.meshes.append(Mesh(verts, faces, vcolor))
        self.meshes.append(Mesh(verts, faces, vcolor, shading='flat'))
        self.meshes.append(Mesh(verts, faces, vcolor, shading='smooth'))

        # Lay out meshes in a grid
        grid = (3, 3)
        s = 300. / max(grid)
        for i, mesh in enumerate(self.meshes):
            x = 800. * (i % grid[0]) / grid[0] + 400. / grid[0] - 2
            y = 800. * (i // grid[1]) / grid[1] + 400. / grid[1] + 2
            mesh.transform = ChainTransform([STTransform(translate=(x, y),
                                                         scale=(s, s, 1)),
                                             self.rotation])

        vispy.scene.SceneCanvas.__init__(self, keys='interactive')

        self.size = (800, 800)
        self.show()

        self.timer = vispy.app.Timer(connect=self.rotate)
        self.timer.start(0.016)
Exemple #4
0
    def __init__(self, layer):
        node = Mesh()
        super().__init__(layer, node)

        self.layer.events.edge_color.connect(self._on_data_change)
        self._reset_base()
        self._on_data_change()
    def _init_mesh(self, x,y,z,d):
        verts, faces = mesh_from_quads(x,y,z)
        face_colors = np.empty((faces.shape[0], 4))
        face_colors[0::2,0] = d.flat
        face_colors[0::2,1] = d.flat
        face_colors[0::2,2] = d.flat
        face_colors[1::2,0] = d.flat
        face_colors[1::2,1] = d.flat
        face_colors[1::2,2] = d.flat
        face_colors[:,3] = 1.0 # transparency
        mdata = MeshData(vertices=verts, faces=faces, face_colors=face_colors)
        mesh = Mesh(meshdata=mdata)

        # mesh.transform = ChainTransform([STTransform(translate=(0, 0, 0),
        #                                              scale=(1.0e-3, 1.0e-3, 1.0e-3) )])
        mesh.transform = vispy.scene.transforms.MatrixTransform()
        mesh.transform.scale([1./1000, 1./1000, 1./1000])
        # mesh.transform.shift([-.2, -.2, -.2])
        return mesh
Exemple #6
0
    def __init__(self, layer):
        # Create a compound visual with the following four subvisuals:
        # Markers: corresponding to the vertices of the interaction box or the
        # shapes that are used for highlights.
        # Lines: The lines of the interaction box used for highlights.
        # Mesh: The mesh of the outlines for each shape used for highlights.
        # Mesh: The actual meshes of the shape faces and edges
        node = Compound([Mesh(), Mesh(), Line(), Markers()])

        super().__init__(layer, node)

        self.layer.events.edge_width.connect(self._on_data_change)
        self.layer.events.edge_color.connect(self._on_data_change)
        self.layer.events.face_color.connect(self._on_data_change)
        self.layer.events.highlight.connect(self._on_highlight_change)

        self._reset_base()
        self._on_data_change()
        self._on_highlight_change()
Exemple #7
0
    def __init__(self):
        self.meshes = []
        self.rotation = AffineTransform()

        # Generate some data to work with
        global mdata
        mdata = create_sphere(20, 40, 1.0)

        # Mesh with pre-indexed vertices, uniform color
        self.meshes.append(Mesh(meshdata=mdata, color='r'))
        #mesh.transform = STTransform(scale=(1, 1, .001), translate=(400, 400))

        ## Mesh with pre-indexed vertices, per-face color
        ##   Because vertices are pre-indexed, we get a different color
        ##   every time a vertex is visited, resulting in sharp color
        ##   differences between edges.
        verts = mdata.vertices(indexed='faces')
        nf = verts.size // 9
        fcolor = np.ones((nf, 3, 4), dtype=np.float32)
        fcolor[..., 0] = np.linspace(1, 0, nf)[:, np.newaxis]
        fcolor[..., 1] = np.random.normal(size=nf)[:, np.newaxis]
        fcolor[..., 2] = np.linspace(0, 1, nf)[:, np.newaxis]
        mesh = Mesh(vertices=verts, face_colors=fcolor)
        self.meshes.append(mesh)

        ## Mesh with unindexed vertices, per-vertex color
        ##   Because vertices are unindexed, we get the same color
        ##   every time a vertex is visited, resulting in no color differences
        ##   between edges.
        verts = mdata.vertices()
        faces = mdata.faces()
        nv = verts.size // 3
        vcolor = np.ones((nv, 4), dtype=np.float32)
        vcolor[:, 0] = np.linspace(1, 0, nv)
        vcolor[:, 1] = np.random.normal(size=nv)
        vcolor[:, 2] = np.linspace(0, 1, nv)
        self.meshes.append(Mesh(verts, faces, vcolor))
        self.meshes.append(Mesh(verts, faces, vcolor, shading='flat'))
        self.meshes.append(Mesh(verts, faces, vcolor, shading='smooth'))

        # Lay out meshes in a grid
        grid = (3, 3)
        s = 300. / max(grid)
        for i, mesh in enumerate(self.meshes):
            x = 800. * (i % grid[0]) / grid[0] + 400. / grid[0] - 2
            y = 800. * (i // grid[1]) / grid[1] + 400. / grid[1] + 2
            mesh.transform = ChainTransform([
                STTransform(translate=(x, y), scale=(s, s, 1)), self.rotation
            ])

        vispy.scene.SceneCanvas.__init__(self, keys='interactive')

        self.size = (800, 800)
        self.show()

        self.timer = vispy.app.Timer(connect=self.rotate)
        self.timer.start(0.016)
Exemple #8
0
    def __init__(
        self,
        vectors,
        *,
        edge_width=1,
        edge_color='red',
        length=1,
        opacity=1,
        blending='translucent',
        visible=True,
        name=None,
    ):

        super().__init__(
            Mesh(),
            name=name,
            opacity=opacity,
            blending=blending,
            visible=visible,
        )

        # events for non-napari calculations
        self.events.add(length=Event, edge_width=Event)

        # Save the vector style params
        self._edge_width = edge_width
        self._edge_color = edge_color
        self._colors = get_color_names()

        self._mesh_vertices = np.empty((0, 2))
        self._mesh_triangles = np.empty((0, 3), dtype=np.uint32)

        # Data containing vectors in the currently viewed slice
        self._data_view = np.empty((0, 2, 2))

        # length attribute
        self._length = length

        # update flags
        self._need_display_update = False
        self._need_visual_update = False

        # assign vector data and establish default behavior
        with self.freeze_refresh():
            self.data = vectors

            # Re intitialize indices depending on image dims
            self._indices = (0,) * (self.ndim - 2) + (
                slice(None, None, None),
                slice(None, None, None),
            )

            # Trigger generation of view slice and thumbnail
            self._set_view_slice()
Exemple #9
0
    def __init__(self, layer):
        node = Mesh()

        super().__init__(layer, node)

        self.layer.events.colormap.connect(self._on_colormap_change)
        self.layer.events.contrast_limits.connect(
            self._on_contrast_limits_change)
        self.layer.events.gamma.connect(self._on_gamma_change)

        self.reset()
        self._on_data_change()
Exemple #10
0
    def _updateShapeData(self, firstTime):
        if firstTime:
            self.shapeVisualNode = Mesh(
                parent=self,
                vertices=self.assimpMesh.vertices,
                faces=self.assimpMesh.faces,
                # vertex_colors=self.assimpMesh.colors,
                shading='flat'
            )
            material = self.assimpScene.materials[self.assimpMesh.materialindex]

            if material.properties['ambient']:
                self.shapeVisualNode.ambient_light_color = material.properties['ambient']
            # if material.properties['shininess']:
            #     self.shapeVisualNode.shininess = material.properties['shininess']
            # if material.properties['diffuse']:
            #     self.shapeVisualNode.color = material.properties['diffuse']
        else:
            pass
        strike = cell.strike
        if strike > 180: strike = 360 - strike
        strikes[i] = strike

      # Append to all collected verts/faces/values.
      if all_verts is None:
        all_verts = verts
        all_faces = faces
        all_strikes = strikes
      else:
        faces += all_verts.shape[0]
        all_verts = np.concatenate((all_verts, verts))
        all_faces = np.concatenate((all_faces, faces))
        all_strikes = np.concatenate((all_strikes, strikes))

  fault_surface = Mesh(all_verts, all_faces,
    vertex_values=all_strikes, shading='smooth')
  fault_surface.cmap = fault_cmap
  fault_surface.clim = fault_range
  fault_surface.shininess = 0.01
  fault_surface.ambient_light_color = Color([.2, .2, .2, 1])
  fault_surface.light_dir = (5, -10, 5)

  visual_nodes = volume_slices(seismic_vol,
    cmaps=seismic_cmap,
    clims=seismic_range,
    interpolation='bilinear', **slicing)
  xyz_axis = XYZAxis()
  colorbar = Colorbar(cmap=fault_cmap, clim=fault_range,
                      label_str='Fault Strike Angle', size=colorbar_size)

  visual_nodes.append(fault_surface)
Exemple #12
0
mesh_path = load_data_file('spot/spot.obj.gz')
texture_path = load_data_file('spot/spot.png')
vertices, faces, normals, texcoords = read_mesh(mesh_path)
texture = np.flipud(imread(texture_path))

canvas = scene.SceneCanvas(keys='interactive', bgcolor='white',
                           size=(800, 600))
view = canvas.central_widget.add_view()

view.camera = 'arcball'
# Adapt the depth to the scale of the mesh to avoid rendering artefacts.
view.camera.depth_value = 10 * (vertices.max() - vertices.min())

shading = None if args.shading == 'none' else args.shading
mesh = Mesh(vertices, faces, shading=shading, color='white')
mesh.shading_filter.shininess = 1e+1
view.add(mesh)

texture_filter = TextureFilter(texture, texcoords)
mesh.attach(texture_filter)


@canvas.events.key_press.connect
def on_key_press(event):
    if event.key == "t":
        texture_filter.enabled = not texture_filter.enabled
        mesh.update()


def attach_headlight(mesh, view, canvas):
    def __init__(self, viewer, parent=None, order=0):
        self._viewer = viewer
        self._scale = 1

        # Target axes length in canvas pixels
        self._target_length = 80
        # CMYRGB for 6 axes data in x, y, z, ... ordering
        self._default_color = [
            [0, 1, 1, 1],
            [1, 0, 1, 1],
            [1, 1, 0, 1],
            [1, 0, 0, 1],
            [0, 1, 0, 1],
            [0, 0, 1, 1],
        ]
        # Text offset from line end position
        self._text_offsets = 0.1 * np.array([1, 1, 1])

        # note order is x, y, z for VisPy
        self._line_data2D = np.array([[0, 0, 0], [1, 0, 0], [0, 0, 0],
                                      [0, 1, 0]])
        self._line_data3D = np.array([[0, 0, 0], [1, 0, 0], [0, 0, 0],
                                      [0, 1, 0], [0, 0, 0], [0, 0, 1]])

        # note order is x, y, z for VisPy
        self._dashed_line_data2D = np.concatenate(
            [[[1, 0, 0], [0, 0, 0]],
             make_dashed_line(4, axis=1)],
            axis=0,
        )
        self._dashed_line_data3D = np.concatenate(
            [
                [[1, 0, 0], [0, 0, 0]],
                make_dashed_line(4, axis=1),
                make_dashed_line(8, axis=2),
            ],
            axis=0,
        )

        # note order is x, y, z for VisPy
        vertices = np.empty((0, 3))
        faces = np.empty((0, 3))
        for axis in range(2):
            v, f = make_arrow_head(self._NUM_SEGMENTS_ARROWHEAD, axis)
            faces = np.concatenate([faces, f + len(vertices)], axis=0)
            vertices = np.concatenate([vertices, v], axis=0)
        self._default_arrow_vertices2D = vertices
        self._default_arrow_faces2D = faces.astype(int)

        vertices = np.empty((0, 3))
        faces = np.empty((0, 3))
        for axis in range(3):
            v, f = make_arrow_head(self._NUM_SEGMENTS_ARROWHEAD, axis)
            faces = np.concatenate([faces, f + len(vertices)], axis=0)
            vertices = np.concatenate([vertices, v], axis=0)
        self._default_arrow_vertices3D = vertices
        self._default_arrow_faces3D = faces.astype(int)

        self.node = Compound(
            [Line(connect='segments', method='gl', width=3),
             Mesh(),
             Text()],
            parent=parent,
        )
        self.node.transform = STTransform()
        self.node.order = order

        # Add a text node to display axes labels
        self.text_node = self.node._subvisuals[2]
        self.text_node.font_size = 10
        self.text_node.anchors = ('center', 'center')
        self.text_node.text = f'{1}'

        self._viewer.events.theme.connect(self._on_data_change)
        self._viewer.axes.events.visible.connect(self._on_visible_change)
        self._viewer.axes.events.colored.connect(self._on_data_change)
        self._viewer.axes.events.dashed.connect(self._on_data_change)
        self._viewer.axes.events.labels.connect(self._on_data_change)
        self._viewer.axes.events.arrows.connect(self._on_data_change)
        self._viewer.dims.events.order.connect(self._on_data_change)
        self._viewer.dims.events.ndisplay.connect(self._on_data_change)
        self._viewer.dims.events.axis_labels.connect(self._on_data_change)
        self._viewer.camera.events.zoom.connect(self._on_zoom_change)

        self._on_visible_change(None)
        self._on_data_change(None)
Exemple #14
0
    def __init__(self, axes, dims, parent=None, order=0):
        self.axes = axes
        self.dims = dims

        # note order is z, y, x
        self._default_data = np.array(
            [[0, 0, 0], [0, 0, 1], [0, 0, 0], [0, 1, 0], [0, 0, 0], [1, 0, 0]]
        )
        self._default_color = np.concatenate(
            [[[0, 1, 1, 1]] * 2, [[1, 1, 0, 1]] * 2, [[1, 0, 1, 1]] * 2],
            axis=0,
        )
        # note order is z, y, x
        self._dashed_data = np.concatenate(
            [
                [[0, 0, 0], [0, 0, 1]],
                make_dashed_line(4, axis=1),
                make_dashed_line(8, axis=0),
            ],
            axis=0,
        )
        self._dashed_color = np.concatenate(
            [
                [[0, 1, 1, 1]] * 2,
                [[1, 1, 0, 1]] * 4 * 2,
                [[1, 0, 1, 1]] * 8 * 2,
            ],
            axis=0,
        )
        vertices = np.empty((0, 3))
        faces = np.empty((0, 3))
        # note order is z, y, x
        for axis in range(3):
            v, f = make_arrow_head(self._NUM_SEGMENTS_ARROWHEAD, 2 - axis)
            faces = np.concatenate([faces, f + len(vertices)], axis=0)
            vertices = np.concatenate([vertices, v], axis=0)
        self._default_arrow_vertices = vertices
        self._default_arrow_faces = faces.astype(int)
        self._default_arrow_color = np.concatenate(
            [
                [[0, 1, 1, 1]] * self._NUM_SEGMENTS_ARROWHEAD,
                [[1, 1, 0, 1]] * self._NUM_SEGMENTS_ARROWHEAD,
                [[1, 0, 1, 1]] * self._NUM_SEGMENTS_ARROWHEAD,
            ],
            axis=0,
        )
        self._target_length = 80
        self.node = Compound(
            [Line(connect='segments', method='gl', width=3), Mesh()],
            parent=parent,
        )
        self.node.transform = STTransform()
        self.node.order = order

        self.axes.events.visible.connect(self._on_visible_change)
        self.axes.events.colored.connect(self._on_data_change)
        self.axes.events.dashed.connect(self._on_data_change)
        self.axes.events.arrows.connect(self._on_data_change)
        self.dims.events.order.connect(self._on_data_change)

        self._on_visible_change(None)
        self._on_data_change(None)

        self._scale = 1
Exemple #15
0
mesh_path = load_data_file('spot/spot.obj.gz')
texture_path = load_data_file('spot/spot.png')
vertices, faces, normals, texcoords = read_mesh(mesh_path)
texture = np.flipud(imread(texture_path))

canvas = scene.SceneCanvas(keys='interactive',
                           bgcolor='white',
                           size=(800, 600))
view = canvas.central_widget.add_view()

view.camera = 'arcball'
# Adapt the depth to the scale of the mesh to avoid rendering artefacts.
view.camera.depth_value = 10 * (vertices.max() - vertices.min())

shading = None if args.shading == 'none' else args.shading
mesh = Mesh(vertices, faces, shading=shading, color='white')
mesh.transform = transforms.MatrixTransform()
mesh.transform.rotate(90, (1, 0, 0))
mesh.transform.rotate(135, (0, 0, 1))
mesh.shading_filter.shininess = 1e+1
view.add(mesh)

texture_filter = TextureFilter(texture, texcoords)
mesh.attach(texture_filter)


@canvas.events.key_press.connect
def on_key_press(event):
    if event.key == "t":
        texture_filter.enabled = not texture_filter.enabled
        mesh.update()
Exemple #16
0
def create_mesh_visual_from_stl(stl_data, **data):
  return Mesh(meshdata=stl_to_meshdata(stl_data), **data)
Exemple #17
0
 def __init__(self):
     super().__init__([Mesh(), Mesh(), Line(), Markers(), Text()])
Exemple #18
0
default_mesh = load_data_file('orig/triceratops.obj.gz')
parser.add_argument('--mesh', default=default_mesh)
parser.add_argument('--shininess', default=100)
parser.add_argument('--wireframe-width', default=1)
args, _ = parser.parse_known_args()

vertices, faces, normals, texcoords = read_mesh(args.mesh)

canvas = scene.SceneCanvas(keys='interactive', bgcolor='white')
view = canvas.central_widget.add_view()

view.camera = 'arcball'
view.camera.depth_value = 1e3

# Create a colored `MeshVisual`.
mesh = Mesh(vertices, faces, color=(.5, .7, .5, 1))
mesh.transform = transforms.MatrixTransform()
mesh.transform.rotate(90, (1, 0, 0))
mesh.transform.rotate(-45, (0, 0, 1))
view.add(mesh)

# Use filters to affect the rendering of the mesh.
wireframe_filter = WireframeFilter(width=args.wireframe_width)
# Note: For convenience, this `ShadingFilter` would be created automatically by
# the `MeshVisual with, e.g. `mesh = MeshVisual(..., shading='smooth')`. It is
# created manually here for demonstration purposes.
shading_filter = ShadingFilter(shininess=args.shininess)
# The wireframe filter is attached before the shading filter otherwise the
# wireframe is not shaded.
mesh.attach(wireframe_filter)
mesh.attach(shading_filter)
Exemple #19
0
default_mesh = load_data_file('orig/triceratops.obj.gz')
parser.add_argument('--mesh', default=default_mesh)
parser.add_argument('--shininess', default=100)
parser.add_argument('--wireframe-width', default=1)
args, _ = parser.parse_known_args()

vertices, faces, normals, texcoords = read_mesh(args.mesh)

canvas = scene.SceneCanvas(keys='interactive', bgcolor='white')
view = canvas.central_widget.add_view()

view.camera = 'arcball'
view.camera.depth_value = 1e3

# Create a colored `MeshVisual`.
mesh = Mesh(vertices, faces, color=(.5, .7, .5, 1))
view.add(mesh)

# Use filters to affect the rendering of the mesh.
wireframe_filter = WireframeFilter(width=args.wireframe_width)
# Note: For convenience, this `ShadingFilter` would be created automatically by
# the `MeshVisual with, e.g. `mesh = MeshVisual(..., shading='smooth')`. It is
# created manually here for demonstration purposes.
shading_filter = ShadingFilter(shininess=args.shininess)
# The wireframe filter is attached before the shading filter otherwise the
# wireframe is not shaded.
mesh.attach(wireframe_filter)
mesh.attach(shading_filter)


def attach_headlight(view):
Exemple #20
0
# -----------------------------------------------------------------------------
# Copyright (c) Vispy Development Team. All Rights Reserved.
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
# -----------------------------------------------------------------------------
"""Show how to display mesh normals on a mesh."""

from vispy import app, scene
from vispy.io import read_mesh, load_data_file
from vispy.scene.visuals import Mesh, MeshNormals
from vispy.visuals.filters import WireframeFilter


mesh_file = load_data_file('orig/triceratops.obj.gz')
vertices, faces, _, _ = read_mesh(mesh_file)

mesh = Mesh(vertices, faces, shading='flat')
meshdata = mesh.mesh_data

wireframe_filter = WireframeFilter(color='lightblue')
mesh.attach(wireframe_filter)

face_normals = MeshNormals(meshdata, primitive='face', color='yellow')
vertex_normals = MeshNormals(meshdata, primitive='vertex', color='orange',
                             width=2)

canvas = scene.SceneCanvas(keys='interactive', bgcolor='white')
view = canvas.central_widget.add_view()
view.camera = 'arcball'
view.add(mesh)
face_normals.parent = mesh
vertex_normals.parent = mesh