Beispiel #1
0
    def updateSegmentation(self, contours):
        self.lastUSContours = contours

        edgeMapper = vtk.vtkPolyDataMapper()
        edgeMapper.SetInputData(self.lastUSContours)

        if self.usActor is not None:
            self.viewer3D.interactor.Disable()
            self.viewer3D.planeWidgets[0].GetDefaultRenderer().RemoveActor(
                self.usActor)
            self.viewer3D.interactor.Enable()

        # Add contours in 3D space (should be misaligned!!!!)
        self.usActor = vtk.vtkActor()
        self.usActor.SetMapper(edgeMapper)
        prop = self.usActor.GetProperty()
        renderLinesAsTubes(prop)
        prop.SetPointSize(4)
        prop.SetLineWidth(3)
        prop.SetColor(red)
        self.viewer3D.planeWidgets[0].GetDefaultRenderer().AddActor(
            self.usActor)

        # Add overlay to 2D ultrasound
        self.viewUS[1].AddOverlay(contours)
        self.Render()
    def updateSegmentation(self, contours):
        self.lastUSContours = contours
        edgeMapper = vtk.vtkPolyDataMapper()
        edgeMapper.SetInputData(self.lastUSContours)

        if self.usOverlayActor is not None:
            self.viewer3D.interactor.Disable()
            self.viewer3D.planeWidgets[0].GetDefaultRenderer().RemoveActor(
                self.usOverlayActor)
            self.viewer3D.interactor.Enable()
            self.usOverlayActor = None

        # Add contours in 3D space (misaligned)
        self.usOverlayActor = vtk.vtkActor()
        self.usOverlayActor.SetMapper(edgeMapper)
        prop = self.usOverlayActor.GetProperty()
        renderLinesAsTubes(prop)
        prop.SetPointSize(4)
        prop.SetLineWidth(3)

        # US contours move opposite of CT contours (was .GetInverse)
        self.usOverlayActor.SetUserTransform(self.alignment)
        self.viewer3D.planeWidgets[0].GetDefaultRenderer().AddActor(
            self.usOverlayActor)

        # Add overlay to 2D ultrasound
        self.viewUS[1].AddOverlay(contours)
        self.btnReg.setEnabled(True)
        self.Render()
Beispiel #3
0
    def InitializeContours(self, contourData, color=yellow):
        # Disable interactor
        self.viewer.GetRenderWindow().GetInteractor().Disable()

        if self.contourActor is not None:
            self.viewer.GetRenderer().RemoveActor(self.contourActor)
            self.contourActor = None

        # Update contours
        self.plane = vtk.vtkPlane()
        RCW = self.viewer.GetResliceCursorWidget()
        ps = RCW.GetResliceCursorRepresentation().GetPlaneSource()
        self.plane.SetOrigin(ps.GetOrigin())
        normal = ps.GetNormal()
        self.plane.SetNormal(normal)

        # We ignore empty ouput (in C++)

        # Transform polydata according to misplacement
        self.transformPolyDataFilter = vtk.vtkTransformPolyDataFilter()
        self.transformPolyDataFilter.SetInputConnection(
            contourData.GetOutputPort())
        self.transformPolyDataFilter.SetTransform(self.transform)

        # Generate line segments
        self.cutEdges = vtk.vtkCutter()
        self.cutEdges.SetInputConnection(
            self.transformPolyDataFilter.GetOutputPort())
        self.cutEdges.SetCutFunction(self.plane)
        self.cutEdges.GenerateCutScalarsOff()
        self.cutEdges.SetValue(0, 0.5)
        self.cutEdges.Update()

        # Put together into polylines
        self.cutStrips = vtk.vtkStripper()
        self.cutStrips.SetInputConnection(self.cutEdges.GetOutputPort())
        self.cutStrips.Update()

        edgeMapper = vtk.vtkPolyDataMapper()
        edgeMapper.SetInputConnection(self.cutStrips.GetOutputPort())

        self.contourActor = vtk.vtkActor()
        self.contourActor.SetMapper(edgeMapper)
        prop = self.contourActor.GetProperty()
        renderLinesAsTubes(prop)
        prop.SetColor(color)

        # Add actor to renderer
        self.viewer.GetRenderer().AddViewProp(self.contourActor)

        # Enable interactor again
        self.viewer.GetRenderWindow().GetInteractor().Enable()
