Example #1
0
def test_sphere():
    """Test sphere function"""
    md = create_sphere(rows=10, cols=20, radius=10, method='latitude')
    radii = np.sqrt((md.get_vertices() ** 2).sum(axis=1))
    assert_allclose(radii, np.ones_like(radii) * 10)
    md = create_sphere(subdivisions=5, radius=10, method='ico')
    radii = np.sqrt((md.get_vertices() ** 2).sum(axis=1))
    assert_allclose(radii, np.ones_like(radii) * 10)
    md = create_sphere(rows=20, cols=20, depth=20, radius=10, method='cube')
    radii = np.sqrt((md.get_vertices() ** 2).sum(axis=1))
    assert_allclose(radii, np.ones_like(radii) * 10)
Example #2
0
def test_sphere():
    """Test sphere function"""
    md = create_sphere(rows=10, cols=20, radius=10, method='latitude')
    radii = np.sqrt((md.get_vertices()**2).sum(axis=1))
    assert_allclose(radii, np.ones_like(radii) * 10)
    md = create_sphere(subdivisions=5, radius=10, method='ico')
    radii = np.sqrt((md.get_vertices()**2).sum(axis=1))
    assert_allclose(radii, np.ones_like(radii) * 10)
    md = create_sphere(rows=20, cols=20, depth=20, radius=10, method='cube')
    radii = np.sqrt((md.get_vertices()**2).sum(axis=1))
    assert_allclose(radii, np.ones_like(radii) * 10)
