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