Beispiel #4
0
    def InitializeContours(self, data, color=yellow):
        self.data = data

        # Disable interactor
        self.viewer.GetRenderWindow().GetInteractor().Disable()

        if self.contourActor is not None:
            self.viewer.GetRenderer().RemoveActor(self.contourActor)
            self.contourActor = None

        # Update contours
        self.plane = vtk.vtkPlane()
        RCW = self.viewer.GetResliceCursorWidget()
        ps = RCW.GetResliceCursorRepresentation().GetPlaneSource()
        self.plane.SetOrigin(ps.GetOrigin())
        normal = ps.GetNormal()
        self.plane.SetNormal(normal)

        # Generate line segments
        self.cutEdges = vtk.vtkCutter()
        self.cutEdges.SetInputConnection(self.data.GetOutputPort())
        self.cutEdges.SetCutFunction(self.plane)
        self.cutEdges.GenerateCutScalarsOff()
        self.cutEdges.SetValue(0, 0.5)

        # Put together into polylines
        cutStrips = vtk.vtkStripper()
        cutStrips.SetInputConnection(self.cutEdges.GetOutputPort())
        cutStrips.Update()

        edgeMapper = vtk.vtkPolyDataMapper()
        edgeMapper.SetInputConnection(cutStrips.GetOutputPort())

        # Attach observer to mapper
        edgeMapper.AddObserver(vtk.vtkCommand.UpdateEvent, myCallback)

        self.contourActor = vtk.vtkActor()
        self.contourActor.SetMapper(edgeMapper)
        prop = self.contourActor.GetProperty()
        renderLinesAsTubes(prop)
        prop.SetColor(color)  # If Scalars are extracted - they turn green

        # Move in front of image (is this necessary?)
        transform = vtk.vtkTransform()
        transform.Translate(normal)
        self.contourActor.SetUserTransform(transform)

        # Add actor to renderer
        self.viewer.GetRenderer().AddViewProp(self.contourActor)

        # Enable interactor again
        self.viewer.GetRenderWindow().GetInteractor().Enable()
Beispiel #5
0
    def __init__(self, parent=None, axes=[0, 1, 2]):
        super(Viewer2DStacked, self).__init__(parent)
        # Create signal
        #planesModified = pyEvent()
        for i in range(len(axes)):
            widget = Viewer2D(self, axes[i])
            self.addWidget(widget)

        # Add corner buttons
        fileName = ['./S00.png', './C00.png', './A00.png']
        for i in range(self.count()):
            reader = vtk.vtkPNGReader()
            reader.SetFileName(fileName[(axes[i] + 1) % 3])
            reader.Update()
            texture = reader.GetOutput()
            self.widget(i).AddCornerButton(texture)

        # TODO: Add function to 2D view to assign a callback for button
        for i in range(self.count()):
            self.widget(i).buttonWidget.AddObserver(
                vtk.vtkCommand.StateChangedEvent, self.btnViewChangeClicked)

        # Make all views share the same cursor object
        for i in range(self.count()):
            self.widget(i).viewer.SetResliceCursor(
                self.widget(0).viewer.GetResliceCursor())

        # Cursor representation (anti-alias)
        for i in range(self.count()):
            for j in range(3):
                prop = self.widget(i).viewer.GetResliceCursorWidget(
                ).GetResliceCursorRepresentation().GetResliceCursorActor(
                ).GetCenterlineProperty(j)
                renderLinesAsTubes(prop)
        for i in range(self.count()):
            color = [0.0, 0.0, 0.0]
            color[axes[i]] = 1
            for j in range(3):
                color[j] = color[j] / 4.0
            self.widget(i).viewer.GetRenderer().SetBackground(color)
            self.widget(i).interactor.Disable()

        # Make them all share the same color map.
        for i in range(self.count()):
            self.widget(i).viewer.SetLookupTable(
                self.widget(0).viewer.GetLookupTable())
Beispiel #6
0
    def SetupPlaneWidgets(self):
        picker = vtk.vtkCellPicker()
        picker.SetTolerance(0.005)
        pwTextureProp = vtk.vtkProperty()
        for i in range(3):
            pw = vtk.vtkImagePlaneWidget()
            pw.SetInteractor(self.interactor)
            pw.SetPicker(picker)
            pw.RestrictPlaneToVolumeOn()
            color = [0.0, 0.0, 0.0]
            color[i] = 1
            pw.GetPlaneProperty().SetColor(color)
            pw.SetTexturePlaneProperty(pwTextureProp)
            pw.TextureInterpolateOn()
            pw.SetResliceInterpolateToLinear()
            pw.DisplayTextOn()
            pw.SetDefaultRenderer(self.renderer)

            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()
            self.planeWidgets.append(pw)