Example #3
0
    def __init__(self):
        app.Canvas.__init__(self, keys='interactive', size=(800, 550))
        
        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(visuals.MeshVisual(meshdata=mdata, color='r'))

        ## 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.get_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 = visuals.MeshVisual(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.get_vertices()
        faces = mdata.get_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(visuals.MeshVisual(verts, faces, vcolor))
        self.meshes.append(visuals.MeshVisual(verts, faces, vcolor, 
                                              shading='flat'))
        self.meshes.append(visuals.MeshVisual(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
            transform = ChainTransform([STTransform(translate=(x, y),
                                                    scale=(s, s, 1)),
                                        self.rotation])
            tr_sys = visuals.transforms.TransformSystem(self)
            tr_sys.visual_to_document = transform
            mesh.tr_sys = tr_sys

        self.show()

        self.timer = app.Timer(connect=self.rotate)
        self.timer.start(0.016)
Example #4
0
    def __init__(self):
        app.Canvas.__init__(self, keys='interactive', size=(800, 550))

        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(visuals.MeshVisual(meshdata=mdata, color='r'))

        ## 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.get_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 = visuals.MeshVisual(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.get_vertices()
        faces = mdata.get_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(visuals.MeshVisual(verts, faces, vcolor))
        self.meshes.append(
            visuals.MeshVisual(verts, faces, vcolor, shading='flat'))
        self.meshes.append(
            visuals.MeshVisual(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
            transform = ChainTransform([
                STTransform(translate=(x, y), scale=(s, s, 1)), self.rotation
            ])
            tr_sys = visuals.transforms.TransformSystem(self)
            tr_sys.visual_to_document = transform
            mesh.tr_sys = tr_sys

        self.show()

        self.timer = app.Timer(connect=self.rotate)
        self.timer.start(0.016)
Example #5
0
def test_mesh_normals_length_scalar():
    size = (45, 40)
    with TestingCanvas(size=size, bgcolor="k") as c:
        v = c.central_widget.add_view(border_width=0)
        v.camera = 'arcball'
        # Create visual.
        mdata = create_sphere(radius=1.0)
        mesh = scene.visuals.Mesh(meshdata=mdata,
                                  shading=None,
                                  color=(0.1, 0.1, 0.1, 1.0))
        v.add(mesh)

        length = 0.5
        normals_0_5 = scene.visuals.MeshNormals(mdata,
                                                color=(1, 0, 0),
                                                length=length)
        normals_0_5.parent = mesh
        rendered_length_0_5 = c.render()
        normals_0_5.parent = None

        length = 1.0
        normals_1_0 = scene.visuals.MeshNormals(mdata,
                                                color=(1, 0, 0),
                                                length=length)
        normals_1_0.parent = mesh
        rendered_length_1_0 = c.render()
        normals_1_0.parent = None

        # There should be more red pixels with the longer normals.
        n_pixels_0_5 = np.sum(rendered_length_0_5[..., 0] > 128)
        n_pixels_1_0 = np.sum(rendered_length_1_0[..., 0] > 128)
        assert n_pixels_1_0 > n_pixels_0_5
Example #6
0
def test_mesh_shading_filter(shading):
    size = (45, 40)
    with TestingCanvas(size=size, bgcolor="k") as c:
        v = c.central_widget.add_view(border_width=0)
        # Create visual
        mdata = create_sphere(20, 40, radius=20)
        mesh = scene.visuals.Mesh(meshdata=mdata,
                                  shading=shading,
                                  color=(0.1, 0.3, 0.7, 0.9))
        v.add(mesh)
        from vispy.visuals.transforms import STTransform
        mesh.transform = STTransform(translate=(20, 20))
        mesh.transforms.scene_transform = STTransform(scale=(1, 1, 0.01))

        rendered = c.render()[..., 0]  # R channel only
        if shading in ("flat", "smooth"):
            # there should be a gradient, not solid colors
            assert np.unique(rendered).size >= 28
            # sphere/circle starts "dark" on the left and gets brighter
            # then hits a bright spot and decreases after
            invest_row = rendered[23].astype(np.float64)
            # overall, we should be increasing brightness up to a "bright spot"
            assert (np.diff(invest_row[:29]) >= -1).all()
        else:
            assert np.unique(rendered).size == 2
Example #7
0
def test_mesh_shading_filter_enabled(shading):
    size = (45, 40)
    with TestingCanvas(size=size, bgcolor="k") as c:
        v = c.central_widget.add_view(border_width=0)
        v.camera = 'arcball'
        mdata = create_sphere(20, 30, radius=1)
        mesh = scene.visuals.Mesh(meshdata=mdata,
                                  shading=None,
                                  color=(0.2, 0.3, 0.7, 1.0))
        shading_filter = ShadingFilter(shading=shading)
        mesh.attach(shading_filter)
        v.add(mesh)

        shading_filter.enabled = False
        rendered_without_shading = c.render()

        shading_filter.enabled = True
        rendered_with_shading = c.render()

        if shading is None:
            # There should be no shading applied, regardless of the value of
            # `enabled`.
            assert np.allclose(rendered_without_shading, rendered_with_shading)
        else:
            # The result should be different with shading applied.
            assert not np.allclose(rendered_without_shading,
                                   rendered_with_shading)
Example #8
0
def generate_skeleton(
        truncated_icosahedron_vertices_coordinates,
        edges_between_vertices,
        sphere_radius=0.4,
        cylinder_radius=0.1,
        sphere_rows=10,
        sphere_cols=10,
        cylinder_rows=10,
        cylinder_cols=10,
        color=(1, 0.6, 0)):
    spheres_geometry = []
    for i, vertex_coordinate in enumerate(truncated_icosahedron_vertices_coordinates):
        new_mesh = geometry.create_sphere(sphere_rows, sphere_cols, radius=sphere_radius)
        new_mesh.set_vertices(new_mesh.get_vertices() + vertex_coordinate, reset_normals=False)
        spheres_geometry.append(new_mesh)

    cylinders_geometry = []
    for first_vertex_index, second_vertex_index in edges_between_vertices:
        first_vertex_coordinate = truncated_icosahedron_vertices_coordinates[first_vertex_index]
        second_vertex_coordinate = truncated_icosahedron_vertices_coordinates[second_vertex_index]
        cylinder = generate_cylinder_geometry(first_vertex_coordinate, second_vertex_coordinate,
                                              cylinder_rows, cylinder_cols, cylinder_radius, sphere_radius)
        cylinders_geometry.append(cylinder)

    final_object_vertices, final_object_faces = append_geometries(np.empty([0, 3], np.float32),
                                                                  np.empty([0, 3], np.uint32),
                                                                  spheres_geometry)
    final_object_vertices, final_object_faces = append_geometries(final_object_vertices, final_object_faces,
                                                                  cylinders_geometry)

    return scene.visuals.Mesh(vertices=final_object_vertices, faces=final_object_faces, color=color, shading='smooth')
Example #9
0
    def updateView(self, param):

        if param.dict["subdiv"] != param.dict["subdiv_old"]:
            subdiv = param.dict['subdiv']
            md = create_sphere(radius=1, subdivisions=subdiv, method='ico')
            verts = md.get_vertices()
            print(verts.shape)
            faces = md.get_faces()
            gamma, phi = xyz_to_gp(verts)
            data = np.cos(5*gamma)+np.cos(phi*4)/2.
            param.dict["data"] = data
            self.sph.mesh.set_data(vertices=verts, faces=faces,
                                   vertex_values=data)
            param.dict["subdiv_old"] = param.dict["subdiv"]

        self.sph.mesh.cmap = param.dict['colormap']
        self.cbar_widget.cmap = param.dict['colormap']
        self.cbar_widget.nband = param.dict['nbr_band']
        self.cbar_widget.banded = param.dict['banded']

        v_min = 0.0
        v_max = 1.0
        if param.dict["data"] is not None:
            v_min = np.min(param.dict["data"], 0)
            v_max = np.max(param.dict["data"], 0)
        self.cbar_widget.clim = (v_min, v_max)

        self.sph.mesh.nband = param.dict['nbr_band']
        self.sph.mesh.banded = param.dict['banded']
Example #10
0
    def add_chan(self, chan, color=CHAN_COLOR, chan_colors=None,
                 values=None, limits_c=None, colormap='coolwarm',
                 shift=(0, 0, 0)):
        """Add channels to visualization

        Parameters
        ----------
        chan : instance of Channels
            channels to plot
        color : tuple
            3-, 4-element tuple, representing RGB and alpha, between 0 and 1
        chan_colors : ndarray
            array with colors for each channel
        values : ndarray
            array with values for each channel
        limits_c : tuple of 2 floats, optional
            min and max values to normalize the color
        colormap : str
            one of the colormaps in vispy
        shift : tuple of 3 floats
            shift all electrodes by this amount (unit and order depend on
            xyz coordinates of the electrodes)
        """
        # larger if colors are meaningful
        if values is not None:
            meshdata = create_sphere(radius=3, method='ico')
        else:
            meshdata = create_sphere(radius=1.5, method='ico')

        chan_colors, limits = _prepare_chan_colors(color, chan_colors, values,
                                                   limits_c, colormap)

        # store values in case we update the values
        self._chan_colormap = colormap
        self._chan_limits_c = limits

        for i, one_chan in enumerate(chan.chan):
            if chan_colors.ndim == 2:
                chan_color = chan_colors[i, :]
            else:
                chan_color = chan_colors

            mesh = SimpleMesh(meshdata, chan_color)
            mesh.transform = STTransform(translate=one_chan.xyz + shift)
            self._plt.view.add(mesh)
            self._chan.append(mesh)
Example #11
0
 def createsphere(self, nrows=20, ncols=20, radius=1.0):
     if not self.mesh:
         mdata = create_sphere(nrows, ncols, radius)
         self.mesh = visuals.Mesh(meshdata=mdata,
                                  vertex_colors='black',
                                  face_colors=(1.0, 0.0, 0.0, 1.0),
                                  color=(0.5, 0.5, 0.5, .75))
         self.view.add(self.mesh)
     else:
         print(dir(self.mesh))
Example #12
0
def test_mesh_normals_length_array(primitive):
    size = (45, 40)
    with TestingCanvas(size=size, bgcolor="k") as c:
        v = c.central_widget.add_view(border_width=0)
        v.camera = 'arcball'
        v.camera.fov = 90
        # Create visual.
        meshdata = create_sphere(radius=1.0)
        mesh = scene.visuals.Mesh(meshdata=meshdata,
                                  shading=None,
                                  color=(0.1, 0.1, 0.1, 1.0))
        v.add(mesh)

        if primitive == 'face':
            n_normals = len(meshdata.get_faces())
        elif primitive == 'vertex':
            n_normals = len(meshdata.get_vertices())

        lengths_0_5 = np.full(n_normals, 0.5, dtype=float)
        normals_0_5 = scene.visuals.MeshNormals(meshdata,
                                                primitive=primitive,
                                                color=(1, 0, 0),
                                                length=lengths_0_5)
        normals_0_5.parent = mesh
        rendered_lengths_0_5 = c.render()
        normals_0_5.parent = None

        lengths_1_0 = np.full(n_normals, 1.0, dtype=float)
        normals_1_0 = scene.visuals.MeshNormals(meshdata,
                                                primitive=primitive,
                                                color=(1, 0, 0),
                                                length=lengths_1_0)
        normals_1_0.parent = mesh
        rendered_lengths_1_0 = c.render()
        normals_1_0.parent = None

        # There should be more red pixels with the longer normals.
        n_pixels_0_5 = np.sum(rendered_lengths_0_5[..., 0] > 128)
        n_pixels_1_0 = np.sum(rendered_lengths_1_0[..., 0] > 128)
        assert n_pixels_1_0 > n_pixels_0_5

        lengths_ramp = np.linspace(0.5, 1.0, n_normals, dtype=float)
        normals_ramp = scene.visuals.MeshNormals(meshdata,
                                                 primitive=primitive,
                                                 color=(1, 0, 0),
                                                 length=lengths_ramp)
        normals_ramp.parent = mesh
        rendered_lengths_ramp = c.render()
        normals_ramp.parent = None

        # With the normals lengths from a ramp in [0.5, 1.0], there should be
        # more red pixels than with all normals of length 0.5 and less than
        # with all normals of length 1.0.
        n_pixels_ramp = np.sum(rendered_lengths_ramp[..., 0] > 128)
        assert n_pixels_0_5 < n_pixels_ramp < n_pixels_1_0
Example #13
0
 def __init__(self, position, radius, color, **kwargs):
     sphere_mesh = geometry.create_sphere(
         rows=int(radius * 30),
         cols=int(radius * 30),
         radius=radius,
         **kwargs
     )
     sphere_buffer, faces = self.make_buffer(sphere_mesh)
     super(self.__class__, self).__init__(sphere_buffer, faces=faces, position=position, color=color)
     self.program['u_shininess'] = 16.0
     self.program['u_specular_color'] = self.color[:3]
Example #14
0
 def __init__(self, position, radius, color, **kwargs):
     sphere_mesh = geometry.create_sphere(rows=int(radius * 30),
                                          cols=int(radius * 30),
                                          radius=radius,
                                          **kwargs)
     sphere_buffer, faces = self.make_buffer(sphere_mesh)
     super(self.__class__, self).__init__(sphere_buffer,
                                          faces=faces,
                                          position=position,
                                          color=color)
     self.program['u_shininess'] = 16.0
     self.program['u_specular_color'] = self.color[:3]
Example #15
0
    def __init__(self,
                 mu,
                 cov,
                 std=2.,
                 cols=15,
                 rows=15,
                 depth=15,
                 subdivisions=3,
                 method='latitude',
                 vertex_colors=None,
                 face_colors=None,
                 color=(0.5, 0.5, 1, 1),
                 edge_color=None,
                 **kwargs):

        mesh = create_sphere(rows,
                             cols,
                             depth,
                             radius=std,
                             subdivisions=subdivisions,
                             method=method)

        # Take the spherical mesh and project through the covariance, like you do
        #  when sampling a multivariate gaussian.
        # https://en.wikipedia.org/wiki/Multivariate_normal_distribution#Drawing_values_from_the_distribution
        A = np.linalg.cholesky(cov)
        verts = mesh.get_vertices()
        verts2 = np.matmul(A[None, :, :], verts[:, :, None])
        verts3 = verts2 + mu[None, :, None]
        mesh.set_vertices(np.squeeze(verts3))

        self._mesh = MeshVisual(vertices=mesh.get_vertices(),
                                faces=mesh.get_faces(),
                                vertex_colors=vertex_colors,
                                face_colors=face_colors,
                                color=color)
        if edge_color:
            self._border = MeshVisual(vertices=mesh.get_vertices(),
                                      faces=mesh.get_edges(),
                                      color=edge_color,
                                      mode='lines')
        else:
            self._border = MeshVisual()

        CompoundVisual.__init__(self, [self._mesh, self._border], **kwargs)
        self.mesh.set_gl_state(polygon_offset_fill=True,
                               polygon_offset=(1, 1),
                               depth_test=True)
Example #16
0
def test_mesh_normals_length_scale():
    size = (45, 40)
    with TestingCanvas(size=size, bgcolor="k") as c:
        v = c.central_widget.add_view(border_width=0)
        v.camera = 'arcball'
        # Create visual.
        meshdata = create_sphere(radius=1.0)
        mesh = scene.visuals.Mesh(meshdata=meshdata,
                                  shading=None,
                                  color=(0.1, 0.1, 0.1, 1.0))
        v.add(mesh)

        length = 1.0
        length_scale_up = 2.0
        length_scale_down = 0.5

        normals = scene.visuals.MeshNormals(meshdata,
                                            color=(1, 0, 0),
                                            length=length)
        normals.parent = mesh
        rendered_length_default = c.render()
        normals.parent = None

        normals_scaled_up = scene.visuals.MeshNormals(
            meshdata,
            color=(1, 0, 0),
            length=length,
            length_scale=length_scale_up)
        normals_scaled_up.parent = mesh
        rendered_length_scaled_up = c.render()
        normals_scaled_up.parent = None

        normals_scaled_down = scene.visuals.MeshNormals(
            meshdata,
            color=(1, 0, 0),
            length=length,
            length_scale=length_scale_down)
        normals_scaled_down.parent = mesh
        rendered_length_scaled_down = c.render()
        normals_scaled_down.parent = None

        # There should be more red pixels with the scaled-up normals and less
        # with the ones scaled down.
        n_pixels_default = np.sum(rendered_length_default[..., 0] > 128)
        n_pixels_scaled_up = np.sum(rendered_length_scaled_up[..., 0] > 128)
        n_pixels_scaled_down = np.sum(
            rendered_length_scaled_down[..., 0] > 128)
        assert n_pixels_scaled_down < n_pixels_default < n_pixels_scaled_up
Example #17
0
    def create_sphere(self, point, time_point, radius):

        mdata = geometry.create_sphere(64, 64, radius=radius)

        color = point["color"]
        if isinstance(color, type(None)):
            color = "gray"

        sphere = scene.visuals.Mesh(meshdata=mdata, shading="flat", color=color)

        t = visuals.transforms.MatrixTransform()
        sphere.transform = t
        sphere.transform.translate(point.traj.loc[time_point, self.coords].values)

        self.points[point.idx] = (sphere, point)
        self.view.add(sphere)
        return sphere
Example #18
0
def test_mesh_wireframe_filter():
    size = (45, 40)
    with TestingCanvas(size=size, bgcolor="k") as c:
        v = c.central_widget.add_view(border_width=0)
        # Create visual
        mdata = create_sphere(20, 40, radius=20)
        mesh = scene.visuals.Mesh(meshdata=mdata,
                                  shading=None,
                                  color=(0.1, 0.3, 0.7, 0.9))
        wireframe_filter = WireframeFilter(color='red')
        mesh.attach(wireframe_filter)
        v.add(mesh)
        from vispy.visuals.transforms import STTransform
        mesh.transform = STTransform(translate=(20, 20))
        mesh.transforms.scene_transform = STTransform(scale=(1, 1, 0.01))

        rendered_with_wf = c.render()
        assert np.unique(rendered_with_wf[..., 0]).size >= 50

        wireframe_filter.enabled = False
        rendered_wo_wf = c.render()
        # the result should be completely different
        # assert not allclose
        pytest.raises(AssertionError, np.testing.assert_allclose,
                      rendered_with_wf, rendered_wo_wf)

        wireframe_filter.enabled = True
        wireframe_filter.wireframe_only = True
        rendered_with_wf_only = c.render()
        # the result should be different from the two cases above
        pytest.raises(AssertionError, np.testing.assert_allclose,
                      rendered_with_wf_only, rendered_with_wf)
        pytest.raises(AssertionError, np.testing.assert_allclose,
                      rendered_with_wf_only, rendered_wo_wf)

        wireframe_filter.enabled = True
        wireframe_filter.wireframe_only = False
        wireframe_filter.faces_only = True
        rendered_with_faces_only = c.render()
        # the result should be different from the cases above
        pytest.raises(AssertionError, np.testing.assert_allclose,
                      rendered_with_faces_only, rendered_with_wf)
        pytest.raises(AssertionError, np.testing.assert_allclose,
                      rendered_with_faces_only, rendered_wo_wf)
        pytest.raises(AssertionError, np.testing.assert_allclose,
                      rendered_with_faces_only, rendered_with_wf_only)
Example #19
0
    def __init__(self, data, istep=1, scale=1., colors='y', R=0.01):
        """
        Initialize an NbodyCanvas

        data : 2d array, (Ntimesteps, Nparticles*9)
            position(3), velocity(3), and acceleration(9) of each particle
        istep : int
            advance timestep by this amount
        scale : float
            scale length
        colors : list of Nparticle size or 1
            list of matplotlib colors
        """
        scene.SceneCanvas.__init__(self, keys='interactive')
        view = self.central_widget.add_view()
        view.set_camera('turntable', mode='ortho', up='z', distance=1.0,
                        azimuth=30., elevation=60.)
        self.view = view
        # Add a 3D axis to keep us oriented
        self.axis = scene.visuals.XYZAxis(parent=view.scene)
        self.timer = app.Timer(0.1, connect=self.on_timer, start=True)
        # create mesh of a phere
        self.mdata = create_sphere(20, 40, R)

        self.i = 0
        self.istep = istep
        self.scale = scale
        self.meshes = []
        self.d = data
        self.np = self.d.shape[1]/9  # number of particles
        self.nt = self.d.shape[0]  # number of timesteps

        colors = list(colors)
        if len(colors) == 1:
            colors *= self.np
        else:
            assert len(colors) == self.np, "invalid number of colors"
        # add particles for the first time
        for (x, y, z), c in\
            zip(np.vstack(np.split(self.d[self.i],self.np))[:,:3], colors):
            m = scene.visuals.Mesh(
                meshdata=self.mdata, color=c, shading='smooth')
            m.transform = scene.transforms.AffineTransform()
            m.transform.translate([x/self.scale, y/self.scale, z/self.scale])
            self.view.add(m)
            self.meshes.append(m)
Example #20
0
def test_mesh_shading_filter_colors(attribute):
    size = (45, 40)
    with TestingCanvas(size=size, bgcolor="k") as c:
        base_color_white = (1.0, 1.0, 1.0, 1.0)
        overlay_color_red = (1.0, 0.0, 0.0, 1.0)

        v = c.central_widget.add_view(border_width=0)
        v.camera = 'arcball'
        mdata = create_sphere(20, 30, radius=1)
        mesh = scene.visuals.Mesh(meshdata=mdata, color=base_color_white)
        v.add(mesh)

        shading_filter = ShadingFilter(
            shading='smooth',
            # Set the light source on the side of
            # and around the camera to get a clearly
            # visible reflection.
            light_dir=(-5, -5, 5),
            # Activate all illumination types as
            # white light but reduce the intensity
            # to prevent saturation.
            ambient_light=0.3,
            diffuse_light=0.3,
            specular_light=0.3,
            # Get a wide highlight.
            shininess=4)
        mesh.attach(shading_filter)

        rendered_white = c.render()

        setattr(shading_filter, attribute, overlay_color_red)
        rendered_red = c.render()

        # The results should be different.
        assert not np.allclose(rendered_white, rendered_red)

        # There should be an equal amount of all colors in the white rendering.
        color_count_white = rendered_white.sum(axis=(0, 1))
        r, g, b, _ = color_count_white
        assert r == g and r == b

        color_count_red = rendered_red.sum(axis=(0, 1))
        # There should be more red in the red-colored rendering.
        r, g, b, _ = color_count_red
        assert r > g and r > b
Example #21
0
def test_mesh_normals_length_method(length_method):
    size = (45, 40)
    with TestingCanvas(size=size, bgcolor="k") as c:
        v = c.central_widget.add_view(border_width=0)
        v.camera = 'arcball'
        # Create visual.
        meshdata = create_sphere(radius=1.0)
        mesh = scene.visuals.Mesh(meshdata=meshdata,
                                  shading=None,
                                  color=(0.1, 0.1, 0.1, 1.0))
        v.add(mesh)

        # The code below should not raise.
        # XXX(asnt): Not sure how to better test `length_method`.
        normals = scene.visuals.MeshNormals(meshdata, color=(1, 0, 0),
                                            length_method=length_method)
        normals.parent = mesh
        _ = c.render()
Example #22
0
    def __init__(self,
                 radius=1.0,
                 cols=30,
                 rows=30,
                 depth=30,
                 subdivisions=3,
                 method='latitude',
                 vertex_colors=None,
                 face_colors=None,
                 color=(0.5, 0.5, 1, 1),
                 edge_color=None,
                 **kwargs):

        EventEmitter.__init__(self)

        self._origin = np.array([0, 0, 0])
        self._pos = np.array([0, 0, 0])
        self._scale_factor = scale

        mesh = create_sphere(cols,
                             rows,
                             depth,
                             radius=radius,
                             subdivisions=subdivisions,
                             method=method)

        self._mesh = MeshVisual(vertices=mesh.get_vertices(),
                                faces=mesh.get_faces(),
                                vertex_colors=vertex_colors,
                                face_colors=face_colors,
                                color=color)
        if edge_color:
            self._border = MeshVisual(vertices=mesh.get_vertices(),
                                      faces=mesh.get_edges(),
                                      color=edge_color,
                                      mode='lines')
        else:
            self._border = MeshVisual()

        CompoundVisual.__init__(self, [self._mesh, self._border], **kwargs)
        self.mesh.set_gl_state(polygon_offset_fill=True,
                               polygon_offset=(1, 1),
                               depth_test=True)
Example #23
0
    def create_sphere(self, point, time_point, radius):

        mdata = geometry.create_sphere(64, 64, radius=radius)

        color = point['color']
        if isinstance(color, type(None)):
            color = "gray"

        sphere = scene.visuals.Mesh(meshdata=mdata,
                                    shading='flat',
                                    color=color)

        t = visuals.transforms.MatrixTransform()
        sphere.transform = t
        sphere.transform.translate(point.traj.loc[time_point,
                                                  self.coords].values)

        self.points[point.idx] = (sphere, point)
        self.view.add(sphere)
        return sphere
Example #24
0
def test_mesh_normals():
    size = (45, 40)
    with TestingCanvas(size=size, bgcolor="k") as c:
        v = c.central_widget.add_view(border_width=0)
        v.camera = 'arcball'
        # Create visual.
        mdata = create_sphere(radius=1.0)
        mesh = scene.visuals.Mesh(meshdata=mdata,
                                  shading=None,
                                  color=(0.1, 0.1, 0.1, 1.0))
        v.add(mesh)

        rendered_without_normals = c.render()
        # The color should be of low intensity.
        assert np.all((rendered_without_normals[..., 0:3]) < 32)

        face_normals = scene.visuals.MeshNormals(mdata,
                                                 primitive="face",
                                                 color=(1, 0, 0))
        face_normals.parent = mesh
        rendered_with_face_normals = c.render()
        face_normals.parent = None
        # There should be some pixels with brighter red.
        assert np.sum(rendered_with_face_normals[..., 0] > 128) > 64
        pytest.raises(AssertionError, np.testing.assert_allclose,
                      rendered_without_normals, rendered_with_face_normals)

        vertex_normals = scene.visuals.MeshNormals(mdata,
                                                   primitive="vertex",
                                                   color=(0, 1, 0))
        vertex_normals.parent = mesh
        rendered_with_vertex_normals = c.render()
        vertex_normals.parent = None
        # There should be some pixels with brighter green.
        assert np.sum(rendered_with_vertex_normals[..., 1] > 128) > 64
        pytest.raises(AssertionError, np.testing.assert_allclose,
                      rendered_without_normals, rendered_with_vertex_normals)
        pytest.raises(AssertionError, np.testing.assert_allclose,
                      rendered_with_face_normals, rendered_with_vertex_normals)
Example #25
0
def test_mesh_shading_filter(shading):
    size = (45, 40)
    with TestingCanvas(size=size, bgcolor="k") as c:
        v = c.central_widget.add_view(border_width=0)
        v.camera = 'arcball'
        mdata = create_sphere(20, 30, radius=1)
        mesh = scene.visuals.Mesh(meshdata=mdata,
                                  shading=shading,
                                  color=(0.2, 0.3, 0.7, 1.0))
        v.add(mesh)

        rendered = c.render()[..., 0]  # R channel only
        if shading in ("flat", "smooth"):
            # there should be a gradient, not solid colors
            assert np.unique(rendered).size >= 28
            # sphere/circle is "dark" on the right and gets brighter as you
            # move to the left, then hits a bright spot and decreases after
            invest_row = rendered[34].astype(np.float64)
            # overall, we should be increasing brightness up to a "bright spot"
            assert (np.diff(invest_row[34:60]) <= 0).all()
        else:
            assert np.unique(rendered).size == 2
Example #26
0
    def __init__(self):
        app.Canvas.__init__(self, keys='interactive', size=(800, 600))
        brain = np.load(load_data_file('brain/brain.npz', force_download='2014-09-04'))

        #brain1 = scipy.io.loadmat('NewBESATri.mat')
        brain2 = brain1['t']


        from numpy import genfromtxt
        my_data = genfromtxt('BESACOORD61.csv', delimiter=',')

        dataTest = brain['vertex_buffer']
        color = dataTest['a_color']
        color = color[750:1500]
        facesTest = brain['index_buffer']

        n = 750
        ps = 100
        data = np.zeros(n, [('a_position', np.float32, 3),
                            ('a_normal', np.float32, 3),
                            ('a_color', np.float32, 3)])
                            #('a_size', np.float32, 1)])

        import scipy.spatial
        tri = scipy.spatial.Delaunay(my_data) # points: np.array() of 3d points
        convex = tri.convex_hull
        indices = tri.simplices
        vertices = my_data[indices]
        data['a_position'] = my_data
        data['a_color'] = np.random.uniform(0, 1, (n, 3))
        faces = brain2
        faces = faces-1
        vertices = my_data
        norm = np.zeros( vertices.shape, dtype=vertices.dtype )
        #Create an indexed view into the vertex array using the array of three indices for triangles
        tris = vertices[faces]

        #Calculate the normal for all the triangles, by taking the cross product of the vectors v1-v0, and v2-v0 in each triangle
        n = np.cross( tris[::,1 ] - tris[::,0]  , tris[::,2 ] - tris[::,0] )
        # n is now an array of normals per triangle. The length of each normal is dependent the vertices,
        # we need to normalize these, so that our next step weights each normal equally.
        lens = np.sqrt( n[:,0]**2 + n[:,1]**2 + n[:,2]**2 )
        n[:,0] /= lens
        n[:,1] /= lens
        n[:,2] /= lens



        norm[ faces[:,0] ] += n
        norm[ faces[:,1] ] += n
        norm[ faces[:,2] ] += n

        ''' Normalize a numpy array of 3 component vectors shape=(n,3) '''
        lens = np.sqrt( norm[:,0]**2 + norm[:,1]**2 + norm[:,2]**2 )
        norm[:,0] /= lens
        norm[:,1] /= lens
        norm[:,2] /= lens

        data['a_normal'] = norm #np.random.uniform(0, 1.0, (n, 3)) #10, 3, 3
        #data['a_size'] = np.random.uniform(5*ps, 10*ps, n)
        u_linewidth = 1.0
        u_antialias = 1.0



        brain2 = np.uint32(brain2)
        convex = np.uint32(convex)
        data = data
        faces = brain2-1

        #data = dataTest
        #faces = facesTest

        self.meshes = []
        self.rotation = MatrixTransform()

        # Generate some data to work with
        global mdata
        mdata = create_sphere(20, 40, 1.0)
        #mdata['_faces'] =faces
        #mdata['_vertices']=data
        # Mesh with pre-indexed vertices, uniform color
        meshData=vispy.geometry.MeshData(vertices=data['a_position'], faces=None, edges=None, vertex_colors=None, face_colors=None)
        meshData._vertices = data['a_position']
        meshData._faces = faces
        #meshData._face_colors = data['a_color']
        #meshData._vertex_colors = data['a_color']

        self.meshes.append(visuals.MeshVisual(meshdata=meshData, color='b'))
        #for mesh in self.meshes:
        #    mesh.draw()

        # 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.
        tris = vertices[faces]
        verts = data['a_position'] #mdata.get_vertices(indexed='faces')

        nf = 1496#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]
        #fcolor = data['a_color']
        mesh = visuals.MeshVisual(vertices=tris, 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.get_vertices()
        faces = faces #mdata.get_faces()
        nv = verts.size//3
        vcolor = np.ones((nv, 4), dtype=np.float32)
        vcolor[:, 0] = np.linspace(.6, .6, nv)
        vcolor[:, 1] = np.random.normal(size=nv)
        vcolor[:, 2] = np.linspace(0.6, .6, nv)
        self.meshes.append(visuals.MeshVisual(verts, faces, vcolor))
        self.meshes.append(visuals.MeshVisual(verts, faces, vcolor,
                                              shading='flat'))
        #
        self.meshes.append(visuals.MeshVisual(verts, faces, vcolor,
                                              shading='smooth'))

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

        self.show()

        self.timer = app.Timer(connect=self.rotate)
        self.timer.start(0.00016)
Example #27
0
                         vmax=8., under='gray', over='red')
sc.add_to_subplot(s_obj_data, row=1, col=2, title='Color sources using data')
cb_data = ColorbarObj(s_obj_data, cblabel='Random data', border=False,
                      **CBAR_STATE)
sc.add_to_subplot(cb_data, row=1, col=3, width_max=60)

"""Display only sources in the left hemisphere
"""
s_obj_left = SourceObj('S_left', xyz, color='#ab4642')
s_obj_left.set_visible_sources('left')
sc.add_to_subplot(s_obj_left, row=2, col=0,
                  title='Display sources in left hemisphere')

"""Create a sphere using VisPy
"""
sphere = create_sphere(rows=100, cols=100, radius=50)
sphere_vertices = sphere.get_vertices()

"""Force sources to fit on the vertices of the sphere. Then, we color sources
according to the hemisphere (left=purple, right=yellow)
"""
s_obj_fit = SourceObj('Fit', xyz, symbol='diamond')
s_obj_fit.fit_to_vertices(sphere_vertices)
df_tal = s_obj_fit.analyse_sources(roi_obj='talairach')
s_obj_fit.color_sources(analysis=df_tal, color_by='hemisphere',
                        roi_to_color={'Left': 'purple', 'Right': 'yellow'})
sc.add_to_subplot(s_obj_fit, row=2, col=1,
                  title="Force sources to fit on a sphere")

"""Use the same sphere to display only sources that are inside
"""
Example #28
0
    def __init__(self):
        app.Canvas.__init__(self, keys='interactive')
        
        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
        verts = mdata.get_vertices(indexed='faces')
        mesh = ModularMesh(pos=verts, color=(1, 0, 0, 1))
        self.meshes.append(mesh)

        # 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.
        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 = ModularMesh(pos=verts, color=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.get_vertices()
        faces = mdata.get_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)
        mesh = ModularMesh(pos=verts, faces=faces, color=vcolor)
        self.meshes.append(mesh)

        # Mesh colored by vertices + grid contours
        mesh = ModularMesh(pos=verts, faces=faces)
        mesh.color_components = [VertexColorComponent(vcolor),
                                 GridContourComponent(spacing=(0.13, 0.13,
                                                               0.13))]
        self.meshes.append(mesh)

        # Phong shaded mesh
        mesh = ModularMesh(pos=verts, faces=faces)
        normal_comp = VertexNormalComponent(mdata)
        mesh.color_components = [VertexColorComponent(vcolor),
                                 GridContourComponent(spacing=(0.1, 0.1, 0.1)),
                                 ShadingComponent(normal_comp,
                                                  lights=[((-1, 1, -1),
                                                          (1.0, 1.0, 1.0))],
                                                  ambient=0.2)]
        self.meshes.append(mesh)

        # Phong shaded mesh, flat faces
        mesh = ModularMesh(pos=mdata.get_vertices(indexed='faces'))
        normal_comp = VertexNormalComponent(mdata, smooth=False)
        mesh.color_components = [
            VertexColorComponent(vcolor[mdata.get_faces()]),
            GridContourComponent(spacing=(0.1, 0.1, 0.1)),
            ShadingComponent(normal_comp, lights=[((-1, 1, -1),
                                                  (1.0, 1.0, 1.0))],
                             ambient=0.2)]
        self.meshes.append(mesh)

        # 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])
            mesh.tr_sys = visuals.transforms.TransformSystem(self)
            mesh.tr_sys.visual_to_document = mesh.transform

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

        self.timer = app.Timer(connect=self.rotate)
        self.timer.start(0.016)
Example #29
0
    def plot_secant_crossings(self, radius=None, **kwargs):
        
        crossings = self.raw_crossings(**kwargs)

        if radius is None:
            radii = self.points - np.average(self.points, axis=0)
            radius = 2.5 * np.max(np.sqrt(np.sum(radii**2, axis=1)))

        unique_crossings = []
        crossings_done = set()
        for crossing in crossings:
            if crossing[0] in crossings_done:
                continue
            crossings_done.add(crossing[1])
            unique_crossings.append(crossing)

        points = self.points

        lines = []

        for i, crossing in enumerate(unique_crossings):
            start1, end1, height1, sign1 = crossing
            for other_crossing in unique_crossings[i+1:]:
                start2, end2, height2, sign2 = other_crossing

                if not (start2 > start1 and end1 > start2 and end2 > end1):
                    continue

                start_point1 = points[int(start1)]
                start_point1 += (start1 - int(start1)) * (
                    points[int(start1) + 1] - points[int(start1)])
                segment_point1s = points[int(start1) + 1:int(start2) + 1]
                end_point1 = points[int(start2)]
                end_point1 += (start2 - int(start2)) * (
                    points[int(start2) + 1] - points[int(start2)])

                segment1 = np.vstack(
                    [start_point1, segment_point1s, end_point1])

                #
                start_point2 = points[int(end1)]
                start_point2 += (end1 - int(end1)) * (
                    points[int(end1) + 1] - points[int(end1)])
                segment_point2s = points[int(end1) + 1:int(end2) + 1]
                end_point2 = points[int(end2)]
                end_point2 += (end2 - int(end2)) * (
                    points[int(end2) + 1] - points[int(end2)])

                segment2 = np.vstack(
                    [start_point2, segment_point2s, end_point2])

                directions = np.vstack([
                    start_point1 - segment2,
                    segment1 - end_point2])

                lines.append(directions)

        sphere_lines = []

        for i, line in enumerate(lines):
            radii = np.sqrt(np.sum(line**2, axis=1))
            thetas = np.arccos(line[:, 2] / radii)
            phis = np.arctan2(line[:, 1], line[:, 0])

            local_radius = radius - 0.02*i*radius*np.sin(2*np.sin(thetas))

            sphere_points = np.zeros(line.shape)
            sphere_points[:, 0] = radius * np.sin(thetas) * np.cos(phis)
            sphere_points[:, 1] = radius * np.sin(thetas) * np.sin(phis)
            sphere_points[:, 2] = radius * np.cos(thetas)

            # sphere_points += 2*(np.random.random(sphere_points.shape) - 0.5) * 0.005 * radius

            sphere_lines.append(sphere_points)

        self.plot(tube_radius=0.1, colour=(0.3, 0.3, 0.3, 1))

        # Plot the poles
        from vispy.geometry import create_sphere
        from vispy.scene import Mesh
        meshdata = create_sphere(radius=0.035 * radius)
        vertices = meshdata.get_vertices()
        faces = meshdata.get_faces()
        vertices[:, 2] += radius
        mesh1 = Mesh(vertices=vertices, faces=faces, vertex_colors=np.array([(0.3, 0.3, 0.3, 1) for v in vertices]))
        vertices = vertices.copy()
        vertices[:, 2] -= 2*radius
        mesh2 = Mesh(vertices=vertices, faces=faces, vertex_colors=np.array([(0.3, 0.3, 0.3, 1) for v in vertices]))

        import pyknotid.visualise as pvis
        pvis.vispy_canvas.view.add(mesh1)
        pvis.vispy_canvas.view.add(mesh2)

        from colorsys import hsv_to_rgb
        colours = [hsv_to_rgb(hue, 1, 0.8) for hue in np.linspace(0, 1, len(sphere_lines) + 1)][:-1]
        colours = np.array(colours)
        np.random.shuffle(colours)
        for line, colour in zip(sphere_lines, colours):
            from pyknotid.spacecurves.openknot import OpenKnot
            k = OpenKnot(line)
            k.plot(clf=False, tube_radius=0.15, colour=colour, zero_centroid=False)
Example #30
0
    def __init__(self):
        app.Canvas.__init__(self, keys='interactive', size=(800, 550))

        self.meshes = []
        self.rotation = MatrixTransform()

        # 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(visuals.MeshVisual(meshdata=mdata, color='b'))

        # 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.
        rng = np.random.RandomState(0)
        verts = mdata.get_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] = rng.randn(nf, 1)
        fcolor[..., 2] = np.linspace(0, 1, nf)[:, np.newaxis]
        mesh = visuals.MeshVisual(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.get_vertices()
        faces = mdata.get_faces()
        nv = verts.size//3
        vcolor = np.ones((nv, 4), dtype=np.float32)
        vcolor[:, 0] = np.linspace(1, 0, nv)
        vcolor[:, 1] = rng.randn(nv)
        vcolor[:, 2] = np.linspace(0, 1, nv)
        self.meshes.append(visuals.MeshVisual(verts, faces, vcolor))
        self.meshes.append(visuals.MeshVisual(verts, faces, vcolor,
                                              shading='flat'))
        self.meshes.append(visuals.MeshVisual(verts, faces, vcolor,
                                              shading='smooth'))

        # Mesh with color indexed into a colormap
        verts = mdata.get_vertices(None)
        faces = mdata.get_faces()
        values = rng.randn(len(verts))
        mesh = visuals.MeshVisual(vertices=verts, faces=faces,
                                  vertex_values=values, shading='smooth')
        mesh.clim = [-1, 1]
        mesh.cmap = 'viridis'
        mesh.shininess = 0.01
        self.meshes.append(mesh)

        # 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
            transform = ChainTransform([STTransform(translate=(x, y),
                                                    scale=(s, s, s)),
                                        self.rotation])
            mesh.transform = transform
            mesh.transforms.scene_transform = STTransform(scale=(1, 1, 0.01))

        self.show()

        self.timer = app.Timer(connect=self.rotate)
        self.timer.start(0.016)
Example #31
0
def skeleton2vispy(neuron, neuron_color, object_id, **kwargs):
    """Convert skeleton (i.e. TreeNeuron) into vispy visuals."""
    visuals = []
    if not kwargs.get('connectors_only', False) and not neuron.nodes.empty:
        # Make sure we have one color for each node
        neuron_color = np.asarray(neuron_color)
        if neuron_color.ndim == 1:
            neuron_color = np.tile(neuron_color, (neuron.nodes.shape[0], 1))

        # Get nodes
        non_roots = neuron.nodes[neuron.nodes.parent_id >= 0]
        connect = np.zeros((non_roots.shape[0], 2), dtype=int)
        node_ix = pd.Series(np.arange(neuron.nodes.shape[0]),
                            index=neuron.nodes.node_id.values)
        connect[:, 0] = node_ix.loc[non_roots.node_id].values
        connect[:, 1] = node_ix.loc[non_roots.parent_id].values

        # Create line plot from segments.
        t = scene.visuals.Line(
            pos=neuron.nodes[['x', 'y', 'z']].values,
            color=neuron_color,
            # Can only be used with method 'agg'
            width=kwargs.get('linewidth', 1),
            connect=connect,
            antialias=True,
            method='gl')
        # method can also be 'agg' -> has to use connect='strip'
        # Make visual discoverable
        t.interactive = True

        # Add custom attributes
        t.unfreeze()
        t._object_type = 'neuron'
        t._neuron_part = 'neurites'
        t._id = neuron.id
        t._name = str(getattr(neuron, 'name', neuron.id))
        t._object = neuron
        t._object_id = object_id
        t.freeze()

        visuals.append(t)

        # Extract and plot soma
        soma = utils.make_iterable(neuron.soma)
        if kwargs.get('soma', True) and any(soma):
            # If soma detection is messed up we might end up producing
            # hundrets of soma which will freeze the session
            if len(soma) >= 10:
                logger.warning(
                    f'Neuron {neuron.id} appears to have {len(soma)}'
                    'somas. That does not look right - will ignore '
                    'them for plotting.')
            else:
                for s in soma:
                    # If we have colors for every vertex, we need to find the
                    # color that corresponds to this root (or it's parent to be
                    # precise)
                    if isinstance(neuron_color,
                                  np.ndarray) and neuron_color.ndim > 1:
                        s_ix = np.where(neuron.nodes.node_id == s)[0][0]
                        soma_color = neuron_color[s_ix]
                    else:
                        soma_color = neuron_color

                    n = neuron.nodes.set_index('node_id').loc[s]
                    r = getattr(n, neuron.soma_radius) if isinstance(
                        neuron.soma_radius, str) else neuron.soma_radius
                    sp = create_sphere(7, 7, radius=r)
                    verts = sp.get_vertices() + n[['x', 'y', 'z']].values
                    s = scene.visuals.Mesh(vertices=verts,
                                           shading='smooth',
                                           faces=sp.get_faces(),
                                           color=soma_color)
                    s.ambient_light_color = vispy.color.Color('white')

                    # Make visual discoverable
                    s.interactive = True

                    # Add custom attributes
                    s.unfreeze()
                    s._object_type = 'neuron'
                    s._neuron_part = 'soma'
                    s._id = neuron.id
                    s._name = str(getattr(neuron, 'name', neuron.id))
                    s._object = neuron
                    s._object_id = object_id
                    s.freeze()

                    visuals.append(s)

    return visuals
Example #32
0
    def create_border_cell(self):

        mdata = geometry.create_sphere(64, 64,  radius=15)
        borders = scene.visuals.Mesh(meshdata=mdata, shading='flat', color="#f5f5f527")
        self.view.add(borders)
Example #33
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
        verts = mdata.get_vertices(indexed='faces')
        mesh = ModularMesh(pos=verts, color=(1, 0, 0, 1))
        self.meshes.append(mesh)

        # 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.
        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 = ModularMesh(pos=verts, color=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.get_vertices()
        faces = mdata.get_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)
        mesh = ModularMesh(pos=verts, faces=faces, color=vcolor)
        self.meshes.append(mesh)

        # Mesh colored by vertices + grid contours
        mesh = ModularMesh(pos=verts, faces=faces)
        mesh.color_components = [VertexColorComponent(vcolor),
                                 GridContourComponent(spacing=(0.13, 0.13,
                                                               0.13))]
        self.meshes.append(mesh)

        # Phong shaded mesh
        mesh = ModularMesh(pos=verts, faces=faces)
        normal_comp = VertexNormalComponent(mdata)
        mesh.color_components = [VertexColorComponent(vcolor),
                                 GridContourComponent(spacing=(0.1, 0.1, 0.1)),
                                 ShadingComponent(normal_comp,
                                                  lights=[((-1, 1, -1),
                                                          (1.0, 1.0, 1.0))],
                                                  ambient=0.2)]
        self.meshes.append(mesh)

        # Phong shaded mesh, flat faces
        mesh = ModularMesh(pos=mdata.get_vertices(indexed='faces'))
        normal_comp = VertexNormalComponent(mdata, smooth=False)
        mesh.color_components = [
            VertexColorComponent(vcolor[mdata.get_faces()]),
            GridContourComponent(spacing=(0.1, 0.1, 0.1)),
            ShadingComponent(normal_comp, lights=[((-1, 1, -1),
                                                  (1.0, 1.0, 1.0))],
                             ambient=0.2)]
        self.meshes.append(mesh)

        # 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)
Example #34
0
    def __init__(self):
        app.Canvas.__init__(self, keys='interactive', size=(800, 550))

        self.meshes = []
        self.rotation = MatrixTransform()

        # Generate some data to work with
        global mdata
        mdata = create_sphere(20, 40, 1.0)
        verts = mdata.get_vertices()
        faces = mdata.get_faces()
        gamma, phi = xyz_to_gp(verts)
        data = np.cos(5*gamma)+np.cos(phi*4)/2.
        mesh = visuals.MeshVisual(vertices=verts, faces=faces,
                                  banded=False, nband=8,
                                  vertex_values=data)
        mesh.cmap = 'viridis'
        self.meshes.append(mesh)
        mesh = visuals.MeshVisual(vertices=verts,
                                  faces=faces,  banded=True, nband=8,
                                  vertex_values=data)
        mesh.cmap = 'viridis'
        self.meshes.append(mesh)
        mesh = visuals.MeshVisual(vertices=verts,
                                  faces=faces,  banded=False, nband=8,
                                  vertex_values=data, shading='flat')
        mesh.cmap = 'viridis'
        self.meshes.append(mesh)
        mesh = visuals.MeshVisual(vertices=verts,
                                  faces=faces,  banded=True, nband=8,
                                  vertex_values=data, shading='flat')
        mesh.cmap = 'viridis'
        self.meshes.append(mesh)
        mesh = visuals.MeshVisual(vertices=verts,
                                  faces=faces,  banded=False, nband=8,
                                  vertex_values=data, shading='smooth')
        mesh.cmap = 'viridis'
        mesh.shininess = 0.01
        self.meshes.append(mesh)
        # Mesh with color indexed into a colormap
        mesh = visuals.MeshVisual(vertices=verts,
                                  faces=faces,  banded=True, nband=8,
                                  vertex_values=data, shading='smooth')
        mesh.cmap = 'viridis'
        mesh.shininess = 0.01
        self.meshes.append(mesh)

        # 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
            transform = ChainTransform([STTransform(translate=(x, y),
                                                    scale=(s, s, s)),
                                        self.rotation])
            mesh.transform = transform
            mesh.transforms.scene_transform = STTransform(scale=(1, 1, 0.01))

        self.show()

        self.timer = app.Timer(connect=self.rotate)
        self.timer.start(0.016)
Example #35
0
labels_layer = viewer.add_labels(
    labeled,
    name='labels',
    blending='translucent',
    experimental_clipping_planes=[plane_parameters],
)

# POINTS
points_layer = viewer.add_points(
    np.random.rand(20, 3) * 64,
    size=5,
    experimental_clipping_planes=[plane_parameters],
)

# SPHERE
mesh = create_sphere(method='ico')
sphere_vert = mesh.get_vertices() * 20
sphere_vert += 32
surface_layer = viewer.add_surface(
    (sphere_vert, mesh.get_faces()),
    experimental_clipping_planes=[plane_parameters],
)

# SHAPES
shapes_data = np.random.rand(3, 4, 3) * 64

shapes_layer = viewer.add_shapes(
    shapes_data,
    face_color=['magenta', 'green', 'blue'],
    experimental_clipping_planes=[plane_parameters],
)
Example #36
0
def test_sphere():
    """Test sphere function"""
    md = create_sphere(10, 20, radius=10)
    radii = np.sqrt((md.get_vertices() ** 2).sum(axis=1))
    assert_allclose(radii, np.ones_like(radii) * 10)
Example #37
0
def test_sphere():
    """Test sphere function"""
    md = create_sphere(10, 20, radius=10)
    radii = np.sqrt((md.get_vertices()**2).sum(axis=1))
    assert_allclose(radii, np.ones_like(radii) * 10)
Example #38
0
    def __init__(self):
        app.Canvas.__init__(self, keys='interactive', size=(800, 550))

        self.meshes = []
        self.rotation = MatrixTransform()

        # 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(visuals.MeshVisual(meshdata=mdata, color='b'))

        # 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.
        rng = np.random.RandomState(0)
        verts = mdata.get_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] = rng.randn(nf, 1)
        fcolor[..., 2] = np.linspace(0, 1, nf)[:, np.newaxis]
        mesh = visuals.MeshVisual(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.get_vertices()
        faces = mdata.get_faces()
        nv = verts.size // 3
        vcolor = np.ones((nv, 4), dtype=np.float32)
        vcolor[:, 0] = np.linspace(1, 0, nv)
        vcolor[:, 1] = rng.randn(nv)
        vcolor[:, 2] = np.linspace(0, 1, nv)
        self.meshes.append(visuals.MeshVisual(verts, faces, vcolor))
        self.meshes.append(
            visuals.MeshVisual(verts, faces, vcolor, shading='flat'))
        self.meshes.append(
            visuals.MeshVisual(verts, faces, vcolor, shading='smooth'))

        # Mesh with color indexed into a colormap
        verts = mdata.get_vertices(None)
        faces = mdata.get_faces()
        values = rng.randn(len(verts))
        mesh = visuals.MeshVisual(vertices=verts,
                                  faces=faces,
                                  vertex_values=values,
                                  shading='smooth')
        mesh.clim = [-1, 1]
        mesh.cmap = 'viridis'
        mesh.shininess = 0.01
        self.meshes.append(mesh)

        # 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
            transform = ChainTransform([
                STTransform(translate=(x, y), scale=(s, s, s)), self.rotation
            ])
            mesh.transform = transform
            mesh.transforms.scene_transform = STTransform(scale=(1, 1, 0.01))

        self.show()

        self.timer = app.Timer(connect=self.rotate)
        self.timer.start(0.016)
Example #39
0
 def __init__(self):
     GpaphicBlueprint.__init__(self)
     self.kind = 'sphere'
     oldMesh = create_sphere(10, 20)
     self._mesh = Mesh(oldMesh.get_vertices(), oldMesh.get_faces())
     self.buildProgram()
Example #40
0
def skeleton2vispy(neuron, neuron_color, object_id, **kwargs):
    """Convert skeleton (i.e. TreeNeuron) into vispy visuals."""
    visuals = []
    if not kwargs.get('connectors_only', False) and not neuron.nodes.empty:
        # Get root node indices (may be more than one if neuron has been
        # cut weirdly)
        root_ix = neuron.nodes[neuron.nodes.parent_id < 0].index.tolist()

        # Get nodes
        nodes = neuron.nodes[neuron.nodes.parent_id >= 0]

        # Extract treenode_coordinates and their parent's coordinates
        tn_coords = nodes[['x', 'y', 'z']].apply(pd.to_numeric).values
        parent_coords = neuron.nodes.set_index('node_id').loc[
            nodes.parent_id.values][['x', 'y',
                                     'z']].apply(pd.to_numeric).values

        # Add alpha to color based on strahler
        if kwargs.get('by_strahler', False) \
                or kwargs.get('by_confidence', False):
            if kwargs.get('by_strahler', False):
                if 'strahler_index' not in neuron.nodes:
                    morpho.strahler_index(neuron)

                # Generate list of alpha values
                alpha = neuron.nodes['strahler_index'].values

            if kwargs.get('by_confidence', False):
                if 'arbor_confidence' not in neuron.nodes:
                    morpho.arbor_confidence(neuron)

                # Generate list of alpha values
                alpha = neuron.nodes['arbor_confidence'].values

            # Pop root from coordinate lists
            alpha = np.delete(alpha, root_ix, axis=0)

            alpha = alpha / (max(alpha) + 1)
            # Duplicate values (start and end of each segment!)
            alpha = np.array([v for l in zip(alpha, alpha) for v in l])

            # Turn color into array
            # (need 2 colors per segment for beginning and end)
            neuron_color = np.array([neuron_color] * (tn_coords.shape[0] * 2),
                                    dtype=float)
            neuron_color = np.insert(neuron_color, 3, alpha, axis=1)

        if not kwargs.get('radius', False):
            # Turn coordinates into segments
            segments = [
                item for sublist in zip(tn_coords, parent_coords)
                for item in sublist
            ]
            # Create line plot from segments.
            t = scene.visuals.Line(
                pos=np.array(segments),
                color=list(neuron_color),
                # Can only be used with method 'agg'
                width=kwargs.get('linewidth', 1),
                connect='segments',
                antialias=True,
                method='gl')
            # method can also be 'agg' -> has to use connect='strip'
            # Make visual discoverable
            t.interactive = True

            # Add custom attributes
            t.unfreeze()
            t._object_type = 'neuron'
            t._neuron_part = 'neurites'
            t._id = neuron.id
            t._name = str(getattr(neuron, 'name', neuron.id))
            t._object_id = object_id
            t.freeze()

            visuals.append(t)
        else:
            # Generate coordinates
            coords = segments_to_coords(neuron,
                                        neuron.segments,
                                        modifier=(1, 1, 1))
            # For each point of each segment get the radius
            nodes = neuron.nodes.set_index('node_id')
            radii = [
                nodes.loc[s, 'radius'].values.astype(float)
                for s in neuron.segments
            ]

            # Generate faces and vertices for the tube
            verts, faces = make_tube(segments=coords,
                                     radii=radii,
                                     use_normals=kwargs.get(
                                         'use_normals', True),
                                     tube_points=kwargs.get('tube_points', 3))

            vertex_colors = np.resize(
                neuron_color, (verts.shape[0], kwargs.get('tube_points', 3)))

            t = scene.visuals.Mesh(vertices=verts,
                                   faces=faces,
                                   vertex_colors=vertex_colors,
                                   shading='smooth',
                                   mode='triangles')

            # Add custom attributes
            t.unfreeze()
            t._object_type = 'neuron'
            t._neuron_part = 'neurites'
            t._id = neuron.id
            t._name = str(getattr(neuron, 'name', neuron.id))
            t._object_id = object_id
            t.freeze()

            visuals.append(t)

        if kwargs.get('by_strahler', False) or \
           kwargs.get('by_confidence', False):
            # Convert array back to a single color without alpha
            neuron_color = neuron_color[0][:3]

        # Extract and plot soma
        soma = utils.make_iterable(neuron.soma)
        if any(soma):
            # If soma detection is messed up we might end up producing
            # dozens of soma which will freeze the kernel
            if len(soma) >= 10:
                logger.warning(f'{neuron.id}: {len(soma)} somas found.')
            for s in soma:
                n = neuron.nodes.set_index('node_id').loc[s]
                r = getattr(n, neuron.soma_radius) if isinstance(
                    neuron.soma_radius, str) else neuron.soma_radius
                sp = create_sphere(7, 7, radius=r)
                verts = sp.get_vertices() + n[['x', 'y', 'z']].values
                s = scene.visuals.Mesh(vertices=verts,
                                       shading='smooth',
                                       faces=sp.get_faces(),
                                       color=neuron_color)
                s.ambient_light_color = vispy.color.Color('white')

                # Make visual discoverable
                s.interactive = True

                # Add custom attributes
                s.unfreeze()
                s._object_type = 'neuron'
                s._neuron_part = 'soma'
                s._id = neuron.id
                s._name = str(getattr(neuron, 'name', neuron.id))
                s._object_id = object_id
                s.freeze()

                visuals.append(s)

    return visuals
Example #41
0
    def update(self, t, crazyflies):
        if len(self.cfs) == 0:
            verts, faces, normals, nothin = io.read_mesh(CF_MESH_PATH)
            for i, cf in enumerate(crazyflies):
                color = cf.ledRGB
                mesh = scene.visuals.Mesh(
                    parent=self.view.scene,
                    vertices=verts,
                    faces=faces,
                    color=color,
                    shading="smooth",
                )
                mesh.light_dir = (0.1, 0.1, 1.0)
                mesh.shininess = 0.01
                mesh.ambient_light_color = [0.5] * 3
                mesh.transform = transforms.MatrixTransform()
                self.cfs.append(mesh)
                self.led_color_cache.append(color)

        if self.ellipsoid_radii is not None and self.ellipsoids is None:
            sphere_mesh = geometry.create_sphere(radius=1.0)
            self.ellipsoids = [
                scene.visuals.Mesh(
                    parent=self.view.scene,
                    meshdata=sphere_mesh,
                    color=ELLIPSOID_COLOR_OK,
                    shading="smooth",
                ) for _ in self.cfs
            ]
            for ell in self.ellipsoids:
                ell.light_dir = (0.1, 0.1, 1.0)
                ell.shininess = 0.0
                ell.ambient_light_color = [0.5] * 3
                ell.transform = transforms.MatrixTransform()

        positions = np.stack([cf.position() for cf in crazyflies])

        for i in range(0, len(self.cfs)):
            x, y, z = crazyflies[i].position()
            roll, pitch, yaw = crazyflies[i].rpy()
            self.cfs[i].transform.reset()
            self.cfs[i].transform.rotate(-90, (1, 0, 0))
            self.cfs[i].transform.rotate(math.degrees(roll), (1, 0, 0))
            self.cfs[i].transform.rotate(math.degrees(pitch), (0, 1, 0))
            self.cfs[i].transform.rotate(math.degrees(yaw), (0, 0, 1))
            self.cfs[i].transform.scale((0.002, 0.002, -0.002))
            self.cfs[i].transform.translate(positions[i])
            # vispy does not do this check
            color = crazyflies[i].ledRGB
            if color != self.led_color_cache[i]:
                self.led_color_cache[i] = color
                self.cfs[i].color = color  # sets dirty flag

        # Update graph line segments to match new Crazyflie positions.
        if self.graph is not None:
            for k, (i, j) in enumerate(self.graph_edges):
                self.graph_lines[2 * k, :] = positions[i]
                self.graph_lines[2 * k + 1, :] = positions[j]
            self.graph.set_data(self.graph_lines)

        # Update collsiion ellipsoids.
        if self.ellipsoids is not None:
            colliding = util.check_ellipsoid_collisions(
                positions, self.ellipsoid_radii)
            for i, pos in enumerate(positions):
                ell = self.ellipsoids[i]
                tf = ell.transform
                tf.reset()
                tf.scale(self.ellipsoid_radii)
                tf.translate(pos)
                new_color = ELLIPSOID_COLOR_COLLISION if colliding[
                    i] else ELLIPSOID_COLOR_OK
                if not (new_color
                        == ell.color):  # vispy Color lacks != override.
                    ell.color = new_color

        self.canvas.app.process_events()
Example #42
0
def dotprop2vispy(x, **kwargs):
    """Converts dotprops(s) to vispy visuals.

    Parameters
    ----------
    x :             core.Dotprops | pd.DataFrame
                    Dotprop(s) to plot.
    colormap :      tuple | dict | array
                    Color to use for plotting. Dictionaries should be mapped
                    to gene names.
    scale_vect :    int, optional
                    Vector to scale dotprops by.

    Returns
    -------
    list
                    Contains vispy visuals for each dotprop.

    """
    if not isinstance(x, (core.Dotprops, pd.DataFrame)):
        raise TypeError(f'Unable to process data of type "{type(x)}"')

    visuals = []

    # Parse colors for dotprops
    colors = kwargs.get('color', kwargs.get('c', kwargs.get('colors', None)))
    _, colormap, _ = prepare_colormap(colors,
                                      dotprops=x,
                                      use_neuron_color=False,
                                      color_range=1)

    scale_vect = kwargs.get('scale_vect', 1)

    for i, n in enumerate(x.itertuples()):
        # Generate random ID -> we need this in case we have duplicate IDs
        object_id = uuid.uuid4()

        color = colormap[i]

        # Prepare lines - this is based on nat:::plot3d.dotprops
        halfvect = n.points[['x_vec', 'y_vec', 'z_vec']] / 2 * scale_vect

        starts = n.points[['x', 'y', 'z']].values - halfvect.values
        ends = n.points[['x', 'y', 'z']].values + halfvect.values

        segments = [item for sublist in zip(starts, ends) for item in sublist]

        t = scene.visuals.Line(pos=np.array(segments),
                               color=color,
                               width=2,
                               connect='segments',
                               antialias=False,
                               method='gl')  # method can also be 'agg'

        # Add custom attributes
        t.unfreeze()
        t._object_type = 'dotprop'
        t._neuron_part = 'neurites'
        t._name = getattr(n, 'gene_name', getattr(n, 'name', 'NoName'))
        t._object_id = object_id
        t.freeze()

        visuals.append(t)

        # Add soma (if provided as X/Y/Z)
        if all([hasattr(n, v) for v in ['X', 'Y', 'Z']]):
            sp = create_sphere(5, 5, radius=4)
            s = scene.visuals.Mesh(vertices=sp.get_vertices() +
                                   np.array([n.X, n.Y, n.Z]),
                                   faces=sp.get_faces(),
                                   color=color)

            # Add custom attributes
            s.unfreeze()
            s._object_type = 'dotprop'
            s._neuron_part = 'soma'
            s._name = n.gene_name
            s._object_id = object_id
            s.freeze()

            visuals.append(s)

    return visuals