def create3dView(self, viewOwnerNode): """ :param viewOwnerNode: ownerNode manages this view instead of the layout manager (it can be any node in the scene) """ viewLayoutName = "BitmapGenerator" # layout label is usually shorter than the full layout name, but in this case it helps if it is # obvious that the widget belongs to this module viewLayoutLabel = "BitmapGenerator" # Retrieve or create MRML view node if not self.threeDViewNode: self.threeDViewNode = slicer.mrmlScene.GetSingletonNode("BitmapGenerator","vtkMRMLViewNode") if not self.threeDViewNode: self.threeDViewNode = slicer.mrmlScene.CreateNodeByClass("vtkMRMLViewNode") self.threeDViewNode.UnRegister(None) self.threeDViewNode.SetSingletonTag("BitmapGenerator") self.threeDViewNode.SetName(viewLayoutName) self.threeDViewNode.SetLayoutName(viewLayoutName) self.threeDViewNode.SetLayoutLabel(viewLayoutLabel) self.threeDViewNode.SetLayoutColor(1, 1, 0) self.threeDViewNode.SetAndObserveParentLayoutNodeID(viewOwnerNode.GetID()) self.threeDViewNode = slicer.mrmlScene.AddNode(self.threeDViewNode) # Create widget if not self.threeDWidget: self.threeDWidget = slicer.qMRMLThreeDWidget() self.threeDWidget.setObjectName("ThreeDWidget"+self.threeDViewNode.GetLayoutLabel()) self.threeDWidget.viewLabel = self.threeDViewNode.GetLayoutLabel() self.threeDWidget.viewColor = qt.QColor.fromRgbF(*self.threeDViewNode.GetLayoutColor()) self.threeDWidget.setMRMLScene(slicer.mrmlScene) self.threeDWidget.setMRMLViewNode(self.threeDViewNode)
def createWindows(self): self.stereoMode = self.stereoCheckBox.isChecked() # Create widgets to hold windows self.leftWidgets = qt.QWidget() self.leftWidgets.setWindowTitle("SlicerCubeMap - Left") leftWidgetsLayout = qt.QHBoxLayout() leftWidgetsLayout.setSpacing(0) leftWidgetsLayout.setContentsMargins(0,0,0,0) self.leftWidgets.setLayout(leftWidgetsLayout) self.rightWidgets = qt.QWidget() self.rightWidgets.setWindowTitle("SlicerCubeMap - Right") rightWidgetsLayout = qt.QHBoxLayout() rightWidgetsLayout.setSpacing(0) rightWidgetsLayout.setContentsMargins(0,0,0,0) self.rightWidgets.setLayout(rightWidgetsLayout) # Per cube face per eye leftFaces = ["lpx", "lnz", "lnx", "lpz", "lpy", "lny"] rightFaces = ["rpx", "rnz", "rnx", "rpz", "rpy", "rny"] slicer.mrmlScene.AddNode(slicer.vtkMRMLViewNode()) # There's some wonky behaviour with the first view node created (ViewNode2?), so this terrible thing exists for now for face in leftFaces: # Initialize View Nodes view = slicer.vtkMRMLViewNode() slicer.mrmlScene.AddNode(view) self.cubeFaceViewNodes.append(view) # Initialize ThreeD Widgets threeDWidget = slicer.qMRMLThreeDWidget() threeDWidget.setFixedSize(qt.QSize(600, 600)) threeDWidget.setMRMLViewNode(view) threeDWidget.setMRMLScene(slicer.mrmlScene) threeDWidget.setWindowTitle("SlicerCubeMap - " + face) threeDWidget.children()[1].hide() # Hide widget controller bar; TODO: maybe a bit more robust self.cubeFaceThreeDWidgets[face] = threeDWidget # Set Stereo settings if (self.stereoCheckBox.isChecked()): threeDWidget.threeDView().renderWindow().StereoRenderOn() threeDWidget.threeDView().renderWindow().SetStereoTypeToLeft() threeDWidget.threeDView().renderWindow().Render() # Add to Left eye cubemap widget self.leftWidgets.layout().addWidget(threeDWidget) if (self.stereoMode is True): for face in rightFaces: # Initialize View Nodes view = slicer.vtkMRMLViewNode() slicer.mrmlScene.AddNode(view) self.cubeFaceViewNodes.append(view) # Initialize ThreeD Widgets threeDWidget = slicer.qMRMLThreeDWidget() threeDWidget.setFixedSize(qt.QSize(600, 600)) threeDWidget.setMRMLViewNode(view) threeDWidget.setMRMLScene(slicer.mrmlScene) threeDWidget.setWindowTitle("SlicerCubeMap - " + face) threeDWidget.children()[1].hide() # Hide widget controller bar; TODO: maybe a bit more robust self.cubeFaceThreeDWidgets[face] = threeDWidget # Set Stereo settings threeDWidget.threeDView().renderWindow().StereoRenderOn() threeDWidget.threeDView().renderWindow().SetStereoTypeToRight() threeDWidget.threeDView().renderWindow().Render() # Add to Right eye cubemap widget self.rightWidgets.layout().addWidget(threeDWidget) # Set background colors depending on face # Front, Left, Right, and Back retain default color gradient # Top and Bottom have opposite sides of the gradient self.cubeFaceThreeDWidgets["lny"].threeDView().setBackgroundColor(qt.QColor(193, 195, 232)) self.cubeFaceThreeDWidgets["lny"].threeDView().setBackgroundColor2(qt.QColor(193, 195, 232)) self.cubeFaceThreeDWidgets["lpy"].threeDView().setBackgroundColor(qt.QColor(116, 120, 190)) self.cubeFaceThreeDWidgets["lpy"].threeDView().setBackgroundColor2(qt.QColor(116, 120, 190)) if (self.stereoMode is True): self.cubeFaceThreeDWidgets["rny"].threeDView().setBackgroundColor(qt.QColor(193, 195, 232)) self.cubeFaceThreeDWidgets["rny"].threeDView().setBackgroundColor2(qt.QColor(193, 195, 232)) self.cubeFaceThreeDWidgets["rpy"].threeDView().setBackgroundColor(qt.QColor(116, 120, 190)) self.cubeFaceThreeDWidgets["rpy"].threeDView().setBackgroundColor2(qt.QColor(116, 120, 190))
def generate(self, volumeRenderingNode, filePattern="/tmp/slice_%04d.png"): # underscore not dash """ """ lm = slicer.app.layoutManager() # switch on the type to get the requested window # just the 3D window mainThreeDWidget = lm.threeDWidget(0).threeDView() viewNode = mainThreeDWidget.mrmlViewNode() # create the dummy threeD widget threeDWidget = slicer.qMRMLThreeDWidget() threeDWidget.resize(self.width, self.height) threeDWidget.setObjectName("ThreeDWidget%s" % viewNode.GetLayoutLabel()) threeDWidget.setMRMLScene(slicer.mrmlScene) threeDWidget.setMRMLViewNode(viewNode) self.threeDWidget = threeDWidget threeDWidget.show() # configure the view cacheViewNode = slicer.vtkMRMLViewNode() cacheViewNode.Copy(viewNode) viewNode.SetBoxVisible(0) viewNode.SetAxisLabelsVisible(0) viewNode.SetBackgroundColor((1, 1, 1)) viewNode.SetBackgroundColor2((1, 1, 1)) roi = volumeRenderingNode.GetROINode() roiCenter = [ 0, ] * 3 roiRadius = [ 0, ] * 3 roi.GetXYZ(roiCenter) roi.GetRadiusXYZ(roiRadius) roi.SetDisplayVisibility(0) camera = vtk.vtkCamera() camera.SetFocalPoint(roiCenter) camera.SetPosition(roiCenter[0], roiCenter[1], roiCenter[2] + roiRadius[2]) camera.SetViewUp((0, 1, 0)) mrmlCamera = slicer.util.getNode('Default Scene Camera') cacheCamera = vtk.vtkCamera() cacheCamera.DeepCopy(mrmlCamera.GetCamera()) mrmlCamera.GetCamera().DeepCopy(camera) viewNode.SetRenderMode(slicer.vtkMRMLViewNode.Orthographic) # cycle through the slabs slabRadius = list(roiRadius) slabRadius[2] = self.slabThickness roi.SetRadiusXYZ(slabRadius) slabCounter = 0 slabCenter = [roiCenter[0], roiCenter[1], roiCenter[2] - roiRadius[2]] slabTop = roiCenter[2] + roiRadius[2] threeDView = threeDWidget.threeDView() renderWindow = threeDView.renderWindow() self.delayDisplay("Starting render...", 300) while slabCenter[2] <= slabTop: roi.SetXYZ(slabCenter) threeDView.forceRender() windowToImage = vtk.vtkWindowToImageFilter() windowToImage.SetInput(renderWindow) writer = vtk.vtkPNGWriter() writer.SetInputConnection(windowToImage.GetOutputPort()) filePath = filePattern % slabCounter windowToImage.Update() writer.SetFileName(filePath) writer.Write() slabCounter += 1 slabCenter[2] = slabCenter[2] + self.slabSpacing # reset things viewNode.Copy(cacheViewNode) mrmlCamera.GetCamera().DeepCopy(cacheCamera) roi.SetXYZ(roiCenter) roi.SetRadiusXYZ(roiRadius) roi.SetDisplayVisibility(1)
def test_ShadedModels1(self): """ Ideally you should have several levels of tests. At the lowest level tests should exercise the functionality of the logic with different inputs (both valid and invalid). At higher levels your tests should emulate the way the user would interact with your code and confirm that it still works the way you intended. One of the most important features of the tests is that it should alert other developers when their changes will have an impact on the behavior of your module. For example, if a developer removes a feature that you depend on, your test should break so they know that the feature is needed. """ self.delayDisplay("Starting the test") import SampleData sampleDataLogic = SampleData.SampleDataLogic() print("Getting MR Head Volume") mrHeadVolume = sampleDataLogic.downloadMRHead() resize = vtk.vtkImageResize() resize.SetInputDataObject(mrHeadVolume.GetImageData()) resize.SetOutputDimensions(256,256,128) resize.Update() tdw = slicer.qMRMLThreeDWidget() tdw.setMRMLScene(slicer.mrmlScene) tdw.setMRMLViewNode(slicer.util.getNode("*ViewNode*")) tdw.show() from vtkSlicerShadedActorModuleLogicPython import * shadedActor=vtkOpenGLShadedActor() tdv = tdw.threeDView() rw = tdv.renderWindow() rens = rw.GetRenderers() ren = rens.GetItemAsObject(0) ren.AddActor(shadedActor) mapper = vtk.vtkPolyDataMapper() shadedActor.SetMapper(mapper) shadedActor.SetVertexShaderSource(""" #version 120 attribute vec3 vertexAttribute; attribute vec2 textureCoordinateAttribute; varying vec4 interpolatedColor; varying vec3 interpolatedTextureCoordinate; void main() { interpolatedColor = vec4(0.5) + vec4(vertexAttribute, 1.); interpolatedTextureCoordinate = vec3(textureCoordinateAttribute, .5); gl_Position = vec4(vertexAttribute, 1.); } """) shadedActor.SetFragmentShaderSource(""" #version 120 varying vec4 interpolatedColor; varying vec3 interpolatedTextureCoordinate; uniform sampler3D volumeSampler; void main() { gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 ); gl_FragColor = interpolatedColor; vec4 volumeSample = texture3D(volumeSampler, interpolatedTextureCoordinate); volumeSample *= 100; gl_FragColor = mix( volumeSample, interpolatedColor, 0.5); vec4 integratedRay = vec4(0.); for (int i = 0; i < 256; i++) { vec3 samplePoint = vec3(interpolatedTextureCoordinate.st, i/256.); vec4 volumeSample = texture3D(volumeSampler, samplePoint); integratedRay += volumeSample; } gl_FragColor = integratedRay; } """) shadedActor.SetTextureImageData(resize.GetOutputDataObject(0)) #shadedActor.SetTextureImageData(mrHeadVolume.GetImageData()) sphereSource = vtk.vtkSphereSource() mapper.SetInputConnection(sphereSource.GetOutputPort()) actor = vtk.vtkActor() actor.SetScale(20,20,20) actor.SetMapper(mapper) ren.AddActor(actor) rw.Render() wti = vtk.vtkWindowToImageFilter() wti.SetInput(rw) iv = vtk.vtkImageViewer() iv.SetColorLevel(128) iv.SetColorWindow(256) iv.SetInputConnection(wti.GetOutputPort()) iv.Render() extensionManager = vtk.vtkOpenGLExtensionManager() extensionManager.SetRenderWindow(rw) extensionManager.Update() print(extensionManager) print(extensionManager.GetDriverGLVendor()) print(extensionManager.GetDriverGLVersion()) print(extensionManager.GetDriverGLRenderer()) slicer.modules.ShadedModelsWidget.tdw = tdw slicer.modules.ShadedModelsWidget.iv = iv
def test_ShadedModels1(self): """ Ideally you should have several levels of tests. At the lowest level tests should exercise the functionality of the logic with different inputs (both valid and invalid). At higher levels your tests should emulate the way the user would interact with your code and confirm that it still works the way you intended. One of the most important features of the tests is that it should alert other developers when their changes will have an impact on the behavior of your module. For example, if a developer removes a feature that you depend on, your test should break so they know that the feature is needed. """ self.delayDisplay("Starting the test") import SampleData sampleDataLogic = SampleData.SampleDataLogic() print("Getting MR Head Volume") mrHeadVolume = sampleDataLogic.downloadMRHead() resize = vtk.vtkImageResize() resize.SetInputDataObject(mrHeadVolume.GetImageData()) resize.SetOutputDimensions(256, 256, 128) resize.Update() tdw = slicer.qMRMLThreeDWidget() tdw.setMRMLScene(slicer.mrmlScene) tdw.setMRMLViewNode(slicer.util.getNode("*ViewNode*")) tdw.show() from vtkSlicerShadedActorModuleLogicPython import * shadedActor = vtkOpenGLShadedActor() tdv = tdw.threeDView() rw = tdv.renderWindow() rens = rw.GetRenderers() ren = rens.GetItemAsObject(0) ren.AddActor(shadedActor) mapper = vtk.vtkPolyDataMapper() shadedActor.SetMapper(mapper) shadedActor.SetVertexShaderSource(""" #version 120 attribute vec3 vertexAttribute; attribute vec2 textureCoordinateAttribute; varying vec4 interpolatedColor; varying vec3 interpolatedTextureCoordinate; void main() { interpolatedColor = vec4(0.5) + vec4(vertexAttribute, 1.); interpolatedTextureCoordinate = vec3(textureCoordinateAttribute, .5); gl_Position = vec4(vertexAttribute, 1.); } """) shadedActor.SetFragmentShaderSource(""" #version 120 varying vec4 interpolatedColor; varying vec3 interpolatedTextureCoordinate; uniform sampler3D volumeSampler; void main() { gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 ); gl_FragColor = interpolatedColor; vec4 volumeSample = texture3D(volumeSampler, interpolatedTextureCoordinate); volumeSample *= 100; gl_FragColor = mix( volumeSample, interpolatedColor, 0.5); vec4 integratedRay = vec4(0.); for (int i = 0; i < 256; i++) { vec3 samplePoint = vec3(interpolatedTextureCoordinate.st, i/256.); vec4 volumeSample = texture3D(volumeSampler, samplePoint); integratedRay += volumeSample; } gl_FragColor = integratedRay; } """) shadedActor.SetTextureImageData(resize.GetOutputDataObject(0)) #shadedActor.SetTextureImageData(mrHeadVolume.GetImageData()) sphereSource = vtk.vtkSphereSource() mapper.SetInputConnection(sphereSource.GetOutputPort()) actor = vtk.vtkActor() actor.SetScale(20, 20, 20) actor.SetMapper(mapper) ren.AddActor(actor) rw.Render() wti = vtk.vtkWindowToImageFilter() wti.SetInput(rw) iv = vtk.vtkImageViewer() iv.SetColorLevel(128) iv.SetColorWindow(256) iv.SetInputConnection(wti.GetOutputPort()) iv.Render() extensionManager = vtk.vtkOpenGLExtensionManager() extensionManager.SetRenderWindow(rw) extensionManager.Update() print(extensionManager) print(extensionManager.GetDriverGLVendor()) print(extensionManager.GetDriverGLVersion()) print(extensionManager.GetDriverGLRenderer()) slicer.modules.ShadedModelsWidget.tdw = tdw slicer.modules.ShadedModelsWidget.iv = iv