Beispiel #7
0
    def AddOverlay(self, polyData):
        # TODO: Add node to position in 3D
        self.viewer.GetRenderWindow().GetInteractor().Disable()
        if self.overlay is not None:
            self.viewer.GetRenderer().RemoveActor(self.overlay)
            self.overlay = None
        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputData(polyData)
        self.overlay = vtk.vtkActor()
        self.overlay.SetMapper(mapper)
        prop = self.overlay.GetProperty()
        renderLinesAsTubes(prop)
        prop.SetColor(red)
        mapper.ScalarVisibilityOff()

        RCW = self.viewer.GetResliceCursorWidget()
        ps = RCW.GetResliceCursorRepresentation().GetPlaneSource()
        normal = ps.GetNormal()
        transform = vtk.vtkTransform()
        transform.Translate(1.1 * normal[0], 1.1 * normal[1], 1.1 * normal[2])
        self.overlay.SetUserTransform(transform)

        self.viewer.GetRenderer().AddActor(self.overlay)
        self.viewer.GetRenderWindow().GetInteractor().Enable()
Beispiel #8
0
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
Beispiel #9
0
def main(argv):
  if os.name == 'nt':
    VTK_DATA_ROOT = "c:/VTK82/build_Release/ExternalData/Testing/"
  else:
    VTK_DATA_ROOT = "/home/jmh/"

  if 1:
    v16 = vtk.vtkMetaImageReader()
    v16.SetFileName("/home/jmh/github/fis/data/Abdomen/CT-Abdomen.mhd")
    v16.Update()
  elif 0:
    fname = os.path.join(VTK_DATA_ROOT, "Data/headsq/quarter")
    v16 = vtk.vtkVolume16Reader()
    v16.SetDataDimensions(64, 64)
    v16.SetDataByteOrderToLittleEndian()
    v16.SetImageRange(1, 93)
    v16.SetDataSpacing(3.2, 3.2, 1.5)
    v16.SetFilePrefix(fname)
    v16.ReleaseDataFlagOn()
    v16.SetDataMask(0x7fff)
    v16.Update()
  else:
    v16 = vtk.vtkMetaImageReader()
    v16.SetFileName("c:/github/fis/data/Abdomen/CT-Abdomen.mhd")
    v16.Update()

  rng = v16.GetOutput().GetScalarRange()

  shifter = vtk.vtkImageShiftScale()
  shifter.SetShift(-1.0*rng[0])
  shifter.SetScale(255.0/(rng[1]-rng[0]))
  shifter.SetOutputScalarTypeToUnsignedChar()
  shifter.SetInputConnection(v16.GetOutputPort())
  shifter.ReleaseDataFlagOff()
  shifter.Update()

 
  ImageViewer = vtk.vtkImageViewer2()
  ImageViewer.SetInputData(shifter.GetOutput())
  ImageViewer.SetColorLevel(127)
  ImageViewer.SetColorWindow(255)

  iren = vtk.vtkRenderWindowInteractor()
  ImageViewer.SetupInteractor(iren)

  ImageViewer.Render()
  ImageViewer.GetRenderer().ResetCamera()

  ImageViewer.Render()    
 
  dims = v16.GetOutput().GetDimensions()

  global minArea
  spacing = v16.GetOutput().GetSpacing()
  minArea = ( spacing[0] * spacing[1] ) / 0.1

  # Slider screen representation
  SliderRepres = vtk.vtkSliderRepresentation2D()
  _min = ImageViewer.GetSliceMin()
  _max = ImageViewer.GetSliceMax()
  SliderRepres.SetMinimumValue(_min)
  SliderRepres.SetMaximumValue(_max)
  SliderRepres.SetValue(int((_min + _max) / 2))
  SliderRepres.SetTitleText("Slice")
  SliderRepres.GetPoint1Coordinate().SetCoordinateSystemToNormalizedDisplay()
  SliderRepres.GetPoint1Coordinate().SetValue(0.3, 0.05)
  SliderRepres.GetPoint2Coordinate().SetCoordinateSystemToNormalizedDisplay()
  SliderRepres.GetPoint2Coordinate().SetValue(0.7, 0.05)
  SliderRepres.SetSliderLength(0.02)
  SliderRepres.SetSliderWidth(0.03)
  SliderRepres.SetEndCapLength(0.01)
  SliderRepres.SetEndCapWidth(0.03)
  SliderRepres.SetTubeWidth(0.005)
  SliderRepres.SetLabelFormat("%3.0lf")
  SliderRepres.SetTitleHeight(0.02)
  SliderRepres.SetLabelHeight(0.02)

  # Slider widget
  SliderWidget = vtk.vtkSliderWidget()
  SliderWidget.SetInteractor(iren)
  SliderWidget.SetRepresentation(SliderRepres)
  SliderWidget.KeyPressActivationOff()
  SliderWidget.SetAnimationModeToAnimate()
  SliderWidget.SetEnabled(True)
 
  SliderCb = vtkSliderCallback()
  SliderCb.SetImageViewer(ImageViewer)
  SliderWidget.AddObserver(vtk.vtkCommand.InteractionEvent, SliderCb.Execute)  

  ImageViewer.SetSlice(int(SliderRepres.GetValue()))

  # Contour representation - responsible for placement of points, calculation of lines and contour manipulation
  global rep
  rep = vtk.vtkOrientedGlyphContourRepresentation()
  # vtkContourRepresentation has GetActiveNodeWorldPostion/Orientation
  rep.GetProperty().SetOpacity(0) #1
  prop = rep.GetLinesProperty()
  from vtkUtils import renderLinesAsTubes
  from vtk.util.colors import red, green, pink, yellow
  renderLinesAsTubes(prop)
  prop.SetColor(yellow)
  propActive = rep.GetActiveProperty()
  #propActive.SetOpacity(0) # 2
  
  renderLinesAsTubes(propActive)

  propActive.SetColor(green)
  shapeActive = rep.GetActiveCursorShape()

  warp = vtk.vtkWarpVector()
  warp.SetInputData(shapeActive)
  warp.SetInputArrayToProcess(0, 0, 0,
                              vtk.vtkDataObject.FIELD_ASSOCIATION_POINTS,
                              vtk.vtkDataSetAttributes.NORMALS)
  scale = 0.4
  warp.SetScaleFactor(scale)
  warp.Update()
  rep.SetActiveCursorShape(warp.GetOutput())

  # Use vtkContourTriangulator to fill contours

  # Point placer
  imageActorPointPlacer = vtk.vtkImageActorPointPlacer()
  imageActorPointPlacer.SetImageActor(ImageViewer.GetImageActor())
  rep.SetPointPlacer(imageActorPointPlacer)

  global ContourWidget
  # Contour widget - has a  vtkWidgetEventTranslator which translate events to vtkContourWidget events
  ContourWidget = vtk.vtkContourWidget()
  ContourWidget.SetRepresentation(rep)
  ContourWidget.SetInteractor(iren)
  ContourWidget.SetEnabled(True)
  ContourWidget.ProcessEventsOn()
  ContourWidget.ContinuousDrawOn()

  # Can be Initialize() using polydata

  # Override methods that returns display position to get an overlay
  # (display postions) instead of computing it from world position and
  # the method BuildLines to interpolate using display positions
  # instead of world positions

  # Thinning of contour control points
  # AddFinalPointAction
  ContourWidget.AddObserver(vtk.vtkCommand.EndInteractionEvent, callback)



  if 0:
    # TODO: Make interior transparent
    contour = ContourWidget.GetContourRepresentation().GetContourRepresentationAsPolyData()
    tc = vtk.vtkContourTriangulator()
    tc.SetInputData(contour)
    tc.Update()

    # Extrusion towards camera
    extruder = vtk.vtkLinearExtrusionFilter()
    extruder.CappingOn()
    extruder.SetScalaFactor(1.0)
    extruder.SetInputData(tc.GetOutput())
    extruder.SetVector(0,0,1.0)
    extruder.SetExtrusionTypeToNormalExtrusion()
    
    polyMapper = vtk.vtkPolyMapper()
    polyMapper.SetInputConnection(extruder.GetOutputPort())
    polyMapper.ScalarVisibilityOn()
    polyMapper.Update()
    polyActor = vtk.vtkActor()
    polyActor.SetMapper(polyMapper)
    prop = polyActor.GetProperty()
    prop.SetColor(0,1,0)
    #prop.SetRepresentationToWireframe()
    renderer.AddActor(polyActor)
    renderer.GetRenderWindow().Render()
  


  iren.Start()
