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 = []
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