def __init__(self): self.IsProcessed = False self.Interaction = True self.ShowAnnotations = True self.ShowDirections = True self.AboutDataVisibility = True self.LinkRender = True self.LinkCameraFocalAndPosition = False self.Renderer = None self.RenderWindow = None self.RenderWindowInteractor = None self.Children = [] self.InteractorStyle = None # Initilize Annotations self.CornerAnnotation = vtk.vtkCornerAnnotation() self.CornerAnnotation.SetNonlinearFontScaleFactor(0.3) self.TextProperty = vtk.vtkTextProperty() self.CornerAnnotation.SetTextProperty(self.TextProperty) #self.OrientationAnnotation = vtkOrientationAnnotation() #self.OrientationAnnotation.SetNonlinearFontScaleFactor(0.25) #self.InteractorStyle = vtk.vtkInteractorStyleSwitch() self.Parent = None self.downRightAnnotation = "" self.upLeftAnnotation = "" self.upRightAnnotation = "" self.downLeftAnnotation = "" self.AboutData = "" self.InternalMTime = 0
def __init__(self): ''' Constructor ''' self.__OrientationMatrix = vtk.vtkMatrix4x4() self.__CornerAnnotation = vtk.vtkCornerAnnotation() self.__TextProperty = vtk.vtkTextProperty() self.__LookupTable = vtk.vtkLookupTable() self.__ScalarBarActor = vtk.vtkScalarBarActor() self.__Prop3DCollection = vtk.vtkProp3DCollection() self.__DataSetCollection = vtk.vtkDataSetCollection() self.__OrientationTransform = vtk.vtkMatrixToLinearTransform() self.__OrientationMatrix.Identity() self.__CornerAnnotation.SetNonlinearFontScaleFactor(0.30) self.__CornerAnnotation.SetText(0, "Jolly - (c) summit 2009 ref vtkINRIA3D") self.__CornerAnnotation.SetMaximumFontSize(46) self.__ScalarBarActor.SetLabelTextProperty(self.__TextProperty) self.__ScalarBarActor.GetLabelTextProperty().BoldOff() self.__ScalarBarActor.GetLabelTextProperty().ItalicOff() self.__ScalarBarActor.SetNumberOfLabels(3) self.__ScalarBarActor.SetWidth(0.1) self.__ScalarBarActor.SetHeight(0.5) self.__ScalarBarActor.SetPosition(0.9, 0.3) self.__LookupTable.SetTableRange(0, 1) self.__LookupTable.SetSaturationRange(0, 0) self.__LookupTable.SetHueRange(0, 0) self.__LookupTable.SetValueRange(0, 1) self.__LookupTable.Build() self.__ShowAnnotations = True self.__ShowScalarBar = True self.__OrientationTransform.SetInput(self.__OrientationMatrix) self.__WindowLevel = self.GetWindowLevel() self.__WindowLevel.SetLookupTable( self.__LookupTable ) self.__ScalarBarActor.SetLookupTable(self.__LookupTable) self.__Renderer = self.GetRenderer() self.__Renderer.AddViewProp(self.__CornerAnnotation) self.__Renderer.AddViewProp(self.__ScalarBarActor) self.__ImageActor = self.GetImageActor() self.__RenderWindow = self.GetRenderWindow () self.__InteractorStyle = self.GetInteractorStyle() self.__Interactor = None self.__CornerAnnotation.SetWindowLevel(self.__WindowLevel) self.__CornerAnnotation.SetImageActor(self.__ImageActor) self.__CornerAnnotation.ShowSliceAndImageOn() # Sometime we would want to set the default window/level value instead # of the ImageData's ScalarRange self.__RefWindow = None self.__RefLevel = None
def make_legend_text_object(self): self.legend = vtk.vtkCornerAnnotation() self.legend.SetText(0,"Quake Cloud 3d Visualiser\n\ Depth Markers are 25Km Apart\n\ Maximum depth for model: {}\n\ All other distances are relative \n\n\n\ Copyright 2013 Jay Gattuso\n\n".format(self.event_max_depth)) self.legend.SetMaximumFontSize(15)
def createCornerAnnotation(self): cornerAnnotation = vtk.vtkCornerAnnotation() cornerAnnotation.SetMaximumFontSize(12) cornerAnnotation.PickableOff() cornerAnnotation.VisibilityOff() cornerAnnotation.GetTextProperty().ShadowOn() self.GetRenderer().AddActor(cornerAnnotation) return cornerAnnotation
def make_legend_text_object(self): self.legend = vtk.vtkCornerAnnotation() self.legend.SetText( 0, "Quake Cloud 3d Visualiser\n\ Depth Markers are 25Km Apart\n\ Maximum depth for model: {}\n\ All other distances are relative \n\n\n\ Copyright 2013 Jay Gattuso\n\n".format(self.event_max_depth)) self.legend.SetMaximumFontSize(15)
def getVtkCornerAnnotation(self,caption= ''): self.annotation = vtk.vtkCornerAnnotation() self.date= datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") self.annotation.SetText(self.upperRight, self.date) self.annotation.SetText(self.upperLeft, self.version) #vtkCornerAnnotation doesn't seems to support UTF-8 very well. caption= su.remove_accents(caption) if(len(caption)>self.captionWidth): caption= textwrap.fill(caption,self.captionWidth) self.annotation.SetText(self.lowerLeft,caption) return self.annotation
def getVtkCornerAnnotation(self, caption=''): self.annotation = vtk.vtkCornerAnnotation() self.date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") self.annotation.SetText(self.upperRight, self.date) self.annotation.SetText(self.upperLeft, self.version) #vtkCornerAnnotation doesn't seems to support UTF-8 very well. caption = su.remove_accents(caption) if (len(caption) > self.captionWidth): caption = textwrap.fill(caption, self.captionWidth) self.annotation.SetText(self.lowerLeft, caption) return self.annotation
def show(self): """Displays the mesh in the meshmagick viewer with additional graphics proper to hydrostatics""" # TODO: Ce n'est pas ce module qui doit savoir utiliser vtk !!! import MMviewer import vtk vtk_polydata = self.mesh._vtk_polydata() self.viewer = MMviewer.MMViewer() self.viewer.add_polydata(vtk_polydata) pd_orig = self.viewer.add_point([0, 0, 0], color=[0, 0, 0]) pd_cog = self.viewer.add_point(self.gravity_center, color=[1, 0, 0]) pd_orig_cog = self.viewer.add_line([0, 0, 0], self.gravity_center, color=[1, 0, 0]) pd_buoy = self.viewer.add_point(self.buoyancy_center, color=[0, 1, 0]) pd_orig_buoy = self.viewer.add_line([0, 0, 0], self.buoyancy_center, color=[0, 1, 0]) scale = self.mass * 1000 # Adding glyph for gravity force gforce = self.get_gravity_force() self.viewer.add_vector(gforce.point, gforce.value, scale=scale, color=[1, 0, 0]) # Adding glyph for buoyancy force bforce = self.get_buoyancy_force() self.viewer.add_vector(bforce.point, bforce.value, scale=scale, color=[0, 1, 0]) # Adding glyph for additional forces for force in self.additional_forces: self.viewer.add_point(force.point, color=[0, 0, 1]) self.viewer.add_vector(force.point, force.value, scale=scale, color=[0, 0, 1]) # TODO: mettre la suite dans une methode de MMViewer # Adding corner annotation ca = vtk.vtkCornerAnnotation() ca.SetLinearFontScaleFactor(2) ca.SetNonlinearFontScaleFactor(1) ca.SetMaximumFontSize(20) labels = "Origin: Black; Gravity Center: Red; Buoyancy Center: Green\nTo see points, press 'w'" ca.SetText(2, labels) ca.GetTextProperty().SetColor(0., 0., 0.) self.viewer.renderer.AddViewProp(ca) # Showing the viewer self.viewer.show() self.viewer.finalize() return
def plot_point_cloud_qt(self, plot, widget): """ :param plot: the specific VTKPointCloud being plotted :param widget: the QVTKRenderWindowInteractor that acts as the container for the specific VTK object A function to plot a single VTKPointCloud """ rw = widget.GetRenderWindow() iren = widget.GetRenderWindow().GetInteractor() # iren.SetRenderWindow(rw) ren = vtk.vtkRenderer() ren.AddActor(plot.vtkActor) self.widget_point_actors.append(plot.vtkActor) rw.AddRenderer(ren) ren.SetBackground(self.background) camera = ren.GetActiveCamera() corner = vtk.vtkCornerAnnotation() orientation = camera.GetOrientation() corner.SetText( 0, "(x, y, z) = (%.3f, %.3f, %.3f)" % (orientation[0], orientation[1], orientation[2])) ren.AddActor(corner) i = self.widgets.index(widget) axes = self.axes_actors[i] axes.SetInputConnection(self.plots[i].outline.GetOutputPort()) axes.SetCamera(camera) axes.SetLabelFormat("%6.4g") axes.SetFlyModeToOuterEdges() axes.SetFontFactor(1.2) if self.axes_on: ren.AddViewProp(axes) ren.ResetCamera() iren.SetInteractorStyle( CustomInteractorStyle(ren=ren, corner=corner, app=self.app)) # a picker is used for clicking interactions if you want any cutsom ones picker = vtk.vtkPointPicker() iren.SetPicker(picker) rw.Render()
def SetCornorAnnotations(self): # Corner annotation, can use <slice>, <slice_pos>, <window_level> self.cornerAnnotation = vtk.vtkCornerAnnotation() self.cornerAnnotation.SetLinearFontScaleFactor(2) self.cornerAnnotation.SetNonlinearFontScaleFactor(1) self.cornerAnnotation.SetMaximumFontSize(20) self.cornerAnnotation.SetText(vtk.vtkCornerAnnotation.UpperLeft, { 2: 'Axial Superior', 0: 'Sagittal Left', 1: 'Coronal Anterior' }[self.iDim]) prop = self.cornerAnnotation.GetTextProperty() prop.BoldOn() color = deque((1, 0, 0)) color.rotate(self.iDim) self.cornerAnnotation.GetTextProperty().SetColor(tuple(color)) self.cornerAnnotation.SetImageActor(self.viewer.GetImageActor()) self.cornerAnnotation.SetWindowLevel(self.viewer.GetWindowLevel()) self.viewer.GetRenderer().AddViewProp(self.cornerAnnotation)
def SetInputData(self, data): self.viewer.SetInputData(data) # Corner annotation, can use <slice>, <slice_pos>, <window_level> cornerAnnotation = vtk.vtkCornerAnnotation() cornerAnnotation.SetLinearFontScaleFactor(2) cornerAnnotation.SetNonlinearFontScaleFactor(1) cornerAnnotation.SetMaximumFontSize(20) cornerAnnotation.SetText(vtk.vtkCornerAnnotation.UpperLeft, { 2: 'Axial', 0: 'Sagittal', 1: 'Coronal' }[self.iDim]) prop = cornerAnnotation.GetTextProperty() prop.BoldOn() color = deque((1, 0, 0)) color.rotate(self.iDim) cornerAnnotation.GetTextProperty().SetColor(tuple(color)) cornerAnnotation.SetImageActor(self.viewer.GetImageActor()) cornerAnnotation.SetWindowLevel(self.viewer.GetWindowLevel()) self.viewer.GetRenderer().AddViewProp(cornerAnnotation)
self.__Reslice.SetOutputSpacing(1.0, 1.0, 1.0) self.__Reslice.SetOutputOrigin(0,0,0) self.__Reslice.SetOutputExtent(0, int(planeSizeX-1), 0, int(planeSizeY-1), 0, 0) self.__Reslice.Update() def getMatrix(self): return self.__Reslice def getReslice(self): return self.__Reslice def getResliceAxes(self): return self.__ResliceAxes def setReslice(self, value): self.__Reslice = value def setResliceAxes(self, value): self.__ResliceAxes = value if __name__ == "__main__": print vtk.vtkCornerAnnotation().GetActors()[0] print vtk.vtkCornerAnnotation().GetActors()[1] print vtk.vtkCornerAnnotation().GetActors()[2] print vtk.vtkCornerAnnotation().GetActors()[3]
def text(txt, pos=(0, 0, 0), normal=(0, 0, 1), s=1, depth=0.1, c='k', alpha=1, bc=None, texture=None, followcam=False, cam=None): ''' Returns a vtkActor that shows a text in 3D. Options: pos = position in 3D space, if an integer is passed [1 -> 8], places text in one of the 4 corners s = size of text depth = text thickness followcam = False, if True the text will auto-orient itself to it. [**Example1**](https://github.com/marcomusy/vtkplotter/blob/master/examples/basic/colorcubes.py) [**Example2**](https://github.com/marcomusy/vtkplotter/blob/master/examples/basic/mesh_coloring.py) ''' if isinstance(pos, int): cornerAnnotation = vtk.vtkCornerAnnotation() cornerAnnotation.SetNonlinearFontScaleFactor(s / 3) cornerAnnotation.SetText(pos - 1, str(txt)) cornerAnnotation.GetTextProperty().SetColor(colors.getColor(c)) return cornerAnnotation tt = vtk.vtkVectorText() tt.SetText(str(txt)) tt.Update() ttmapper = vtk.vtkPolyDataMapper() if followcam: depth = 0 normal = (0, 0, 1) if depth: extrude = vtk.vtkLinearExtrusionFilter() extrude.SetInputConnection(tt.GetOutputPort()) extrude.SetExtrusionTypeToVectorExtrusion() extrude.SetVector(0, 0, 1) extrude.SetScaleFactor(depth) ttmapper.SetInputConnection(extrude.GetOutputPort()) else: ttmapper.SetInputConnection(tt.GetOutputPort()) if followcam: ttactor = vtk.vtkFollower() ttactor.SetCamera(cam) else: ttactor = Actor() ttactor.SetMapper(ttmapper) ttactor.GetProperty().SetColor(colors.getColor(c)) # check if color string contains a float, in this case ignore alpha al = colors.getAlpha(c) if al: alpha = al ttactor.GetProperty().SetOpacity(alpha) nax = np.linalg.norm(normal) if nax: normal = np.array(normal) / nax theta = np.arccos(normal[2]) phi = np.arctan2(normal[1], normal[0]) ttactor.SetScale(s, s, s) ttactor.RotateZ(phi * 57.3) ttactor.RotateY(theta * 57.3) ttactor.SetPosition(pos) if bc: # defines a specific color for the backface backProp = vtk.vtkProperty() backProp.SetDiffuseColor(colors.getColor(bc)) backProp.SetOpacity(alpha) ttactor.SetBackfaceProperty(backProp) if texture: ttactor.texture(texture) return ttactor
def __init__(self): self.text_actor = vtk.vtkCornerAnnotation()
def make_timed_text_object(self): self.timer_text = vtk.vtkCornerAnnotation() self.timer_text.SetMaximumFontSize(20)
def text(txt, pos=(0, 0, 0), normal=(0, 0, 1), s=1, depth=0.1, justify='bottom-left', c='k', alpha=1, bc=None, texture=None, followcam=False, cam=None): ''' Returns a ``vtkActor`` that shows a 3D text. :param pos: position in 3D space, if an integer is passed [1,8], place text in one of the 4 corners. :type pos: list, int :param float s: size of text. :param float depth: text thickness. :param str justify: text justification (bottom-left, bottom-right, top-left, top-right, centered). :param bool followcam: if `True` the text will auto-orient itself to the cam. .. hint:: Example: `colorcubes.py <https://github.com/marcomusy/vtkplotter/blob/master/examples/basic/colorcubes.py>`_ .. image:: https://user-images.githubusercontent.com/32848391/50738867-c0658e80-11d8-11e9-9e05-ac69b546b7ec.png ''' if isinstance(pos, int): cornerAnnotation = vtk.vtkCornerAnnotation() cornerAnnotation.SetNonlinearFontScaleFactor(s / 3) cornerAnnotation.SetText(pos - 1, str(txt)) cornerAnnotation.GetTextProperty().SetColor(colors.getColor(c)) return cornerAnnotation tt = vtk.vtkVectorText() tt.SetText(str(txt)) tt.Update() ttmapper = vtk.vtkPolyDataMapper() if followcam: depth = 0 normal = (0, 0, 1) if depth: extrude = vtk.vtkLinearExtrusionFilter() extrude.SetInputConnection(tt.GetOutputPort()) extrude.SetExtrusionTypeToVectorExtrusion() extrude.SetVector(0, 0, 1) extrude.SetScaleFactor(depth) ttmapper.SetInputConnection(extrude.GetOutputPort()) else: ttmapper.SetInputConnection(tt.GetOutputPort()) if followcam: ttactor = vtk.vtkFollower() ttactor.SetCamera(cam) else: ttactor = Actor() ttactor.SetMapper(ttmapper) ttactor.GetProperty().SetColor(colors.getColor(c)) ttmapper.Update() bb = tt.GetOutput().GetBounds() dx, dy = (bb[1] - bb[0]) / 2 * s, (bb[3] - bb[2]) / 2 * s cm = np.array([(bb[1] + bb[0]) / 2, (bb[3] + bb[2]) / 2, (bb[5] + bb[4]) / 2]) * s shift = -cm if 'cent' in justify: pass elif 'bottom-left' in justify: shift += np.array([dx, dy, 0]) elif 'top-left' in justify: shift += np.array([dx, -dy, 0]) elif 'bottom-right' in justify: shift += np.array([-dx, dy, 0]) elif 'top-right' in justify: shift += np.array([-dx, -dy, 0]) else: colors.printc("text(): Unknown justify type", justify, c=1) # check if color string contains a float, in this case ignore alpha al = colors._getAlpha(c) if al: alpha = al ttactor.GetProperty().SetOpacity(alpha) nax = np.linalg.norm(normal) if nax: normal = np.array(normal) / nax theta = np.arccos(normal[2]) phi = np.arctan2(normal[1], normal[0]) ttactor.SetScale(s, s, s) ttactor.RotateZ(phi * 57.3) ttactor.RotateY(theta * 57.3) ttactor.SetPosition(pos + shift) if bc: # defines a specific color for the backface backProp = vtk.vtkProperty() backProp.SetDiffuseColor(colors.getColor(bc)) backProp.SetOpacity(alpha) ttactor.SetBackfaceProperty(backProp) if texture: ttactor.texture(texture) ttactor.PickableOff() return ttactor
def Text( txt, pos=3, s=1, depth=0.1, justify="bottom-left", c=None, alpha=1, bc=None, bg=None, font="courier", followcam=False, ): """ Returns an ``Actor`` that shows a 2D/3D text. :param pos: position in 3D space, if an integer is passed [1,8], a 2D text is placed in one of the 4 corners: 1, bottom-left 2, bottom-right 3, top-left 4, top-right 5, bottom-middle 6, middle-right 7, middle-left 8, top-middle If a pair (x,y) is passed as input the 2D text is place at that position in the coordinate system of the 2D screen (with the origin sitting at the bottom left). :type pos: list, int :param float s: size of text. :param float depth: text thickness. :param str justify: text justification (bottom-left, bottom-right, top-left, top-right, centered). :param bg: background color of corner annotations. Only applies of `pos` is ``int``. :param str font: additional available fonts are: - Ageo - Aldora - CallingCode - Godsway - Gula - ImpactLabel - Komiko - Lamborgini - MidnightDrive - Militech - MonaShark - Montserrat - MyDisplaySt - PointedLaidSt - SchoolTeacher - SpecialElite Font choice does not apply for 3D text. A path to `otf` or `ttf` font-file can also be supplied as input. All fonts are free for personal use. Check out conditions in `vtkplotter/fonts/licenses` for commercial use and: https://www.1001freefonts.com :param followcam: if `True` the text will auto-orient itself to the active camera. A ``vtkCamera`` object can also be passed. :type followcam: bool, vtkCamera .. hint:: Examples, |fonts.py|_ |colorcubes.py|_ |markpoint.py|_ |annotations.py|_ |colorcubes| |markpoint| |fonts| """ if c is None: # automatic black or white if settings.plotter_instance and settings.plotter_instance.renderer: c = (0.9, 0.9, 0.9) if np.sum(settings.plotter_instance.renderer.GetBackground()) > 1.5: c = (0.1, 0.1, 0.1) else: c = (0.6, 0.6, 0.6) if isinstance(pos, int): # corners if pos > 8: pos = 8 if pos < 1: pos = 1 ca = vtk.vtkCornerAnnotation() ca.SetNonlinearFontScaleFactor(s/2.7) ca.SetText(pos - 1, str(txt)) ca.PickableOff() cap = ca.GetTextProperty() cap.SetColor(colors.getColor(c)) if font.lower() == "courier": cap.SetFontFamilyToCourier() elif font.lower() == "times": cap.SetFontFamilyToTimes() elif font.lower() == "arial": cap.SetFontFamilyToArial() else: cap.SetFontFamily(vtk.VTK_FONT_FILE) cap.SetFontFile(settings.fonts_path+font+'.ttf') if bg: bgcol = colors.getColor(bg) cap.SetBackgroundColor(bgcol) cap.SetBackgroundOpacity(alpha * 0.5) cap.SetFrameColor(bgcol) cap.FrameOn() setattr(ca, 'renderedAt', set()) settings.collectable_actors.append(ca) return ca elif len(pos)==2: # passing (x,y) coords actor2d = vtk.vtkActor2D() actor2d.SetPosition(pos) tmapper = vtk.vtkTextMapper() actor2d.SetMapper(tmapper) tp = tmapper.GetTextProperty() tp.BoldOff() tp.SetFontSize(s*20) tp.SetColor(colors.getColor(c)) tp.SetJustificationToLeft() tp.SetVerticalJustificationToBottom() if font.lower() == "courier": tp.SetFontFamilyToCourier() elif font.lower() == "times": tp.SetFontFamilyToTimes() elif font.lower() == "arial": tp.SetFontFamilyToArial() else: tp.SetFontFamily(vtk.VTK_FONT_FILE) import os if font in settings.fonts: tp.SetFontFile(settings.fonts_path + font + '.ttf') elif os.path.exists(font): tp.SetFontFile(font) else: colors.printc("~sad Font", font, "not found in", settings.fonts_path, c="r") colors.printc("~pin Available fonts are:", settings.fonts, c="m") return None if bg: bgcol = colors.getColor(bg) tp.SetBackgroundColor(bgcol) tp.SetBackgroundOpacity(alpha * 0.5) tp.SetFrameColor(bgcol) tp.FrameOn() tmapper.SetInput(str(txt)) actor2d.PickableOff() setattr(actor2d, 'renderedAt', set()) settings.collectable_actors.append(actor2d) return actor2d else: # otherwise build the 3D text, fonts do not apply tt = vtk.vtkVectorText() tt.SetText(str(txt)) tt.Update() tpoly = tt.GetOutput() bb = tpoly.GetBounds() dx, dy = (bb[1] - bb[0]) / 2 * s, (bb[3] - bb[2]) / 2 * s cm = np.array([(bb[1] + bb[0]) / 2, (bb[3] + bb[2]) / 2, (bb[5] + bb[4]) / 2]) * s shift = -cm if "bottom" in justify: shift += np.array([ 0, dy, 0]) if "top" in justify: shift += np.array([ 0,-dy, 0]) if "left" in justify: shift += np.array([ dx, 0, 0]) if "right" in justify: shift += np.array([-dx, 0, 0]) t = vtk.vtkTransform() t.Translate(shift) t.Scale(s, s, s) tf = vtk.vtkTransformPolyDataFilter() tf.SetInputData(tpoly) tf.SetTransform(t) tf.Update() tpoly = tf.GetOutput() if followcam: ttactor = vtk.vtkFollower() ttactor.GetProperty().SetOpacity(alpha) ttactor.GetProperty().SetColor(colors.getColor(c)) if isinstance(followcam, vtk.vtkCamera): ttactor.SetCamera(followcam) else: ttactor.SetCamera(settings.plotter_instance.camera) else: if depth: extrude = vtk.vtkLinearExtrusionFilter() extrude.SetInputData(tpoly) extrude.SetExtrusionTypeToVectorExtrusion() extrude.SetVector(0, 0, 1) extrude.SetScaleFactor(depth*dy) extrude.Update() tpoly = extrude.GetOutput() ttactor = Actor(tpoly, c, alpha, bc=bc) ttactor.SetPosition(pos) settings.collectable_actors.append(ttactor) return ttactor
def text(txt, pos=(0, 0, 0), normal=(0, 0, 1), s=1, depth=0.1, c='k', alpha=1, bc=None, texture=None, followcam=False, cam=None): ''' Returns a vtkActor that shows a text in 3D. pos = position in 3D space if an integer is passed [1 -> 8], places text in a corner s = size of text depth = text thickness followcam = True, the text will auto-orient itself to it ''' if isinstance(pos, int): cornerAnnotation = vtk.vtkCornerAnnotation() cornerAnnotation.SetNonlinearFontScaleFactor(s / 3) cornerAnnotation.SetText(pos - 1, txt) cornerAnnotation.GetTextProperty().SetColor(vc.getColor(c)) return cornerAnnotation tt = vtk.vtkVectorText() tt.SetText(txt) tt.Update() ttmapper = vtk.vtkPolyDataMapper() if depth: extrude = vtk.vtkLinearExtrusionFilter() extrude.SetInputConnection(tt.GetOutputPort()) extrude.SetExtrusionTypeToVectorExtrusion() extrude.SetVector(0, 0, 1) extrude.SetScaleFactor(depth) ttmapper.SetInputConnection(extrude.GetOutputPort()) else: ttmapper.SetInputConnection(tt.GetOutputPort()) if followcam: #follow cam ttactor = vtk.vtkFollower() ttactor.SetCamera(cam) else: ttactor = vtk.vtkActor() ttactor.SetMapper(ttmapper) ttactor.GetProperty().SetColor(vc.getColor(c)) # check if color string contains a float, in this case ignore alpha al = vc.getAlpha(c) if al: alpha = al ttactor.GetProperty().SetOpacity(alpha) nax = np.linalg.norm(normal) if nax: normal = np.array(normal) / nax theta = np.arccos(normal[2]) phi = np.arctan2(normal[1], normal[0]) ttactor.SetScale(s, s, s) ttactor.RotateZ(phi * 57.3) ttactor.RotateY(theta * 57.3) ttactor.SetPosition(pos) if bc: # defines a specific color for the backface backProp = vtk.vtkProperty() backProp.SetDiffuseColor(vc.getColor(bc)) backProp.SetOpacity(alpha) ttactor.SetBackfaceProperty(backProp) if texture: vu.assignTexture(ttactor, texture) vu.assignConvenienceMethods(ttactor, None) vu.assignPhysicsMethods(ttactor) return ttactor
def setup(self): self.setupUi(self) loadAct = QAction('&Open', self) loadAct.setShortcut('Ctrl+O') loadAct.setStatusTip('Load data') loadAct.triggered.connect(lambda: self.onLoadClicked(0)) surfAct = QAction('&Open Surface', self) surfAct.setShortcut('Ctrl+S') surfAct.setStatusTip('Surf data') surfAct.triggered.connect(lambda: self.onLoadClicked(1)) exitAct = QAction('&Exit', self) exitAct.setShortcut('ALT+F4') exitAct.setStatusTip('Exit application') exitAct.triggered.connect(self.close) menubar = self.menuBar() fileMenu = menubar.addMenu('&File') fileMenu.addAction(loadAct) fileMenu.addAction(surfAct) fileMenu.addAction(exitAct) self.vtk_widgets = [ Viewer2D(self.vtk_panel, 0), Viewer2D(self.vtk_panel, 1), Viewer2D(self.vtk_panel, 2) ] # Make all views share the same cursor object for i in range(3): self.vtk_widgets[i].viewer.SetResliceCursor( self.vtk_widgets[0].viewer.GetResliceCursor()) # Cursor representation (anti-alias) for i in range(3): for j in range(3): prop = self.vtk_widgets[i].viewer.GetResliceCursorWidget( ).GetResliceCursorRepresentation().GetResliceCursorActor( ).GetCenterlineProperty(j) renderLinesAsTubes(prop) # Make 3D viewer picker = vtk.vtkCellPicker() picker.SetTolerance(0.005) ipwProp = vtk.vtkProperty() ren = vtk.vtkRenderer() interactor = QVTKRenderWindowInteractor() # Gradient background ren.SetBackground(245.0 / 255.0, 245.0 / 255.0, 245.0 / 255.0) ren.SetBackground2(170.0 / 255.0, 170.0 / 255.0, 170.0 / 255.0) ren.GradientBackgroundOn() interactor.GetRenderWindow().AddRenderer(ren) self.vtk_widgets.append(interactor) # Create plane widgets self.planeWidget = [] for i in range(3): pw = vtk.vtkImagePlaneWidget() pw.SetInteractor(interactor) pw.SetPicker(picker) pw.RestrictPlaneToVolumeOn() color = [0.0, 0.0, 0.0] color[i] = 1 pw.GetPlaneProperty().SetColor(color) pw.SetTexturePlaneProperty(ipwProp) pw.TextureInterpolateOn() pw.SetResliceInterpolateToLinear() pw.DisplayTextOn() pw.SetDefaultRenderer(ren) prop = pw.GetPlaneProperty() renderLinesAsTubes(prop) pw.SetPlaneProperty(prop) prop = pw.GetSelectedPlaneProperty() renderLinesAsTubes(prop) pw.SetSelectedPlaneProperty(prop) prop = pw.GetCursorProperty() renderLinesAsTubes(prop) pw.SetCursorProperty(prop) prop = pw.GetTextProperty() prop.SetColor(black) pw.Modified() # Set background for 2D views for j in range(3): color[j] = color[j] / 4.0 self.vtk_widgets[i].viewer.GetRenderer().SetBackground(color) self.vtk_widgets[i].interactor.Disable() self.planeWidget.append(pw) # Annotation cornerAnnotation = vtk.vtkCornerAnnotation() cornerAnnotation.SetLinearFontScaleFactor(2) cornerAnnotation.SetNonlinearFontScaleFactor(1) cornerAnnotation.SetMaximumFontSize(20) cornerAnnotation.SetText(vtk.vtkCornerAnnotation.UpperLeft, '3D') cornerAnnotation.GetTextProperty().SetColor(1, 1, 1) cornerAnnotation.SetWindowLevel( self.vtk_widgets[0].viewer.GetWindowLevel()) ren.AddViewProp(cornerAnnotation) # Create cube, Right Anterior Superior colors = vtk.vtkNamedColors() xyzLabels = ['X', 'Y', 'Z'] scale = (1.5, 1.5, 1.5) axes2 = MakeCubeActor(scale, xyzLabels, colors) self.om2 = vtk.vtkOrientationMarkerWidget() self.om2.SetOrientationMarker(axes2) # Position lower right in the viewport. self.om2.SetInteractor(self.vtk_widgets[3]) self.om2.SetViewport(0.75, 0, 1.0, 0.25) self.establishCallbacks() # Show widgets but hide non-existing data for i in range(3): self.vtk_widgets[i].show() self.vtk_widgets[i].viewer.GetImageActor().SetVisibility(False) # Layouts horz_layout0 = QHBoxLayout() vert_splitter = QSplitter(Qt.Vertical) horz_splitter0 = QSplitter(Qt.Horizontal) horz_splitter0.addWidget(self.vtk_widgets[0]) horz_splitter0.addWidget(self.vtk_widgets[1]) vert_splitter.addWidget(horz_splitter0) horz_splitter1 = QSplitter(Qt.Horizontal) horz_splitter1.addWidget(self.vtk_widgets[2]) horz_splitter1.addWidget(self.vtk_widgets[3]) vert_splitter.addWidget(horz_splitter1) horz_layout0.addWidget(vert_splitter) horz_layout0.setContentsMargins(0, 0, 0, 0) self.vtk_panel.setLayout(horz_layout0) vert_layout = QVBoxLayout() horz_layout1 = QHBoxLayout() self.btnSagittal = QPushButton("S") self.btnSagittal.setCheckable(True) self.btnSagittal.setChecked(True) horz_layout1.addWidget(self.btnSagittal) self.btnCoronal = QPushButton("C") self.btnCoronal.setCheckable(True) self.btnCoronal.setChecked(True) horz_layout1.addWidget(self.btnCoronal) self.btnAxial = QPushButton("A") self.btnAxial.setCheckable(True) self.btnAxial.setChecked(True) self.btnSagittal.clicked.connect(self.togglePlanes) self.btnCoronal.clicked.connect(self.togglePlanes) self.btnAxial.clicked.connect(self.togglePlanes) horz_layout1.addWidget(self.btnAxial) verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) vert_layout.addItem(verticalSpacer) vert_layout.addItem(horz_layout1) self.frame.setLayout(vert_layout)
def __init__(self): # Building renderer self.renderer = vtk.vtkRenderer() self.renderer.SetBackground(0.7706, 0.8165, 1.0) # Building render window self.render_window = vtk.vtkRenderWindow() # self.render_window.FullScreenOn() # BUGFIX: It causes the window to fail to open... self.render_window.SetSize(1024, 768) self.render_window.SetWindowName("Meshmagick viewer") self.render_window.AddRenderer(self.renderer) # Building interactor self.render_window_interactor = vtk.vtkRenderWindowInteractor() self.render_window_interactor.SetRenderWindow(self.render_window) self.render_window_interactor.GetInteractorStyle( ).SetCurrentStyleToTrackballCamera() self.render_window_interactor.AddObserver('KeyPressEvent', self.on_key_press, 0.0) # Building axes view axes = vtk.vtkAxesActor() widget = vtk.vtkOrientationMarkerWidget() widget.SetOrientationMarker(axes) self.widget = widget self.widget.SetInteractor(self.render_window_interactor) self.widget.SetEnabled(1) self.widget.InteractiveOn() # Building command annotations command_text = "left mouse : rotate\n" + \ "right mouse : zoom\n" + \ "middle mouse : pan\n" + \ "ctrl+left mouse : spin\n" + \ "n : (un)show normals\n" + \ "b : (un)show axes box\n" + \ "f : focus on the mouse cursor\n" + \ "r : reset view\n" + \ "s : surface representation\n" + \ "w : wire representation\n" + \ "h : (un)show Oxy plane\n" + \ "g : (un)show Axes planes\n" + \ "x : save\n" + \ "c : screenshot\n" + \ "q : quit" corner_annotation = vtk.vtkCornerAnnotation() corner_annotation.SetLinearFontScaleFactor(2) corner_annotation.SetNonlinearFontScaleFactor(1) corner_annotation.SetMaximumFontSize(20) corner_annotation.SetText(3, command_text) corner_annotation.GetTextProperty().SetColor(0., 0., 0.) self.renderer.AddViewProp(corner_annotation) copyright_text = "Meshmagick Viewer\nCopyright 2014-%u, Ecole Centrale de Nantes" % __year__ copyright_annotation = vtk.vtkCornerAnnotation() copyright_annotation.SetLinearFontScaleFactor(1) copyright_annotation.SetNonlinearFontScaleFactor(1) copyright_annotation.SetMaximumFontSize(12) copyright_annotation.SetText(1, copyright_text) copyright_annotation.GetTextProperty().SetColor(0., 0., 0.) self.renderer.AddViewProp(copyright_annotation) self.normals = [] self.axes = [] self.oxy_plane = None self.axes_planes = None self.polydatas = list() self.hiden = dict() # TODO: A terminer -> cf methode self.hide()
def main(argv): imageViewer = vtk.vtkImageViewer2() if len(argv) < 2: noiseSource = vtk.vtkImageNoiseSource() noiseSource.SetWholeExtent(0, 512, 0, 512, 0, 0) noiseSource.SetMinimum(0.0) noiseSource.SetMaximum(65535.0) # cast noise image to unsigned short imageCast = vtk.vtkImageCast() imageCast.SetInputConnection(noiseSource.GetOutputPort()) imageCast.SetOutputScalarTypeToUnsignedShort() imageCast.Update() # connect to image viewer pipeline imageViewer.SetInputConnection(imageCast.GetOutputPort()) else: # Parse input argument inputFilename = str(argv[1]) # Read the image tiffReader = vtk.vtkTIFFReader() if not tiffReader.CanReadFile(inputFilename): return tiffReader.SetFileName(inputFilename) # connect to image viewer pipeline imageViewer.SetInputConnection(tiffReader.GetOutputPort()) # Picker to pick pixels propPicker = vtk.vtkPropPicker() propPicker.PickFromListOn() # Give the picker a prop to pick imageActor = imageViewer.GetImageActor() propPicker.AddPickList(imageActor) # disable interpolation, so we can see each pixel imageActor.InterpolateOff() # Visualize renderWindowInteractor = vtk.vtkRenderWindowInteractor() imageViewer.SetupInteractor(renderWindowInteractor) imageViewer.SetSize(600, 600) renderer = imageViewer.GetRenderer() renderer.ResetCamera() renderer.GradientBackgroundOn() renderer.SetBackground(0.6, 0.6, 0.5) renderer.SetBackground2(0.3, 0.3, 0.2) # Annotate the image with window/level and mouse over pixel # information cornerAnnotation = vtk.vtkCornerAnnotation() cornerAnnotation.SetLinearFontScaleFactor(2) cornerAnnotation.SetNonlinearFontScaleFactor(1) cornerAnnotation.SetMaximumFontSize(20) cornerAnnotation.SetText(0, "Off Image") cornerAnnotation.SetText(3, "<window>\n<level>") cornerAnnotation.GetTextProperty().SetColor(1, 0, 0) imageViewer.GetRenderer().AddViewProp(cornerAnnotation) # Callback listens to MouseMoveEvents invoked by the interactor's style callback = vtkImageInteractionCallback() callback.SetViewer(imageViewer) callback.SetAnnotation(cornerAnnotation) callback.SetPicker(propPicker) # InteractorStyleImage allows for the following controls: # 1) middle mouse + move = camera pan # 2) left mouse + move = window/level # 3) right mouse + move = camera zoom # 4) middle mouse wheel scroll = zoom # 5) 'r' = reset window/level # 6) shift + 'r' = reset camera imageStyle = imageViewer.GetInteractorStyle() imageStyle.AddObserver('MouseMoveEvent', callback.Execute) if len(argv) > 1: imageViewer.GetImageActor().GetMapper().SetInputConnection( tiffReader.GetOutputPort()) renderWindowInteractor.Initialize() renderWindowInteractor.Start()
def __init__(self, world_to_slice, layers=None, annotations=None, interpolation=False, display_coordinates="physical", scalar_bar_visibility=False, orientation_visibility=True, corner_annotations_visibility=False, crosshair="full"): layers = layers or [] annotations = annotations or ObservableList() ############################ # Property-related members # ############################ self._interpolation = None self._display_coordinates = None self._scalar_bar_visibility = True self._orientation_visibility = None self._corner_annotations_visibility = None self._crosshair = None self._world_to_slice = None self._slice_to_world = None self._layers = [] self._annotations = None self._gui_annotations = {} self._image_physical_position = None self._image_index_position = None self._cursor_physical_position = None self._cursor_index_position = None self._zoom = None self._mouse_tools = {} self._keyboard_tools = {} self._renderer = vtkRenderer() ################### # Private members # ################### # World-to-slice matrix, with rows and columns added or removed so that # it is 3x3. self._3d_world_to_slice = None self._3d_slice_to_world = None # Slice extent is the physical extent of all layers, # given as (x_min, x_max, y_min, y_max) self._slice_extent = (-100, 100, -100, 100) # VTK objects self._scalar_bar_actor = vtkScalarBarActor() self._corner_annotation = vtkCornerAnnotation() self._orientation_annotation = vtkOrientationAnnotation() self._crosshair = Crosshair() # Tools and interactions self._observer_tags = [] self._active_source = None ################## # Initialization # ################## super(Slice, self).__init__([ "world_to_slice", "interpolation", "display_coordinates", "scalar_bar_visibility", "orientation_visibility", "corner_annotations_visibility", "crosshair", "zoom" ]) self.add_allowed_event("cursor_position") self.add_allowed_event("image_position") self.add_allowed_event("center") self.add_allowed_event("layer_visibility") # Configure camera camera = self._renderer.GetActiveCamera() camera.ParallelProjectionOn() camera.SetPosition(0, 0, self._actors_altitudes["camera"]) camera.SetFocalPoint(0, 0, 0) # Create cursor self._crosshair.altitude = self._actors_altitudes["cursor"] self._crosshair.hole_size = 5 self._renderer.AddActor(self._crosshair.actor) # Create scalar bar (from vtkInria3D) self._scalar_bar_actor.GetLabelTextProperty().SetColor(1.0, 1.0, 1.0) self._scalar_bar_actor.GetTitleTextProperty().SetColor(1.0, 1.0, 1.0) self._scalar_bar_actor.GetLabelTextProperty().BoldOff() self._scalar_bar_actor.GetLabelTextProperty().ShadowOff() self._scalar_bar_actor.GetLabelTextProperty().ItalicOff() self._scalar_bar_actor.SetNumberOfLabels(3) self._scalar_bar_actor.GetLabelTextProperty().SetFontSize(8) self._scalar_bar_actor.GetPositionCoordinate( ).SetCoordinateSystemToNormalizedViewport() self._scalar_bar_actor.SetWidth(0.1) self._scalar_bar_actor.SetHeight(0.5) self._scalar_bar_actor.SetPosition(0.8, 0.3) self._scalar_bar_actor.PickableOff() self._renderer.AddActor(self._scalar_bar_actor) # Setup text-annotation actors self._corner_annotation.SetNonlinearFontScaleFactor(0.3) self._renderer.AddActor(self._corner_annotation) self._orientation_annotation.SetNonlinearFontScaleFactor(0.25) self._renderer.AddActor(self._orientation_annotation) self._set_interpolation(interpolation) self._set_display_coordinates(display_coordinates) self._set_scalar_bar_visibility(scalar_bar_visibility) self._set_orientation_visibility(orientation_visibility) self._set_corner_annotations_visibility(corner_annotations_visibility) self._set_crosshair(crosshair) self._set_world_to_slice(world_to_slice) for layer in layers: self.append_layer(**layer) if annotations is not None: self._set_annotations(annotations) # Position slice at middle of layer 0 self.reset_view() # Configure default tools self.set_mouse_button_tool("Left", mouse_tools.Select()) self.set_mouse_button_tool("Middle", mouse_tools.Pan()) self.set_mouse_button_tool("Right", mouse_tools.WindowLevel()) self.set_wheel_tool("Forward", mouse_tools.Zoom(1.1)) self.set_wheel_tool("Backward", mouse_tools.Zoom(1. / 1.1)) self.set_keyboard_tool("Left", keyboard_tools.MoveCursor()) self.set_keyboard_tool("Right", keyboard_tools.MoveCursor()) self.set_keyboard_tool("Up", keyboard_tools.MoveCursor()) self.set_keyboard_tool("Down", keyboard_tools.MoveCursor()) self.set_keyboard_tool("Prior", keyboard_tools.MoveCursor()) self.set_keyboard_tool("Next", keyboard_tools.MoveCursor()) self.set_keyboard_tool("PageUp", keyboard_tools.MoveCursor()) self.set_keyboard_tool("PageDown", keyboard_tools.MoveCursor()) self.set_keyboard_tool("+", keyboard_tools.Zoom(1.1)) self.set_keyboard_tool("-", keyboard_tools.Zoom(1. / 1.1)) self.set_keyboard_tool("i", keyboard_tools.ToggleInterpolation()) self.set_keyboard_tool("b", keyboard_tools.ToggleScalarBarVisibility()) self.set_keyboard_tool( "c", keyboard_tools.ToggleCornerAnnotationsVisibility()) self.set_keyboard_tool("o", keyboard_tools.ToggleOrientationVisibility())
def main(): session = Set_Render_Variables("quake(13).csv") data = Data_Extractor(session) bounds = Model_Bounds_Points_Maker(data, session) events = Timed_Event_List_Maker(data.event_list, session) # sets up the VTK session ren = vtk.vtkRenderer() renderWindow = vtk.vtkRenderWindow() #renderWindow.AddRenderer(ren) i_ren = vtk.vtkRenderWindowInteractor() i_ren.SetRenderWindow(renderWindow) # text / legend object legend = vtk.vtkCornerAnnotation() legend.SetText(0, " Quake Cloud 3d Visualiser\n Depth Markers are 25Km Apart\n" " All other distances are relative \n\n\n Copyright 2013 Jay Gattuso\n\n") legend.SetMaximumFontSize(15) # handles the overlay map image input_image = session.overlay_image_fname reader = vtk.vtkJPEGReader() reader.SetFileName(input_image) texture = vtk.vtkTexture() texture.SetInput(reader.GetOutput()) texture.SetInputConnection(reader.GetOutputPort()) texture.InterpolateOn() ren = vtk.vtkRenderer() renderWindow.AddRenderer(ren) plane = vtk.vtkPlaneSource() plane.SetOrigin((0, 0, 0)) plane.SetPoint1(bounds.lat_max_distance) plane.SetPoint2(bounds.long_max_distance) # Create texture object planeMapper = vtk.vtkPolyDataMapper() planeMapper.SetInputConnection(plane.GetOutputPort()) planeActor = vtk.vtkActor() planeActor.SetMapper(planeMapper) planeActor.SetTexture(texture) pointCloud_bounds = VtkPointCloud(data.event_max_depth) if session.plot_boundary_markers: for bound in bounds.bounds: pointCloud_bounds.addPoint(bound, 10) # the number is what makes the bound markers larger if session.plot_depth_scale: for bound in bounds.bounds_scale: pointCloud_bounds.addPoint(bound, 10) # the number is what makes the bound markers larger # add basic objects (bounds, overlay, background) ren.AddActor(pointCloud_bounds.vtkActor) ren.AddViewProp(legend) ren.AddActor(planeActor) ren.SetBackground(.2, .2, .2) ren.ResetCamera() renderWindowInteractor = vtk.vtkRenderWindowInteractor() renderWindowInteractor.SetRenderWindow(renderWindow) # Begin Interaction renderWindow.Render() # Initialize must be called prior to creating timer events. renderWindowInteractor.Initialize() # Sign up to receive TimerEvent cb = vtkTimerCallback(events.timed_event_dict, data.event_max_depth, ren, renderWindow, session) cb.actor = vtk.vtkActor() renderWindowInteractor.AddObserver('TimerEvent', cb.execute) timerId = renderWindowInteractor.CreateRepeatingTimer(session.replay_frame_speed) renderWindowInteractor.Start()
def setup(self): self.setupUi(self) loadAct = QAction('&Open', self) loadAct.setShortcut('Ctrl+O') loadAct.setStatusTip('Load data') loadAct.triggered.connect(lambda: self.onLoadClicked(0)) surfAct = QAction('&Open Surface', self) surfAct.setShortcut('Ctrl+S') surfAct.setStatusTip('Surf data') surfAct.triggered.connect(lambda: self.onLoadClicked(1)) exitAct = QAction('&Exit', self) exitAct.setShortcut('ALT+F4') exitAct.setStatusTip('Exit application') exitAct.triggered.connect(self.close) menubar = self.menuBar() fileMenu = menubar.addMenu('&File') fileMenu.addAction(loadAct) fileMenu.addAction(surfAct) fileMenu.addAction(exitAct) self.vtk_widgets = [ Viewer2D(self.vtk_panel, 0), Viewer2D(self.vtk_panel, 1), Viewer2D(self.vtk_panel, 2) ] # Make all views share the same cursor object for i in range(3): self.vtk_widgets[i].viewer.SetResliceCursor( self.vtk_widgets[0].viewer.GetResliceCursor()) # Cursor representation (anti-alias) for i in range(3): for j in range(3): prop = self.vtk_widgets[i].viewer.GetResliceCursorWidget( ).GetResliceCursorRepresentation().GetResliceCursorActor( ).GetCenterlineProperty(j) renderLinesAsTubes(prop) # Make 3D viewer picker = vtk.vtkCellPicker() picker.SetTolerance(0.005) ipwProp = vtk.vtkProperty() ren = vtk.vtkRenderer() interactor = QVTKRenderWindowInteractor() # Gradient background ren.SetBackground(245.0 / 255.0, 245.0 / 255.0, 245.0 / 255.0) ren.SetBackground2(170.0 / 255.0, 170.0 / 255.0, 170.0 / 255.0) ren.GradientBackgroundOn() interactor.GetRenderWindow().AddRenderer(ren) self.vtk_widgets.append(interactor) # Create plane widgets self.planeWidget = [] for i in range(3): pw = vtk.vtkImagePlaneWidget() pw.SetInteractor(interactor) pw.SetPicker(picker) pw.RestrictPlaneToVolumeOn() color = [0.0, 0.0, 0.0] color[i] = 1 pw.GetPlaneProperty().SetColor(color) pw.SetTexturePlaneProperty(ipwProp) pw.TextureInterpolateOn() pw.SetResliceInterpolateToLinear() pw.DisplayTextOn() pw.SetDefaultRenderer(ren) prop = pw.GetPlaneProperty() renderLinesAsTubes(prop) pw.SetPlaneProperty(prop) prop = pw.GetSelectedPlaneProperty() renderLinesAsTubes(prop) pw.SetSelectedPlaneProperty(prop) prop = pw.GetCursorProperty() renderLinesAsTubes(prop) pw.SetCursorProperty(prop) prop = pw.GetTextProperty() prop.SetColor(black) pw.Modified() # Set background for 2D views for j in range(3): color[j] = color[j] / 4.0 self.vtk_widgets[i].viewer.GetRenderer().SetBackground(color) self.vtk_widgets[i].interactor.Disable() self.planeWidget.append(pw) # Annotation cornerAnnotation = vtk.vtkCornerAnnotation() cornerAnnotation.SetLinearFontScaleFactor(2) cornerAnnotation.SetNonlinearFontScaleFactor(1) cornerAnnotation.SetMaximumFontSize(20) cornerAnnotation.SetText(vtk.vtkCornerAnnotation.UpperLeft, '3D') cornerAnnotation.GetTextProperty().SetColor(1, 1, 1) cornerAnnotation.SetWindowLevel( self.vtk_widgets[0].viewer.GetWindowLevel()) ren.AddViewProp(cornerAnnotation) self.establishCallbacks() # Show widgets but hide non-existing data for i in range(3): self.vtk_widgets[i].show() self.vtk_widgets[i].viewer.GetImageActor().SetVisibility(False) # Layouts horz_layout0 = QHBoxLayout() vert_splitter = QSplitter(Qt.Vertical) horz_splitter0 = QSplitter(Qt.Horizontal) horz_splitter0.addWidget(self.vtk_widgets[0]) horz_splitter0.addWidget(self.vtk_widgets[1]) vert_splitter.addWidget(horz_splitter0) horz_splitter1 = QSplitter(Qt.Horizontal) horz_splitter1.addWidget(self.vtk_widgets[2]) horz_splitter1.addWidget(self.vtk_widgets[3]) vert_splitter.addWidget(horz_splitter1) horz_layout0.addWidget(vert_splitter) horz_layout0.setContentsMargins(0, 0, 0, 0) self.vtk_panel.setLayout(horz_layout0) vert_layout = QVBoxLayout() # Sagittal/Coronal/Axial planes - not used horz_layout1 = QHBoxLayout() self.btnSagittal = QPushButton("S") self.btnSagittal.setCheckable(True) self.btnSagittal.setChecked(True) horz_layout1.addWidget(self.btnSagittal) self.btnCoronal = QPushButton("C") self.btnCoronal.setCheckable(True) self.btnCoronal.setChecked(True) horz_layout1.addWidget(self.btnCoronal) self.btnAxial = QPushButton("A") self.btnAxial.setCheckable(True) self.btnAxial.setChecked(True) horz_layout1.addWidget(self.btnAxial) self.btnSagittal.clicked.connect(self.togglePlanes) self.btnCoronal.clicked.connect(self.togglePlanes) self.btnAxial.clicked.connect(self.togglePlanes) verticalSpacer = QSpacerItem(10, 10, QSizePolicy.Minimum, QSizePolicy.Expanding) vert_layout.addSpacerItem(verticalSpacer) # Misalignment groupBox = QGroupBox("Misalignment") vert_layout.addWidget(groupBox) mis_layout = QVBoxLayout() # Local and reset horzSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding, QSizePolicy.Minimum) self.btnLocal = QCheckBox("local") self.btnReset = QPushButton("Reset") self.btnReset.clicked.connect(self.onResetOffset) # Misalignment buttons horz_layout4 = QHBoxLayout() horz_layout4.addWidget(self.btnLocal) horz_layout4.addSpacerItem(horzSpacer) horz_layout4.addWidget(self.btnReset) mis_layout.addItem(horz_layout4) # Misalignment sliders [(self.sliderTX, self.btnTransX), (self.sliderTY, self.btnTransY), (self.sliderTZ, self.btnTransZ), (self.sliderRX, self.btnRotX), (self.sliderRY, self.btnRotY), (self.sliderRZ, self.btnRotZ) ] = self.createMisAlignment(mis_layout, self.onOrientationClicked) groupBox.setLayout(mis_layout) # Movement groupBox = QGroupBox("Movement") vert_layout.addWidget(groupBox) groupLayout = QVBoxLayout() # Local and reset horzSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding, QSizePolicy.Minimum) # TODO: Return values self.btnMoveLocal = QCheckBox("local") self.btnReset1 = QPushButton("Reset") self.btnReset1.clicked.connect(self.onResetMovement) # Movement sliders layout = QHBoxLayout() layout.addWidget(self.btnMoveLocal) layout.addSpacerItem(horzSpacer) layout.addWidget(self.btnReset1) groupLayout.addItem(layout) [ (self.sliderMTX, self.sliderMTY, self.sliderMTZ), (self.sliderMRX, self.sliderMRY, self.sliderMRZ) ] = self.createMovement(groupLayout, self.onSliderPressed, self.onMove) groupBox.setLayout(groupLayout) self.frame.setLayout(vert_layout)
def loadFile(self, fileName): # Load VTK Meta Image reader = vtk.vtkMetaImageReader() reader.SetFileName(fileName) reader.Update() imageDims = reader.GetOutput().GetDimensions() # Disable renderers and widgets for i in range(3): self.vtk_widgets[i].viewer.GetInteractor().EnableRenderOff() self.vtk_widgets[3].EnableRenderOff() # Turn-off plane widgets for i in range(3): self.planeWidget[i].Off() # Assign data to 2D viewers sharing one cursorobject for i in range(3): self.vtk_widgets[i].viewer.SetInputData(reader.GetOutput()) # Corner annotation for i in range(3): # TODO: Use (<slice>, <slice_pos>, <window_level>). WindowLevel not signaled when changed in RIW's cornerAnnotation = vtk.vtkCornerAnnotation() cornerAnnotation.SetLinearFontScaleFactor(2) cornerAnnotation.SetNonlinearFontScaleFactor(1) cornerAnnotation.SetMaximumFontSize(20) cornerAnnotation.SetText(vtk.vtkCornerAnnotation.UpperLeft, { 2: 'Axial', 0: 'Sagittal', 1: 'Coronal' }[i]) cornerAnnotation.GetTextProperty().SetColor(1, 1, 1) cornerAnnotation.SetImageActor( self.vtk_widgets[i].viewer.GetImageActor()) cornerAnnotation.SetWindowLevel( self.vtk_widgets[0].viewer.GetWindowLevel()) self.vtk_widgets[i].viewer.GetRenderer().AddViewProp( cornerAnnotation) # Issue # Enable plane widgets for i in range(3): self.planeWidget[i].SetInputConnection(reader.GetOutputPort()) self.planeWidget[i].SetPlaneOrientation(i) self.planeWidget[i].SetSliceIndex(imageDims[i] // 2) self.planeWidget[i].GetInteractor().Enable() self.planeWidget[i].On() self.planeWidget[i].InteractionOn() # Enable 2D viewers for i in range(3): self.vtk_widgets[i].viewer.GetRenderer().ResetCamera() self.vtk_widgets[i].viewer.GetInteractor().EnableRenderOn() # Enable interactors for i in range(3): self.vtk_widgets[i].interactor.Enable() self.vtk_widgets[i].viewer.GetInteractor().Enable() # Enable 3D rendering self.vtk_widgets[3].EnableRenderOn() # Reset camera for the renderer - otherwise it is set using dummy data self.planeWidget[0].GetDefaultRenderer().ResetCamera() # Update 3D self.ResetViews() self.SetResliceMode(1)
def doReslice(renWin, reader, viewNr, orientation, level, window): # Calculate the center of the volume reader.Update() (xMin, xMax, yMin, yMax, zMin, zMax) = reader.GetExecutive().GetWholeExtent( reader.GetOutputInformation(0)) (xSpacing, ySpacing, zSpacing) = reader.GetOutput().GetSpacing() (x0, y0, z0) = reader.GetOutput().GetOrigin() center = [ x0 + xSpacing * 0.5 * (xMin + xMax), y0 + ySpacing * 0.5 * (yMin + yMax), z0 + zSpacing * 0.5 * (zMin + zMax) ] # Matrices for axial, coronal, sagittal, oblique view orientations axial = vtk.vtkMatrix4x4() axial.DeepCopy((1, 0, 0, center[0], 0, 1, 0, center[1], 0, 0, 1, center[2], 0, 0, 0, 1)) coronal = vtk.vtkMatrix4x4() coronal.DeepCopy((1, 0, 0, center[0], 0, 0, 1, center[1], 0, -1, 0, center[2], 0, 0, 0, 1)) sagittal = vtk.vtkMatrix4x4() sagittal.DeepCopy((0, 0, -1, center[0], 1, 0, 0, center[1], 0, -1, 0, center[2], 0, 0, 0, 1)) # Extract a slice in the desired orientation reslice = vtk.vtkImageReslice() reslice.SetInputConnection(reader.GetOutputPort()) reslice.SetOutputDimensionality(2) reslice.SetResliceAxes(axial) if orientation == "coronal": reslice.SetResliceAxes(coronal) if orientation == "sagittal": reslice.SetResliceAxes(sagittal) reslice.SetInterpolationModeToLinear() range1 = int(level) - int(window) / 2 range2 = int(level) + int(window) / 2 # Create a greyscale lookup table table = vtk.vtkLookupTable() table.SetRange(range1, range2) # image intensity range table.SetValueRange(0.0, 1.0) # from black to white table.SetSaturationRange(0.0, 0.0) # no color saturation table.SetRampToLinear() table.Build() # Map the image through the lookup table color = vtk.vtkImageMapToColors() color.SetLookupTable(table) color.SetInputConnection(reslice.GetOutputPort()) # Display the image actor = vtk.vtkImageActor() actor.GetMapper().SetInputConnection(color.GetOutputPort()) cornerAnnotation = vtk.vtkCornerAnnotation() cornerAnnotation.SetLinearFontScaleFactor(1) cornerAnnotation.SetNonlinearFontScaleFactor(1) cornerAnnotation.SetMinimumFontSize(12) cornerAnnotation.SetMaximumFontSize(20) cornerAnnotation.SetText(0, "lower left") cornerAnnotation.SetText(1, "lower right") cornerAnnotation.SetText(2, "upper left") cornerAnnotation.SetText(3, "upper right") cornerAnnotation.GetTextProperty().SetColor(1, 1, 1) ren = vtk.vtkRenderer() ren.SetBackground(0.0, 0.0, 0.0) ren.AddActor(actor) #ren.AddViewProp( cornerAnnotation ) ren.SetViewport(*getViewport(viewNr)) renWin.AddRenderer(ren) ren.ResetCamera() camera = ren.GetActiveCamera() camera.Zoom(1.4) ViewportBorder(ren, [1, 1, 1], False) return reslice
def Text( txt, pos=3, normal=(0, 0, 1), s=1, depth=0.1, justify="bottom-left", c=None, alpha=1, bc=None, bg=None, font="courier", followcam=False, ): """ Returns a ``vtkActor`` that shows a 3D text. :param pos: position in 3D space, if an integer is passed [1,8], a 2D text is placed in one of the 4 corners: 1, bottom-left 2, bottom-right 3, top-left 4, top-right 5, bottom-middle 6, middle-right 7, middle-left 8, top-middle :type pos: list, int :param float s: size of text. :param float depth: text thickness. :param str justify: text justification (bottom-left, bottom-right, top-left, top-right, centered). :param bg: background color of corner annotations. Only applies of `pos` is ``int``. :param str font: either `arial`, `courier` or `times`. Only applies of `pos` is ``int``. :param followcam: if `True` the text will auto-orient itself to the active camera. A ``vtkCamera`` object can also be passed. :type followcam: bool, vtkCamera .. hint:: |colorcubes.py|_ |markpoint.py|_ |annotations.py|_ |colorcubes| |markpoint| """ if c is None: # automatic black or white if settings.plotter_instance and settings.plotter_instance.renderer: c = (0.9, 0.9, 0.9) if np.sum( settings.plotter_instance.renderer.GetBackground()) > 1.5: c = (0.1, 0.1, 0.1) else: c = (0.6, 0.6, 0.6) if isinstance(pos, int): if pos > 8: pos = 8 if pos < 1: pos = 1 ca = vtk.vtkCornerAnnotation() ca.SetNonlinearFontScaleFactor(s / 2.7) ca.SetText(pos - 1, str(txt)) ca.PickableOff() cap = ca.GetTextProperty() cap.SetColor(colors.getColor(c)) if font.lower() == "courier": cap.SetFontFamilyToCourier() elif font.lower() == "times": cap.SetFontFamilyToTimes() else: cap.SetFontFamilyToArial() if bg: bgcol = colors.getColor(bg) cap.SetBackgroundColor(bgcol) cap.SetBackgroundOpacity(alpha * 0.5) cap.SetFrameColor(bgcol) cap.FrameOn() setattr(ca, 'renderedAt', set()) settings.collectable_actors.append(ca) return ca tt = vtk.vtkVectorText() tt.SetText(str(txt)) tt.Update() ttmapper = vtk.vtkPolyDataMapper() if followcam: depth = 0 normal = (0, 0, 1) if depth: extrude = vtk.vtkLinearExtrusionFilter() extrude.SetInputConnection(tt.GetOutputPort()) extrude.SetExtrusionTypeToVectorExtrusion() extrude.SetVector(0, 0, 1) extrude.SetScaleFactor(depth) ttmapper.SetInputConnection(extrude.GetOutputPort()) else: ttmapper.SetInputConnection(tt.GetOutputPort()) if followcam: ttactor = vtk.vtkFollower() if isinstance(followcam, vtk.vtkCamera): ttactor.SetCamera(followcam) else: ttactor.SetCamera(settings.plotter_instance.camera) else: ttactor = Actor() ttactor.SetMapper(ttmapper) ttactor.GetProperty().SetColor(colors.getColor(c)) ttmapper.Update() bb = tt.GetOutput().GetBounds() dx, dy = (bb[1] - bb[0]) / 2 * s, (bb[3] - bb[2]) / 2 * s cm = np.array([(bb[1] + bb[0]) / 2, (bb[3] + bb[2]) / 2, (bb[5] + bb[4]) / 2]) * s shift = -cm if "cent" in justify: pass elif "bottom-left" in justify: shift += np.array([dx, dy, 0]) elif "top-left" in justify: shift += np.array([dx, -dy, 0]) elif "bottom-right" in justify: shift += np.array([-dx, dy, 0]) elif "top-right" in justify: shift += np.array([-dx, -dy, 0]) else: colors.printc("~lightning Text(): Unknown justify type", justify, c=1) ttactor.GetProperty().SetOpacity(alpha) nax = np.linalg.norm(normal) if nax: normal = np.array(normal) / nax theta = np.arccos(normal[2]) phi = np.arctan2(normal[1], normal[0]) ttactor.SetScale(s, s, s) ttactor.RotateZ(np.rad2deg(phi)) ttactor.RotateY(np.rad2deg(theta)) ttactor.SetPosition(pos + shift) if bc: # defines a specific color for the backface backProp = vtk.vtkProperty() backProp.SetDiffuseColor(colors.getColor(bc)) backProp.SetOpacity(alpha) ttactor.SetBackfaceProperty(backProp) ttactor.PickableOff() settings.collectable_actors.append(ttactor) return ttactor
def __init__(self, parent, slice_mode="multiplanar", layers=None, annotations=None, interpolation=False, display_coordinates="physical", scalar_bar_visibility=False, orientation_visibility=True, corner_annotations_visibility=False, convention="radiological", crosshair="full", *args, **kwargs): if annotations is None: annotations = ObservableList() ############## # Properties # ############## self._slice_mode = None self._interpolation = None self._display_coordinates = None self._scalar_bar_visibility = None self._orientation_visibility = None self._convention = None self._crosshair = None self._corner_annotations_visibility = None self._annotations = None self._cursor_physical_position = None self._cursor_index_position = None self._center_physical_position = None self._center_index_position = None self._zoom = None self._mouse_tools = {} self._keyboard_tools = {} ################### # Private members # ################### self._rwi = None self._layers = ObservableList() self._slices = [] self._slices_names = [] self._informations_renderer = vtkRenderer() self._informations_renderer.SetViewport( *self._viewport["informations"]) self._informations_corner_annotation = vtkCornerAnnotation() self._informations_corner_annotation.SetNonlinearFontScaleFactor(0.3) self._informations_renderer.AddActor( self._informations_corner_annotation) ################## # Initialization # ################## wx.Panel.__init__(self, parent, *args, **kwargs) # Explicitely pass size to RWI to propagate it correctly self._rwi = wxVTKRenderWindowInteractor(self, wx.ID_ANY, size=self.GetSize()) self._rwi.Enable(1) sizer = wx.BoxSizer() sizer.Add(self._rwi, 1, wx.EXPAND | wx.ALL, 3) self.SetSizer(sizer) self._rwi.Bind(wx.EVT_LEFT_DOWN, self._on_button_down) self._rwi.Bind(wx.EVT_MIDDLE_DOWN, self._on_button_down) self._rwi.Bind(wx.EVT_RIGHT_DOWN, self._on_button_down) self._rwi.Bind(wx.EVT_MOUSEWHEEL, self._on_button_down) self.Bind(wx.EVT_CLOSE, self._on_close) PropertySynchronized.__init__(self, [ "interpolation", "display_coordinates", "scalar_bar_visibility", "orientation_visibility", "zoom" ]) self.add_allowed_event("cursor_position") self.add_allowed_event("image_position") self.add_allowed_event("center") self.add_allowed_event("layer_visibility") for event in [ "data", "display_range", "cut_low", "cut_high", "zero_transparency" ]: self.add_allowed_event("colormap_{0}".format(event)) # self.add_allowed_event("layer_modified") # self.add_allowed_event("activated") self._set_interpolation(interpolation) self._set_display_coordinates(display_coordinates) self._set_scalar_bar_visibility(scalar_bar_visibility) self._set_orientation_visibility(orientation_visibility) self._set_convention(convention) self._set_crosshair(crosshair) self._set_corner_annotations_visibility(corner_annotations_visibility) for layer in layers or []: self.append_layer(**layer) self._set_slice_mode(slice_mode) self._set_annotations(annotations) # Position image at middle of layer 0 self.reset_view()