Beispiel #10
0
    def setup(self):
        self.setupUi(self)

        loadAct = QAction('&Open', self)
        loadAct.setShortcut('Ctrl+O')
        loadAct.setStatusTip('Load data')
        loadAct.triggered.connect(self.onLoadClicked)

        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(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()

        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)

            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)

        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
        self.stack = QStackedWidget(self)
        self.stack.addWidget(self.vtk_widgets[0])
        self.stack.addWidget(self.vtk_widgets[1])
        self.stack.addWidget(self.vtk_widgets[2])

        vert_layout0 = QVBoxLayout()
        horz_splitter0 = QSplitter(Qt.Horizontal)
        horz_splitter0.addWidget(self.stack)
        horz_splitter0.addWidget(self.vtk_widgets[3])
        vert_layout0.addWidget(horz_splitter0)
        vert_layout0.setContentsMargins(0, 0, 0, 0)
        self.vtk_panel.setLayout(vert_layout0)

        layout = QVBoxLayout()
        self.btn = QPushButton("Next")
        layout.addWidget(self.btn)
        self.frame.setLayout(layout)
        self.btn.clicked.connect(self.onPlaneClicked)
Beispiel #11
0
    def setup(self):
        self.setupUi(self)
        self.setupMenu()
        style = QCommonStyle()
        self.btnUpAzimuth.setIcon(style.standardIcon(QStyle.SP_ArrowUp))
        self.btnDownAzimuth.setIcon(style.standardIcon(QStyle.SP_ArrowDown))
        self.btnRightAzimuth.setIcon(style.standardIcon(
            QStyle.SP_ArrowForward))
        self.btnLeftAzimuth.setIcon(style.standardIcon(QStyle.SP_ArrowBack))

        self.btnUpElevation.setIcon(style.standardIcon(QStyle.SP_ArrowUp))
        self.btnDownElevation.setIcon(style.standardIcon(QStyle.SP_ArrowDown))
        self.btnRightElevation.setIcon(
            style.standardIcon(QStyle.SP_ArrowForward))
        self.btnLeftElevation.setIcon(style.standardIcon(QStyle.SP_ArrowBack))

        self.centralWidget().layout().setContentsMargins(0, 0, 0, 0)
        self.statusBar().hide()

        all_widgets = QApplication.instance().allWidgets()
        for widget in all_widgets:
            if type(widget) == QSplitter:
                widget.setStyleSheet(""
                                     " QSplitter::handle:horizontal { "
                                     "    border: 1px outset darkgrey "
                                     " } "
                                     " QSplitter::handle:vertical{ "
                                     "    border: 1px outset darkgrey "
                                     " } ")
                widget.setHandleWidth(2)  # Default is 3
        # Setup 3D viewer
        self.viewer3D = Viewer3D(self)
        self.viewer3D.AddPlaneCornerButtons()

        self.layout3D.setContentsMargins(0, 0, 0, 0)
        self.layout3D.addWidget(self.viewer3D)

        # Setup CT viewer
        self.stackCT = Viewer2DStacked(self)
        self.layoutCT.setContentsMargins(0, 0, 0, 0)
        self.layoutCT.insertWidget(0, self.stackCT)

        # Setup US views
        self.viewUS = []
        self.viewUS.append(Viewer2D(self, 1))
        self.viewUS.append(Viewer2D(self, 2))

        # Make all views share the same cursor object
        for i in range(2):
            self.viewUS[i].viewer.SetResliceCursor(
                self.viewUS[0].viewer.GetResliceCursor())

        # Cursor representation (anti-alias)
        for i in range(len(self.viewUS)):
            for j in range(3):
                prop = self.viewUS[i].viewer.GetResliceCursorWidget(
                ).GetResliceCursorRepresentation().GetResliceCursorActor(
                ).GetCenterlineProperty(j)
                renderLinesAsTubes(prop)

        # Remove when stacked works for 2 images
        for i in range(len(self.viewUS)):
            # Set background for 2D views
            color = [0.0, 0.0, 0.0]
            color[self.viewUS[i].iDim] = 1
            for j in range(3):
                color[j] = color[j] / 4.0
            self.viewUS[i].viewer.GetRenderer().SetBackground(color)
            self.viewUS[i].interactor.Disable()

        self.establishCallbacks()

        # Show widgets but hide non-existing data
        for i in range(self.stackCT.count()):
            self.stackCT.widget(i).show()
            self.stackCT.widget(i).viewer.GetImageActor().SetVisibility(False)

        # Show widgets but hide non-existing data
        for i in range(len(self.viewUS)):
            self.viewUS[i].show()
            self.viewUS[i].viewer.GetImageActor().SetVisibility(False)

        self.layoutUS0.setContentsMargins(0, 0, 0, 0)
        self.layoutUS0.insertWidget(0, self.viewUS[0])
        self.layoutUS1.setContentsMargins(0, 0, 0, 0)
        self.layoutUS1.insertWidget(0, self.viewUS[1])
