def draw_scene(self): self.fixed_frame = scene.node.Node(self.view.scene) self.fixed_frame.transform = STTransform( translate=(-self.moving_volume.shape[2] // 2, -self.moving_volume.shape[1] // 2, -500)) fixed_volume = scene.visuals.Volume( self.fixed_volume, parent=self.fixed_frame, threshold=self.model.fixed_display_threshold.get(), emulate_texture=False) fixed_volume.cmap = TranslucentFixedColormap() fixed_volume.method = VOLUME_RENDERING_METHOD # # The transformation is done as follows: # # The translation frame handles the offset # # The centering frame picks the center of the moving frame # # The rotation frame rotates about the center # # The uncentering frame readjusts the coordinates so that 0, 0 is # placed away from the center. # self.translation_frame = scene.node.Node(self.fixed_frame) moving_volume = scene.visuals.Volume( self.moving_volume, parent=self.translation_frame, threshold=self.model.moving_display_threshold.get(), emulate_texture=False) moving_volume.cmap = TranslucentMovingColormap() moving_volume.method = VOLUME_RENDERING_METHOD self.camera = scene.cameras.TurntableCamera( parent=self.view.scene, fov=60., elevation=self.fixed_volume.shape[2] // 2, name="Turntable") self.view.camera = self.camera self.center_frame = scene.node.Node(parent=self.view) self.axis = scene.visuals.XYZAxis(parent=self.center_frame) axis_t = STTransform(scale=(50, 50, 50, 1)) self.axis.transform = axis_t.as_matrix() self.apply_translation() self.scene.events.mouse_move.connect(self.on_mouse_move)
volume2 = scene.visuals.Volume(vol2, parent=view.scene, threshold=0.2) volume2.visible = False # Create three cameras (Fly, Turntable and Arcball) fov = 60. cam1 = scene.cameras.FlyCamera(parent=view.scene, fov=fov, name='Fly') cam2 = scene.cameras.TurntableCamera(parent=view.scene, fov=fov, name='Turntable') cam3 = scene.cameras.ArcballCamera(parent=view.scene, fov=fov, name='Arcball') view.camera = cam2 # Select turntable at first # Create an XYZAxis visual axis = scene.visuals.XYZAxis(parent=view) s = STTransform(translate=(50, 50), scale=(50, 50, 50, 1)) affine = s.as_matrix() axis.transform = affine # create colormaps that work well for translucent and additive volume rendering class TransFire(BaseColormap): glsl_map = """ vec4 translucent_fire(float t) { return vec4(pow(t, 0.5), t, t*t, max(0, t*1.05 - 0.05)); } """ class TransGrays(BaseColormap): glsl_map = """ vec4 translucent_grays(float t) {
def __init__(self, vol1_path, vol2_path): vol1_path = vol1_path vol2_path = vol2_path vol1 = load_numpy_array(vol1_path) if vol2_path is not None: vol2 = load_numpy_array(vol2_path) canvas = scene.SceneCanvas(keys='interactive', size=(800, 600), show=True) # Set up a viewbox to display the image with interactive pan/zoom view = canvas.central_widget.add_view() # Set whether we are emulating a 3D texture emulate_texture = False # Create the volume visuals, only one is visible volume1 = scene.visuals.Volume(vol1, parent=view.scene, threshold=0.225, emulate_texture=emulate_texture) volume1.transform = scene.STTransform(translate=(64, 64, 0)) if vol2_path is not None: volume2 = scene.visuals.Volume(vol2, parent=view.scene, threshold=0.2, emulate_texture=emulate_texture) volume2.visible = False # Create three cameras (Fly, Turntable and Arcball) fov = 60. cam1 = scene.cameras.FlyCamera(parent=view.scene, fov=fov, name='Fly') cam2 = scene.cameras.TurntableCamera(parent=view.scene, fov=fov, name='Turntable') cam3 = scene.cameras.ArcballCamera(parent=view.scene, fov=fov, name='Arcball') view.camera = cam2 # Select turntable at first # Create an XYZaxis visual axis = scene.visuals.XYZAxis(parent=view) s = STTransform(translate=(50, 50), scale=(50, 50, 50, 1)) affine = s.as_matrix() axis.transform = affine # Implement axis connection with cam2 @canvas.events.mouse_move.connect def on_mouse_move(event): if event.button == 1 and event.is_dragging: axis.transform.reset() axis.transform.rotate(cam2.roll, (0, 0, 1)) axis.transform.rotate(cam2.elevation, (1, 0, 0)) axis.transform.rotate(cam2.azimuth, (0, 1, 0)) axis.transform.scale((50, 50, 0.001)) axis.transform.translate((50., 50.)) axis.update() # Implement key presses @canvas.events.key_press.connect def on_key_press(event): global opaque_cmap, translucent_cmap if event.text == '1': cam_toggle = {cam1: cam2, cam2: cam3, cam3: cam1} view.camera = cam_toggle.get(view.camera, cam2) print(view.camera.name + ' camera') if view.camera is cam2: axis.visible = True else: axis.visible = False elif event.text == '2': methods = ['mip', 'translucent', 'iso', 'additive'] method = methods[(methods.index(volume1.method) + 1) % 4] print("Volume render method: %s" % method) cmap = \ opaque_cmap if method in ['mip', 'iso'] else \ translucent_cmap volume1.method = method volume1.cmap = cmap if vol2_path is not None: volume2.method = method volume2.cmap = cmap elif event.text == '3': volume1.visible = not volume1.visible volume2.visible = not volume1.visible elif event.text == '4': if volume1.method in ['mip', 'iso']: cmap = opaque_cmap = next(opaque_cmaps) else: cmap = translucent_cmap = next(translucent_cmaps) volume1.cmap = cmap if vol2_path is not None: volume2.cmap = cmap elif event.text == '0': cam1.set_range() cam3.set_range() elif event.text != '' and event.text in '[]': s = -0.025 if event.text == '[' else 0.025 volume1.threshold += s if vol2_path is not None: volume2.threshold += s if volume1.visible: th = volume1.threshold if vol2_path is not None: th = volume2.threshold print("Isosurface threshold: %0.3f" % th)
class AxesVisual3D(object): def __init__(self, view=None, transform=None, **kwargs): self.view = view # Add a 3D cube to show us the unit cube. The 1.001 factor is to make # sure that the grid lines are not 'hidden' by volume renderings on the # front side due to numerical precision. vertices, filled_indices, outline_indices = create_cube() self.axis = scene.visuals.Mesh(vertices['position'], outline_indices, parent=self.view.scene, color=kwargs['axis_color'], mode='lines') self.axis.transform = transform self.xax = Axis(pos=[[-1.0, 0], [1.0, 0]], tick_direction=(0, -1), parent=self.view.scene, axis_label='X', anchors=['center', 'middle'], **kwargs) self.yax = Axis(pos=[[0, -1.0], [0, 1.0]], tick_direction=(-1, 0), parent=self.view.scene, axis_label='Y', anchors=['center', 'middle'], **kwargs) self.zax = Axis(pos=[[0, -1.0], [0, 1.0]], tick_direction=(-1, 0), parent=self.view.scene, axis_label='Z', anchors=['center', 'middle'], **kwargs) self.xtr = STTransform() self.xtr = self.xtr.as_matrix() self.xtr.rotate(45, (1, 0, 0)) self.xtr.translate((0, -1., -1.)) self.ytr = STTransform() self.ytr = self.ytr.as_matrix() self.ytr.rotate(-45, (0, 1, 0)) self.ytr.translate((-1, 0, -1.)) self.ztr = STTransform() self.ztr = self.ztr.as_matrix() self.ztr.rotate(45, (0, 1, 0)) self.ztr.rotate(90, (1, 0, 0)) self.ztr.translate((-1, -1, 0.)) self.xax.transform = ChainTransform(transform, self.xtr) self.yax.transform = ChainTransform(transform, self.ytr) self.zax.transform = ChainTransform(transform, self.ztr) @property def tick_color(self): return self.xax.tick_color @tick_color.setter def tick_color(self, value): self.xax.tick_color = value self.yax.tick_color = value self.zax.tick_color = value @property def label_color(self): return self._label_color @label_color.setter def label_color(self, value): self.xax.label_color = value self.yax.label_color = value self.zax.label_color = value @property def axis_color(self): return self._axis_color @axis_color.setter def axis_color(self, value): self.axis.color = value @property def tick_font_size(self): return self.xax.tick_font_size @tick_font_size.setter def tick_font_size(self, value): self.xax.tick_font_size = value self.yax.tick_font_size = value self.zax.tick_font_size = value @property def axis_font_size(self): return self.xax.axis_font_size @axis_font_size.setter def axis_font_size(self, value): self.xax.axis_font_size = value self.yax.axis_font_size = value self.zax.axis_font_size = value @property def xlabel(self): return self.xax.axis_label @xlabel.setter def xlabel(self, value): self.xax.axis_label = value @property def ylabel(self): return self.yax.axis_label @ylabel.setter def ylabel(self, value): self.yax.axis_label = value @property def zlabel(self): return self.zax.axis_label @zlabel.setter def zlabel(self, value): self.zax.axis_label = value @property def xlim(self): return self.xax.domain @xlim.setter def xlim(self, value): self.xax.domain = value @property def ylim(self): return self.yax.domain @ylim.setter def ylim(self, value): self.yax.domain = value @property def zlim(self): return self.zax.domain @zlim.setter def zlim(self, value): self.zax.domain = value @property def parent(self): return self.axis.parent @parent.setter def parent(self, value): self.axis.parent = value self.xax.parent = value self.yax.parent = value self.zax.parent = value
volume2 = scene.visuals.Volume(vol2, parent=view.scene, threshold=0.2, emulate_texture=emulate_texture) volume2.visible = False # Create three cameras (Fly, Turntable and Arcball) fov = 60. cam1 = scene.cameras.FlyCamera(parent=view.scene, fov=fov, name='Fly') cam2 = scene.cameras.TurntableCamera(parent=view.scene, fov=fov, name='Turntable') cam3 = scene.cameras.ArcballCamera(parent=view.scene, fov=fov, name='Arcball') view.camera = cam2 # Select turntable at first # Create an XYZAxis visual axis = scene.visuals.XYZAxis(parent=view) s = STTransform(translate=(50, 50), scale=(50, 50, 50, 1)) affine = s.as_matrix() axis.transform = affine # create colormaps that work well for translucent and additive volume rendering class TransFire(BaseColormap): glsl_map = """ vec4 translucent_fire(float t) { return vec4(pow(t, 0.5), t, t*t, max(0, t*1.05 - 0.05)); } """ class TransGrays(BaseColormap): glsl_map = """ vec4 translucent_grays(float t) {
def preview_volume(vols, shifts=None): canvas = scene.SceneCanvas(keys="interactive") canvas.size = 1024, 1024 canvas.show() # create view box view = canvas.central_widget.add_view() # genereate colormap """ n_colors = 256 alphas = np.linspace(0.0, 1.0, n_colors) color = np.c_[ alphas, alphas, alphas, alphas ] cmap = Colormap(color) """ from utoolbox.data.io.amira import AmiraColormap color = AmiraColormap("volrenGlow.am") color = np.array(color) color[0, :] = 0 color[:, 3] /= 100 cmap = Colormap(color) for i, vol in enumerate(vols): volume = scene.visuals.Volume(vol, cmap=cmap, parent=view.scene, emulate_texture=False) volume.method = "translucent" volume.transform = scene.STTransform(scale=(2, 2, 5.5)) volume.set_gl_state("translucent", depth_test=False) if shifts: volume.transform = scene.STTransform(translate=shifts[i]) # assign camera camera = scene.cameras.TurntableCamera(parent=view.scene, fov=60.0, name="Arcball", elevation=30.0) view.camera = camera view.camera.flip = (False, True, True) view.camera.reset() # axis axis = scene.visuals.XYZAxis(parent=view) s = STTransform(translate=(50, 50), scale=(50, 50, 50, 1)) affine = s.as_matrix() axis.transform = affine # link with camera @canvas.events.mouse_move.connect def on_mouse_move(event): if event.button == 1 and event.is_dragging: axis.transform.reset() axis.transform.rotate(camera.roll, (0, 0, 1)) axis.transform.rotate(camera.elevation, (1, 0, 0)) axis.transform.rotate(camera.azimuth, (0, 1, 0)) axis.transform.scale((50, 50, 0.001)) axis.transform.translate((50.0, 50.0)) axis.update() # render rotation movie """ n_steps = 240 axis = [0, 0, 0] logger.debug(".. rendering") step_angle = 360.0 / n_steps writer = imageio.get_writer("t1-head_split_rotate.mp4", fps=24) for i in range(n_steps): im = canvas.render() writer.append_data(im) view.camera.transform.rotate(step_angle, axis) writer.close() """ app.run()