def create_foliation(self, X, Y, Z, f, Gx, Gy, Gz, n_sphere=0, n_render=0, n_index=0, r=0.1, alpha=0.5): d = vtk.vtkPlaneWidget() d.SetInteractor(self.interactor) d.SetRepresentationToSurface() # Position print(X, Y, Z) source = vtk.vtkPlaneSource() source.SetCenter(X, Y, Z) source.SetNormal(Gx, Gy, Gz) source.Update() d.SetInputData(source.GetOutput()) d.SetHandleSize(0.05) d.SetPlaceFactor(250) d.PlaceWidget() d.SetNormal(Gx, Gy, Gz) d.GetPlaneProperty().SetColor(self.C_LOT[f]) d.GetHandleProperty().SetColor(self.C_LOT[f]) d.GetHandleProperty().SetOpacity(alpha) d.SetCurrentRenderer(self.ren_list[n_render]) d.n_plane = n_sphere d.n_render = n_render d.index = n_index d.AddObserver("InteractionEvent", self.planesCallback) d.On() return d
def createPlaneWidget(native=False): pw = vtk.vtkPlaneWidget() if native: return pw pw.SetHandleSize(0.0025) pw.Modified() return pw
def __init__(self, transform = None): self.planeWidget = vtk.vtkPlaneWidget() self.axes = vtk.vtkAxesActor() pOrigin = vtk.vtkVector3d(np.r_[0, 0, 0]) pPoint1 = vtk.vtkVector3d(np.r_[1, 0, 0]) pPoint2 = vtk.vtkVector3d(np.r_[0, 1, 0]) if transform is not None: self.axes.SetUserTransform(transform) pOrigin = transform.TransformPoint(pOrigin) pPoint1 = transform.TransformPoint(pPoint1) pPoint2 = transform.TransformPoint(pPoint2) self.planeWidget.SetOrigin(pOrigin) self.planeWidget.SetPoint1(pPoint1) self.planeWidget.SetPoint2(pPoint2) self.planeWidget.Modified() self.lastNormal = self.planeWidget.GetNormal() self.lastAxis1 = vtk.vtkVector3d() vtk.vtkMath.Subtract(self.planeWidget.GetPoint1(), self.planeWidget.GetOrigin(), self.lastAxis1) print(self.lastNormal) print(self.lastAxis1) self.axes.SetOrigin(self.planeWidget.GetOrigin()) self.axes.Modified() self.planeWidget.AddObserver(vtk.vtkCommand.EndInteractionEvent, self.SynchronizeAxes, 1.0)
def __init__(self, parent, visualizer, **kws): """ Initialization """ self.x, self.y, self.z = -1, -1, -1 #self.name = "Clipping Plane" self.parent = parent self.on = 0 self.renew = 1 self.currentPlane = None self.clipped = 0 self.clippedModules = [] self.planeWidget = vtk.vtkPlaneWidget() self.planeWidget.AddObserver("InteractionEvent", self.clipVolumeRendering) self.planeWidget.SetResolution(20) self.planeWidget.SetRepresentationToOutline() self.planeWidget.NormalToXAxisOn() self.renderer = self.parent.getRenderer() self.plane = vtk.vtkPlane() iactor = parent.wxrenwin.GetRenderWindow().GetInteractor() self.planeWidget.SetInteractor(iactor) VisualizationModule.__init__(self, parent, visualizer, **kws) self.descs = { "ShowControl": "Show controls", "AllModules": "Clip all modules", "ClippedModule": "Module to clip" } self.filterDesc = "Clip rendering using a plane"
def __init__(self, parent, visualizer, **kws): """ Initialization """ self.x, self.y, self.z = -1, -1, -1 #self.name = "Clipping Plane" self.parent = parent self.on = 0 self.renew = 1 self.currentPlane = None self.clipped = 0 self.clippedModules = [] self.planeWidget = vtk.vtkPlaneWidget() self.planeWidget.AddObserver("InteractionEvent", self.clipVolumeRendering) self.planeWidget.SetResolution(20) self.planeWidget.SetRepresentationToOutline() self.planeWidget.NormalToXAxisOn() self.renderer = self.parent.getRenderer() self.plane = vtk.vtkPlane() iactor = parent.wxrenwin.GetRenderWindow().GetInteractor() self.planeWidget.SetInteractor(iactor) VisualizationModule.__init__(self, parent, visualizer, **kws) self.descs = {"ShowControl": "Show controls", "AllModules": "Clip all modules", "ClippedModule": "Module to clip"} self.filterDesc = "Clip rendering using a plane"
def init_plane_widget(self): self.scalar_bar = vtk.vtkScalarBarActor() # Must add this to avoid vtkTextActor error self.scalar_bar.SetTitle("Number of counts") self.scalar_bar.SetWidth(0.1) self.scalar_bar.SetHeight(0.9) self.scalar_bar.SetLookupTable(self.lut) # The image plane widget are used to probe the dataset. self.plane_widget = vtk.vtkPlaneWidget() if vtk.vtkVersion.GetVTKMajorVersion() < 6: self.plane_widget.SetInput(self.data) else: self.plane_widget.SetInputData(self.data) #VTK6 self.plane_widget.NormalToXAxisOn() #TODO self.plane_widget.SetRepresentationToOutline() self.plane_widget.PlaceWidget() self.plane_widget.SetResolution(350) #TODO self.plane = vtk.vtkPolyData() self.plane_widget.GetPolyData(self.plane) self.implicit_plane = vtk.vtkPlane() self.plane_widget.GetPlane(self.implicit_plane) self.probe = vtk.vtkProbeFilter() if vtk.vtkVersion.GetVTKMajorVersion() < 6: self.probe.SetInput(self.plane) self.probe.SetSource(self.data) else: self.probe.SetInputData(self.plane) #VTK6 self.probe.SetSourceData(self.data) self.probe.Update() contour_mapper = vtk.vtkPolyDataMapper() contour_mapper.SetInputConnection(self.probe.GetOutputPort()) contour_mapper.SetScalarRange(self.mi, self.ma) contour_mapper.SetLookupTable(self.lut) self.contour_actor = vtk.vtkActor() self.contour_actor.SetMapper(contour_mapper) self.contour_actor.GetProperty().ShadingOff() self.contour_actor.GetProperty().SetAmbient(0.6) self.contour_actor.GetProperty().SetDiffuse(0.4) self.plane_widget.AddObserver('InteractionEvent', self.update_interactive_plane_widget) self.plane_widget.AddObserver('StartInteractionEvent', self.on_pick) # Associate the widget with the interactor self.plane_widget.SetInteractor(self.iren) self.plane_widget.SetEnabled(1) self.disablation_mode = True self.renderer.AddActor(self.contour_actor) self.renderer.AddActor2D(self.scalar_bar) #TODO self.renwin.Render()
def __init__(self): ''' Constructor ''' vtkPythonViewImage.__init__(self) # texture mapper in 3D: vtkVolumeMapper self.__VolumeMapper = None # texture mapper in 3D: vtkVolumeTextureMapper3D self.__VolumeTextureMapper = vtk.vtkVolumeTextureMapper3D() # volume ray cast mapper vtkFixedPointVolumeRayCastMapper self.__VolumeRayCastMapper = vtk.vtkFixedPointVolumeRayCastMapper() # volume property: vtkVolumeProperty self.__VolumeProperty = vtk.vtkVolumeProperty() # volume actor: vtkVolume self.__VolumeActor = vtk.vtkVolume() # opacity transfer function: vtkPiecewiseFunction self.__OpacityFunction = vtk.vtkPiecewiseFunction() # color transfer function: vtkColorTransferFunction self.__ColorFunction = vtk.vtkColorTransferFunction() # vtkProp3DCollection self.__PhantomCollection = vtk.vtkProp3DCollection() # blender: vtkImageBlend self.__Blender = None # image 3D cropping box callback: vtkImage3DCroppingBoxCallback self.__Callback = vtkPythonImage3DCroppingBoxCallback() # box widget: vtkOrientedBoxWidget # self.__BoxWidget = vtkOrientedBoxWidget() # Now I could not wrap vtkOrientedBoxWidget self.__BoxWidget = vtk.vtkBoxWidget() # vtkPlane widget: vtkPlaneWidget self.__PlaneWidget = vtk.vtkPlaneWidget() # annotated cube actor: vtkAnnotatedCubeActor, vtkOrientationMarkerWidget self.__Cube = vtk.vtkAnnotatedCubeActor() self.__Marker = vtk.vtkOrientationMarkerWidget() self.SetupVolumeRendering() self.SetupWidgets() self.ShowAnnotationsOn() self.getTextProperty().SetColor(0, 0, 0) self.SetBackground(0.9, 0.9, 0.9) # white self.__FirstRender = 1 self.__RenderingMode = self.PLANAR_RENDERING self.__VRQuality = 1 self.__InteractorStyleSwitcher = None
def create_foliation(self, X, Y, Z, fn, Gx, Gy, Gz, n_plane=0, n_render=0, n_index=0, alpha=0.5): """ Method to create a plane given a foliation Args: X : X coord Y: Y coord Z: Z corrd fn (int): Formation number Gx (str): Component of the gradient x Gy (str): Component of the gradient y Gz (str): Component of the gradient z n_plane (int): Number of the plane n_render (int): Number of the render where the plane belongs n_index (int): index value in the PandasDataframe of InupData.interfaces alpha: Opacity of the plane Returns: vtk.vtkPlaneWidget """ d = vtk.vtkPlaneWidget() d.SetInteractor(self.interactor) d.SetRepresentationToSurface() # Position source = vtk.vtkPlaneSource() source.SetCenter(X, Y, Z) source.SetNormal(Gx, Gy, Gz) source.Update() d.SetInputData(source.GetOutput()) d.SetHandleSize(0.05) min_extent = np.min([self._e_dx, self._e_dy, self._e_dz]) d.SetPlaceFactor(min_extent/10) d.PlaceWidget() d.SetNormal(Gx, Gy, Gz) d.GetPlaneProperty().SetColor(self.C_LOT[fn]) d.GetHandleProperty().SetColor(self.C_LOT[fn]) d.GetHandleProperty().SetOpacity(alpha) d.SetCurrentRenderer(self.ren_list[n_render]) d.n_plane = n_plane d.n_render = n_render d.index = n_index d.AddObserver("EndInteractionEvent", self.planesCallback) d.On() return d
def CreateOutline(depth=80.0, transform=None): # Create planeWidget aligned with sector outline outline = CreateOutline9076(depth=depth) bounds = outline.GetBounds() planeWidget = vtk.vtkPlaneWidget() origin = (bounds[0], 0.0, bounds[4]) point1 = (bounds[1], 0.0, bounds[4]) point2 = (bounds[0], 0.0, bounds[5]) if initialMovement and transform is not None: origin = transform.TransformPoint(origin) point1 = transform.TransformPoint(point1) point2 = transform.TransformPoint(point2) planeWidget.SetOrigin(origin) planeWidget.SetPoint1(point1) planeWidget.SetPoint2(point2) prop = planeWidget.GetPlaneProperty() prop.SetColor(.2, .8, 0.1) renderLinesAsTubes(prop) prop = planeWidget.GetHandleProperty() prop.SetColor(0, .4, .7) prop.SetLineWidth(1.5) #//Set plane lineweight renderLinesAsTubes(prop) planeWidget.Modified() planeWidget.AddObserver(vtk.vtkCommand.EndInteractionEvent, Callback, 1.0) mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(outline) actor = vtk.vtkActor() actor.SetMapper(mapper) # Origin used for book-keeping center = (0.0, 0.0, 0.5 * (bounds[4] + bounds[5])) if initialMovement and transform is not None: actor.SetUserTransform(transform) center = transform.TransformPoint(center) actor.SetOrigin(center) prop = actor.GetProperty() prop.SetLineWidth(4) renderLinesAsTubes(prop) return actor, planeWidget
def __init__(self): # Working arrays, constructed once for speed. self._c = N.zeros(3) self._o = N.zeros(3) self._p1 = N.zeros(3) self._p2 = N.zeros(3) self._n = N.zeros(3) self.widget = vtkPlaneWidget() self.widget.KeyPressActivationOff() self.widget.SetRepresentationToOutline() # As a fraction of BB diagonal self.widget.SetHandleSize(0.01) # self.representation = vtkPolyData() # This is effectively a copy and is guaranteed to be up to # date when InteractionEvent or EndInteraction events are # invoked self.representation = self.widget.GetPolyDataAlgorithm() self.mapper = vtkPolyDataMapper() self.mapper.SetInputConnection(self.representation.GetOutputPort()) self.actor = vtkActor() self.actor.SetMapper(self.mapper) self.actor.GetProperty().SetColor(self.colour) # Keep a cached copy of the radius etc to minimise the number of notifications we must send self._lastRadius = self.Radius self._lastCentre = self.Centre self._lastNormal = self.Normal # We can only enable after self.SetInteractor() has been called. self._Enabled = False self.widget.AddObserver("EndInteractionEvent", self.HandleInteraction) # self.AddObserver('Enabled', self.EnabledSet) return
def add_plane_widget(self, callback, normal='x', origin=None, bounds=None, factor=1.25, color=None, assign_to_axis=None, tubing=False, outline_translation=False, origin_translation=True, implicit=True, pass_widget=False, test_callback=True): """Add a plane widget to the scene. This is useless without a callback function. You can pass a callable function that takes two arguments, the normal and origin of the plane in that order output from this widget, and performs a task with that plane. Parameters ---------- callback : callable The method called every time the plane is updated. Takes two arguments, the normal and origin of the plane in that order. normal : str or tuple(float) The starting normal vector of the plane origin : tuple(float) The starting coordinate of the center of the place bounds : tuple(float) Length 6 tuple of the bounding box where the widget is placed. factor : float, optional An inflation factor to expand on the bounds when placing color : string or 3 item list, optional, defaults to white Either a string, rgb list, or hex color string. assign_to_axis : str or int Assign the normal of the plane to be parallel with a given axis: options are (0, 'x'), (1, 'y'), or (2, 'z'). tubing : bool When using an implicit plane wiget, this controls whether or not tubing is shown around the plane's boundaries. outline_translation : bool If ``False``, the plane widget cannot be translated and is strictly placed at the given bounds. Only valid when using an implicit plane. origin_translation : bool If ``False``, the plane widget cannot be translated by its origin and is strictly placed at the given origin. Only valid when using an implicit plane. implicit : bool When ``True``, a ``vtkImplicitPlaneWidget`` is ued and when ``False``, a ``vtkPlaneWidget`` is used. pass_widget : bool If true, the widget will be passed as the last argument of the callback test_callback: bool if true, run the callback function after the widget is created. """ if hasattr(self, 'notebook') and self.notebook: raise AssertionError( 'Plane widget not available in notebook plotting') if not hasattr(self, 'iren'): raise AttributeError( 'Widgets must be used with an intereactive renderer. No off screen plotting.' ) if not hasattr(self, "plane_widgets"): self.plane_widgets = [] if origin is None: origin = self.center if bounds is None: bounds = self.bounds if isinstance(normal, str): normal = NORMALS[normal.lower()] if color is None: color = rcParams['font']['color'] def _the_callback(widget, event_id): the_plane = vtk.vtkPlane() widget.GetPlane(the_plane) normal = the_plane.GetNormal() origin = the_plane.GetOrigin() if hasattr(callback, '__call__'): if pass_widget: try_callback(callback, normal, origin, widget) else: try_callback(callback, normal, origin) return if implicit: plane_widget = vtk.vtkImplicitPlaneWidget() plane_widget.GetNormalProperty().SetColor(parse_color(color)) plane_widget.GetOutlineProperty().SetColor(parse_color(color)) plane_widget.GetOutlineProperty().SetColor(parse_color(color)) plane_widget.SetTubing(tubing) plane_widget.SetOutlineTranslation(outline_translation) plane_widget.SetOriginTranslation(origin_translation) _start_interact = lambda plane_widget, event: plane_widget.SetDrawPlane( True) _stop_interact = lambda plane_widget, event: plane_widget.SetDrawPlane( False) plane_widget.SetDrawPlane(False) plane_widget.AddObserver(vtk.vtkCommand.StartInteractionEvent, _start_interact) plane_widget.AddObserver(vtk.vtkCommand.EndInteractionEvent, _stop_interact) plane_widget.SetPlaceFactor(factor) plane_widget.PlaceWidget(bounds) plane_widget.SetOrigin(origin) else: # Position of the small plane source = vtk.vtkPlaneSource() source.SetNormal(normal) source.SetCenter(origin) source.SetPoint1(origin[0] + (bounds[1] - bounds[0]) * 0.01, origin[1] - (bounds[3] - bounds[2]) * 0.01, origin[2]) source.SetPoint2(origin[0] - (bounds[1] - bounds[0]) * 0.01, origin[1] + (bounds[3] - bounds[2]) * 0.01, origin[2]) source.Update() plane_widget = vtk.vtkPlaneWidget() plane_widget.SetHandleSize(.01) # Position of the widget plane_widget.SetInputData(source.GetOutput()) plane_widget.SetRepresentationToOutline() plane_widget.SetPlaceFactor(factor) plane_widget.PlaceWidget(bounds) plane_widget.SetCenter(origin) # Necessary plane_widget.GetPlaneProperty().SetColor( parse_color(color)) # self.C_LOT[fn]) plane_widget.GetHandleProperty().SetColor(parse_color(color)) plane_widget.GetPlaneProperty().SetOpacity(0.5) plane_widget.SetInteractor(self.iren) plane_widget.SetCurrentRenderer(self.renderer) if assign_to_axis: # TODO: how do we now disable/hide the arrow? if assign_to_axis in [0, "x", "X"]: plane_widget.NormalToXAxisOn() plane_widget.SetNormal(NORMALS["x"]) elif assign_to_axis in [1, "y", "Y"]: plane_widget.NormalToYAxisOn() plane_widget.SetNormal(NORMALS["y"]) elif assign_to_axis in [2, "z", "Z"]: plane_widget.NormalToZAxisOn() plane_widget.SetNormal(NORMALS["z"]) else: raise RuntimeError("assign_to_axis not understood") else: plane_widget.SetNormal(normal) plane_widget.Modified() plane_widget.UpdatePlacement() plane_widget.On() plane_widget.AddObserver(vtk.vtkCommand.EndInteractionEvent, _the_callback) if test_callback: _the_callback(plane_widget, None) # Trigger immediate update self.plane_widgets.append(plane_widget) return plane_widget
def __init__(self, transform=None): self.planeWidget = vtk.vtkPlaneWidget()
def renderVolume(self, vtkWidget): #def renderVolume(self,vtkWidget,vtkWidgetXY): #self.readVolume(loadedDataInfo) # The following class is used to store transparencyv-values for later retrival. In our case, we want the value 0 to be # completly opaque whereas the three different cubes are given different transperancy-values to show how it works. self.alphaChannelFunc = vtk.vtkPiecewiseFunction() self.alphaChannelFunc.AddPoint(self.cMin, 0) self.alphaChannelFunc.AddPoint(self.cMax, 1) # This class stores color data and can create color tables from a few color points. self.colorFunc = vtk.vtkColorTransferFunction() self.histWidg = HistogramWidget() self.histWidg.setColorMap( self.colorFunc, 'viridis', self.cMin, self.cMax) # This function set the vslues for color function # The preavius two classes stored properties. Because we want to apply these properties to the volume we want to render, # we have to store them in a class that stores volume prpoperties. self.volumeProperty = vtk.vtkVolumeProperty() self.volumeProperty.SetColor(self.colorFunc) self.volumeProperty.SetScalarOpacity(self.alphaChannelFunc) # This class describes how the volume is rendered (through ray tracing). self.compositeFunction = vtk.vtkVolumeRayCastCompositeFunction() # We can finally create our volume. We also have to specify the data for it, as well as how the data will be rendered. self.volumeMapper = vtk.vtkVolumeRayCastMapper() self.volumeMapper.SetVolumeRayCastFunction(self.compositeFunction) self.volumeMapper.SetInput(self.reader.GetOutput()) # The class vtkVolume is used to pair the preaviusly declared volume as well as the properties to be used when rendering that volume. self.volume = vtk.vtkVolume() self.volume.SetMapper(self.volumeMapper) self.volume.SetProperty(self.volumeProperty) # With almost everything else ready, its time to initialize the renderer and window, as well as creating a method for exiting the application self.renderer = vtk.vtkRenderer() self.renderWin = vtkWidget.GetRenderWindow() self.renderWin.AddRenderer(self.renderer) self.renderInteractor = vtkWidget.GetRenderWindow().GetInteractor() self.renderInteractor.SetRenderWindow(self.renderWin) # We add the volume to the renderer ... self.renderer.AddVolume(self.volume) # ... set background color to gray ... self.renderer.SetBackground(0.321, 0.349, 0.435) # ... and set window size. #self.renderWin.SetSize(800,800) # in the UI of PMainWindow we have set "auto fill background" property of QVTKWidget to true, so no need to set the size # Setting up the Plane Widget which will be used for viewing the slice as well as a clipping plane self.planeWidget = vtk.vtkPlaneWidget() self.planeWidget.SetInteractor(self.renderInteractor) self.planeWidget.SetResolution( 300) # this can be changed by the user from the Ui self.planeWidget.SetPlaceFactor(1.15) self.planeWidget.SetInput(self.reader.GetOutput()) self.planeWidget.PlaceWidget() # Code for slicing and clipping the volume self.plane = vtk.vtkPlane( ) # vtkPlane is used to add the current plane as a clipping plane in vtkVolumeMapper self.planeWidget.GetPlane( self.plane) # we get the current vtkPlane from the plane widget self.plane2 = vtk.vtkPolyData( ) # vtkPolyData is used to get the slice and show it on the actor, tried this using the above vtkPlane, but didn't worked self.planeWidget.GetPolyData(self.plane2) self.planeWidget.SetRepresentationToOutline() # probe filter computes point attributes (e.g., scalars, vectors, etc.) at specified point positions. If not added, renders just a white plane self.probe = vtk.vtkProbeFilter() self.probe.SetInput(self.plane2) self.probe.SetSource(self.reader.GetOutput()) self.contourMapper = vtk.vtkPolyDataMapper() self.contourMapper.SetInputConnection(self.probe.GetOutputPort()) self.contourMapper.SetScalarRange( self.reader.GetOutput().GetScalarRange()) self.contourMapper.SetLookupTable( self.colorFunc ) # this is like setting up the color map for the slice, we can directly pass the vtkColorFunction as a Lookup Table self.contourActor = vtk.vtkActor() self.contourActor.SetMapper(self.contourMapper) self.contourActor.VisibilityOff() self.renderer.AddActor(self.contourActor) # Actually generate contour lines. def BeginInteraction(obj, event): obj.GetPolyData(self.plane2) self.contourActor.VisibilityOn() def ProbeData(obj, event): obj.GetPolyData(self.plane2) # Associate the widget with the interactor self.planeWidget.SetInteractor(self.renderInteractor) # Handle the events. self.planeWidget.AddObserver("EnableEvent", BeginInteraction) self.planeWidget.AddObserver("StartInteractionEvent", BeginInteraction) self.planeWidget.AddObserver("InteractionEvent", ProbeData) self.planeWidget.SetNormalToXAxis(True) # For getting the outline(3D box) around the object outline = vtk.vtkOutlineFilter() outline.SetInput(self.reader.GetOutput()) outlineMapper = vtk.vtkPolyDataMapper() outlineMapper.SetInputConnection(outline.GetOutputPort()) self.outlineActor = vtk.vtkActor() self.outlineActor.SetMapper(outlineMapper) # We add outline actor to the renderer self.renderer.AddActor(self.outlineActor) # The Box widget # The SetInteractor method is how 3D widgets are associated with the # render window interactor. Internally, SetInteractor sets up a bunch # of callbacks using the Command/Observer mechanism (AddObserver()). self.boxWidget = vtk.vtkBoxWidget() self.boxWidget.SetInteractor(self.renderInteractor) self.boxWidget.SetPlaceFactor(1.0) # When interaction starts, the requested frame rate is increased. def StartInteraction(obj, event): self.renderWin.SetDesiredUpdateRate(10) # When interaction ends, the requested frame rate is decreased to # normal levels. This causes a full resolution render to occur. def EndInteraction(obj, event): self.renderWin.SetDesiredUpdateRate(0.001) # The implicit function vtkPlanes is used in conjunction with the # volume ray cast mapper to limit which portion of the volume is # volume rendered. self.planes = vtk.vtkPlanes() def ClipVolumeRender(obj, event): obj.GetPlanes(self.planes) self.volumeMapper.SetClippingPlanes(self.planes) # Place the interactor initially. The output of the reader is used to # place the box widget. self.boxWidget.SetInput(self.reader.GetOutput()) self.boxWidget.PlaceWidget() self.boxWidget.InsideOutOn() self.boxWidget.AddObserver("StartInteractionEvent", StartInteraction) self.boxWidget.AddObserver("InteractionEvent", ClipVolumeRender) self.boxWidget.AddObserver("EndInteractionEvent", EndInteraction) self.outlineProperty = self.boxWidget.GetOutlineProperty() self.outlineProperty.SetRepresentationToWireframe() self.outlineProperty.SetAmbient(1.0) self.outlineProperty.SetAmbientColor(1, 1, 1) self.outlineProperty.SetLineWidth(3) self.selectedOutlineProperty = self.boxWidget.GetSelectedOutlineProperty( ) self.selectedOutlineProperty.SetRepresentationToWireframe() self.selectedOutlineProperty.SetAmbient(1.0) self.selectedOutlineProperty.SetAmbientColor(1, 0, 0) self.selectedOutlineProperty.SetLineWidth(3) # Add the actors to the renderer, self.boxWidget.Off() # A simple function to be called when the user decides to quit the application. def exitCheck(obj, event): if obj.GetEventPending() != 0: obj.SetAbortRender(1) # Tell the application to use the function as an exit check. self.renderWin.AddObserver("AbortCheckEvent", exitCheck) self.alignedPlaneWidget = vtk.vtkImagePlaneWidget() self.alignedPlaneWidget.DisplayTextOn() self.alignedPlaneWidget.SetInput(self.reader.GetOutput()) self.alignedPlaneWidget.SetPlaneOrientationToZAxes() self.alignedPlaneWidget.GetColorMap().SetLookupTable(self.colorFunc) self.prop3 = self.alignedPlaneWidget.GetPlaneProperty() self.prop3.SetColor(0, 0, 1) self.alignedPlaneWidget.SetInteractor(self.renderInteractor) #alignedPlaneWidget.On() axes = vtk.vtkAxesActor() self.widgetAxes = vtk.vtkOrientationMarkerWidget() #widget->SetOutlineColor( 0.9300, 0.5700, 0.1300 ); self.widgetAxes.SetOrientationMarker(axes) self.widgetAxes.SetInteractor(self.renderInteractor) self.widgetAxes.SetViewport(0.0, 0.0, 0.3, 0.3) #self.widgetA.SetEnabled( 1 ) #self.widgetA.InteractiveOff() # XY plot in another renderer window """self.volumeMapperXY = vtk.vtkVolumeRayCastMapper() self.volumeMapperXY.SetVolumeRayCastFunction(self.compositeFunction) self.volumeMapperXY.SetInput(self.reader.GetOutput()) self.volumeXY = vtk.vtkVolume() self.volumeXY.SetMapper(self.volumeMapper) self.volumeXY.SetProperty(self.volumeProperty) self.rendererXY = vtk.vtkRenderer() self.renderWinXY = vtkWidgetXY.GetRenderWindow() self.renderWinXY.AddRenderer(self.rendererXY) #self.rendererXY.AddVolume(self.volumeXY) self.rendererXY.SetBackground(0.321, 0.349, 0.435) self.renderWinXY.SetSize(724,724) self.xyActor = vtk.vtkActor2D() self.xyMapper = vtk.vtkPolyDataMapper2D() self.polyData = vtk.vtkPolyData() self.alignedPlaneWidget.GetPolyData(self.polyData) self.probe2 = vtk.vtkProbeFilter() self.probe2.SetInput(self.polyData) self.probe2.SetSource(self.reader.GetOutput()) self.xyMapper.SetInputConnection(self.probe2.GetOutputPort()) self.xyMapper.SetScalarRange(self.reader.GetOutput().GetScalarRange()) self.xyMapper.SetLookupTable(self.colorFunc) self.xyActor.SetMapper(self.xyMapper) self.rendererXY.AddActor(self.xyActor) self.renderWinXY.Render()""" """# create object of vtkFFMPEGWriter so as to record a avi of all the interactions done with visualized obj windowToImageFilter = vtk.vtkWindowToImageFilter() windowToImageFilter.SetInput(self.renderWin) windowToImageFilter.SetInputBufferTypeToRGBA() windowToImageFilter.ReadFrontBufferOff() windowToImageFilter.Update() self.recorder = vtk.vtkFFMPEGWriter() self.recorder.SetQuality(1) self.recorder.SetInput(windowToImageFilter.GetOutput())""" # Because nothing will be rendered without any input, we order the first render manually before control is handed over to the main-loop. self.renderInteractor.Initialize() self.renderWin.Render() self.renderer.ResetCamera() self.renderInteractor.Start()
def CreateOutline(depth=80.0, transform=None): # Create planeWidget aligned with sector outline outline = CreateOutline9076(depth=depth) bounds = outline.GetBounds() planeWidget = vtk.vtkPlaneWidget() origin = (bounds[0], bounds[2], 0.0) point1 = (bounds[1], bounds[2], 0.0) point2 = (bounds[0], bounds[3], 0.0) if initialMovement and transform is not None: origin = transform.TransformPoint(origin) point1 = transform.TransformPoint(point1) point2 = transform.TransformPoint(point2) planeWidget.SetOrigin(origin) planeWidget.SetPoint1(point1) planeWidget.SetPoint2(point2) prop = planeWidget.GetPlaneProperty() #prop.SetColor( .2, .8, 0.1 ) renderLinesAsTubes(prop) prop = planeWidget.GetHandleProperty() #prop.SetColor(0, .4, .7 ) #prop.SetLineWidth( 1.5 )#//Set plane lineweight renderLinesAsTubes(prop) planeWidget.Modified() planeWidget.AddObserver(vtk.vtkCommand.EndInteractionEvent, Callback, 1.0) mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(outline) actor0 = vtk.vtkActor() actor0.SetMapper(mapper) # Origin used for book-keeping #center = (0.0, 0.0, 0.5*(bounds[4]+ bounds[5])) center = (0.0, 0.5 * (bounds[2] + bounds[3]), 0.0) prop = actor0.GetProperty() prop.SetLineWidth(4) renderLinesAsTubes(prop) probeSurface = CreateSurface9076() mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(probeSurface) probeActor = vtk.vtkActor() probeActor.SetMapper(mapper) if vtk.VTK_VERSION > '9.0.0': prop = probeActor.GetProperty() prop.SetInterpolationToPBR() prop.SetMetallic(0.5) prop.SetRoughness(0.4) #actor = actor0 assemblyActor = vtk.vtkAssembly() #assemblyActor.AddPart(cutActor) assemblyActor.AddPart(probeActor) #assemblyActor.AddPart(outLineActor) assemblyActor.AddPart(actor0) if initialMovement and transform is not None: assemblyActor.SetUserTransform(transform) center = transform.TransformPoint(center) assemblyActor.SetOrigin(center) return assemblyActor, planeWidget, outline
def vtk_test(self): global plane global m_pPlaneWidget global volumeMapper2 global clippingVolume def my_call_back(pWidget, ev): # 表示当pWidget控件改变时,触发函数,监听函数 if (pWidget): print(pWidget.GetClassName(), "Event Id:", ev) m_pPlaneWidget.GetPlane(plane) volumeMapper2.AddClippingPlane(plane) clippingVolume.SetMapper(volumeMapper2) print("Plane Normal = " + str(plane.GetNormal())) print("Plane Origin = " + str(plane.GetOrigin())) data = sitk.GetArrayFromImage(self.ds) + self.npz_data * 3000 min5 = sitk.GetArrayFromImage(self.ds).min() max5 = sitk.GetArrayFromImage(self.ds).max() print(min5, max5) data = data[:, :, :] data = np.ascontiguousarray(data) spacing = self.ds.GetSpacing() # 三维数据的间隔 img_arr = vtkImageImportFromArray( ) # 创建一个空的vtk类-----vtkImageImportFromArray img_arr.SetArray( data) # 把array_data塞到vtkImageImportFromArray(array_data) img_arr.SetDataSpacing(spacing) # 设置spacing origin = (0, 0, 0) img_arr.SetDataOrigin(origin) # 设置vtk数据的坐标系原点 img_arr.Update() srange = img_arr.GetOutput().GetScalarRange() min = min5 max = max5 + 300 diff = max - min # 体数据极差 inter = 4000 / diff shift = -min # 可以加,不能减,人体内外分割处 ren1 = vtk.vtkRenderer() ren1.SetViewport(0, 0.5, 0.5, 1.0) # 设置窗口大小 ren1.SetBackground(1.0, 0.9, 0.9) # 设置背景颜色,RGB ren1.SetBackground2(1.0, 1.0, 1.0) # 设置第二个背景颜色 ren1.SetGradientBackground(1) # 背景颜色渐变 ren1.ResetCameraClippingRange() renWin = vtk.vtkRenderWindow() renWin.AddRenderer(ren1) # 把一个空的渲染器添加到一个空的窗口上 renWin.SetSize(2800, 1680) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) style = vtk.vtkInteractorStyleTrackballCamera() iren.SetInteractorStyle(style) shifter = vtk.vtkImageShiftScale( ) # 对偏移和比例参数来对图像数据进行操作 数据转换,之后直接调用shifter shifter.SetShift(shift) shifter.SetScale(inter) shifter.SetOutputScalarTypeToUnsignedShort() shifter.SetInputData(img_arr.GetOutput()) shifter.ReleaseDataFlagOff() shifter.Update() tfun = vtk.vtkPiecewiseFunction() # 不透明度传输函数---放在tfun tfun.AddPoint(1129, 0) # 不切片时配置 tfun.AddPoint(1300.0, 0.02) tfun.AddPoint(1600.0, 0.03) tfun.AddPoint(2000.0, 0.04) tfun.AddPoint(2200.0, 0.05) tfun.AddPoint(2500.0, 0.09) tfun.AddPoint(2800.0, 0.1) tfun.AddPoint(3000.0, 0.11) '''tfun.AddPoint(1129, 0) # 不切片时配置 tfun.AddPoint(1300.0, 0.02) tfun.AddPoint(1600.0, 0.03) tfun.AddPoint(2000.0, 0.04) tfun.AddPoint(2200.0, 0.05) tfun.AddPoint(2500.0, 0.2) tfun.AddPoint(2800.0, 0.3) tfun.AddPoint(3000.0, 0.4)''' gradtfun = vtk.vtkPiecewiseFunction( ) # 梯度不透明度函数---放在gradtfun,目前还没有加??? gradtfun.AddPoint(-1000, 8) gradtfun.AddPoint(0.5, 9) gradtfun.AddPoint(1, 10) ctfun = vtk.vtkColorTransferFunction() # 颜色传输函数---放在ctfun # ctfun.AddRGBPoint(0.0, 0.2, 1.0, 1.0) # 蓝色模型配置 # ctfun.AddRGBPoint(600.0, 0.4, 0.6, 1.0) # ctfun.AddRGBPoint(1280.0, 0.4, 0.3, 1.0) # ctfun.AddRGBPoint(1960.0, 0.2, 0.37, 0.91) # ctfun.AddRGBPoint(2200.0, 0.4, 0.3, 1.0) # ctfun.AddRGBPoint(2500.0, 0.4, 0.6, 1.0) # ctfun.AddRGBPoint(3024.0, 0.6, 0.6, 0.6) ctfun.AddRGBPoint(900.0, 0.8, 0.8, 0.8) ctfun.AddRGBPoint(1900.0, 0.8, 0.8, 0.8) ctfun.AddRGBPoint(2800.0, 0.8, 0.8, 0.8) ctfun.AddRGBPoint(3600.0, 1.0, 0.2, 0.2) volumeMapper = vtk.vtkGPUVolumeRayCastMapper( ) # 映射器volumnMapper使用vtk的管线投影算法 volumeMapper.SetInputData( shifter.GetOutput()) # 向映射器中输入数据:shifter(预处理之后的数据) volumeProperty = vtk.vtkVolumeProperty() # 创建vtk属性存放器,向属性存放器中存放颜色和透明度 volumeProperty.SetColor(ctfun) volumeProperty.SetScalarOpacity(tfun) # volumeProperty.SetGradientOpacity(gradtfun) volumeProperty.SetInterpolationTypeToLinear() # ??? volumeProperty.ShadeOn() outline1 = vtk.vtkOutlineFilter() outline1.SetInputConnection(shifter.GetOutputPort()) outlineMapper1 = vtk.vtkPolyDataMapper() outlineMapper1.SetInputConnection(outline1.GetOutputPort()) outlineMapper1.ScalarVisibilityOff() outlineActor1 = vtk.vtkActor() outlineActor1.SetMapper(outlineMapper1) outlineActor1.GetProperty().SetColor(1, 0, 0) ########第一个容器配置完成 newvol = vtk.vtkVolume() # 演员 newvol.SetMapper(volumeMapper) newvol.SetProperty(volumeProperty) aCamera = vtk.vtkCamera() # 设置相机,参数不是很懂 aCamera.SetViewUp(0, 0, 1) aCamera.SetPosition(0, -1, 0) aCamera.SetFocalPoint(0, 0, 0) aCamera.ComputeViewPlaneNormal() aCamera.Azimuth(30.0) aCamera.Elevation(30.0) aCamera.Dolly(1.5) ren1.AddActor(outlineActor1) # 添加演员和外壳 ren1.AddVolume(newvol) ren1.SetActiveCamera(aCamera) ren1.ResetCamera() # 设置切割的模型 volumeMapper2 = vtk.vtkGPUVolumeRayCastMapper() volumeMapper2.SetInputData(shifter.GetOutput()) m_pPlaneWidget = vtk.vtkPlaneWidget() # 设置隐平面 m_pPlaneWidget.SetInteractor(iren) # 与交互器关联 m_pPlaneWidget.SetInputData(shifter.GetOutput()) # 设置数据集,用于初始化平面,可以不设置 m_pPlaneWidget.SetResolution(80) # 即:设置网格数 m_pPlaneWidget.GetPlaneProperty().SetColor(.2, .8, 0.1) # 设置颜色 m_pPlaneWidget.GetPlaneProperty().SetOpacity(0.5) # 设置透明度 m_pPlaneWidget.GetHandleProperty().SetColor(0, .4, .7) # 设置平面顶点颜色 m_pPlaneWidget.GetHandleProperty().SetLineWidth(2) # 设置平面线宽 m_pPlaneWidget.NormalToZAxisOn() # 初始法线方向平行于Z轴 # m_pPlaneWidget.SetRepresentationToWireframe() #平面显示为网格属性 # m_pPlaneWidget.SetCenter(newvol.GetCenter()) #设置平面坐标 # m_pPlaneWidget.SetInteractor(renWin.GetInteractor() ) #与交互器关联,感觉同上 # m_pPlaneWidget.SetPlaceFactor(0.75) # 设置控件大小 m_pPlaneWidget.PlaceWidget() # 放置平面 m_pPlaneWidget.AddObserver("EndInteractionEvent", my_call_back) m_pPlaneWidget.On() # 显示平面 plane = vtk.vtkPlane() # plane.SetOrigin(90,0, 90) #设置原点位置 # plane.SetNormal(1, 0, 1) #设置法向量 m_pPlaneWidget.GetPlane(plane) volumeMapper2.AddClippingPlane(plane) clippingVolume = vtk.vtkVolume() # 设置参数同上 clippingVolume.SetMapper(volumeMapper2) clippingVolume.SetProperty(volumeProperty) outline2 = vtk.vtkOutlineFilter() outline2.SetInputConnection(shifter.GetOutputPort()) outlineMapper2 = vtk.vtkPolyDataMapper() outlineMapper2.SetInputConnection(outline2.GetOutputPort()) outlineMapper2.ScalarVisibilityOff() outlineActor2 = vtk.vtkActor() outlineActor2.SetMapper(outlineMapper2) outlineActor2.GetProperty().SetColor(1, 0, 0) ren2 = vtk.vtkRenderer() ren2.SetBackground(0.9, 1.0, 0.9) # 设置背景颜色,RGB ren2.SetBackground2(1.0, 1.0, 1.0) # 设置第二个背景颜色 ren2.SetGradientBackground(1) ren2.SetViewport(0.5, 0.5, 1.0, 1.0) ren2.AddVolume(clippingVolume) # 添加演员和外壳 ren2.AddActor(outlineActor2) renWin.AddRenderer(ren2) # 第二个窗口完成 ren3 = vtk.vtkRenderer() ren3.SetBackground(0.9, 1.0, 0.9) # 设置背景颜色,RGB ren3.SetBackground2(1.0, 1.0, 1.0) # 设置第二个背景颜色 ren3.SetGradientBackground(1) ren3.SetViewport(0.0, 0.0, 0.5, 0.5) img_arr1 = vtkImageImportFromArray( ) # 创建一个空的vtk类-----vtkImageImportFromArray img_arr1.SetArray(sitk.GetArrayFromImage( self.ds)) # 把array_data塞到vtkImageImportFromArray(array_data) img_arr1.SetDataSpacing(spacing) # 设置spacing img_arr1.SetDataOrigin(origin) # 设置vtk数据的坐标系原点 img_arr1.Update() srange = img_arr1.GetOutput().GetScalarRange() min1 = srange[0] max1 = srange[1] diff = max1 - min1 # 体数据极差 inter = 5000 / diff shift = -min1 # 可以加,不能减,人体内外分割处 shifter1 = vtk.vtkImageShiftScale( ) # 对偏移和比例参数来对图像数据进行操作 数据转换,之后直接调用shifter shifter1.SetShift(shift) shifter1.SetScale(inter) shifter1.SetOutputScalarTypeToUnsignedShort() shifter1.SetInputData(img_arr1.GetOutput()) shifter1.ReleaseDataFlagOff() shifter1.Update() volumeMapper3 = vtk.vtkGPUVolumeRayCastMapper( ) # 映射器volumnMapper使用vtk的管线投影算法 volumeMapper3.SetInputData( shifter1.GetOutput()) # 向映射器中输入数据:shifter(预处理之后的数据) volume3 = vtk.vtkVolume() # 演员 volume3.SetMapper(volumeMapper3) volume3.SetProperty(volumeProperty) ren3.AddVolume(volume3) # 添加演员和外壳 ren3.AddActor(outlineActor2) renWin.AddRenderer(ren3) # 第三个窗口完成 ren4 = vtk.vtkRenderer() ren4.SetBackground(1.0, 0.9, 0.9) # 设置背景颜色,RGB ren4.SetBackground2(1.0, 1.0, 1.0) # 设置第二个背景颜色 ren4.SetGradientBackground(1) ren4.SetViewport(0.5, 0.0, 1.0, 0.5) img_arr2 = vtkImageImportFromArray( ) # 创建一个空的vtk类-----vtkImageImportFromArray img_arr2.SetArray( self.npz_data) # 把array_data塞到vtkImageImportFromArray(array_data) img_arr2.SetDataSpacing(spacing) # 设置spacing img_arr2.SetDataOrigin(origin) # 设置vtk数据的坐标系原点 img_arr2.Update() srange = img_arr2.GetOutput().GetScalarRange() min2 = srange[0] max2 = srange[1] diff2 = max2 - min2 # 体数据极差 inter2 = 5000 / diff2 shift2 = -min2 # 可以加,不能减,人体内外分割处 shifter2 = vtk.vtkImageShiftScale( ) # 对偏移和比例参数来对图像数据进行操作 数据转换,之后直接调用shifter shifter2.SetShift(shift2) shifter2.SetScale(inter2) shifter2.SetOutputScalarTypeToUnsignedShort() shifter2.SetInputData(img_arr2.GetOutput()) shifter2.ReleaseDataFlagOff() shifter2.Update() volumeMapper4 = vtk.vtkGPUVolumeRayCastMapper( ) # 映射器volumnMapper使用vtk的管线投影算法 volumeMapper4.SetInputData( shifter2.GetOutput()) # 向映射器中输入数据:shifter(预处理之后的数据) volume4 = vtk.vtkVolume() # 演员 volume4.SetMapper(volumeMapper4) volume4.SetProperty(volumeProperty) ren4.AddVolume(volume4) # 添加演员和外壳 ren4.AddActor(outlineActor2) renWin.AddRenderer(ren4) # 第四个窗口完成 iren.Initialize() renWin.Render() renWin.SetWindowName("Medical Image Air V1.0") iren.Start()
import vtk data = vtk.vtkXMLImageDataReader() data.SetFileName("fuel.vti") data.Update() dataset = data.GetOutput() planeWidget = vtk.vtkPlaneWidget() planeWidget.SetInput(dataset) planeWidget.NormalToZAxisOn() planeWidget.SetResolution(20) planeWidget.SetRepresentationToOutline() planeWidget.PlaceWidget([0, 63, 0, 63, 0, 63]) planeWidget.SetHandleSize(planeWidget.GetHandleSize() * 0.5) planeWidget.GetPlaneProperty().SetColor(1, 0, 0) planeWidget.GetHandleProperty().SetColor(0, 1, 0) plane = vtk.vtkPlane() planeWidget.GetPlane(plane) clip = vtk.vtkClipVolume() clip.SetClipFunction(plane) clip.SetInputConnection(data.GetOutputPort()) cut = vtk.vtkCutter() cut.SetInputConnection(data.GetOutputPort()) cut.SetCutFunction(plane) iso = vtk.vtkContourFilter() iso.SetInputConnection(cut.GetOutputPort()) iso.SetNumberOfContours(8)
import vtk data = vtk.vtkXMLImageDataReader() data.SetFileName("/Users/y1275963/Documents/homework/ScivisDemos/fuel.vti") data.Update() dataset = data.GetOutput() planeWidget = vtk.vtkPlaneWidget() planeWidget.SetInput(dataset) planeWidget.NormalToZAxisOn() planeWidget.SetResolution(20) planeWidget.SetRepresentationToOutline() planeWidget.PlaceWidget([0,63, 0,63, 0,63]) planeWidget.SetHandleSize(planeWidget.GetHandleSize() * 0.5) planeWidget.GetPlaneProperty().SetColor(0,0,0) planeWidget.GetHandleProperty().SetColor(0,1,0) plane = vtk.vtkPlane() planeWidget.GetPlane(plane) clip = vtk.vtkClipVolume() clip.SetClipFunction(plane) clip.SetInputConnection(data.GetOutputPort()) cut = vtk.vtkCutter() cut.SetInputConnection(data.GetOutputPort()) cut.SetCutFunction(plane) iso = vtk.vtkContourFilter() iso.SetInputConnection(cut.GetOutputPort()) iso.SetNumberOfContours(8)
def initPlaneWidgets(self, index): qDebug('initPlaneWidgets()') center, htrans = self.getReferencePosition(index) hw = self.imgWidth shw = self.worldScale * hw source = vtk.vtkPlaneSource() source.SetOrigin(0, 0, 0) source.SetPoint1(shw, 0, 0) source.SetPoint2(0, shw, 0) transform = vtk.vtkTransform() mat = vtk.vtkMatrix4x4() for i in range(4): for j in range(4): mat.SetElement(i, j, htrans[i, j]) # Should transformation also be scaled?? for i in range(3): mat.SetElement(i, 3, self.worldScale * mat.GetElement(i, 3)) transform.SetMatrix(mat) transform.Update() origin = source.GetOrigin() origin = transform.TransformPoint(origin) source.SetOrigin(origin) p1 = source.GetPoint1() p1 = transform.TransformPoint(p1) source.SetPoint1(p1) p2 = source.GetPoint2() p2 = transform.TransformPoint(p2) source.SetPoint2(p2) source.Update() source.SetCenter(self.worldScale * center) source.Update() # Test position good for slice 17 (HACK) if (IOUSFAN): source.SetOrigin(-36.00039424299387, 58.447421532729656, 116.93018531955384) source.SetPoint1(13.731795848152041, 54.203001711976306, 119.87877296847647) source.SetPoint2(-40.18599847580337, 8.635225461941415, 115.82300881527104) source.Update() self.planeSources.append(source) ##################################### # Blue reference plane ##################################### # mapper if self.showReferencePlane: mapper0 = vtk.vtkPolyDataMapper() mapper0.SetInputConnection(source.GetOutputPort()) # actor refActor = vtk.vtkActor() refActor.SetMapper(mapper0) prop = refActor.GetProperty() prop.SetColor(blue) prop.SetOpacity(self.opacity) self.refplanes.append(refActor) self.renderer.AddActor(refActor) else: self.refplanes.append(None) ##################################### # Compute contours, tubes and clipping ##################################### tubes, oldContours = self.computeContoursAndTubes(source) edgeMapper = vtk.vtkPolyDataMapper() edgeMapper.ScalarVisibilityOff() edgeMapper.SetInputConnection(tubes.GetOutputPort()) planes = self.computeClippingPlanes(source) edgeMapper.SetClippingPlanes(planes) actor = vtk.vtkActor() actor.SetMapper(edgeMapper) prop = actor.GetProperty() prop.SetColor(green) prop.SetLineWidth(3) self.contours.append(actor) self.renderer.AddActor(actor) ################################################### # Plane widget for interaction ################################################### planeWidget = vtk.vtkPlaneWidget() planeWidget.SetInteractor(self.interactor) planeWidget.SetOrigin(source.GetOrigin()) planeWidget.SetPoint1(source.GetPoint1()) planeWidget.SetPoint2(source.GetPoint2()) prop = planeWidget.GetHandleProperty() prop.SetColor(QLiverViewer.colors.GetColor3d("Red")) prop = planeWidget.GetPlaneProperty() prop.SetColor(QLiverViewer.colors.GetColor3d("Red")) # Original position and orientation of reference plane self.lastPositions['reset'][index] = [ planeWidget.GetOrigin(), planeWidget.GetPoint1(), planeWidget.GetPoint2(), planeWidget.GetCenter(), np.array(planeWidget.GetNormal()) ] # Redundant print('normal') print(planeWidget.GetNormal()) planeWidget.SetEnabled(1) planeWidget.AddObserver(vtk.vtkCommand.EndInteractionEvent, self.onWidgetMoved, 1.0) attempt = vtk.vtkActor() self.fullcontours.append(oldContours) mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(oldContours) attempt.SetMapper(mapper) attempt.GetProperty().SetColor(red) self.userAttempts.append(attempt) self.renderer.AddActor(attempt) lastNormal = planeWidget.GetNormal() lastAxis1 = vtk.vtkVector3d() vtk.vtkMath.Subtract(planeWidget.GetPoint1(), planeWidget.GetOrigin(), lastAxis1) lastOrigin = planeWidget.GetCenter() self.lastPositions['origin'][index] = lastOrigin self.lastPositions['normal'][index] = lastNormal self.lastPositions['axis1'][index] = lastAxis1 self.planeWidgets.append(planeWidget) self.render_window.Render()