Beispiel #12
0
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 setup(self):
        self.setupUi(self)
        self.setupMenu()
        """
    style = QCommonStyle()
    self.btnUpAzimuth.setIcon(style.standardIcon(QStyle.SP_ArrowUp))
    self.btnDownAzimuth.setIcon(style.standardIcon(QStyle.SP_ArrowDown))
    self.btnRightAzimuth.setIcon(style.standardIcon(QStyle.SP_ArrowForward))
    self.btnLeftAzimuth.setIcon(style.standardIcon(QStyle.SP_ArrowBack))
    self.btnResetAzimuth.setIcon(style.standardIcon(QStyle.SP_BrowserStop))

    self.btnUpElevation.setIcon(style.standardIcon(QStyle.SP_ArrowUp))
    self.btnDownElevation.setIcon(style.standardIcon(QStyle.SP_ArrowDown))
    self.btnRightElevation.setIcon(style.standardIcon(QStyle.SP_ArrowForward))
    self.btnLeftElevation.setIcon(style.standardIcon(QStyle.SP_ArrowBack))
    self.btnResetElevation.setIcon(style.standardIcon(QStyle.SP_BrowserStop))
    """
        # Add misalignment
        vert_layout = self.verticalLayout
        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)

        self.centralWidget().layout().setContentsMargins(0, 0, 0, 0)
        self.statusBar().hide()

        all_widgets = QApplication.instance().allWidgets()
        for widget in all_widgets:
            if type(widget) == QSplitter:
                widget.setStyleSheet(""
                                     " QSplitter::handle:horizontal { "
                                     "    border: 1px outset darkgrey "
                                     " } "
                                     " QSplitter::handle:vertical{ "
                                     "    border: 1px outset darkgrey "
                                     " } ")
                widget.setHandleWidth(2)  # Default is 3
        # Setup 3D viewer
        self.viewer3D = Viewer3D(self,
                                 showOrientation=True,
                                 showPlaneTextActors=False)
        self.viewer3D.AddPlaneCornerButtons()

        self.layout3D.setContentsMargins(0, 0, 0, 0)
        self.layout3D.addWidget(self.viewer3D)

        # Setup CT viewer
        self.stackCT = Viewer2DStacked(self)
        self.layoutCT.setContentsMargins(0, 0, 0, 0)
        self.layoutCT.insertWidget(0, self.stackCT)

        # Setup US views
        self.viewUS = []
        self.viewUS.append(Viewer2D(self, 1))
        self.viewUS.append(Viewer2D(self, 2))

        # Make all views share the same cursor object
        for i in range(2):
            self.viewUS[i].viewer.SetResliceCursor(
                self.viewUS[0].viewer.GetResliceCursor())

        # Make them all share the same color map.
        for i in range(2):
            self.viewUS[i].viewer.SetLookupTable(
                self.viewUS[0].viewer.GetLookupTable())

        # Cursor representation (anti-alias)
        for i in range(len(self.viewUS)):
            for j in range(3):
                prop = self.viewUS[i].viewer.GetResliceCursorWidget(
                ).GetResliceCursorRepresentation().GetResliceCursorActor(
                ).GetCenterlineProperty(j)
                renderLinesAsTubes(prop)

        # Remove when stacked works for 2 images
        for i in range(len(self.viewUS)):
            # Set background for 2D views
            color = [0.0, 0.0, 0.0]
            color[self.viewUS[i].iDim] = 1
            for j in range(3):
                color[j] = color[j] / 4.0
            self.viewUS[i].viewer.GetRenderer().SetBackground(color)
            self.viewUS[i].interactor.Disable()

        self.establishCallbacks()

        # Show widgets but hide non-existing data
        for i in range(self.stackCT.count()):
            self.stackCT.widget(i).show()
            self.stackCT.widget(i).viewer.GetImageActor().SetVisibility(False)

        # Show widgets but hide non-existing data
        for i in range(len(self.viewUS)):
            self.viewUS[i].show()
            self.viewUS[i].viewer.GetImageActor().SetVisibility(False)

        self.layoutUS0.setContentsMargins(0, 0, 0, 0)
        self.layoutUS0.insertWidget(0, self.viewUS[0])
        self.layoutUS1.setContentsMargins(0, 0, 0, 0)
        self.layoutUS1.insertWidget(0, self.viewUS[1])