class RotationViewer(module_template.Viewer): """Uses mayavi to plot a sphere made up of small spheres as pixels. The colors indicate the responsability density.""" def __init__(self, parent=None): super(RotationViewer, self).__init__() #self._widget = QtGui.QWidget(parent) self._vtk_widget = QVTKRenderWindowInteractor(self._widget) # _vtk_widget is actually the RenderWindowInteractor self._vtk_widget.SetInteractorStyle(vtk.vtkInteractorStyleRubberBandPick()) #self._vtk_widget.Initialize() layout = QtGui.QVBoxLayout() layout.addWidget(self._vtk_widget) self._widget.setLayout(layout) self._renderer = vtk.vtkRenderer() self._vtk_widget.GetRenderWindow().AddRenderer(self._renderer) #self._mlab_widget = embedded_mayavi.MlabWidget() self._setup_done = False self._points = None self._default_sphere_n = 10 self._sphere = vtk_tools.SphereMap(self._default_sphere_n) self._renderer.AddViewProp(self._sphere.get_actor()) self._renderer.SetBackground(1., 1., 1.) #self._renderer.Render() def initialize(self): self._vtk_widget.Initialize() # def get_widget(self): # """Return the widget containing the view.""" # return self._vtk_widget def set_sampling_n(self, sampling_n): """Rerun when the array size changes.""" self._sphere.set_n(sampling_n) def get_coordinates(self): return self._sphere.get_coordinates() def get_number_of_points(): pass def plot_rotations(self, values): """Update the viewer to show the new values.""" if len(values) != self._sphere.get_number_of_points(): #raise ValueError("values must be array of length {0}. Length {1} array received.".format(self._sphere.get_number_of_points(), len(values))) sampling_n = icosahedral_sphere.points_to_n(len(values)) self.set_sampling_n(sampling_n) self._sphere.set_lookup_table(vtk_tools.get_lookup_table(0., values.max(), log=False, colorscale="jet", number_of_colors=1000)) self._sphere.set_values(values) #self._sphere #self._renderer.Render() self._vtk_widget.Render()
def __init__(self, parent): super(WirnikVtk, self).__init__(parent) interactor = QVTKRenderWindowInteractor(self) self.layout = QtGui.QHBoxLayout() self.layout.addWidget(interactor) self.layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.layout) renderer = vtk.vtkRenderer() render_window = interactor.GetRenderWindow() render_window.AddRenderer(renderer) # Zdefiniuj sposob obracania obiektu myszka interactor.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera()) render_window.SetInteractor(interactor) renderer.SetBackground(0.2, 0.2, 0.2) # Wczytaj obiekt z pliku filename = "wirnik.stl" source = vtk.vtkSTLReader() source.SetFileName(filename) # Zdefiniuj mapper mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(source.GetOutputPort()) # Zdefiniuj aktora actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetColor(1, 1, 1) renderer.AddActor(actor) renderer.GradientBackgroundOn() # Zmien kolor tla - gradient niebiesko-bialy renderer.SetBackground(0.5, .9, 1) renderer.SetBackground2(1, 1, 1) renderer.ResetCamera() self.source = source self.mapper = mapper self.renderer = renderer self.interactor = interactor self.render_window = render_window
class Main(QtGui.QMainWindow): def resizeEvent(self, Event): pass #self.ModelView.resize(self.ui.ModelFrame.geometry().width()-15,self.ui.ModelFrame.geometry().height()-39) def __init__(self): QtGui.QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setWindowTitle( QtGui.QApplication.translate("MainWindow", "3DLP Slicer", None, QtGui.QApplication.UnicodeUTF8)) #load previous settings from config file here: self.parser = SafeConfigParser() filename = 'sliceconfig.ini' if hasattr(sys, '_MEIPASS'): # PyInstaller >= 1.6 os.chdir(sys._MEIPASS) filename = os.path.join(sys._MEIPASS, filename) APPNAME = '3DLP' APPDATA = os.path.join(os.environ['APPDATA'], APPNAME) if not os.path.isdir(os.path.join(APPDATA)): os.mkdir(os.path.join(APPDATA)) shutil.copy(filename, os.path.join(APPDATA, '')) self.parser.read(os.path.join(APPDATA, 'sliceconfig.ini')) self.LoadSettingsFromConfigFile() else: if not os.path.isfile(os.path.join(APPDATA, 'sliceconfig.ini')): shutil.copy(filename, os.path.join(APPDATA)) else: self.parser.read(os.path.join(APPDATA, 'sliceconfig.ini')) self.LoadSettingsFromConfigFile() else: #otherwise it's running in pydev environment: use the dev config file os.chdir(os.path.dirname(sys.argv[0])) filename = os.path.join(os.path.dirname(sys.argv[0]), filename) self.parser.read('sliceconfig.ini') self.LoadSettingsFromConfigFile() self.ren = vtk.vtkRenderer() self.ren.SetBackground(.4, .4, .4) # create the modelview widget self.ModelView = QVTKRenderWindowInteractor(self.ui.ModelFrame) self.ModelView.SetInteractorStyle(MyInteractorStyle()) self.ModelView.Initialize() self.ModelView.Start() self.renWin = self.ModelView.GetRenderWindow() self.renWin.AddRenderer(self.ren) self.ModelView.show() self.ModelView.resize(1006 - 17, 716 - 39) #self.ModelView.resize(self.ui.ModelFrame.geometry().width()-1,self.ui.ModelFrame.geometry().height()-1) self.modelList = [] def AddModel(self): filename = QtGui.QFileDialog.getOpenFileName(self, 'Open 3D Model', '.', '*.stl') if filename == '': #user hit cancel return modelObject = model(self, filename) self.modelList.append(modelObject) self.ui.modelList.addItem(os.path.basename(str(filename))) if len(self.modelList) == 1: self.FirstOpen() self.ren.ResetCamera() self.ModelView.Render() #update model view def FirstOpen(self): #create annotated cube anchor actor self.axesActor = vtk.vtkAnnotatedCubeActor() self.axesActor.SetXPlusFaceText('Right') self.axesActor.SetXMinusFaceText('Left') self.axesActor.SetYMinusFaceText('Front') self.axesActor.SetYPlusFaceText('Back') self.axesActor.SetZMinusFaceText('Bot') self.axesActor.SetZPlusFaceText('Top') self.axesActor.GetTextEdgesProperty().SetColor(.8, .8, .8) self.axesActor.GetZPlusFaceProperty().SetColor(.8, .8, .8) self.axesActor.GetZMinusFaceProperty().SetColor(.8, .8, .8) self.axesActor.GetXPlusFaceProperty().SetColor(.8, .8, .8) self.axesActor.GetXMinusFaceProperty().SetColor(.8, .8, .8) self.axesActor.GetYPlusFaceProperty().SetColor(.8, .8, .8) self.axesActor.GetYMinusFaceProperty().SetColor(.8, .8, .8) self.axesActor.GetTextEdgesProperty().SetLineWidth(2) self.axesActor.GetCubeProperty().SetColor(.2, .2, .2) self.axesActor.SetFaceTextScale(0.25) self.axesActor.SetZFaceTextRotation(90) #create orientation markers self.axes = vtk.vtkOrientationMarkerWidget() self.axes.SetOrientationMarker(self.axesActor) self.axes.SetInteractor(self.ModelView) self.axes.EnabledOn() self.axes.InteractiveOff() self.ui.Transform_groupbox.setEnabled(True) def SliceModel(self): try: if self.modelActor: #check to see if a model is loaded, if not it will throw an exception pass except: #self.modelActor doesn't exist (hasn't been instantiated with a model yet) QtGui.QMessageBox.critical( self, 'Error slicing model', "You must first load a model to slice it!", QtGui.QMessageBox.Ok) return self.outputFile = str( QFileDialog.getSaveFileName(self, "Save file", "", ".3dlp")) self.slicer = slicer.slicer(self) self.slicer.imageheight = int(self.imageHeight) self.slicer.imagewidth = int(self.imageWidth) # check to see if starting depth is less than ending depth!! this assumption is crucial self.slicer.startingdepth = float(self.startingDepth) self.slicer.endingdepth = float(self.endingDepth) self.slicer.layerincrement = float(self.slicingIncrement) self.slicer.OpenModel(self.filename) self.slicer.slice() def UpdateModelOpacity(self): try: if self.modelActor: #check to see if a model is loaded, if not it will throw an exception opacity, ok = QtGui.QInputDialog.getText( self, 'Model Opacity', 'Enter the desired opacity (0-100):') if not ok: #the user hit the "cancel" button return self.modelActor.GetProperty().SetOpacity(float(opacity) / 100) self.ren.Render() self.ModelView.Render() except: #self.modelActor doesn't exist (hasn't been instantiated with a model yet) QtGui.QMessageBox.critical( self, 'Error setting opacity', "You must first load a model to change its opacity!", QtGui.QMessageBox.Ok) def ModelIndexChanged(self, new, previous): modelObject = self.modelList[self.ui.modelList.currentRow()] self.ui.positionX.setValue(modelObject.CurrentXPosition) self.ui.positionY.setValue(modelObject.CurrentYPosition) self.ui.positionZ.setValue(modelObject.CurrentZPosition) self.ui.rotationX.setValue(modelObject.CurrentXRotation) self.ui.rotationY.setValue(modelObject.CurrentYRotation) self.ui.rotationZ.setValue(modelObject.CurrentZRotation) self.ui.scale.setValue(modelObject.CurrentScale) def Update_Position_X(self, position): modelObject = self.modelList[self.ui.modelList.currentRow()] transform = modelObject.transform transform.Translate((float(position) - modelObject.CurrentXPosition), 0.0, 0.0) modelObject.CurrentXPosition = modelObject.CurrentXPosition + ( float(position) - modelObject.CurrentXPosition) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetTransform(transform) transformFilter.SetInputConnection(modelObject.reader.GetOutputPort()) transformFilter.Update() modelObject.mapper.SetInputConnection(transformFilter.GetOutputPort()) modelObject.mapper.Update() self.ren.Render() self.ModelView.Render() def Update_Position_Y(self, position): modelObject = self.modelList[self.ui.modelList.currentRow()] transform = modelObject.transform transform.Translate(0.0, (float(position) - modelObject.CurrentYPosition), 0.0) modelObject.CurrentYPosition = modelObject.CurrentYPosition + ( float(position) - modelObject.CurrentYPosition) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetTransform(transform) transformFilter.SetInputConnection(modelObject.reader.GetOutputPort()) transformFilter.Update() modelObject.mapper.SetInputConnection(transformFilter.GetOutputPort()) modelObject.mapper.Update() self.ren.Render() self.ModelView.Render() def Update_Position_Z(self, position): modelObject = self.modelList[self.ui.modelList.currentRow()] transform = modelObject.transform transform.Translate(0.0, 0.0, (float(position) - modelObject.CurrentZPosition)) modelObject.CurrentZPosition = modelObject.CurrentZPosition + ( float(position) - modelObject.CurrentZPosition) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetTransform(transform) transformFilter.SetInputConnection(modelObject.reader.GetOutputPort()) transformFilter.Update() modelObject.mapper.SetInputConnection(transformFilter.GetOutputPort()) modelObject.mapper.Update() self.ren.Render() self.ModelView.Render() def Update_Rotation_X(self, rotation): modelObject = self.modelList[self.ui.modelList.currentRow()] transform = modelObject.transform transform.RotateX((float(rotation) - modelObject.CurrentXRotation)) modelObject.CurrentXRotation = modelObject.CurrentXRotation + ( float(rotation) - modelObject.CurrentXRotation) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetTransform(transform) transformFilter.SetInputConnection(modelObject.reader.GetOutputPort()) transformFilter.Update() modelObject.mapper.SetInputConnection(transformFilter.GetOutputPort()) modelObject.mapper.Update() self.ren.Render() self.ModelView.Render() def Update_Rotation_Y(self, rotation): modelObject = self.modelList[self.ui.modelList.currentRow()] transform = modelObject.transform transform.RotateY((float(rotation) - modelObject.CurrentYRotation)) modelObject.CurrentYRotation = modelObject.CurrentYRotation + ( float(rotation) - modelObject.CurrentYRotation) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetTransform(transform) transformFilter.SetInputConnection(modelObject.reader.GetOutputPort()) transformFilter.Update() modelObject.mapper.SetInputConnection(transformFilter.GetOutputPort()) modelObject.mapper.Update() self.ren.Render() self.ModelView.Render() def Update_Rotation_Z(self, rotation): modelObject = self.modelList[self.ui.modelList.currentRow()] transform = modelObject.transform transform.RotateZ((float(rotation) - modelObject.CurrentZRotation)) modelObject.CurrentZRotation = modelObject.CurrentZRotation + ( float(rotation) - modelObject.CurrentZRotation) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetTransform(transform) transformFilter.SetInputConnection(modelObject.reader.GetOutputPort()) transformFilter.Update() modelObject.mapper.SetInputConnection(transformFilter.GetOutputPort()) modelObject.mapper.Update() self.ren.Render() self.ModelView.Render() def Update_Scale(self, scale): modelObject = self.modelList[self.ui.modelList.currentRow()] transform = modelObject.transform self.reader = vtk.vtkSTLReader() self.reader.SetFileName(str(self.filename)) self.mapper = vtk.vtkPolyDataMapper() self.mapper.SetInputConnection(self.reader.GetOutputPort()) #create model actor self.actor = vtk.vtkActor() self.actor.GetProperty().SetColor(1, 1, 1) self.actor.GetProperty().SetOpacity(1) self.actor.SetMapper(self.mapper) #create outline mapper self.outline = vtk.vtkOutlineFilter() self.outline.SetInputConnection(self.reader.GetOutputPort()) self.outlineMapper = vtk.vtkPolyDataMapper() self.outlineMapper.SetInputConnection(self.outline.GetOutputPort()) #create outline actor self.outlineActor = vtk.vtkActor() self.outlineActor.SetMapper(self.outlineMapper) #add actors to parent render window self.parent.ren.AddActor(self.actor) self.parent.ren.AddActor(self.outlineActor) delta = modelObject.PreviousScale - modelObject.CurrentScale modelObject.transform #transform.Scale((float(scale)-modelObject.CurrentScale)/100.0, (float(scale)-modelObject.CurrentScale)/100.0, (float(scale)-modelObject.CurrentScale)/100.0) transform.Scale modelObject.CurrentScale = modelObject.CurrentScale + ( float(scale) - modelObject.CurrentScale) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetTransform(modelObject.transform) transformFilter.SetInputConnection(modelObject.reader.GetOutputPort()) transformFilter.Update() modelObject.mapper.SetInputConnection(transformFilter.GetOutputPort()) modelObject.mapper.Update() self.ren.Render() self.ModelView.Render() def LoadSettingsFromConfigFile(self): self.imageHeight = int( self.parser.get('slicing_settings', 'Image_Height')) self.imageWidth = int( self.parser.get('slicing_settings', 'Image_Width')) self.startingDepth = int( self.parser.get('slicing_settings', 'Starting_Depth')) self.endingDepth = int( self.parser.get('slicing_settings', 'Ending_Depth')) self.slicingIncrement = int( self.parser.get('slicing_settings', 'Slicing_Increment')) self.slicingplane = self.parser.get('slicing_settings', 'Slicing_Plane') def OpenSettingsDialog(self): self.SettingsDialog = StartSettingsDialog(self) self.connect(self.SettingsDialog, QtCore.SIGNAL('ApplySettings()'), self.getSettingsDialogValues) self.SettingsDialog.imageHeight.setText(str(self.imageHeight)) self.SettingsDialog.imageWidth.setText(str(self.imageWidth)) self.SettingsDialog.startingDepth.setText(str(self.startingDepth)) self.SettingsDialog.endingDepth.setText(str(self.endingDepth)) self.SettingsDialog.slicingIncrement.setText(str( self.slicingIncrement)) self.slicingplaneDict = {"XZ": 0, "XY": 1, "YZ": 2} try: self.SettingsDialog.slicingPlane.setCurrentIndex( self.slicingplaneDict[self.slicingplane]) except: #anything other than a valid entry will default to XZ (index 0) self.SettingsDialog.slicingPlane.setCurrentIndex(0) self.SettingsDialog.exec_() def getSettingsDialogValues(self): self.imageHeight = int(self.SettingsDialog.imageHeight.text()) self.parser.set('slicing_settings', 'Image_Height', "%s" % self.imageHeight) self.imageWidth = int(self.SettingsDialog.imageWidth.text()) self.parser.set('slicing_settings', 'Image_Width', "%s" % self.imageWidth) self.startingDepth = int(self.SettingsDialog.startingDepth.text()) self.parser.set('slicing_settings', 'Starting_Depth', "%s" % self.startingDepth) self.endingDepth = int(self.SettingsDialog.endingDepth.text()) self.parser.set('slicing_settings', 'Ending_Depth', "%s" % self.endingDepth) self.slicingIncrement = int( self.SettingsDialog.slicingIncrement.text()) self.parser.set('slicing_settings', 'Slicing_Increment', "%s" % self.slicingIncrement) self.slicingplane = self.SettingsDialog.slicingPlane.currentText() self.parser.set('slicing_settings', 'Slicing_Plane', "%s" % self.slicingplane) filename = 'sliceconfig.ini' if hasattr(sys, '_MEIPASS'): # PyInstaller >= 1.6 APPNAME = '3DLP' APPDATA = os.path.join(os.environ['APPDATA'], APPNAME) filename = os.path.join(APPDATA, filename) outputini = open( filename, 'w' ) #open a file pointer for the config file parser to write changes to self.parser.write(outputini) outputini.close() #done writing config file changes else: #otherwise it's running in pydev environment: use the dev config file os.chdir(os.path.dirname(sys.argv[0])) filename = os.path.join(os.path.dirname(sys.argv[0]), filename) outputini = open( filename, 'w' ) #open a file pointer for the config file parser to write changes to self.parser.write(outputini) outputini.close() #done writing config file changes
class Editor(QtGui.QDialog): def __init__(self): super(Editor,self).__init__() self.loadedImage = 0 self.loadedSegmentation = 0 self.images = [] self.img_data = [] self.vols = [] self.ui = uic.loadUi('window.ui',self) self.minVal = 10000; self.maxVal = -10000; self.initRenderWindow() self.initFunctionality() self.show() self.vtkWidget.resize(self.frame.width(),self.frame.height()) def initFunctionality(self): self.quitButton.clicked.connect(QtCore.QCoreApplication.instance().quit) self.searchButton.clicked.connect(lambda: self.loadImage()) self.segmentationButton.clicked.connect(lambda: self.loadSegmentation()) self.spinBox.valueChanged.connect(lambda: self.horizontalSlider.setValue(self.spinBox.value())) self.horizontalSlider.valueChanged.connect(lambda: self.spinBox.setValue(self.horizontalSlider.value())) self.horizontalSlider.valueChanged.connect(lambda: self.updateImage()) self.horizontalSlider.setValue(0) self.verticalSlider.valueChanged.connect(lambda: self.updateOpacityTransferFunction()) self.verticalSlider_2.valueChanged.connect(lambda: self.updateOpacityTransferFunction()) self.checkBox.stateChanged.connect(lambda: self.segmentationOnOff()) def initRenderWindow(self): pix_diag = 5.0 self.nVolumes = 0 self.vtkWidget = QVTKRenderWindowInteractor(self.frame) self.ren = vtk.vtkRenderer() self.ren.SetBackground(1.0, 1.0, 1.0) self.vtkWidget.GetRenderWindow().AddRenderer(self.ren) self.window = self.vtkWidget.GetRenderWindow() self.iren = self.vtkWidget.GetRenderWindow().GetInteractor() drange = [0,400] self.vtkWidget.opacity_tf = vtk.vtkPiecewiseFunction() self.vtkWidget.opacity_tf.AddPoint(drange[0],0.0) self.vtkWidget.opacity_tf.AddPoint(drange[1],0.0) self.vtkWidget.color_tf = vtk.vtkColorTransferFunction() self.vtkWidget.color_tf.AddRGBPoint(drange[0], 0.0, 0.0, 0.0) self.vtkWidget.color_tf.AddRGBPoint(drange[1], 1.0, 1.0, 1.0) self.vtkWidget.volProperty = vtk.vtkVolumeProperty() self.vtkWidget.volProperty.SetColor(self.vtkWidget.color_tf); self.vtkWidget.volProperty.SetScalarOpacity(self.vtkWidget.opacity_tf) self.vtkWidget.volProperty.ShadeOn() self.vtkWidget.volProperty.SetInterpolationTypeToLinear() self.vtkWidget.volProperty.SetScalarOpacityUnitDistance(pix_diag) def getImage(self,filename): if str(filename).endswith('nii') or str(filename).endswith('nii.gz'): nim = NiftiImage(str(filename)) shape = nim.data.shape img_data = nim.data miny = np.amin(img_data) arr = img_data.astype(float) arr -= miny maxy = np.amax(arr) arr = arr / (maxy/2) arr -= 1 arr = sk.img_as_ubyte(arr) img_data = arr elif str(filename).endswith('hdr'): # Use the header to figure out the shape of the data # then load the raw data and reshape the array img_data = np.frombuffer(open(str(filename).replace('.hdr', '.dat'), 'rb').read(), np.uint8)\ .reshape((shape[2], shape[1], shape[0])) return (img_data,shape) def addVolumeToRenderer(self,img): pix_diag = 5.0 self.compositeFunction = vtk.vtkVolumeRayCastCompositeFunction() self.compositeFunction.SetCompositeMethodToInterpolateFirst() self.vtkWidget.Render() self.volMapper = vtk.vtkVolumeRayCastMapper() self.window.Render() self.extensions = vtk.vtkOpenGLExtensionManager() self.extensions.SetRenderWindow(self.window) self.extensions.Update() string = self.extensions.GetExtensionsString() print(self.extensions.GetExtensionsString()) self.volMapper.SetVolumeRayCastFunction(self.compositeFunction) self.volMapper.SetSampleDistance(pix_diag / 5.0) self.volMapper.SetInputConnection(img.GetOutputPort()) self.updateColourTransferFunction() self.updateOpacityTransferFunction() self.plane = vtk.vtkPlanes() def ClipVolumeRender(obj, event): obj.GetPlanes(self.plane) self.volMapper.SetClippingPlanes(self.plane) self.boxWidget = vtk.vtkBoxWidget() self.boxWidget.SetInteractor(self.vtkWidget) self.boxWidget.SetPlaceFactor(1.0) self.boxWidget.SetInput(img.GetOutput()) self.boxWidget.PlaceWidget() self.boxWidget.InsideOutOn() self.boxWidget.AddObserver("InteractionEvent", ClipVolumeRender) self.outlineProperty = self.boxWidget.GetOutlineProperty() self.outlineProperty.SetRepresentationToWireframe() self.outlineProperty.SetAmbient(1.0) self.outlineProperty.SetAmbientColor(0, 0, 0) 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) self.outline = vtk.vtkOutlineFilter() self.outline.SetInputConnection(img.GetOutputPort()) self.outlineMapper = vtk.vtkPolyDataMapper() self.outlineMapper.SetInputConnection(self.outline.GetOutputPort()) self.outlineActor = vtk.vtkActor() self.outlineActor.SetMapper(self.outlineMapper) self.vol = vtk.vtkVolume() self.vol.SetMapper(self.volMapper) self.vol.SetProperty(self.vtkWidget.volProperty) self.ren.AddVolume(self.vol) self.ren.AddActor(self.outlineActor) self.window.Render() def arrayToVTKImage(self, array, shape): if len(shape) == 4 and shape[0] == 1: shape = (shape[1], shape[2], shape[3]) image = vtk.vtkImageImport() image.CopyImportVoidPointer(array, array.nbytes) image.SetDataScalarTypeToUnsignedChar() image.SetNumberOfScalarComponents(1) image.SetDataExtent(0, shape[2]-1, 0, shape[1]-1, 0, shape[0]-1) image.SetWholeExtent(0, shape[2]-1, 0, shape[1]-1, 0, shape[0]-1) return image def addSegmentationToImage(self): dmc = vtk.vtkDiscreteMarchingCubes() dmc.SetInputConnection(self.segImage.GetOutputPort()) dmc.GenerateValues(1, 255, 255) dmc.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(dmc.GetOutputPort()) self.checkBox.setEnabled(True) self.checkBox.setCheckState(2) actor = vtk.vtkActor() actor.SetMapper(mapper) self.ren.AddActor(actor) self.window.Render() @pyqtSlot() def loadImage(self): filename = QtGui.QFileDialog.getOpenFileName(self, 'Open File', '/media/My Passport/CTPaperCTData/Russ/C34R1/VesselSegmentation'); self.img_data, shape = self.getImage(filename) self.image = self.arrayToVTKImage(self.img_data, shape) self.maxVal = max(self.maxVal, np.amax(self.img_data)) self.minVal = min(self.minVal, np.amin(self.img_data)) self.range = self.maxVal - self.minVal self.addVolumeToRenderer(self.image) self.ren.ResetCamera() self.cam1 = self.ren.GetActiveCamera() self.style = vtk.vtkInteractorStyleTrackballCamera() self.vtkWidget.SetInteractorStyle(self.style) self.vtkWidget.lighting = True self.update() self.iren.Render() self.loadedImage = 1 def loadSegmentation(self): filename = QtGui.QFileDialog.getOpenFileName(self, 'Open File', '/media/My Passport/CTPaperCTData/Russ/C34R1/VesselSegmentation'); self.seg_data, self.seg_shape = self.getImage(filename) self.segImage = self.arrayToVTKImage(self.seg_data, self.seg_shape) self.addSegmentationToImage() def updateOpacityTransferFunction(self): bottomSliderVal = self.verticalSlider.value() topSliderVal = self.verticalSlider_2.value() upperVal = min(self.maxVal, bottomSliderVal+topSliderVal/2) lowerVal = max(self.minVal, bottomSliderVal-topSliderVal/2) self.vtkWidget.opacity_tf.RemoveAllPoints() self.vtkWidget.opacity_tf.AddPoint(self.minVal, 0.0) self.vtkWidget.opacity_tf.AddPoint(lowerVal, 0.0) self.vtkWidget.opacity_tf.AddPoint(upperVal, 1.0) self.vtkWidget.opacity_tf.AddPoint(self.maxVal, 1.0) self.vtkWidget.color_tf.RemoveAllPoints() self.vtkWidget.color_tf.AddRGBPoint(self.minVal, 0, 0, 0) self.vtkWidget.color_tf.AddRGBPoint(lowerVal, 0, 0, 0) self.vtkWidget.color_tf.AddRGBPoint(upperVal, 1, 1, 1) self.vtkWidget.color_tf.AddRGBPoint(self.maxVal, 1, 1, 1) self.vtkWidget.Render() def updateColourTransferFunction(self): self.vtkWidget.color_tf.RemoveAllPoints() self.vtkWidget.color_tf.AddRGBPoint(self.minVal, 0, 0, 0) self.vtkWidget.color_tf.AddRGBPoint(self.maxVal, 1, 1, 1) def resizeEvent(self, QResizeEvent): if self.loadedImage == 1: self.vtkWidget.resize(self.frame.width(), self.frame.height()) def segmentationOnOff(self): props = self.ren.GetViewProps() props.InitTraversal() if self.checkBox.checkState() == 0: props.GetNextProp() props.GetNextProp() props.GetNextProp().VisibilityOff() self.vtkWidget.Render() elif self.checkBox.checkState() == 2: props.GetNextProp() props.GetNextProp() props.GetNextProp().VisibilityOn() self.vtkWidget.Render()
def __init__(self, parent, data_dir): super(QGlyphViewer,self).__init__(parent) # Make tha actual QtWidget a child so that it can be re parented interactor = QVTKRenderWindowInteractor(self) self.layout = QtGui.QHBoxLayout() self.layout.addWidget(interactor) self.layout.setContentsMargins(0,0,0,0) self.setLayout(self.layout) # Read the data xyx_file = os.path.join(data_dir, "combxyz.bin") q_file = os.path.join(data_dir, "combq.bin") pl3d = vtk.vtkMultiBlockPLOT3DReader() pl3d.SetXYZFileName(xyx_file) pl3d.SetQFileName(q_file) pl3d.SetScalarFunctionNumber(100) pl3d.SetVectorFunctionNumber(202) pl3d.Update() blocks = pl3d.GetOutput() b0 = blocks.GetBlock(0) # Setup VTK environment renderer = vtk.vtkRenderer() render_window = interactor.GetRenderWindow() render_window.AddRenderer(renderer) interactor.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera()) render_window.SetInteractor(interactor) renderer.SetBackground(0.2,0.2,0.2) # Draw Outline outline = vtk.vtkStructuredGridOutlineFilter() outline.SetInputData(b0) outline_mapper = vtk.vtkPolyDataMapper() outline_mapper.SetInputConnection(outline.GetOutputPort()) outline_actor = vtk.vtkActor() outline_actor.SetMapper(outline_mapper) outline_actor.GetProperty().SetColor(1,1,1) renderer.AddActor(outline_actor) renderer.ResetCamera() # Draw Outline outline = vtk.vtkStructuredGridOutlineFilter() outline.SetInputData(b0) outline_mapper = vtk.vtkPolyDataMapper() outline_mapper.SetInputConnection(outline.GetOutputPort()) outline_actor = vtk.vtkActor() outline_actor.SetMapper(outline_mapper) outline_actor.GetProperty().SetColor(1,1,1) renderer.AddActor(outline_actor) renderer.ResetCamera() # Threshold points threshold = vtk.vtkThresholdPoints() threshold.SetInputData(b0) threshold.ThresholdByUpper(0.5) # Draw arrows arrow = vtk.vtkArrowSource() glyphs = vtk.vtkGlyph3D() glyphs.SetInputData(b0) glyphs.SetSourceConnection(arrow.GetOutputPort()) glyphs.SetInputConnection(threshold.GetOutputPort()) glyphs.SetVectorModeToUseVector() glyphs.SetScaleModeToScaleByVector() glyphs.SetScaleFactor(0.005) glyphs.SetColorModeToColorByVector() # Mapper glyph_mapper = vtk.vtkPolyDataMapper() glyph_mapper.SetInputConnection(glyphs.GetOutputPort()) glyph_actor = vtk.vtkActor() glyph_actor.SetMapper(glyph_mapper) glyph_mapper.UseLookupTableScalarRangeOn() renderer.AddActor(glyph_actor) # Set color lookuptable glyphs.Update() s0,sf = glyphs.GetOutput().GetScalarRange() lut = vtk.vtkColorTransferFunction() lut.AddRGBPoint(s0, 1,0,0) lut.AddRGBPoint(sf, 0,1,0) glyph_mapper.SetLookupTable(lut) self.b0 = b0 self.renderer = renderer self.interactor = interactor self.threshold = threshold self.render_window = render_window
class SliceCompareViewerWidget(QWidget, Interactor): """ SliceCompareViewerWidget shows slices that you can scroll through. Slicing happens in world coordinates. It can be synced to another slicer widget. """ slicePositionChanged = Signal(object) mouseMoved = Signal(object) def __init__(self): super(SliceCompareViewerWidget, self).__init__() self.renderer = vtkRenderer() self.renderer.SetBackground(0.0, 0.0, 0.0) self.renderer.SetLayer(0) # Overlay renderer which is synced with the default renderer self.rendererOverlay = vtkRenderer() self.rendererOverlay.SetLayer(1) self.rendererOverlay.SetInteractive(0) self.renderer.GetActiveCamera().AddObserver("ModifiedEvent", self._syncCameras) self.rwi = QVTKRenderWindowInteractor(parent=self) self.rwi.SetInteractorStyle(vtkInteractorStyleUser()) self.rwi.GetRenderWindow().AddRenderer(self.renderer) self.rwi.GetRenderWindow().AddRenderer(self.rendererOverlay) self.rwi.GetRenderWindow().SetNumberOfLayers(2) # Set camera to parallel camera = self.renderer.GetActiveCamera() camera.SetParallelProjection(1) # Add new observers for mouse wheel self.AddObserver(self.rwi, "CharEvent", self.charTyped) self.AddObserver(self.rwi, "MouseWheelBackwardEvent", self.mouseWheelChanged) self.AddObserver(self.rwi, "MouseWheelForwardEvent", self.mouseWheelChanged) self.AddObserver(self.rwi, "MouseMoveEvent", self.mouseMovedEvent, 1) self.picker = vtkCellPicker() self.picker.SetTolerance(1e-6) self.locator = [] self.setStyleSheet("background-color: #333") layout = QGridLayout() layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.rwi) self.setLayout(layout) def _syncCameras(self, camera, ev): """ Camera modified event callback. Copies the parameters of the renderer camera into the camera of the overlay so they stay synced at all times. """ self.rendererOverlay.GetActiveCamera().ShallowCopy(camera) def charTyped(self, arg1, arg2): # print arg1.GetKeyCode() pass def setLocatorPosition(self, position): for actor in self.locator: actor.SetPosition(position[0], position[1], position[2]) def setFixedImageData(self, fixed): self.fixedImagedata = fixed def setSlicerWidget(self, fixed, moving): self.fixedSlicerWidget = fixed self.movingSlicerWidget = moving self.slicer = None def mouseWheelChanged(self, arg1, arg2): pass def mouseMovedEvent(self, arg1, arg2): self.rwi.HideCursor() x, y = arg1.GetEventPosition() camera = self.renderer.GetActiveCamera() cameraFP = list(camera.GetFocalPoint()) + [1.0] self.renderer.SetWorldPoint(cameraFP[0], cameraFP[1], cameraFP[2], cameraFP[3]) self.renderer.WorldToDisplay() # Convert the selection point into world coordinates. self.renderer.SetDisplayPoint(x, y, 1) self.renderer.DisplayToWorld() worldCoords = self.renderer.GetWorldPoint() pickPosition = map(lambda x: x / worldCoords[3], worldCoords[0:-1]) self.mouseMoved.emit(pickPosition) def adjustTransferFunction(self, transferfunction, lower, upper): transfer = vtkColorTransferFunction() val1 = [0.0 for _ in range(6)] val2 = [0.0 for _ in range(6)] transferfunction.GetNodeValue(0, val1) transferfunction.GetNodeValue(1, val2) val1[0] = lower val2[0] = upper transfer.AddRGBPoint(val1[0], val1[1], val1[2], val1[3], val1[4], val1[5]) transfer.AddRGBPoint(val2[0], val2[1], val2[2], val2[3], val2[4], val2[5]) transfer.Build() return transfer def updateCompareView(self): fixedSlice = self.fixedSlicerWidget.slicer.GetResliceOutput() movingSlice = self.movingSlicerWidget.slicer.GetResliceOutput() window = self.fixedSlicerWidget.slicer.GetWindow() level = self.fixedSlicerWidget.slicer.GetLevel() lower = level - window / 2.0 upper = level + window / 2.0 fixedTransfer = self.adjustTransferFunction( self.fixedSlicerWidget.transfer, lower, upper) movingTransfer = self.adjustTransferFunction( self.movingSlicerWidget.transfer, lower, upper) fixedMap = vtkImageMapToColors() fixedMap.SetInputData(fixedSlice) fixedMap.SetLookupTable(fixedTransfer) movingMap = vtkImageMapToColors() movingMap.SetInputData(movingSlice) movingMap.SetLookupTable(movingTransfer) maths = vtkImageMathematics() maths.SetInputConnection(0, fixedMap.GetOutputPort()) maths.SetInputConnection(1, movingMap.GetOutputPort()) maths.SetOperationToAdd() maths.Update() # self.blender = vtkImageBlend() # self.blender.SetOpacity(0, 0.5) # self.blender.SetOpacity(1, 0.5) # self.blender.AddInputConnection(fixedMap.GetOutputPort()) # self.blender.AddInputConnection(movingMap.GetOutputPort()) # redChannel = vtkImageExtractComponents() # greenChannel = vtkImageExtractComponents() # blueChannel = vtkImageExtractComponents() # redChannel.SetInputConnection(self.blender.GetOutputPort()) # greenChannel.SetInputConnection(self.blender.GetOutputPort()) # blueChannel.SetInputConnection(self.blender.GetOutputPort()) # redChannel.SetComponents(0) # greenChannel.SetComponents(1) # blueChannel.SetComponents(2) # redScale = vtkImageShiftScale() # greenScale = vtkImageShiftScale() # blueScale = vtkImageShiftScale() # redScale.SetInputConnection(redChannel.GetOutputPort()) # greenScale.SetInputConnection(greenChannel.GetOutputPort()) # blueScale.SetInputConnection(blueChannel.GetOutputPort()) # redScale.SetScale(2.0) # greenScale.SetScale(2.0) # blueScale.SetScale(2.0) # result = vtkImageAppendComponents() # result.AddInputConnection(redScale.GetOutputPort()) # result.AddInputConnection(greenScale.GetOutputPort()) # result.AddInputConnection(blueScale.GetOutputPort()) # fixedMap.Update() # otherMath = vtkImageMathematics() # otherMath.SetOperationToMax() # otherMath.AddInputData(maths.GetOutput()) # otherMath.SetConstantK(1.0) if not hasattr(self, "dataSetMapper"): self.dataSetMapper = vtkDataSetMapper() # Do not establish a vtk pipeline connection! # Otherwise the pipeline will be executed on every render call... self.dataSetMapper.SetInputData(maths.GetOutput()) if not hasattr(self, "actor"): self.actor = vtkActor() self.actor.SetMapper(self.dataSetMapper) self.renderer.AddViewProp(self.actor) orig = self.fixedSlicerWidget.slicer.GetOrigin() self.actor.SetPosition(orig[0], orig[1], orig[2]) if not self.locator: bounds = self.fixedImagedata.GetBounds() size = [ bounds[1] - bounds[0], bounds[3] - bounds[2], bounds[5] - bounds[4] ] meanSize = sum(size) / len(size) width = meanSize / 20.0 color = [1.0, 1.0, 1.0] square = CreateSquare(width, color, 2) square.GetProperty().SetLineWidth(2) color = [0.2, 0.2, 0.2] line1 = CreateLine([0, width / 2.0, 0], [0, 10000, 0], color) line2 = CreateLine([0, -width / 2.0, 0], [0, -10000, 0], color) line3 = CreateLine([width / 2.0, 0, 0], [10000, 0, 0], color) line4 = CreateLine([-width / 2.0, 0, 0], [-10000, 0, 0], color) self.locator = [square, line1, line2, line3, line4] # , otherSquare] for actor in self.locator: self.rendererOverlay.AddViewProp(actor) def render(self): self.renderer.Render() self.rwi.GetRenderWindow().Render()
class MainWindow(QtGui.QMainWindow): def __init__(self, filename, parent=None): QtGui.QMainWindow.__init__(self, parent) # Initiate the UI as defined by Qt Designer self.ui = Ui_MainWindow() self.ui.setupUi(self) self.poly_data = None self.node_ids = None self.element_ids = None self.node_count = 0 self.read_data(filename) self.ui.txt_msg.appendPlainText("Model Loaded.") # initialize colors self.eidcolor = (0, 0.5, 0.5) self.edgecolor = (0, 0, 0) self.bgcolor1 = (0, 0, 1) self.bgcolor2 = (0.8, 0.8, 1) self.perspective = 0 self.solid = 1 self.idFilter = vtk.vtkIdFilter() self.idFilter.SetInputData(self.poly_data) self.idFilter.SetIdsArrayName("OriginalIds") self.idFilter.Update() self.surfaceFilter = vtk.vtkDataSetSurfaceFilter() self.surfaceFilter.SetInputConnection(self.idFilter.GetOutputPort()) self.surfaceFilter.Update() self.input = self.surfaceFilter.GetOutput() self.renderer = vtk.vtkRenderer() #self.renderer2 = vtk_widget.vtkRenderer() viewport = [0.0,0.0,0.15,0.15] #self.renderer2.SetViewport(viewport) #self.renderer2.Transparent() self.renderWindowInteractor = QVTKRenderWindowInteractor(self.ui.frame) self.renderWindowInteractor.GetRenderWindow().AddRenderer(self.renderer) #self.renderWindowInteractor.GetRenderWindow().AddRenderer(self.renderer2) self.renderWindowInteractor.GetRenderWindow().SetAlphaBitPlanes(1) self.axes = CoordinateAxes(self.renderWindowInteractor) self.ui.vl.addWidget(self.renderWindowInteractor) self.iren = vtk.vtkRenderWindowInteractor() self.iren = self.renderWindowInteractor.GetRenderWindow().GetInteractor() self.mapper = vtk.vtkPolyDataMapper() self.mapper.SetInputData(self.input) self.mapper.ScalarVisibilityOff() self.actor = vtk.vtkActor() self.actor.SetMapper(self.mapper) self.actor.GetProperty().SetPointSize(2) self.actor.GetProperty().EdgeVisibilityOn() self.actor.GetProperty().SetColor(self.eidcolor) self.actor.GetProperty().SetEdgeColor(self.edgecolor) self.camera = vtk.vtkCamera() #self.camera2 = vtk_widget.vtkCamera() # trial... add glyph pd = vtk.vtkPolyData() pts = vtk.vtkPoints() scalars = vtk.vtkFloatArray() vectors = vtk.vtkFloatArray() vectors.SetNumberOfComponents(3) pd.SetPoints(pts) pd.GetPointData().SetScalars(scalars) pd.GetPointData().SetVectors(vectors) pts.InsertNextPoint(30, 30, 0.0) scalars.InsertNextValue(1) vectors.InsertNextTuple3(1, 1, 0.0) # Create simple PolyData for glyph table cs = vtk.vtkCubeSource() cs.SetXLength(0.5) cs.SetYLength(1) cs.SetZLength(2) # Set up the glyph filter glyph = vtk.vtkGlyph3D() #glyph.SetInputConnection(elev.GetOutputPort()) point_list = vtk.vtkPoints() point_list.InsertNextPoint([30, 30, 0]) poly_data = vtk.vtkPolyData() poly_data.SetPoints(point_list) idFilter = vtk.vtkIdFilter() idFilter.SetInputData(poly_data) idFilter.SetIdsArrayName("OriginalIds") idFilter.Update() surfaceFilter = vtk.vtkDataSetSurfaceFilter() surfaceFilter.SetInputConnection(idFilter.GetOutputPort()) surfaceFilter.Update() # Here is where we build the glyph table # that will be indexed into according to the IndexMode glyph.SetSourceData(0,cs.GetOutput()) #glyph.SetInputConnection(surfaceFilter.GetOutputPort()) glyph.SetInputData(pd) glyph.SetIndexModeToScalar() glyph.SetRange(0, 1) glyph.SetScaleModeToDataScalingOff() glyph.OrientOn() mapper3 = vtk.vtkPolyDataMapper() mapper3.SetInputConnection(glyph.GetOutputPort()) mapper3.SetScalarModeToUsePointFieldData() mapper3.SetColorModeToMapScalars() mapper3.ScalarVisibilityOn() mapper3.SetScalarRange(0, 1) actor3 = vtk.vtkActor() actor3.SetMapper(mapper3) #actor3.GetProperty().SetBackgroundOpacity(0.5) gs = vtk.vtkGlyphSource2D() gs.SetGlyphTypeToCircle() gs.SetScale(25) gs.FilledOff() #gs.CrossOn() gs.Update() # Create a table of glyphs glypher = vtk.vtkGlyph2D() glypher.SetInputData(pd) glypher.SetSourceData(0, gs.GetOutput()) glypher.SetIndexModeToScalar() glypher.SetRange(0, 1) glypher.SetScaleModeToDataScalingOff() mapper = vtk.vtkPolyDataMapper2D() mapper.SetInputConnection(glypher.GetOutputPort()) mapper.SetScalarRange(0, 1) actor2D = vtk.vtkActor2D() actor2D.SetMapper(mapper) self.renderer.AddActor(self.actor) #self.renderer.AddActor(mapper) #self.renderer2.AddActor(actor3) self.renderer.SetBackground(self.bgcolor1) self.renderer.SetBackground2(self.bgcolor2) self.renderer.GradientBackgroundOn() self.renderer.SetActiveCamera(self.camera) self.renderer.ResetCamera() #self.camera.ZoomOff() #self.renderer2.SetActiveCamera(self.camera) #self.renderer2.ResetCamera() #self.renderer2.SetBackground(0,0,0) #self.renderer2.GetProperty().SetBackgroundOpacity(0.5) #self.renderer2.SetLayer(1) #self.renderer2.Clear() self.areaPicker = vtk.vtkAreaPicker() self.renderWindowInteractor.SetPicker(self.areaPicker) self.style = MyInteractorStyle() self.style.SetPoints(self.input) self.style.SetDefaultRenderer(self.renderer) self.style.Data = self.idFilter.GetOutput() self.style.camera = self.camera self.style.node_ids = self.node_ids self.style.element_ids = self.element_ids self.style.node_count = self.node_count self.style.window = self self.style.print_message = self.ui.txt_msg.appendPlainText self.renderWindowInteractor.SetInteractorStyle(self.style) self.renderWindowInteractor.Start() # screenshot code:e #self.w2if = vtk_widget.vtkWindowToImageFilter() #self.w2if.SetInput(self.renWin) #self.w2if.Update() self.show() self.iren.Initialize() #self.iren.Start() # Setup Connections self.ui.btn_bgcolor1.clicked.connect(self.on_color1) self.ui.btn_bgcolor2.clicked.connect(self.on_color2) self.ui.btn_edgecolor.clicked.connect(self.on_edgecolor) self.ui.btn_elementcolor.clicked.connect(self.on_elementcolor) self.ui.btn_nofillededge.clicked.connect(self.on_nofillededge) self.ui.btn_switch.clicked.connect(self.on_switch) self.ui.btn_perspectivetoggle.clicked.connect(self.on_toggleperspective) self.ui.btn_saveimg.clicked.connect(self.on_saveimg) self.ui.btn_togglewire.clicked.connect(self.on_togglewire) # Setup a shortcuts self.setusrstyle = QtGui.QShortcut(self) self.setusrstyle.setKey(("CTRL+c")) self.setusrstyle.activated.connect(self.on_copyimg) def read_data(self, filename): # Create source point_list = vtk.vtkPoints() cell_list = vtk.vtkCellArray() nodes = {} self.node_ids = array('i') from fem_reader.nastran.bdf.reader import BDFReader bdf = BDFReader() bdf.read_bdf(r'../data/wing.bdf') grids = bdf.nodes.keys() elements = bdf.elements.keys() for i in xrange(len(grids)): # grids data_type = bdf.nodes[grids[i]].card_name if data_type != 'GRID': continue node_id = str(grids[i]) self.node_ids.append(int(node_id)) nodes[node_id] = {} nodes[node_id]['order'] = i nodes[node_id]['id'] = node_id #x = bdf.nodes[grids[i]].X1 #float(line[2]) # grids[i].x #y = bdf.nodes[grids[i]].X2 # float(line[3]) #z = bdf.nodes[grids[i]].X3 # float(line[4]) x, y, z = bdf.nodes[grids[i]].to_global() nodes[node_id]['x'] = float(x) nodes[node_id]['y'] = float(y) nodes[node_id]['z'] = float(z) _id = point_list.InsertNextPoint([x, y, z]) cell_list.InsertNextCell(1) cell_list.InsertCellPoint(_id) self.node_count = len(self.node_ids) last_i = self.node_count self.element_ids = array('i') for i in xrange(len(elements)): #line = lines[i].split(',') #data_type = line[0] #print i data_type = bdf.elements[elements[i]].card_name if data_type == 'GRID': continue try: self.element_ids.append(int(bdf.elements[elements[i]].ID)) except IndexError: break if data_type == 'CBEAM': beam = Bar2() beam.id = bdf.elements[elements[i]].ID beam.order = last_i + i node1 = nodes[str(bdf.elements[elements[i]].G1)] node2 = nodes[str(bdf.elements[elements[i]].G2)] beam.set_nodes(node1, node2) cell_list.InsertNextCell(beam.vtk_cell) point_list.InsertNextPoint(beam.center) if data_type == 'CTRIA3': tria = Tria3() tria.id = bdf.elements[elements[i]].ID tria.order = last_i + i node1 = nodes[str(bdf.elements[elements[i]].G1)] #bdf.elements[elements[i]].G1 node2 = nodes[str(bdf.elements[elements[i]].G2)] node3 = nodes[str(bdf.elements[elements[i]].G3)] tria.set_nodes(node1, node2, node3) cell_list.InsertNextCell(tria.vtk_cell) point_list.InsertNextPoint(tria.center) if data_type == 'CQUAD4': quad = Quad4() quad.id = bdf.elements[elements[i]].ID quad.order = last_i + i node1 = nodes[str(bdf.elements[elements[i]].G1)] node2 = nodes[str(bdf.elements[elements[i]].G2)] node3 = nodes[str(bdf.elements[elements[i]].G3)] node4 = nodes[str(bdf.elements[elements[i]].G4)] quad.set_nodes(node1, node2, node3, node4) cell_list.InsertNextCell(quad.vtk_cell) point_list.InsertNextPoint(quad.center) self.poly_data = vtk.vtkPolyData() self.poly_data.SetPoints(point_list) self.poly_data.SetPolys(cell_list) self.poly_data.SetLines(cell_list) #self.poly_data.SetVerts(cell_list) def on_color1(self): color = QtGui.QColorDialog.getColor(QtCore.Qt.blue,self) red = color.red() / 255. blue = color.blue() / 255. green = color.green() / 255. self.bgcolor1 = (red, green, blue) self.renderer.SetBackground(self.bgcolor1) self.show() def on_color2(self): color = QtGui.QColorDialog.getColor(QtCore.Qt.blue,self) red = color.red() / 255. blue = color.blue() / 255. green = color.green() / 255. self.bgcolor2 = (red, green, blue) self.renderer.SetBackground2(self.bgcolor2) self.show() def on_edgecolor(self): color = QtGui.QColorDialog.getColor(QtCore.Qt.blue,self) red = color.red() / 255. blue = color.blue() / 255. green = color.green() / 255. self.edgecolor = (red, green, blue) self.actor.GetProperty().SetEdgeColor(self.edgecolor) self.actor.GetProperty().EdgeVisibilityOn() self.actor.GetProperty().SetPointSize(2) self.show() def on_elementcolor(self): color = QtGui.QColorDialog.getColor(QtCore.Qt.blue,self) red = color.red() / 255. blue = color.blue() / 255. green = color.green() / 255. self.eidcolor = (red, green, blue) self.actor.GetProperty().SetColor(self.eidcolor) self.show() def on_nofillededge(self): self.actor.GetProperty().EdgeVisibilityOff() self.actor.GetProperty().SetPointSize(0.001) self.show() def on_switch(self): if self.bgcolor1 == (1,1,1) and self.bgcolor2 == (1,1,1): self.bgcolor1 = (0, 0, 1) self.bgcolor2 = (0.8, 0.8, 1) self.renderer.SetBackground(self.bgcolor1) self.renderer.SetBackground2(self.bgcolor2) self.show() else: self.bgcolor1 = (1, 1, 1) self.bgcolor2 = (1, 1, 1) self.renderer.SetBackground(self.bgcolor1) self.renderer.SetBackground2(self.bgcolor2) self.show() def on_toggleperspective(self): if self.perspective == 0: #self.actor.GetProperty().ParallelProjectionOn() self.camera.ParallelProjectionOn() self.show() self.perspective = 1 else: #self.actor.GetProperty().ParallelProjectionOff() self.camera.ParallelProjectionOff() self.show() self.perspective = 0 def on_saveimg(self): try: picfile = QtGui.QFileDialog.getSaveFileName(self, "Save Image", '', "Image files (*.png)") except IOError as err: print err if picfile == []: return print picfile[0] # screenshot code: w2if = vtk.vtkWindowToImageFilter() w2if.SetInput(self.renderWindowInteractor.GetRenderWindow()) w2if.Update() writer = vtk.vtkPNGWriter() writer.SetFileName(picfile[0]) writer.SetInput(w2if.GetOutput()) writer.Write() def on_copyimg(self): # Take a screenshot: w2if = vtk.vtkWindowToImageFilter() w2if.SetInput(self.renderWindowInteractor.GetRenderWindow()) w2if.Update() # screenshot is a vtk_widget object image = w2if.GetOutput() # write a temp image file writer = vtk.vtkPNGWriter() writer.SetFileName("tempfile.png") writer.SetInput(image) writer.Write() # read the temp image file ### This works... copying image from file to clipboard self.clipboard = QtGui.QApplication.clipboard() data = QtCore.QMimeData() #data.setImageData(QtGui.QImage(r'D:\PGM\01_DEV\VTK\MVC\1.png')) data.setImageData(QtGui.QImage("tempfile.png")) self.clipboard.setMimeData(data) # remove the tempfile os.remove("tempfile.png") # how to covert vtkobject image to Qimage?? def on_togglewire(self): pass
class SliceViewerWidget(QWidget, Interactor): """ SliceViewerWidget shows slices that you can scroll through. Slicing happens in world coordinates. It can be synced to another slicer widget. """ slicePositionChanged = Signal(object) mouseMoved = Signal(object) def __init__(self): super(SliceViewerWidget, self).__init__() self.color = [1, 1, 1] self.renderer = vtkRenderer() self.renderer.SetBackground(0.0, 0.0, 0.0) self.renderer.SetLayer(0) # Overlay renderer which is synced with the default renderer self.rendererOverlay = vtkRenderer() self.rendererOverlay.SetLayer(1) self.rendererOverlay.SetInteractive(0) self.renderer.GetActiveCamera().AddObserver("ModifiedEvent", self._syncCameras) self.rwi = QVTKRenderWindowInteractor(parent=self) self.rwi.SetInteractorStyle(vtkInteractorStyleUser()) self.rwi.GetRenderWindow().AddRenderer(self.renderer) self.rwi.GetRenderWindow().AddRenderer(self.rendererOverlay) self.rwi.GetRenderWindow().SetNumberOfLayers(2) # Set camera to parallel camera = self.renderer.GetActiveCamera() camera.SetParallelProjection(1) # Add new observers for mouse wheel self.AddObserver(self.rwi, "CharEvent", self.charTyped) self.AddObserver(self.rwi, "MouseWheelBackwardEvent", self.mouseWheelChanged) self.AddObserver(self.rwi, "MouseWheelForwardEvent", self.mouseWheelChanged) self.AddObserver(self.rwi, "MouseMoveEvent", self.mouseMovedEvent, 1) self.picker = vtkCellPicker() self.picker.SetTolerance(1e-6) self.locator = [] self.setStyleSheet("background-color: #333") layout = QGridLayout() layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.rwi) self.setLayout(layout) def _syncCameras(self, camera, ev): """ Camera modified event callback. Copies the parameters of the renderer camera into the camera of the overlay so they stay synced at all times. """ self.rendererOverlay.GetActiveCamera().ShallowCopy(camera) def charTyped(self, arg1, arg2): # print arg1.GetKeyCode() pass def setLocatorPosition(self, position): for actor in self.locator: actor.SetPosition(position[0], position[1], position[2]) def setImageData(self, imageData): self.imagedata = imageData scalarRange = self.imagedata.GetScalarRange() self.transfer = vtkColorTransferFunction() self.transfer.SetRange(scalarRange[0], scalarRange[1]) self.transfer.AddRGBPoint(scalarRange[0], 0, 0, 0) self.transfer.AddRGBPoint(scalarRange[1], self.color[0], self.color[1], self.color[2]) self.transfer.Build() # Add a slicer widget that looks at camera self.slicer = vtkImagePlaneWidget() self.slicer.DisplayTextOn() self.slicer.SetInteractor(self.rwi) self.slicer.SetInputData(imageData) self.slicer.SetPlaneOrientation(2) self.slicer.SetRestrictPlaneToVolume(1) self.slicer.PlaceWidget() self.slicer.On() cursorProperty = self.slicer.GetCursorProperty() cursorProperty.SetOpacity(0.0) planeProperty = self.slicer.GetPlaneProperty() planeProperty.SetColor(0, 0, 0) selectedPlaneProperty = self.slicer.GetSelectedPlaneProperty() selectedPlaneProperty.SetColor(0, 0, 0) # Reset the camera and set the clipping range self.renderer.ResetCamera() camera = self.renderer.GetActiveCamera() camera.SetClippingRange(0.1, 10000) if not self.locator: bounds = self.imagedata.GetBounds() size = [ bounds[1] - bounds[0], bounds[3] - bounds[2], bounds[5] - bounds[4] ] meanSize = sum(size) / len(size) width = meanSize / 20.0 square = CreateSquare(width, self.color) square.GetProperty().SetLineWidth(2) line1 = CreateLine([0, width / 2.0, 0], [0, 10000, 0], self.color) line2 = CreateLine([0, -width / 2.0, 0], [0, -10000, 0], self.color) line3 = CreateLine([width / 2.0, 0, 0], [10000, 0, 0], self.color) line4 = CreateLine([-width / 2.0, 0, 0], [-10000, 0, 0], self.color) self.locator = [square, line1, line2, line3, line4] for actor in self.locator: self.rendererOverlay.AddViewProp(actor) def mouseWheelChanged(self, arg1, arg2): sign = 1 if arg2 == "MouseWheelForwardEvent" else -1 index = self.slicer.GetSliceIndex() nextIndex = index + sign self.slicer.SetSliceIndex(nextIndex) self.slicePositionChanged.emit(self) def mouseMovedEvent(self, arg1, arg2): self.rwi.HideCursor() x, y = arg1.GetEventPosition() camera = self.renderer.GetActiveCamera() cameraFP = list(camera.GetFocalPoint()) + [1.0] self.renderer.SetWorldPoint(cameraFP[0], cameraFP[1], cameraFP[2], cameraFP[3]) self.renderer.WorldToDisplay() # Convert the selection point into world coordinates. self.renderer.SetDisplayPoint(x, y, 1) self.renderer.DisplayToWorld() worldCoords = self.renderer.GetWorldPoint() pickPosition = map(lambda x: x / worldCoords[3], worldCoords[0:-1]) self.mouseMoved.emit(pickPosition) def render(self): self.slicer.UpdatePlacement() self.renderer.Render() self.rwi.GetRenderWindow().Render()
class VTKWidget(object): def __init__(self, main_window): super(VTKWidget, self).__init__() self.renderer = vtk.vtkRenderer() self.renderer_picked = vtk.vtkRenderer() self.renderer_hovered = vtk.vtkRenderer() self.data_source = BDFDataSource() self.group_selections_ = vtk.vtkPolyData() self.group_filter = GroupFilter() self.visible_filter = VisibleFilter() self.main_pipeline = MainPipelineHelper(self.renderer) self.selected_pipeline = SelectedPipelineHelper( self, self.renderer_picked) self.hovered_pipeline = HoveredPipelineHelper(self, self.renderer_hovered) self.set_up_pipeline() self.set_up_view(main_window) self.visible_filter.add_callback( self.interactor_style.model_picker.set_data) ui = self.main_window.ui ui.left_click_combo.currentIndexChanged[str].connect( self.interactor_style.set_left_button) ui.middle_click_combo.currentIndexChanged[str].connect( self.interactor_style.set_middle_button) ui.right_click_combo.currentIndexChanged[str].connect( self.interactor_style.set_right_button) ui.ctrl_left_click_combo.currentIndexChanged[str].connect( self.interactor_style.set_ctrl_left_button) self.show_hide = False self.show = True self.bdf = None self.toggle_filter = vtk.vtkExtractSelection() self.toggle_filter.SetInputConnection(0, self.visible_filter.all_port()) self.toggle_selection_node = vtk.vtkSelectionNode() self.toggle_selection_node.SetContentType( vtk.vtkSelectionNode.GLOBALIDS) self.toggle_selection = vtk.vtkSelection() self.toggle_selection.AddNode(self.toggle_selection_node) self.toggle_filter.SetInputData(1, self.toggle_selection) def set_up_view(self, main_window): self.main_window = main_window self.interactor = QVTKRenderWindowInteractor(self.main_window.ui.frame) self.renderer.SetLayer(0) self.renderer.SetInteractive(1) #self.renderer.BackingStoreOn() self.renderer_picked.SetLayer(1) self.renderer_picked.SetInteractive(1) #self.renderer_picked.BackingStoreOn() self.renderer_hovered.SetLayer(2) self.renderer_hovered.SetInteractive(1) self.interactor.GetRenderWindow().SetNumberOfLayers(3) self.interactor.GetRenderWindow().AddRenderer(self.renderer_hovered) self.interactor.GetRenderWindow().AddRenderer(self.renderer_picked) self.interactor.GetRenderWindow().AddRenderer(self.renderer) self.interactor.GetRenderWindow().SetAlphaBitPlanes(1) self.main_window.ui.vl.addWidget(self.interactor) self.iren = self.interactor.GetRenderWindow().GetInteractor() self.bg_color_1_default = (0, 0, 1) self.bg_color_2_default = (0.8, 0.8, 1) self.bg_color_1 = self.bg_color_1_default self.bg_color_2 = self.bg_color_2_default self.axes = CoordinateAxes(self.interactor) self.renderer.SetBackground(self.bg_color_1) self.renderer.SetBackground2(self.bg_color_2) self.renderer.GradientBackgroundOn() self.perspective = 0 self.camera = vtk.vtkCamera() self.renderer.SetActiveCamera(self.camera) self.renderer.ResetCamera() self.renderer_picked.SetActiveCamera(self.camera) self.renderer_hovered.SetActiveCamera(self.camera) self.interactor_style = DefaultInteractorStyle(self) self.interactor_style.set_default_renderer(self.renderer) #self.interactor_style.SetDefaultRenderer(self.renderer) self.interactor.SetInteractorStyle(self.interactor_style) self.interactor.Start() # http://www.paraview.org/Wiki/VTK/Examples/Python/Widgets/EmbedPyQt # http://www.vtk.org/pipermail/vtk-developers/2013-July/014005.html # see above why self.main_window.show() is done here self.main_window.show() self.iren.Initialize() def set_up_pipeline(self): self.group_selections = self.group_selections_.GetCellData() # this is temporary for now until grouping features are added self.group_selections.AddArray(self.data_source.default_group) self.group_filter.SetInputConnection(0, self.data_source.GetOutputPort(0)) self.group_filter.set_group_selections(self.group_selections) self.visible_filter.SetInputConnection( 0, self.group_filter.GetOutputPort(0)) self.main_pipeline.split_data_filter.SetInputConnection( self.visible_filter.all_port()) self.selected_pipeline.global_id_filter.SetInputConnection( self.visible_filter.all_port()) self.hovered_pipeline.global_id_filter.SetInputConnection( self.visible_filter.all_port()) def render(self): self.interactor.GetRenderWindow().Render() def set_bdf_data(self, bdf): self.bdf = bdf self.data_source.set_bdf(self.bdf) self.bdf = None self.data_source.Update() self.render() # needs to be renamed def toggle_visible(self): self.visible_filter.toggle_visible() self.render() # needs to be renamed def toggle_selected(self): # toggles selected between shown and hidden self.toggle_selection_node.SetSelectionList( self.interactor_style.model_picker.picked_selection. all_selection_vtk_array()) self.toggle_selection_node.Modified() self.toggle_selection.Modified() self.toggle_filter.Modified() self.toggle_filter.Update() selected_data = self.toggle_filter.GetOutput() original_ids = selected_data.GetCellData().GetArray("original_ids") original_data = self.group_filter.GetOutputDataObject(0) visible_array = original_data.GetCellData().GetArray("visible") # TODO: speed this up using numpy? for i in xrange(original_ids.GetNumberOfTuples()): id = int(original_ids.GetValue(i)) previous_value = int(visible_array.GetTuple1(id)) visible_array.SetTuple1(id, -previous_value) self.visible_filter.Modified() self.render() def toggle_picking(self, entity_type, index=None): self.interactor_style.model_picker.toggle_picking(entity_type, index) def update_ui_selection(self, selection): self.main_window.ui.selection_box.setText(selection) def replace_selection_button(self): self.interactor_style.model_picker.picked_selection.selection_type = vtk_globals.SELECTION_REPLACE def append_selection_button(self): self.interactor_style.model_picker.picked_selection.selection_type = vtk_globals.SELECTION_APPEND def remove_selection_button(self): self.interactor_style.model_picker.picked_selection.selection_type = vtk_globals.SELECTION_REMOVE def single_pick_button(self): self.interactor_style.set_selection_type(vtk_globals.SELECTION_SINGLE) def box_pick_button(self): self.interactor_style.set_selection_type(vtk_globals.SELECTION_BOX) def poly_pick_button(self): self.interactor_style.set_selection_type(vtk_globals.SELECTION_POLY)
class ModelmapViewer(module_template.Viewer): """Uses vtk to display the model in 3D as an isosurface or a slice. This is not a widget but contains one, accessible with get_widget()""" def __init__(self, parent=None): super(ModelmapViewer, self).__init__(parent) self._surface_algorithm = None self._surface_actor = None self._volume_scalars = None self._volume = None self._surface_level = 0.5 self._color = (0.2, 0.8, 0.2) self._planes = [] self._volume_max = 0. self._volume_numpy = None self._vtk_widget = QVTKRenderWindowInteractor( self._widget) # _vtk_widget is actually the RenderWindowInteractor self._vtk_widget.SetInteractorStyle( vtk.vtkInteractorStyleRubberBandPick()) layout = QtGui.QVBoxLayout() layout.addWidget(self._vtk_widget) self._widget.setLayout(layout) #self._vtk_widget.Initialize() #self._vtk_widget.Start() self._renderer = vtk.vtkRenderer() self._renderer.SetDraw(0) self._vtk_render_window = self._vtk_widget.GetRenderWindow() self._vtk_render_window.AddRenderer(self._renderer) #self._renderer = self._vtk_widget.GetRenderWindow().GetRenderer() self._lut = vtk_tools.get_lookup_table(0., 1., log=False, colorscale="jet") self._create_volume_map() #self._setup_slices() #self._setup_surface() white = (1., 1., 1.) self._renderer.SetBackground(white) #self.set_view_type(VIEW_TYPE.slice) #self._vtk_widget.GetRenderWindow().Render() def initialize(self): super(ModelmapViewer, self).initialize() self._vtk_widget.Initialize() self._setup_slices() self._setup_surface() #self.set_view_type(VIEW_TYPE.surface) self.set_view_type(VIEW_TYPE.slice) #self._vtk_widget.GetRenderWindow().Render() self._renderer.ResetCamera() # camera = self._renderer.GetActiveCamera() # camera.SetPosition(2., 2., 2.) # camera.SetFocalPoint(0., 0., 0.) self._vtk_render_window.Render() # print self._renderer.GetVolumes() # print self._renderer.VisibleActorCount() # print self._surface_actor.GetBounds() # print self._renderer.GetActiveCamera().GetPosition() def set_active(self, state): super(ModelmapViewer, self).set_active(state) self._renderer.SetDraw(int(state)) def _create_volume_map(self): """Create the vtk objects containing the data.""" self._volume_max = 1. self._volume = vtk.vtkImageData() default_side = 100 self._volume.SetExtent(0, default_side - 1, 0, default_side - 1, 0, default_side - 1) self._volume_numpy = numpy.zeros((default_side, ) * 3, dtype="float32", order="C") self._volume_numpy[:] = 0. self._volume_max = self._volume_numpy.max() self._volume_scalars = vtk.vtkFloatArray() self._volume_scalars.SetNumberOfValues(default_side**3) self._volume_scalars.SetNumberOfComponents(1) self._volume_scalars.SetName("Values") self._volume_scalars.SetVoidArray(self._volume_numpy, default_side**3, 1) self._volume.GetPointData().SetScalars(self._volume_scalars) def _setup_surface(self): """Create the isosurface object, mapper and actor""" self._surface_level = INIT_SURFACE_LEVEL self._surface_algorithm = vtk.vtkMarchingCubes() if VTK_VERSION < 6: self._surface_algorithm.SetInput(self._volume) else: self._surface_algorithm.SetInputData(self._volume) self._surface_algorithm.ComputeNormalsOn() self._surface_algorithm.SetValue(0, self._surface_level) mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(self._surface_algorithm.GetOutputPort()) mapper.ScalarVisibilityOff() self._surface_actor = vtk.vtkActor() self._surface_actor.GetProperty().SetColor(self._color[0], self._color[1], self._color[2]) self._surface_actor.SetMapper(mapper) self._renderer.AddViewProp(self._surface_actor) def _setup_slices(self): """Create the slices. No actor required in this case""" picker = vtk.vtkCellPicker() picker_tolerance = 0.005 picker.SetTolerance(picker_tolerance) text_color = (0., 0., 0.) if len(self._planes) != 0: raise RuntimeError("planes initialized twice") self._planes.append(vtk.vtkImagePlaneWidget()) if VTK_VERSION < 6: self._planes[0].SetInput(self._volume) else: self._planes[0].SetInputData(self._volume) self._planes[0].UserControlledLookupTableOn() self._planes[0].SetLookupTable(self._lut) self._planes[0].SetPlaneOrientationToXAxes() self._planes[0].SetSliceIndex( self._volume.GetExtent()[1] / 2) # GetExtent returns a six length array, begin-end pairs self._planes[0].DisplayTextOn() self._planes[0].GetTextProperty().SetColor(text_color) self._planes[0].SetPicker(picker) self._planes[0].SetLeftButtonAction(1) self._planes[0].SetMiddleButtonAction(2) self._planes[0].SetRightButtonAction(0) self._planes[0].SetInteractor(self._vtk_widget) # self._planes[0].On() self._planes.append(vtk.vtkImagePlaneWidget()) if VTK_VERSION < 6: self._planes[1].SetInput(self._volume) else: self._planes[1].SetInputData(self._volume) self._planes[1].UserControlledLookupTableOn() self._planes[1].SetLookupTable(self._lut) self._planes[1].SetPlaneOrientationToZAxes() self._planes[1].SetSliceIndex( self._volume.GetExtent()[5] / 2) # GetExtent returns a six length array, begin-end pairs self._planes[1].DisplayTextOn() self._planes[1].GetTextProperty().SetColor(text_color) self._planes[1].SetPicker(picker) self._planes[1].SetLeftButtonAction(1) self._planes[1].SetMiddleButtonAction(2) self._planes[1].SetRightButtonAction(0) self._planes[1].SetInteractor(self._vtk_widget) # self._planes[1].On() def set_surface_visibility(self, state): """Hide or show the surface, used when swithching between the surface and""" if state: self._surface_actor.SetVisibility(1) else: self._surface_actor.SetVisibility(0) def set_slice_visibility(self, state): """Hide or show the slices, used when swithching between the surface and""" if state: self._planes[0].SetEnabled(1) self._planes[1].SetEnabled(1) else: self._planes[0].SetEnabled(0) self._planes[1].SetEnabled(0) def set_view_type(self, view_type): """Switch between viewing slices or isosurface.""" if view_type == VIEW_TYPE.surface: self.set_slice_visibility(False) self.set_surface_visibility(True) elif view_type == VIEW_TYPE.slice: self.set_surface_visibility(False) self.set_slice_visibility(True) def _update_surface_level(self): """Set the isosurface level based on the relative level in _surface_level and the maximum value of the current model.""" if self._surface_algorithm != None: self._surface_algorithm.SetValue( 0, self._surface_level * self._volume_max) self._surface_algorithm.Modified() self._vtk_widget.Render() def set_surface_level(self, value): """Change the relative isosurface level""" if value < 0. or value > 1.: raise ValueError("Surface value must be in [0.,1.], was %g\n", value) self._surface_level = value self._update_surface_level() def get_surface_level(self): """Get the relative isosurface level""" return self._surface_level def plot_map(self, new_data_array): """Update the viwer to show the provided map.""" if (new_data_array.shape != self._volume_numpy.shape): self.plot_map_init(new_data_array) return self._volume_numpy[:, :, :] = new_data_array self._volume_max = new_data_array.max() self._lut.SetTableRange(new_data_array.min(), new_data_array.max()) self._update_surface_level() self._volume_scalars.Modified() #self._vtk_widget.GetRenderWindow().Render() self._vtk_render_window.Render() def plot_map_init(self, new_data_array): """As opposed to plot_map() this function accepts maps of different side than the active one""" self._volume_max = new_data_array.max() old_extent = numpy.array(self._volume.GetExtent()) self._volume.SetExtent(0, new_data_array.shape[0] - 1, 0, new_data_array.shape[1] - 1, 0, new_data_array.shape[2] - 1) self._volume_numpy = numpy.ascontiguousarray(new_data_array, dtype="float32") self._volume_scalars = vtk.vtkFloatArray() self._volume_scalars.SetNumberOfValues( numpy.product(self._volume_numpy.shape)) self._volume_scalars.SetNumberOfComponents(1) self._volume_scalars.SetName("Values") self._volume_scalars.SetVoidArray( self._volume_numpy, numpy.product(self._volume_numpy.shape), 1) self._volume.GetPointData().SetScalars(self._volume_scalars) # self._volume_scalars.SetNumberOfValues(new_data_array.shape[0]*new_data_array.shape[1]*new_data_array.shape[2]) # for i, this_value in enumerate(numpy.ravel(new_data_array.swapaxes(0, 2))): # self._volume_scalars.SetValue(i, this_value) self._lut.SetTableRange(new_data_array.min(), new_data_array.max()) #self._volume.GetPointData().SetScalars(self._volume_scalars) self._update_surface_level() self._volume_scalars.Modified() self._volume.Modified() new_extent = numpy.array(self._volume.GetExtent()) scaling_factors = numpy.float64(new_extent[1::2]) / numpy.float64( old_extent[1::2]) self._planes[0].SetOrigin( numpy.array(self._planes[0].GetOrigin() * scaling_factors)) self._planes[0].SetPoint1( numpy.array(self._planes[0].GetPoint1() * scaling_factors)) self._planes[0].SetPoint2( numpy.array(self._planes[0].GetPoint2() * scaling_factors)) self._planes[1].SetOrigin( numpy.array(self._planes[1].GetOrigin() * scaling_factors)) self._planes[1].SetPoint1( numpy.array(self._planes[1].GetPoint1() * scaling_factors)) self._planes[1].SetPoint2( numpy.array(self._planes[1].GetPoint2() * scaling_factors)) # self._planes[0].Modified() # self._planes[1].Modified() self._planes[0].UpdatePlacement() self._planes[1].UpdatePlacement() self._vtk_widget.Render() self._renderer.Render()
class SliceViewer(module_template.Viewer): """Plots the slices using vtk.""" def __init__(self, data, parent): super(SliceViewer, self).__init__() self._data = data self._lut = None self._actors = {} self._camera = None #self._slice_generator = SliceGenerator(self._data.get_image_side(), self._data.get_curvature()) #self._workspace = QtGui.QWorkspace() self._widget = QtGui.QWidget(parent) self._vtk_widget = QVTKRenderWindowInteractor(self._widget) self._vtk_widget.SetInteractorStyle( vtk.vtkInteractorStyleRubberBandPick()) #self._vtk_widget = QtGui.QPushButton("Foo", parent=self._widget) layout = QtGui.QVBoxLayout() #layout.addWidget(self._workspace) layout.addWidget(self._vtk_widget) #self._workspace.addWindow(self._vtk_widget) self._widget.setLayout(layout) # self._vtk_widget.Initialize() # self._vtk_widget.Start() self._renderer = vtk.vtkRenderer() self._renderer.SetDraw(0) self._vtk_render_window = self._vtk_widget.GetRenderWindow() self._vtk_render_window.AddRenderer(self._renderer) #self._setup_slice_view() def initialize(self): #pass self._vtk_widget.Initialize() self._setup_slice_view() self._slice_generator = SliceGenerator(self._data.get_image_side(), self._data.get_curvature()) def set_active(self, state): super(SliceViewer, self).set_active(state) self._renderer.SetDraw(int(state)) def _draw(self): if VTK_VERSION < 6: self._vtk_render_window.Render() else: if self._vtk_render_window.IsDrawable(): self._vtk_render_window.Render() def _setup_slice_view(self): """Setup background, camera and LUT.""" self._renderer.SetBackground(1, 1, 1) # camera self._camera = vtk.vtkCamera() self._camera.SetPosition(130, 130, 170) self._camera.SetFocalPoint(0., 0., 0.) self._camera.SetViewUp(0, 0, 1) self._renderer.SetActiveCamera(self._camera) # self._lut = vtk_tools.get_lookup_table(self._data.get_total_min(), self._data.get_total_max(), # log=True, colorscale="jet") self._lut = vtk_tools.get_lookup_table(0.1, 10., log=True, colorscale="jet") def _update_lut(self): """Call after new images were added to update the LUT to include the entire range.""" # self._lut = vtk_tools.get_lookup_table(self._data.get_total_min(), self._data.get_total_max(), # log=True, colorscale="jet") #self._lut.SetTableRange(self._data.get_total_min(), self._data.get_total_max()) self._lut.SetTableRange( max(self._data.get_total_min(), 0.0001 * self._data.get_total_max()), self._data.get_total_max()) self._lut.Build() self._draw() def _add_poly_data(self, this_poly_data, identifier): """Add a polydata and give it an id by which it can be accessed later.""" if identifier in self._actors: raise ValueError("Actor with identifier %d is already plotted" % identifier) mapper = vtk.vtkPolyDataMapper() #mapper.SetInput(this_poly_data) if VTK_VERSION < 6: mapper.SetInput(this_poly_data) else: mapper.SetInputData(this_poly_data) mapper.SetScalarModeToUsePointData() mapper.UseLookupTableScalarRangeOn() self._update_lut() mapper.SetLookupTable(self._lut) actor = vtk.vtkActor() actor.SetMapper(mapper) #actor.GetProperty().SetOpacity(0.999999) self._actors[identifier] = actor self._renderer.AddActor(actor) #self._renderer.UseDepthPeelingOn() def _remove_poly_data(self, identifier): """Remove polydata with the specified id.""" if not identifier in self._actors: raise ValueError( "Trying to remove actor with id %d that doesn't exist." % identifier) self._renderer.RemoveActor(self._actors[identifier]) del self._actors[identifier] def add_slice(self, index): """Add the image with the specified index to the view.""" self._add_poly_data( self._slice_generator.get_slice(self._data.get_image(index), self._data.get_rotation(index)), index) self._draw() def add_multiple_slices(self, index_list): """Add all the specified images to the view.""" for index in index_list: self._add_poly_data( self._slice_generator.get_slice( self._data.get_image(index), self._data.get_rotation(index)), index) self._draw() def remove_slice(self, index, render=True): """Remove the specified image from the view.""" self._remove_poly_data(index) #self._vtk_widget.GetRenderWindow().Render() if render: self._draw() def remove_all_slices(self): """Clear the view.""" for index in self.get_all_indices(): self._remove_poly_data(index) def get_all_indices(self): """Get all ids currently known to the viewer.""" return self._actors.keys()
class VTKCanvas(QtGui.QFrame): ''' the Qt4 frame that holds the main VTK canvas ''' def __init__(self, parent, Qt4GUI): super(VTKCanvas, self).__init__(parent) # dictionary to keep track of tree widget items that correspond to actors/icons - used to handle vtk->Qt4 scene changes self.actors_to_tree_widget_items = {} # Qt4 GUI that this canvas is associated with self.Qt4GUI = Qt4GUI # camera perspective type check self.camera_perspective = False # setup the vtk renderers - one for objects, one for overlay icons/text (which always renders on top) self.vtk_renderer = vtk.vtkRenderer() # setup the vtk interactor self.vtk_interactor = QVTKRenderWindowInteractor(self) # setup the vtk render window self.vtk_render_window = self.vtk_interactor.GetRenderWindow() self.vtk_render_window.AddRenderer(self.vtk_renderer) self.vtk_render_window.SetInteractor(self.vtk_interactor) #setup the layout of the vtk interactor in Qt self.layout = QtGui.QHBoxLayout() self.layout.addWidget(self.vtk_interactor) self.layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.layout) def setupTimerCallback(self, targetFPS=30): # calling this function will setup a timer and callback to continuously render the scene at the target FPS self.vtk_interactor.AddObserver('TimerEvent', self.requestUpdate) self.vtk_interactor.CreateRepeatingTimer(long(targetFPS)) def requestUpdate(self, obj, event): # request a render update of the scene self.vtk_render_window.Render() def start(self): # setup the vtk background - as default, set to light self.vtk_renderer.GradientBackgroundOn() self.setBackgroundLight() # setup the default camera self.camera_perspective = False self.defaultPerspectiveCamera() # setup a default light kit (simple sun illumination + camera spotlight) self.light_kit = vtk.vtkLightKit() self.light_kit.MaintainLuminanceOn() self.light_kit.AddLightsToRenderer(self.vtk_renderer) # add the orientation axes to the bottom left of the canvas self.Qt4GUI.addOrientationAxes() # setup the default base grid - 1x1km, 10m squares self.Qt4GUI.addGrid(['grids', '1 km x 1 km, 10 m'], 1000, 10) # startup vtk self.vtk_interactor.Initialize() self.vtk_interactor.Start() def resetCamera(self): if self.camera_perspective: self.camera_perspective = False self.defaultPerspectiveCamera() else: self.camera_perspective = True self.defaultTopDownCamera() def defaultPerspectiveCamera(self): self.Qt4GUI.camera_perspective_signal.emit(True) if not self.camera_perspective: self.vtk_renderer.SetActiveCamera(vtk.vtkCamera()) self.vtk_interactor.SetInteractorStyle(TerrainInteractorStyle()) self.vtk_renderer.GetActiveCamera().SetViewUp(0, 0, 1) self.vtk_renderer.GetActiveCamera().SetPosition(0, 1, 10) self.vtk_renderer.GetActiveCamera().SetFocalPoint(0, 0, 0) self.vtk_renderer.GetActiveCamera().Azimuth(135) self.vtk_renderer.GetActiveCamera().Elevation(86) self.vtk_renderer.GetActiveCamera().Dolly(0.4) self.vtk_renderer.GetActiveCamera().Zoom(1) self.vtk_renderer.ResetCameraClippingRange() self.camera_perspective = True self.vtk_interactor.Render() def perspectiveCamera(self): self.Qt4GUI.camera_perspective_signal.emit(True) if not self.camera_perspective: curr_fp = self.vtk_renderer.GetActiveCamera().GetFocalPoint() curr_pos = [curr_fp[0], curr_fp[1] + 1, 10] curr_fp = [curr_fp[0], curr_fp[1], 0] self.vtk_renderer.SetActiveCamera(vtk.vtkCamera()) self.vtk_interactor.SetInteractorStyle(TerrainInteractorStyle()) self.vtk_renderer.GetActiveCamera().SetViewUp(0, 0, 1) self.vtk_renderer.GetActiveCamera().SetPosition(curr_pos) self.vtk_renderer.GetActiveCamera().SetFocalPoint(curr_fp) self.vtk_renderer.GetActiveCamera().Azimuth(135) self.vtk_renderer.GetActiveCamera().Elevation(86) self.vtk_renderer.GetActiveCamera().Dolly(0.4) self.vtk_renderer.GetActiveCamera().Zoom(1) self.vtk_renderer.ResetCameraClippingRange() self.camera_perspective = True self.vtk_interactor.Render() def defaultTopDownCamera(self): self.Qt4GUI.camera_perspective_signal.emit(False) if self.camera_perspective: self.vtk_renderer.SetActiveCamera(vtk.vtkCamera()) self.vtk_interactor.SetInteractorStyle(TopDownInteractorStyle()) self.vtk_renderer.GetActiveCamera().SetViewUp(0, 1, 0) self.vtk_renderer.GetActiveCamera().ParallelProjectionOn() self.vtk_renderer.GetActiveCamera().SetParallelScale(1000) self.vtk_renderer.GetActiveCamera().SetPosition(0, 0, 1e4) self.vtk_renderer.GetActiveCamera().SetFocalPoint(0, 0, 0) self.vtk_renderer.GetActiveCamera().Elevation(0) self.vtk_renderer.GetActiveCamera().Azimuth(0) self.vtk_renderer.GetActiveCamera().Dolly(0.4) self.vtk_renderer.GetActiveCamera().Zoom(100) self.vtk_renderer.ResetCameraClippingRange() self.camera_perspective = False self.vtk_interactor.Render() def topDownCamera(self): self.Qt4GUI.camera_perspective_signal.emit(False) if self.camera_perspective: curr_fp = self.vtk_renderer.GetActiveCamera().GetFocalPoint() curr_pos = [curr_fp[0], curr_fp[1], 1e4] curr_fp = [curr_fp[0], curr_fp[1], 0] self.vtk_renderer.SetActiveCamera(vtk.vtkCamera()) self.vtk_interactor.SetInteractorStyle(TopDownInteractorStyle()) self.vtk_renderer.GetActiveCamera().SetViewUp(0, 1, 0) self.vtk_renderer.GetActiveCamera().ParallelProjectionOn() self.vtk_renderer.GetActiveCamera().SetParallelScale(1000) self.vtk_renderer.GetActiveCamera().SetPosition(curr_pos) self.vtk_renderer.GetActiveCamera().SetFocalPoint(curr_fp) self.vtk_renderer.GetActiveCamera().Elevation(0) self.vtk_renderer.GetActiveCamera().Azimuth(0) self.vtk_renderer.GetActiveCamera().Dolly(0.4) self.vtk_renderer.GetActiveCamera().Zoom(100) self.vtk_renderer.ResetCameraClippingRange() self.camera_perspective = False self.vtk_interactor.Render() def setBackgroundLight(self): self.Qt4GUI.background_light_signal.emit(True) self.vtk_renderer.SetBackground2(220.0 / 255, 225.0 / 255, 235.0 / 255) self.vtk_renderer.SetBackground(105.0 / 255, 135.0 / 255, 155.0 / 255) self.vtk_interactor.Render() def setBackgroundDark(self): self.Qt4GUI.background_light_signal.emit(False) self.vtk_renderer.SetBackground(0.0 / 255, 10.0 / 255, 15.0 / 255) self.vtk_renderer.SetBackground2(60.0 / 255, 80.0 / 255, 110.0 / 255) self.vtk_interactor.Render() def addActorFrameAxes(self, tree_widget): frame_axes = Primitives.Axes() frame_axes.AxisLabelsOff() frame_axes.VisibilityOff() self.vtk_renderer.AddActor(frame_axes) self.vtk_interactor.Render() return frame_axes def removeActorFrameAxes(self, actor): self.vtk_renderer.RemoveActor(actor) self.vtk_interactor.Render() def addActor(self, tree_widget, actor): self.actors_to_tree_widget_items[actor] = tree_widget self.vtk_renderer.AddActor(actor) self.vtk_interactor.Render() def removeActor(self, actor): del self.actors_to_tree_widget_items[actor] self.vtk_renderer.RemoveActor(actor) self.vtk_interactor.Render() def replaceActor(self, remove_actor, tree_widget, actor): self.removeActor(remove_actor) self.addActor(tree_widget, actor) def setActorVisibility(self, actor, visible): if visible: actor.VisibilityOn() else: actor.VisibilityOff() self.vtk_interactor.Render() def setActorScale(self, actor, scale): if actor.GetClassName() == "vtkAxesActor": actor.SetTotalLength(scale, scale, scale) else: if actor.__class__ == Billboards.TextBillboard or actor.__class__ == Billboards.ImageBillboard: # billboards have no scaling return actor.SetScale(scale) self.vtk_interactor.Render() def getActorScale(self, actor): if actor.GetClassName() == "vtkAxesActor": return actor.GetTotalLength() else: if actor.__class__ == Billboards.TextBillboard or actor.__class__ == Billboards.ImageBillboard: # billboards have no scaling return [1, 1, 1] return actor.GetScale() def setActorOpacity(self, actor, opacity): actor.GetProperty().SetOpacity(opacity) self.vtk_interactor.Render() def getActorOpacity(self, actor): return actor.GetProperty().GetOpacity() def setActorPointSize(self, actor, size): actor.GetProperty().SetPointSize(size) self.vtk_interactor.Render() def getActorPointSize(self, actor): return actor.GetProperty().GetPointSize() def setActorLineWidth(self, actor, width): actor.GetProperty().SetLineWidth(width) self.vtk_interactor.Render() def getActorLineWidth(self, actor): return actor.GetProperty().GetLineWidth() def setActorToSurface(self, actor): if actor.__class__ == Billboards.TextBillboard or actor.__class__ == Billboards.ImageBillboard: # billboards have no render mode return actor.GetProperty().EdgeVisibilityOff() actor.GetProperty().SetRepresentationToSurface() self.vtk_interactor.Render() def setActorToWireframe(self, actor): if actor.__class__ == Billboards.TextBillboard or actor.__class__ == Billboards.ImageBillboard: # billboards have no render mode return actor.GetProperty().EdgeVisibilityOff() actor.GetProperty().SetRepresentationToWireframe() self.vtk_interactor.Render() def setActorToSurfaceEdges(self, actor): if actor.__class__ == Billboards.TextBillboard or actor.__class__ == Billboards.ImageBillboard: # billboards have no render mode return actor.GetProperty().EdgeVisibilityOn() actor.GetProperty().SetRepresentationToSurface() self.vtk_interactor.Render() def setActorToPoints(self, actor): if actor.__class__ == Billboards.TextBillboard or actor.__class__ == Billboards.ImageBillboard: # billboards have no render mode return actor.GetProperty().EdgeVisibilityOff() actor.GetProperty().SetRepresentationToPoints() self.vtk_interactor.Render() def getActorRenderMode(self, actor): if actor.__class__ == Billboards.TextBillboard or actor.__class__ == Billboards.ImageBillboard: # billboards have no render mode return None, None edge = actor.GetProperty().GetEdgeVisibility() mode = actor.GetProperty().GetRepresentation() return edge, mode def getActorColor(self, actor): return actor.GetProperty().GetColor() def setActorColor(self, actor, r, g, b): actor.GetProperty().SetColor(r, g, b) self.vtk_interactor.Render() def setActorTexture(self, actor, image_path): if actor.__class__ == Billboards.TextBillboard: # text billboards have no texture return if image_path[-4:].lower() == '.jpg' or image_path[-4:].lower( ) == '.jpeg': reader = vtk.vtkJPEGReader() reader.SetFileName(image_path) reader.Update() elif image_path[-4:].lower() == '.png': reader = vtk.vtkPNGReader() reader.SetFileName(image_path) reader.Update() texture = vtk.vtkTexture() texture.RepeatOn() texture.SetInputConnection(reader.GetOutputPort()) actor.SetTexture(texture) # polydata = actor.GetMapper().GetInput() # pointdata = polydata.GetPointData() # celldata = polydata.GetCellData() # numtuples = celldata.GetNumberOfTuples() # numpolygons = polydata.GetNumberOfPolys() self.vtk_interactor.Render() def removeActorTexture(self, actor): actor.SetTexture(None) self.vtk_interactor.Render() def setActorOffset(self, actor, x_offset, y_offset, z_offset): if actor.__class__ == Billboards.TextBillboard or actor.__class__ == Billboards.ImageBillboard: # billboards are unaffected by offset changes pass else: actor.SetPosition(x_offset, y_offset, z_offset) self.vtk_interactor.Render() def setActorOrientation(self, actor, roll, pitch, yaw): actor.SetOrientation(roll, pitch, yaw) self.vtk_interactor.Render()
class VTKFrame(QtGui.QFrame): def __init__(self, parent=None): super(VTKFrame, self).__init__(parent) self.vl = QtGui.QVBoxLayout(self) self.vl.setContentsMargins(0, 0, 0, 0) self.vtkWidget = QVTKRenderWindowInteractor(self) self.vl.addWidget(self.vtkWidget) self._renderer = vtk.vtkRenderer() self.vtkWidget.GetRenderWindow().AddRenderer(self._renderer) self.iren = self.vtkWidget.GetRenderWindow().GetInteractor() #Create an style self._interactorStyle = MouseInteractorActor() self._interactorStyle.SetDefaultRenderer(self._renderer) self.vtkWidget.SetInteractorStyle(self._interactorStyle) self._actor1 = self.createActor1() self._actor2 = self.createActor2() self._renderer.AddActor(self._actor1) self._renderer.AddActor(self._actor2) self._renderer.ResetCamera() self._renderer.SetBackground(.1, .2, .3) self._initialized = False def createActor1(self): # Create source polyDataPoints = vtk.vtkPoints() polyDataPoints.InsertPoint(0, 1., 0., 0.) polyDataPoints.InsertPoint(1, 1., 0., 10.) polyDataPoints.InsertPoint(2, 3., 0., 10.) polyDataPoints.InsertPoint(3, 2., 0., 0.) polygon = vtk.vtkPolygon() polygon.GetPointIds().SetNumberOfIds(4) polygon.GetPointIds().SetId(0, 0) polygon.GetPointIds().SetId(1, 1) polygon.GetPointIds().SetId(2, 2) polygon.GetPointIds().SetId(3, 3) polygons = vtk.vtkCellArray() polygons.InsertNextCell(polygon) polyData = vtk.vtkPolyData() polyData.SetPoints(polyDataPoints) #polyData.SetLines(polygons) polyData.SetPolys(polygons) rotationalExtrusionFilter = vtk.vtkRotationalExtrusionFilter() rotationalExtrusionFilter.SetInput(polyData) rotationalExtrusionFilter.SetResolution(10) rotationalExtrusionFilter.SetAngle(240) rotationalExtrusionFilter.SetTranslation(0) # Create a mapper mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(rotationalExtrusionFilter.GetOutputPort()) # Create an actor actor = vtk.vtkActor() actor.SetMapper(mapper) #actor.GetProperty().SetColor(1.0, 0, 0) return actor def createActor2(self): # Create source source = vtk.vtkSphereSource() source.SetCenter(0, 0, 0) source.SetRadius(0.8) # Create a mapper mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(source.GetOutputPort()) # Create an actor actor = vtk.vtkActor() actor.SetMapper(mapper) return actor def showEvent(self, evt): if self._initialized: return self.iren.Initialize() self._initialized = True
class PickWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.setStyleSheet('background-color:#333333') self.vtk_layout = QtGui.QGridLayout(self) self.vtk_widget = QVTKRenderWindowInteractor(self) self.vtk_layout.addWidget(self.vtk_widget) self.ren = vtk.vtkRenderer() self.vtk_widget.GetRenderWindow().AddRenderer(self.ren) self.meshMapper = vtk.vtkPolyDataMapper() self.meshActor = vtk.vtkActor() self.meshActor.SetMapper(self.meshMapper) self.ren.AddActor(self.meshActor) self.interactionStyle = RubberBandFacePicker() self.interactionStyle.SetDefaultRenderer(self.ren) self.vtk_widget.SetInteractorStyle(self.interactionStyle) self.vtk_widget.SetPicker(vtk.vtkAreaPicker()) self.iren = self.vtk_widget.GetRenderWindow().GetInteractor() self.show() self.iren.Initialize() # name2actor map for calls to display_XXXX self.name2actor = {} def start(self): self.reader = vtk.vtkOBJReader() self.reader.SetFileName(self.filename) self.meshMapper.SetInputConnection(self.reader.GetOutputPort()) self.interactionStyle.Data = self.reader.GetOutput() self.interactionStyle.Widget = self def set_source(self, filename): self.filename = filename def set_selected_color(self, color): self.interactionStyle.set_selected_pt_color(color) def get_selected_vertices(self): V = self.interactionStyle.get_selected_vertices() return V def display_cloud(self, actorName, list_points, size, vec3_color): # extract inlier points vtk_points = vtk.vtkPoints() for p in list_points: vtk_points.InsertNextPoint(p[0], p[1], p[2]) temp_cloud = vtk.vtkPolyData() temp_cloud.SetPoints(vtk_points) # add 0D topology to every point glfilter = vtk.vtkVertexGlyphFilter() glfilter.SetInput(temp_cloud) glfilter.Update() cloud = glfilter.GetOutput() cloudMapper = vtk.vtkPolyDataMapper() cloudMapper.SetInput(cloud) actor = vtk.vtkActor() actor.SetMapper(cloudMapper) actor.GetProperty().SetColor(vec3_color[0], vec3_color[1], vec3_color[2]) actor.GetProperty().SetPointSize(size) self.ren.AddActor(actor) self.name2actor[actorName] = actor pass def display_sphere(self, actorName, vec3_center, radius, vec3_color): sphere = vtk.vtkSphereSource() sphere.SetRadius(radius) sphere.SetCenter(vec3_center) sphere.SetThetaResolution(40) sphere.SetPhiResolution(40) sphere.SetCenter(vec3_center[0], vec3_center[1], vec3_center[2]) sphere.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(sphere.GetOutputPort()) actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetColor(vec3_color[0], vec3_color[1], vec3_color[2]) self.ren.AddActor(actor) self.name2actor[actorName] = actor pass def display_cylinder(self, actorName, vec3_origin, vec3_direction, height, radius, vec3_color): cyl = vtk.vtkCylinderSource() cyl.SetRadius(radius) cyl.SetHeight(height) cyl.SetCapping(1) cyl.Update() # transform to center with orientation according to normal axis1 = [vec3_direction[0], vec3_direction[1], vec3_direction[2]] axis2 = np.cross(axis1, [1, 1, 1]) axis2 = axis2 / np.linalg.norm(axis2) axis3 = np.cross(axis2, axis1) # print axis1 # print axis2 # print axis3 trans = np.eye(4) trans[0, 0] = axis2[0] trans[0, 1] = axis1[0] trans[0, 2] = axis3[0] trans[0, 3] = vec3_origin[0] trans[1, 0] = axis2[1] trans[1, 1] = axis1[1] trans[1, 2] = axis3[1] trans[1, 3] = vec3_origin[1] trans[2, 0] = axis2[2] trans[2, 1] = axis1[2] trans[2, 2] = axis3[2] trans[2, 3] = vec3_origin[2] trans[3, 0] = 0 trans[3, 1] = 0 trans[3, 2] = 0 trans[3, 3] = 1 vtk_trans = vtk.vtkMatrix4x4() for i in range(0, 4): for j in range(0, 4): vtk_trans.SetElement(i, j, trans[i, j]) ar_trans = vtk.vtkTransform() ar_trans.SetMatrix(vtk_trans) ar_trans_filter = vtk.vtkTransformPolyDataFilter() ar_trans_filter.SetTransform(ar_trans) ar_trans_filter.SetInputConnection(cyl.GetOutputPort()) mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(ar_trans_filter.GetOutputPort()) actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetColor(vec3_color[0], vec3_color[1], vec3_color[2]) self.ren.AddActor(actor) self.name2actor[actorName] = actor return def display_disk(self, actorName, vec3_origin, vec3_direction, outer_radius, inner_radius, vec3_color): disk = vtk.vtkDiskSource() disk.SetInnerRadius(inner_radius) disk.SetOuterRadius(outer_radius) disk.SetRadialResolution(30) disk.SetCircumferentialResolution(30) disk.Update() # transform to center with orientation according to normal axis1 = [vec3_direction[0], vec3_direction[1], vec3_direction[2]] axis2 = np.cross(axis1, [1, 1, 1]) axis2 = axis2 / np.linalg.norm(axis2) axis3 = np.cross(axis1, axis2) # print axis1 # print axis2 # print axis3 trans = np.eye(4) trans[0, 0] = axis3[0] trans[0, 1] = axis2[0] trans[0, 2] = axis1[0] trans[0, 3] = vec3_origin[0] trans[1, 0] = axis3[1] trans[1, 1] = axis2[1] trans[1, 2] = axis1[1] trans[1, 3] = vec3_origin[1] trans[2, 0] = axis3[2] trans[2, 1] = axis2[2] trans[2, 2] = axis1[2] trans[2, 3] = vec3_origin[2] trans[3, 0] = 0 trans[3, 1] = 0 trans[3, 2] = 0 trans[3, 3] = 1 vtk_trans = vtk.vtkMatrix4x4() for i in range(0, 4): for j in range(0, 4): vtk_trans.SetElement(i, j, trans[i, j]) ar_trans = vtk.vtkTransform() ar_trans.SetMatrix(vtk_trans) ar_trans_filter = vtk.vtkTransformPolyDataFilter() ar_trans_filter.SetTransform(ar_trans) ar_trans_filter.SetInputConnection(disk.GetOutputPort()) diskMapper = vtk.vtkPolyDataMapper() diskMapper.SetInputConnection(ar_trans_filter.GetOutputPort()) actor = vtk.vtkActor() actor.SetMapper(diskMapper) actor.GetProperty().SetColor(vec3_color[0], vec3_color[1], vec3_color[2]) self.ren.AddActor(actor) self.name2actor[actorName] = actor return def display_arrow(self, actorName, vec3_origin, vec3_direction, length_in_m, shaft_radius, vec3_color): # visualize direction arrow arrow = vtk.vtkArrowSource() arrow.SetTipLength(0.25) arrow.SetTipRadius((1.5 * shaft_radius) / length_in_m) arrow.SetTipResolution(20) arrow.SetShaftRadius(shaft_radius / length_in_m) # account for scaling arrow.SetShaftResolution(20) arrow.Update() # scale scale = vtk.vtkTransform() scale.Scale(length_in_m, length_in_m, length_in_m) scale_filter = vtk.vtkTransformPolyDataFilter() scale_filter.SetTransform(scale) scale_filter.SetInputConnection(arrow.GetOutputPort()) # transform to center with orientation according to normal axis1 = [vec3_direction[0], vec3_direction[1], vec3_direction[2]] axis2 = np.cross(axis1, [1, 1, 1]) axis2 = axis2 / np.linalg.norm(axis2) axis3 = np.cross(axis1, axis2) # print axis1 # print axis2 # print axis3 trans = np.eye(4) trans[0, 0] = axis1[0] trans[0, 1] = axis2[0] trans[0, 2] = axis3[0] trans[0, 3] = vec3_origin[0] trans[1, 0] = axis1[1] trans[1, 1] = axis2[1] trans[1, 2] = axis3[1] trans[1, 3] = vec3_origin[1] trans[2, 0] = axis1[2] trans[2, 1] = axis2[2] trans[2, 2] = axis3[2] trans[2, 3] = vec3_origin[2] trans[3, 0] = 0 trans[3, 1] = 0 trans[3, 2] = 0 trans[3, 3] = 1 vtk_trans = vtk.vtkMatrix4x4() for i in range(0, 4): for j in range(0, 4): vtk_trans.SetElement(i, j, trans[i, j]) ar_trans = vtk.vtkTransform() ar_trans.SetMatrix(vtk_trans) ar_trans_filter = vtk.vtkTransformPolyDataFilter() ar_trans_filter.SetTransform(ar_trans) ar_trans_filter.SetInputConnection(scale_filter.GetOutputPort()) arrowMapper = vtk.vtkPolyDataMapper() arrowMapper.SetInputConnection(ar_trans_filter.GetOutputPort()) actor = vtk.vtkActor() actor.SetMapper(arrowMapper) actor.GetProperty().SetColor(vec3_color[0], vec3_color[1], vec3_color[2]) self.ren.AddActor(actor) self.name2actor[actorName] = actor pass def display_affordance_primitive(self, g, type_): self.remove_all_displays() if type_ == 'axis': self.display_arrow('p', g.base, g.direction, g.length, g.radius, [1, .2, 0]) elif type_ == 'plane': self.display_disk('p', g.center, g.normal, g.radius, 0, [1, .2, 0]) self.display_arrow('p', g.center, g.normal, .1, .002, [1, .3, 0]) def remove_display(self, actorName): actor = self.name2actor.get(actorName) if (actor != None): self.ren.RemoveActor(actor) self.name2actor.pop(actorName) pass def remove_all_displays(self): for actor in self.name2actor.viewvalues(): self.ren.RemoveActor(actor) self.name2actor.clear() pass
class RenderWidget(QWidget): """ RenderWidget for rendering volumes. It has a few render types which can be set and adjusted. """ dataChanged = Signal() updated = Signal() def __init__(self): super(RenderWidget, self).__init__() # Default volume renderer self.renderer = vtkRenderer() self.renderer.SetBackground2(0.4, 0.4, 0.4) self.renderer.SetBackground(0.1, 0.1, 0.1) self.renderer.SetGradientBackground(True) self.renderer.SetLayer(0) # Overlay renderer which is synced with the default renderer self.rendererOverlay = vtkRenderer() self.rendererOverlay.SetLayer(1) self.rendererOverlay.SetInteractive(0) self.renderer.GetActiveCamera().AddObserver("ModifiedEvent", self._syncCameras) self.rwi = QVTKRenderWindowInteractor(parent=self) self.rwi.SetInteractorStyle(vtkInteractorStyleTrackballCamera()) self.rwi.GetRenderWindow().AddRenderer(self.renderer) self.rwi.GetRenderWindow().AddRenderer(self.rendererOverlay) self.rwi.GetRenderWindow().SetNumberOfLayers(2) self.rwi.SetDesiredUpdateRate(0) self.imagePlaneWidgets = [vtkImagePlaneWidget() for i in range(3)] for index in range(3): self.imagePlaneWidgets[index].DisplayTextOn() self.imagePlaneWidgets[index].SetInteractor(self.rwi) # Disable the margin for free rotation self.imagePlaneWidgets[index].SetMarginSizeX(0.0) self.imagePlaneWidgets[index].SetMarginSizeY(0.0) self.mapper = vtkOpenGLGPUVolumeRayCastMapper() self.mapper.SetAutoAdjustSampleDistances(1) self.volume = None self.imageData = None self.VolumeVisualization = None self.shouldResetCamera = False self.gridItems = [] self.orientationGridItems = [] self.clippingBox = ClippingBox() self.clippingBox.setWidget(self) # Keep track of the base and user transforms self.baseTransform = vtkTransform() self.userTransform = vtkTransform() self.setMinimumWidth(340) self.setMinimumHeight(340) layout = QGridLayout(self) layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.rwi, 0, 0) self.setLayout(layout) def render(self): self.clippingBox.update() if self.shouldResetCamera: self.renderer.ResetCamera() self.shouldResetCamera = False self.rwi.Render() # Prevent warning messages on OSX by not asking to render # when the render window has never rendered before if not self.rwi.GetRenderWindow().GetNeverRendered(): self.rwi.GetRenderWindow().Render() @Slot(object) def setData(self, imageData): """ Updates the image data. If the image data is none, then the volume gets removed from the renderer. Otherwise, the new image data is given to the mapper. """ self.imageData = imageData # Clean up the data grid self._cleanUpGrids() if self.imageData is None: if self.volume is not None: self.renderer.RemoveViewProp(self.volume) print "Warning: image data is None" self.clippingBox.setImageData(None) self.mapper.RemoveAllInputs() self.render() return # Set the image data for the mapper self.mapper.SetInputData(self.imageData) # Set the image data for the slices for index in range(3): self.imagePlaneWidgets[index].SetInputData(self.imageData) self.imagePlaneWidgets[index].SetPlaneOrientation(index) self._createGrid() self._createOrientationGrid() self.clippingBox.setImageData(self.imageData) self.clippingBox.resetClippingBox() self.shouldResetCamera = True # Don't call render, because camera should only be reset # when a volume property is loaded def showClippingBox(self, show): self.clippingBox.showClippingBox(show) self.render() def showClippingPlanes(self, show): self.clippingBox.showClippingPlanes(show) self.render() def resetClippingBox(self): self.clippingBox.resetClippingBox() self.render() @Slot(object) def setVolumeVisualization(self, volumeVisualization): """ Updates the volume property. It actually removes the volume, creates a new volume and sets the updated volume property and then adds the new volume to the renderer. Just updating the vtkVolumeProperty gives artifacts and seems to not work correctly. :type volumeVisualization: volumeVisualization """ self.volumeVisualization = volumeVisualization if self.imageData is None or self.volumeVisualization is None: if self.volume is not None: self.renderer.RemoveViewProp(self.volume) self.volume = None return if self.volume is None: self.volume = vtkVolume() self.renderer.AddViewProp(self.volume) self.volumeVisualization.setMapper(self.mapper) self.mapper.SetShaderType(self.volumeVisualization.shaderType()) if self.volume.GetProperty() != self.volumeVisualization.volProp: self.volume.SetProperty(self.volumeVisualization.volProp) if self.volume.GetMapper() != self.mapper: self.volume.SetMapper(self.mapper) self.render() @Slot(object) def setSlices(self, slices): for sliceIndex in range(len(slices)): if slices[sliceIndex]: self.imagePlaneWidgets[sliceIndex].On() else: self.imagePlaneWidgets[sliceIndex].Off() @Slot(object) def transformationsUpdated(self, transformations): """ Get the scaling transform from the transformations and apply it to the volume and to the grid that shows the bounds of the volume. At the moment it is deprecated. It makes more trouble than that it solves any real (user) problem... """ # transform = transformations.scalingTransform() # if self.volume: # self.volume.SetUserTransform(transform) # for item in self.gridItems: # item.SetUserTransform(transform) # self.clippingBox.setTransform(transform) pass def _syncCameras(self, camera, ev): """ Camera modified event callback. Copies the parameters of the renderer camera into the camera of the overlay so they stay synced at all times. """ self.rendererOverlay.GetActiveCamera().ShallowCopy(camera) def _createGrid(self): """ Create a grid that shows the bounds of the dataset. These parts need to be updated when the user is transformed. """ bounds = self.imageData.GetBounds() self.gridItems = CreateBounds(bounds) for item in self.gridItems: self.renderer.AddViewProp(item) def _createOrientationGrid(self): """ Create 3 axis that show the location / coords in 3D space. """ bounds = self.imageData.GetBounds() self.orientationGridItems = CreateOrientationGrid( bounds, self.renderer.GetActiveCamera()) for item in self.orientationGridItems: self.renderer.AddViewProp(item) def _cleanUpGrids(self): for item in self.gridItems: self.renderer.RemoveViewProp(item) for item in self.orientationGridItems: self.renderer.RemoveViewProp(item) self.gridItems = [] self.orientationGridItems = []
class MeshViewer(QtGui.QWidget): app = QtGui.QApplication(sys.argv) """ Qt GUI for visu. the output """ def __init__(self, truss, algo): QtGui.QWidget.__init__(self) self.truss = truss self.algo = algo self.algo.dhook = self self.running = 'init' print "starting MeshViewer init..." self.__setupGUI() self.__setupVTK() self.app.lastWindowClosed.connect(self.app.quit) self.show() print "MeshViewer ready." def closeEvent(self, event): self.algo.stopit=True self.running='running' # sort de "while self.running=='pause'" print "GUI killed!" QtGui.QWidget.closeEvent(self,event) def start(self): self.app.exec_() def __setupGUI(self): self.setWindowTitle("MeshViewer") self.resize(800, 600) # vtk window self.vtkwidget = QVTKRenderWindowInteractor(self) # "self" sinon, rien ne s'affiche self.vtkwidget.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)) self.vtkwidget.setMinimumSize(QtCore.QSize(300, 300)); self.vtkwidget.setSizePolicy(QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Expanding) self.vtkwidget.Initialize() self.renderer = vtk.vtkRenderer() self.renderer.SetBackground(1.0, 1.0, 1.0) self.vtkwidget.GetRenderWindow().AddRenderer(self.renderer) style = vtk.vtkInteractorStyleTrackballCamera() self.vtkwidget.SetInteractorStyle(style) hbox = QtGui.QHBoxLayout() self.setLayout(hbox) hbox.addWidget(self.vtkwidget) pan = QtGui.QFrame() pan.setMaximumSize(QtCore.QSize(200,999999)) hbox.addWidget(pan) vbox = QtGui.QVBoxLayout() pan.setLayout(vbox) self.startBut = QtGui.QPushButton(self.tr("start!")) self.connect(self.startBut, QtCore.SIGNAL("clicked()"), self.startSlot) vbox.addWidget(self.startBut) groupBox = QtGui.QGroupBox("Infos") self.steplabel = QtGui.QLabel("step # 0") self.loadlabel = QtGui.QLabel("lambda = %2.8f" % 0) gbox = QtGui.QVBoxLayout() groupBox.setLayout(gbox) gbox.addWidget(self.steplabel) gbox.addWidget(self.loadlabel) vbox.addWidget(groupBox) vbox.addStretch(1) def startSlot(self): if self.running=='init': self.startBut.setText('Pause') # on demarre et on affiche "pause" self.running='running' self.algo.run() self.startBut.setText("Quit") self.running='quit' elif self.running=='running': # on stoppe et on affiche 'continue" self.running='pause' self.startBut.setText("Continue") while self.running=='pause': self.app.processEvents(QtCore.QEventLoop.WaitForMoreEvents) elif self.running=='pause': self.running='running' self.startBut.setText("Pause") elif self.running=='quit': self.app.quit() def disableStart(self): self.startBut.setDisabled(True) def __setupVTK(self): # polydata self.__createPolyData() self.poly = PolyData(self.polydata) self.renderer.AddActor(self.poly.actor) self.renderer.AddActor2D(self.poly.pointLabels) self.resetCamera() def resetCamera(self): self.renderer.ResetCamera() cam1 = self.renderer.GetActiveCamera() # 3D if 0: cam1.Elevation(35) cam1.SetViewUp(0, 1, 0) cam1.Azimuth(30) #2D else: cam1.Elevation(0) cam1.SetViewUp(0, 1, 0) cam1.Azimuth(0) self.renderer.ResetCameraClippingRange() def display(self, step, lamda): self.steplabel.setText("step # %d" % step) self.loadlabel.setText("lambda = %2.8f" % lamda) self.points.Reset() self.vertices.Reset() self.lines.Reset() self.scalars.Reset() # points nmap={} i=0 for nod in self.truss.nodes: nmap[nod.nb]=i self.points.InsertPoint(i, nod.x, nod.y, 0.0) self.scalars.InsertNextValue(nod.nb) # node cells vertex = vtk.vtkVertex() vertex.GetPointIds().SetId(0, i) self.vertices.InsertNextCell(vertex) i+=1 self.points.Modified() self.vertices.Modified() for bar in self.truss.bars: line = vtk.vtkLine() ids = line.GetPointIds() ids.SetNumberOfIds(2) for j in range(len(bar.nodes)): ids.SetId(j, nmap[bar.nodes[j].nb]) self.lines.InsertNextCell(line) self.lines.Modified() self.polydata.Modified() self.render() def ragequit(self): print "rage quit!" self.algo.stopit=True self.app.quit() def render(self): # draw the scene self.vtkwidget.Render() self.app.processEvents() def refresh(self): self.app.processEvents() def __createPolyData(self): print 'creating vtkPolyData...' self.points = vtk.vtkPoints() self.polydata = vtk.vtkPolyData() self.vertices = vtk.vtkCellArray() self.lines = vtk.vtkCellArray() self.polydata.SetPoints(self.points) self.polydata.SetVerts(self.vertices) self.polydata.SetLines(self.lines) # points self.scalars = vtk.vtkFloatArray() self.scalars.SetNumberOfComponents(1) self.polydata.GetPointData().SetScalars(self.scalars) nmap={} i=0 for nod in self.truss.nodes: nmap[nod.nb]=i self.points.InsertPoint(i, nod.x, nod.y, 0.0) self.scalars.InsertNextValue(nod.nb) # node cells vertex = vtk.vtkVertex() vertex.GetPointIds().SetId(0, i) self.vertices.InsertNextCell(vertex) i+=1 self.points.Modified() self.vertices.Modified() for bar in self.truss.bars: line = vtk.vtkLine() ids = line.GetPointIds() ids.SetNumberOfIds(2) for j in range(len(bar.nodes)): ids.SetId(j, nmap[bar.nodes[j].nb]) self.lines.InsertNextCell(line) self.lines.Modified()