''' Created on 14/06/2018 @author: rjag008 ''' import numpy as np from os import path import os,sys,shutil,json from opencmiss.zinc.context import Context from opencmiss.zinc.glyph import Glyph from opencmiss.zinc._graphics import Graphicslineattributes_SHAPE_TYPE_CIRCLE_EXTRUSION from digitiser.qtdigitiser import PainterWidget from digitiser.zincwidgets import SceneViewerWidget, ZincPainterWidget from digitiser.mapping import MeshMapper dir_path = path.dirname(path.realpath(sys.argv[0])) if not hasattr(sys, 'frozen'): #For py2exe dir_path = path.join(dir_path,"..") uiFile = path.join(dir_path,"./gui/stomachannotator.ui") projectDetailsUi = path.join(dir_path,"./gui/projectdetails.ui") projectDetailsEditUi = path.join(dir_path,"./gui/projectdetailsEdit.ui") try: from PySide import QtGui from PySide.QtGui import QApplication from PySide import QtCore, QtOpenGL from pysideuiutils.uic import loadUi from PySide import QtGui, QtWebKit signalHandle = QtCore.Signal class ProjectDetailsWindowBase(QtGui.QDialog): def __init__(self, parent=None): super(ProjectDetailsWindowBase, self).__init__(parent) loadUi(projectDetailsUi, self) class ProjectDetailsEditWindowBase(QtGui.QDialog): def __init__(self, parent=None): super(ProjectDetailsEditWindowBase, self).__init__(parent) loadUi(projectDetailsEditUi, self) class ApplicationWindowBase(QtGui.QMainWindow): def __init__(self, parent=None): super(ApplicationWindowBase, self).__init__(parent) loadUi(uiFile, self) self.projectOpened = False def closeEvent(self,event): if self.projectOpened: reply = QtGui.QMessageBox.question(self,"Unsaved new project"," The new project has not been saved! Do you wish to exit anyway?", QtGui.QMessageBox.Yes|QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.No: event.ignore() return return QtGui.QMainWindow.closeEvent(self, event) except ImportError: #from PyQt4 import QtGui, QtCore, uic #from PyQt4.QtGui import QApplication #from PyQt4 import QtGui, QtWebKit #signalHandle = QtCore.pyqtSignal ''' form,base = uic.loadUiType(uiFile) class ApplicationWindowBase(base,form): def __init__(self,parent=None): super(base,self).__init__(parent) self.setupUi(self) ''' pass class MainModelController(object): def __init__(self,appwidget): self.appWidget = appwidget self.context = appwidget.zincContext self.rootRegion = self.context.getDefaultRegion() self.pointTypeGraphics = dict() self.appWidget.mainModelInitialized.connect(self.linkToSceneViewer) self.appWidget.textureChanged.connect(self.setTexture) def loadMesh(self,meshString): region = self.rootRegion.findChildByName('stomach') if region.isValid(): self.rootRegion.removeChild(region) region = self.rootRegion.createChild('stomach') sir = region.createStreaminformationRegion() sir.createStreamresourceMemoryBuffer(str(meshString)) region.read(sir) self.mesh = meshString self.region = region #Create a dict of elements self.elements = dict() fieldModule = self.region.getFieldmodule() mesh = fieldModule.findMeshByDimension(3) ei = mesh.createElementiterator() elem = ei.next() while elem.isValid(): self.elements[int(elem.getIdentifier())] = elem elem = ei.next() if len(self.elements) == 0: #A 2d mesh mesh = fieldModule.findMeshByDimension(2) ei = mesh.createElementiterator() elem = ei.next() while elem.isValid(): self.elements[int(elem.getIdentifier())] = elem elem = ei.next() #Create the texture coordinates self.createTextureCoordinates() #Create the scene filter and set the app's sceneview to use it sceneFilterModule = self.context.getScenefiltermodule() self.sceneFilter = sceneFilterModule.createScenefilterRegion(region) def linkToSceneViewer(self): if hasattr(self, 'sceneFilter') and self.sceneFilter.isValid(): self.appWidget.getMainModelSceneViewer().setScenefilter(self.sceneFilter) def createTextureCoordinates(self,circumferentialElements=8,lengthElements=11,wallElements=3): fieldModule = self.region.getFieldmodule() coordinates = fieldModule.findFieldByName('coordinates') cylindericalCoordinates = fieldModule.findFieldByName('cylindericalCoordinates') #Theta does not change monotonically, ensure this xiCoordinates = fieldModule.createFieldCoordinateTransformation (cylindericalCoordinates) xiCoordinates.setCoordinateSystemType(coordinates.COORDINATE_SYSTEM_TYPE_CYLINDRICAL_POLAR) r = fieldModule.createFieldComponent(xiCoordinates, 1) theta = fieldModule.createFieldComponent(xiCoordinates, 2) wi = fieldModule.createFieldComponent(xiCoordinates, 3) zero = fieldModule.createFieldConstant(0.0) one = fieldModule.createFieldConstant(1.0) theta_lt_zero = fieldModule.createFieldLessThan(theta, zero) twopi = fieldModule.createFieldConstant(np.pi*2) mod_theta = fieldModule.createFieldIf(theta_lt_zero, fieldModule.createFieldAdd(theta, twopi), theta) vi = fieldModule.createFieldDivide(mod_theta, twopi) w = fieldModule.createFieldSubtract(one,wi) #Ensure node 1 is at 0.0 one25 = fieldModule.createFieldConstant(0.125) vx = fieldModule.createFieldSubtract(vi,one25) v = fieldModule.createFieldSubtract(one,vx) self.xiCoordinates = fieldModule.createFieldConcatenate([v, w, r]) ''' nodeset = fieldModule.findNodesetByFieldDomainType(coordinates.DOMAIN_TYPE_NODES) nodeIterator = nodeset.createNodeiterator () nodes = dict() node = nodeIterator.next() while node.isValid(): nodes[int(node.getIdentifier())] = node node = nodeIterator.next() fieldCache = fieldModule.createFieldcache() for nd,node in nodes.items(): fieldCache.setNode(node) _,coord = coordinates.evaluateReal(fieldCache,3) _,th = self.xiCoordinates.evaluateReal(fieldCache,3) print nd,' '.join(map(str,coord)),' '.join(map(str,th)) ''' def setTexture(self,imageFile): fieldModule = self.region.getFieldmodule() image_field = fieldModule.createFieldImage() image_field.setFilterMode(image_field.FILTER_MODE_LINEAR) image_field.setWrapMode(image_field.WRAP_MODE_EDGE_CLAMP) coordinates = fieldModule.findFieldByName('coordinates') image_field.setDomainField(coordinates) image_field.setTextureCoordinateSizes([1, 1]) # Create a stream information object that we can use to read the # image file from disk stream_information = image_field.createStreaminformationImage() stream_information.createStreamresourceFile(imageFile) image_field.read(stream_information) scene = self.region.getScene() textureMaterial = scene.getMaterialmodule().createMaterial() textureMaterial.setManaged(True) textureMaterial.setName("regionMap") textureMaterial.setTextureField(1, image_field) #textureMaterial.setAttributeReal(Material.ATTRIBUTE_ALPHA, 0.2) if hasattr(self, 'textureMaterial'): del self.textureMaterial self.textureMaterial = textureMaterial if hasattr(self, 'surfaceGraphics'): self.surfaceGraphics.setMaterial(self.textureMaterial) def showGraphics(self): scene = self.region.getScene() #Show nodes # We use the beginChange and endChange to wrap any immediate changes and will # streamline the rendering of the scene. scene.beginChange() # createSurfaceGraphic graphic start fieldModule = self.region.getFieldmodule() coordinateField = fieldModule.findFieldByName('coordinates') #Create necessary fields nodeAnnotationField = fieldModule.findFieldByName('nodeAnnotation') if not nodeAnnotationField.isValid(): nodeAnnotationField = fieldModule.createFieldStoredString() nodeAnnotationField.setName('nodeAnnotation') self.nodeAnnotationField = nodeAnnotationField nodeVisibilityFlagField = fieldModule.findFieldByName('nodeVisibilityFlag') if not nodeVisibilityFlagField.isValid(): nodeVisibilityFlagField = fieldModule.createFieldFiniteElement(1) nodeVisibilityFlagField.setName('nodeVisibilityFlag') self.nodeVisibilityFlagField = nodeVisibilityFlagField nodeSizeField = fieldModule.findFieldByName('nodeSizeField') if not nodeSizeField.isValid(): nodeSizeField = fieldModule.createFieldFiniteElement(9) nodeSizeField.setName('nodeSizeField') self.nodeSizeField = nodeSizeField nodeColorField = fieldModule.findFieldByName('nodeColor') if not nodeColorField.isValid(): nodeColorField = fieldModule.createFieldFiniteElement(3) nodeColorField.setName('nodeColor') self.nodeColorField = nodeColorField self.datanodeset = fieldModule.findNodesetByFieldDomainType(self.xiCoordinates.DOMAIN_TYPE_DATAPOINTS) self.fieldCache = fieldModule.createFieldcache() self.coordinatesField = fieldModule.findFieldByName('coordinates').castFiniteElement() self.nodetemplate = self.datanodeset.createNodetemplate() self.nodetemplate.defineField(self.coordinatesField) self.nodetemplate.defineField(self.nodeAnnotationField) self.nodetemplate.defineField(self.nodeVisibilityFlagField) self.nodetemplate.defineField(self.nodeSizeField) self.nodetemplate.defineField(self.nodeColorField) glyphModule = scene.getGlyphmodule() glyphModule.defineStandardGlyphs() glyphModule.beginChange() axisGlyph = glyphModule.findGlyphByGlyphShapeType(Glyph.SHAPE_TYPE_AXES_SOLID_XYZ) glyphModule.endChange() ''' graphics1 = scene.createGraphicsPoints() graphics1.setFieldDomainType(self.coordinatesField.DOMAIN_TYPE_MESH_HIGHEST_DIMENSION) graphics1.setCoordinateField(coordinateField) gpa1 = graphics1.getGraphicspointattributes() cmiss_number = fieldModule.findFieldByName('cmiss_number') gpa1.setLabelField(cmiss_number) gpa1.setGlyphShapeType(Glyph.SHAPE_TYPE_NONE) ''' ''' graphics = scene.findGraphicsByName("axis") if graphics.isValid(): scene.removeGraphics(graphics) graphics = scene.createGraphicsPoints() graphics.setName("axis") graphics.setScenecoordinatesystem(SCENECOORDINATESYSTEM_NORMALISED_WINDOW_FIT_BOTTOM) pointattributes = graphics.getGraphicspointattributes() pointattributes.setGlyph(axisGlyph) pointattributes.setBaseSize([0.1,0.1,0.1]) #pointattributes.setGlyphOffset([-0.9,0.0,0.0]) ''' materialModule = scene.getMaterialmodule () materialModule.defineStandardMaterials () surfaceMaterial = materialModule.findMaterialByName('gold') lineMaterial = materialModule.findMaterialByName('silver') # Create Surface self.surfaceGraphics = scene.createGraphicsSurfaces() self.surfaceGraphics.setCoordinateField(coordinateField) self.surfaceGraphics.setTextureCoordinateField(self.xiCoordinates) self.surfaceGraphics.setMaterial(surfaceMaterial) #Create lines self.surfaceLines = scene.createGraphicsLines() self.surfaceLines.setCoordinateField(coordinateField) lineattributes = self.surfaceLines.getGraphicslineattributes() lineattributes.setShapeType(Graphicslineattributes_SHAPE_TYPE_CIRCLE_EXTRUSION) lineattributes.setBaseSize([0.01,0.01,0.01]) self.surfaceLines.setMaterial(lineMaterial) #Create spectrum to pick up rgb from nodeColor Field spectrumModule = scene.getSpectrummodule() spectrum = spectrumModule.createSpectrum() spectrum.setMaterialOverwrite(True) #This will ensure that the transparency of the material is used spectrum.setName("RGB") spectrumR = spectrum.createSpectrumcomponent() spectrumR.setColourMappingType(spectrumR.COLOUR_MAPPING_TYPE_RED) spectrumR.setFieldComponent(1) spectrumG = spectrum.createSpectrumcomponent() spectrumG.setColourMappingType(spectrumR.COLOUR_MAPPING_TYPE_GREEN) spectrumG.setFieldComponent(2) spectrumB = spectrum.createSpectrumcomponent() spectrumB.setColourMappingType(spectrumR.COLOUR_MAPPING_TYPE_BLUE) spectrumB.setFieldComponent(3) for spec in [spectrumR,spectrumG,spectrumB]: spec.setRangeMinimum(0.0) spec.setRangeMaximum(1.0) spec.setColourMinimum(0.0) spec.setColourMaximum(1.0) spec.setExtendBelow(True) spec.setExtendAbove(True) self.spectrumR = spectrumR self.spectrumB = spectrumB self.spectrumG = spectrumG self.spectrum = spectrum #Code for rendering datapoints graphics = scene.createGraphicsPoints() graphics.setFieldDomainType(self.coordinatesField.DOMAIN_TYPE_DATAPOINTS) graphics.setCoordinateField(coordinateField) graphics.setSubgroupField(self.nodeVisibilityFlagField) graphics.setDataField(self.nodeColorField) gpa = graphics.getGraphicspointattributes() gpa.setGlyphShapeType(Glyph.SHAPE_TYPE_SPHERE) gpa.setOrientationScaleField(self.nodeSizeField) graphics.setSpectrum(spectrum) scene.endChange() def showDataPoints(self,listofpoints): fieldModule = self.region.getFieldmodule() fieldModule.beginChange() self.datanodeset.destroyAllNodes() self.dataNodeGroups = dict() for nd,v in listofpoints.items(): mloc = [1.0-v[1][0],1.0-v[1][1]] #Xi needs to be inverted to match self.fieldCache.setMeshLocation(self.elements[v[0]],mloc) _,c = self.coordinatesField.evaluateReal(self.fieldCache,3) node = self.datanodeset.createNode(nd, self.nodetemplate) self.fieldCache.setNode(node) self.nodeAnnotationField.assignString(self.fieldCache,v[2]) self.nodeVisibilityFlagField.assignReal(self.fieldCache,v[3]) self.nodeSizeField.assignReal(self.fieldCache,v[4]) self.nodeColorField.assignReal(self.fieldCache,v[5]) self.coordinatesField.assignReal(self.fieldCache,c) if v[2] in self.dataNodeGroups: self.dataNodeGroups[v[2]].append(node) else: self.dataNodeGroups[v[2]] = [node] fieldModule.endChange() class ProjectDetailsWindow(ProjectDetailsWindowBase): datacollected = signalHandle(object) userCancelled = signalHandle() def __init__(self,parent=None,title="New Project"): super(ProjectDetailsWindow,self).__init__(parent) self.searchProjectFolder.clicked.connect(self.searchForAProjectFolder) #self.searchMeshFile.clicked.connect(self.searchForMeshFile) #self.choose.toggled.connect(self.enableUserMesh) self.Ok.clicked.connect(self.okclicked) self.cancel.clicked.connect(self.cancelclicked) self.setModal(True) self.setWindowTitle(title) self.screenCenterDialog() def screenCenterDialog(self): frameGm = self.frameGeometry() screen = QtGui.QApplication.desktop().screenNumber(QtGui.QApplication.desktop().cursor().pos()) centerPoint = QtGui.QApplication.desktop().screenGeometry(screen).center() frameGm.moveCenter(centerPoint) self.move(frameGm.topLeft()) def searchForAProjectFolder(self): filename = QtGui.QFileDialog.getExistingDirectory(self,'Project folder', '') if isinstance(filename,tuple): #Handle pyside filename = str(filename[0]) if filename is not None and not str(filename) == "": self.projectFolder.setText(filename) def searchForMeshFile(self): filename = QtGui.QFileDialog.getOpenFileName(self,'Mesh or pickled mesh file', '',"Zinc exregion files (*.ex2);; Project Pickles (*.pkl *.pickle)") if isinstance(filename,tuple): #Handle pyside filename = str(filename[0]) if filename is not None and not str(filename) == "": self.symmetric.setChecked(False) self.human.setChecked(False) self.sourceMesh.setText(filename) def okclicked(self): result = dict() result['name'] = str(self.projectName.text()) if len(result['name'])==0: QtGui.QMessageBox.critical(self,'Missing value','Project name is required!') return result['author'] = str(self.author.text()) if len(result['author'])==0: QtGui.QMessageBox.critical(self,'Missing value','Author name is required!') return result['comments'] = str(self.projectComments.toPlainText()) result['projectFolder'] = str(self.projectFolder.text()) if len(result['projectFolder'])==0: QtGui.QMessageBox.critical(self,'Missing value','A Project folder is required!') return if not path.exists(result['projectFolder']): QtGui.QMessageBox.critical(self,'Missing value','A Valid project folder is required!') return if self.symmetric.isChecked(): result['meshtype'] = 'symmetric' elif self.human.isChecked(): result['meshtype'] = 'human' else: result['meshtype'] = 'user' result['mesh'] = str(self.sourceMesh.text()) if len(result['mesh'])==0: QtGui.QMessageBox.critical(self,'Missing value','A Mesh file should be specified!') return result['circumferentialelements'] = str(self.circumferentialElements.text()) if len(result['circumferentialelements'])==0: QtGui.QMessageBox.critical(self,'Missing value','Number of circumferential elements should be specified!') return try: result['circumferentialelements'] = int(str(self.circumferentialElements.text())) except: QtGui.QMessageBox.critical(self,'Missing value','Integer number of circumferential elements should be specified!') return result['axialelements'] = str(self.circumferentialElements.text()) if len(result['axialelements'])==0: QtGui.QMessageBox.critical(self,'Missing value','Number of Axial elements should be specified!') return try: result['axialelements'] = int(str(self.axialElements.text())) except: QtGui.QMessageBox.critical(self,'Missing value','Integer number of Axial elements should be specified!') return self.datacollected.emit(result) self.close() def cancelclicked(self): self.userCancelled.emit() self.close() def enableUserMesh(self): state = self.choose.isChecked() self.sourceMesh.setEnabled(state) self.searchMeshFile.setEnabled(state) self.circumferentialElements.setEnabled(state) self.axialElements.setEnabled(state) class ProjectDetailsEditWindow(ProjectDetailsEditWindowBase): changed = signalHandle(object) def __init__(self,projectRecord,parent=None,title="Current Project Details"): super(ProjectDetailsEditWindow,self).__init__(parent) self.projectRecord = projectRecord self.projectName.setText(projectRecord['name']) self.author.setText(projectRecord['author']) self.projectComments.clear() self.projectComments.appendPlainText(projectRecord['comments']) self.projectFolder.setText(projectRecord['projectFolder']) if projectRecord['meshtype']=='symmetric': self.meshType.setText('Symmetric') else: self.meshType.setText('Human') if 'texture' in projectRecord: self.textureFile.setText(projectRecord['texture']) if 'regionMarkers' in projectRecord: self.regionsFile.setText(projectRecord['regionMarkers']) if 'cellMarkers' in projectRecord: self.annotationFile.setText(projectRecord['cellMarkers']) self.Ok.clicked.connect(self.okclicked) self.cancel.clicked.connect(self.cancelclicked) self.setModal(True) self.setWindowTitle(title) self.screenCenterDialog() def screenCenterDialog(self): frameGm = self.frameGeometry() screen = QtGui.QApplication.desktop().screenNumber(QtGui.QApplication.desktop().cursor().pos()) centerPoint = QtGui.QApplication.desktop().screenGeometry(screen).center() frameGm.moveCenter(centerPoint) self.move(frameGm.topLeft()) def cancelclicked(self): self.close() def okclicked(self): projectFolder = self.projectRecord['projectFolder'] name = self.projectRecord['name'] self.projectRecord['author'] = str(self.author.text()) self.projectRecord['comments'] = str(self.projectComments.toPlainText()) with open(path.join(projectFolder,'%s.ann'%name),'wb') as ser: json.dump(self.projectRecord,ser,2) self.changed.emit(self.projectRecord) self.close() class ApplicationWindow(ApplicationWindowBase): mainModelInitialized = signalHandle() zincDigitizerInitialized = signalHandle() textureChanged = signalHandle(object) def __init__(self,parent=None): super(ApplicationWindow,self).__init__(parent) #Equally distribute the splitter contents self.splitter.setSizes([16777215,16777215]) self.zincContext = Context("MainContext") self.mkLayout = QtGui.QVBoxLayout(self.markerWidget) self.mkLayout.setSpacing(0) self.mkLayout.setContentsMargins(0,0,0,0) self.mkLayout.setObjectName("mkLayout") self.regionMarkerWidget = PainterWidget(0) self.mkLayout.addWidget(self.regionMarkerWidget) #Setup zinc widgets self.mvLayout = QtGui.QVBoxLayout(self.mainModel) self.mvLayout.setSpacing(0) self.mvLayout.setContentsMargins(0,0,0,0) self.mvLayout.setObjectName("mvLayout") self.mainModelqgl = QtOpenGL.QGLWidget(self.mainModel) self.mainModelView = SceneViewerWidget(self.mainModelqgl) self.mainModelView.setContext(self.zincContext) self.mvLayout.addWidget(self.mainModelView) self.dvLayout = QtGui.QVBoxLayout(self.zincDigitiser) self.dvLayout.setSpacing(0) self.dvLayout.setContentsMargins(0,0,0,0) self.dvLayout.setObjectName("dvLayout") self.digitiserqgl = QtOpenGL.QGLWidget(self.zincDigitiser) self.digitiserView = ZincPainterWidget(self.zincContext,self.digitiserqgl,self.mainModelView) self.dvLayout.addWidget(self.digitiserView) self._setConnections() self.mainModelView.graphicsInitialized.connect(self.setupMainModelGraphics) self.digitiserView.graphicsInitialized.connect(self.setupDigitiserGraphics) self.mainModelView.doubleClicked.connect(self.mainModelViewViewAll) self.currentProject = dict() def setupDigitizationMeshBackground(self,pkl,circumferentialElements=8,axialElements=11): self.backgroundMesh = MeshMapper() self.backgroundMesh.setupByPickle(pkl) class MeshGen(object): def __init__(self,mesh): self.meshgen = mesh def generateMesh(self,region): self.meshgen.generateFlatMesh(region, circumferentialElements,axialElements) self.digitiserView.setupMeshBackground(MeshGen(self.backgroundMesh)) def _setConnections(self): self.actionLoad_mesh.triggered.connect(self.loadMesh) self.actionOpen_Project.triggered.connect(self.openProject) self.actionSave_Project.triggered.connect(self.saveExisting) self.actionSave_As.triggered.connect(self.saveProject) self.actionExport_Ex2.triggered.connect(self.saveInEx2Format) self.actionProject_Details.triggered.connect(self.showProjectDetails) self.actionUser_documentation.triggered.connect(self.showUserDocumentation) self.actionExit.triggered.connect(self.exitApp) self.applyRegion.clicked.connect(self.createAndApplyTexture) self.updateMarkers.clicked.connect(self.updateSourceMarkers) def createAndApplyTexture(self): markers,colors = self.regionMarkerWidget.getMarkersAndColors() self.backgroundMesh.assignRegions(markers,colors) self.backgroundMesh.createImage(self.textureFile) self.digitiserView.setTexture(self.textureFile) self.textureChanged.emit(self.textureFile) def updateSourceMarkers(self): self.mainModelController.showDataPoints(self.digitiserView.getUsedNodesWithXiAndData()) def mainModelViewViewAll(self): #self.mainModelView.viewAll() self.mainModelView.setViewParameters([0.006591612769376118, -0.28280922217064075, 2.5081264404696726], [0.08671705424785614, 0.029457375407218933, -0.07984980940818787], [0.15726460806804382, 0.9798543449214825, 0.12309876436305625], 0.6981317007977258) def digitiserViewViewAll(self): self.digitiserView.viewAll() def getMainModelSceneViewer(self): return self.mainModelView def getDigitizerSceneViewer(self): return self.digitiserView def loadRegionMarker(self): self.regionMarkerWidget.setupMeshBackground(self.backgroundMesh,11) def loadMesh(self): ''' Present a dialog to get details regarding the project ''' def loadUserInput(result): #Just to ensure that the sceneviewer is setup, as it is lazy loaded and if it is not visible, then it is not ready self.annotationWidgetsTab.setCurrentIndex(1) if hasattr(self, 'mainModelController'): del self.mainModelController self.mainModelController = MainModelController(self) del self.currentProject self.currentProject = result self.textureFile = path.join(result['projectFolder'],'Texture%s.png'%result['name']) ctr = 0 while path.exists(self.textureFile): self.textureFile = path.join(result['projectFolder'],'Texture%s_%d.png'%(result['name'],ctr)) ctr +=1 if result['meshtype']=='symmetric': pklp = path.join(dir_path,"./gui/symmetricstomachsurface.pkl") self.setupDigitizationMeshBackground(pklp,8,11) self.mainModelController.loadMesh(self.backgroundMesh.mesh) self.mainModelController.linkToSceneViewer() self.currentProject['circumferentialelements'] = 8 self.currentProject['axialelements'] = 11 elif result['meshtype']=='human': pklp = path.join(dir_path,"./gui/stomachsurface.pkl") self.setupDigitizationMeshBackground(pklp,8,11) self.mainModelController.loadMesh(self.backgroundMesh.mesh) self.mainModelController.linkToSceneViewer() self.currentProject['circumferentialelements'] = 8 self.currentProject['axialelements'] = 11 else: pass self.annotationWidgetsTab.setCurrentIndex(0) self.mainModelController.showGraphics() self.loadRegionMarker() self.projectOpened = True data = ProjectDetailsWindow(self) data.datacollected.connect(loadUserInput) data.show() #result = {'projectFolder': r'D:\Jagir_Hussan\Research\SPARC\workspace\StomachAnnotation\pwork', 'name': 'testing', 'meshtype': 'human', 'axialelements': 2, 'author': 'sdf', 'comments': 'temporary','mesh': 'no mesh', 'circumferentialelements': 1} #loadUserInput(result) def openProject(self): filename = QtGui.QFileDialog.getOpenFileName(self,'Pickled project file', '',"Annotator (*.ann);; All Files (*.*)") if isinstance(filename,tuple): #Handle pyside filename = str(filename[0]) if filename is not None and not str(filename) == "": with open(filename,'rb') as ser: project = json.load(ser) projectFolder = project['projectFolder'] if projectFolder != path.dirname(filename): #File has been moved projectFolder = path.dirname(filename) project['projectFolder'] = projectFolder backgroudMesh = project['backgroundMesh'] texture = '' if 'texture' in project: texture = project['texture'] regionMarker = '' if 'regionMarkers' in project: regionMarker = project['regionMarkers'] cellMarker = '' if 'cellMarkers' in project: cellMarker = project['cellMarkers'] if path.isdir(projectFolder): backgroudMesh = path.join(projectFolder,backgroudMesh) if path.isfile(backgroudMesh): texture = path.join(projectFolder,texture) if not path.isfile(texture): texture = None regionMarker = path.join(projectFolder,regionMarker) if not path.isfile(regionMarker): regionMarker = None cellMarker = path.join(projectFolder,cellMarker) if not path.isfile(cellMarker): cellMarker = None else: QtGui.QMessageBox.critical('Missing file','Project mesh %s is missing!!'%backgroudMesh) return else: QtGui.QMessageBox.critical('Missing folder','Project folder %s is missing!!'%projectFolder) return self.currentProject = dict() pkeys = ['projectFolder','name','meshtype', 'axialelements', 'author', 'comments','mesh', 'circumferentialelements'] for k in pkeys: if k in project: self.currentProject[k] = project[k] self.currentProject['backgroundMesh'] = path.basename(backgroudMesh) if not regionMarker is None: self.currentProject['regionMarkers']=path.basename(regionMarker) if not cellMarker is None: self.currentProject['cellMarkers']=path.basename(cellMarker) self.annotationWidgetsTab.setCurrentIndex(1) if hasattr(self, 'mainModelController'): del self.mainModelController self.mainModelController = MainModelController(self) self.setupDigitizationMeshBackground(backgroudMesh,project['circumferentialelements'],project['axialelements']) self.mainModelController.loadMesh(self.backgroundMesh.mesh) self.loadRegionMarker() self.mainModelController.linkToSceneViewer() self.annotationWidgetsTab.setCurrentIndex(0) self.mainModelController.showGraphics() if not texture is None: self.textureFile = texture self.mainModelController.setTexture(texture) self.digitiserView.setTexture(texture) else: self.textureFile = path.join(project['projectFolder'],'Texture%s.png'%project['name']) ctr = 0 while path.exists(self.textureFile): self.textureFile = path.join(project['projectFolder'],'Texture%s_%d.png'%(project['name'],ctr)) ctr +=1 if not regionMarker is None: self.regionMarkerWidget.loadRegions(regionMarker) if not cellMarker is None: self.digitiserView.loadRegions(cellMarker) self.updateSourceMarkers() def saveInEx2Format(self): if self.currentProject is None or len(self.currentProject)==0: return project = self.currentProject if 'regionMarkers' in project: if 'cellMarkers' in project: filename = QtGui.QFileDialog.getSaveFileName(self,'Ex2 file', '',"OpenCMISS Zinc (*.ex2);; All Files (*.*)") if isinstance(filename,tuple): #Handle pyside filename = str(filename[0]) if filename is not None and not str(filename) == "": self.mainModelController.rootRegion.writeFile(filename) else: QtGui.QMessageBox.information(self,'','No cell markers attached! Save project to associate them and retry') else: QtGui.QMessageBox.information(self,'','Annotation free mesh cannot be saved!') def saveExisting(self): self.projectOpened = False if self.currentProject is None or len(self.currentProject)==0: return project = self.currentProject projectFolder = project['projectFolder'] name = project['name'] if 'backgroundMesh' in project: backgroundMesh = project['backgroundMesh'] else: backgroundMesh = 'BackgroundMesh%s.pkl' % name ctr = 0 while path.exists(path.join(projectFolder,backgroundMesh)): backgroundMesh = 'BackgroundMesh%s_%d.pkl' % (name,ctr) ctr +=1 project['backgroundMesh'] = backgroundMesh if 'regionMarkers' in project: regionMarker = project['regionMarkers'] else: regionMarker = 'Regions%s.dat' %name ctr = 0 while path.exists(path.join(projectFolder,regionMarker)): regionMarker = 'Regions%s_%d.dat' % (name,ctr) ctr +=1 project['regionMarkers'] = regionMarker if 'cellMarkers' in project: cellMarker = project['cellMarkers'] else: cellMarker = 'Markers%s.dat' %name ctr = 0 while path.exists(path.join(projectFolder,cellMarker)): cellMarker = 'Markers%s_%d.dat' % (name,ctr) ctr +=1 project['cellMarkers'] = cellMarker project['texture'] =path.basename(self.textureFile) self.backgroundMesh.serialize(path.join(projectFolder,backgroundMesh)) if not self.regionMarkerWidget.saveRegions(path.join(projectFolder,regionMarker)): try: os.remove(path.join(projectFolder,regionMarker)) except: pass del project['regionMarkers'] if not self.digitiserView.saveRegions(path.join(projectFolder,cellMarker)): try: os.remove(path.join(projectFolder,cellMarker)) except: pass del project['cellMarkers'] with open(path.join(projectFolder,'%s.ann'%name),'wb') as ser: json.dump(project,ser,2) def saveProject(self): self.projectOpened = False if self.currentProject is None or len(self.currentProject)==0: return filename = QtGui.QFileDialog.getExistingDirectory(self,'Project directory', '') if isinstance(filename,tuple): #Handle pyside filename = str(filename[0]) if filename is not None and not str(filename) == "": project = dict(self.currentProject) project['projectFolder'] = filename projectFolder = project['projectFolder'] name = project['name'] backgroundMesh = 'BackgroundMesh%s.pkl' % name ctr = 0 while path.exists(path.join(projectFolder,backgroundMesh)): backgroundMesh = 'BackgroundMesh%s_%d.pkl' % (name,ctr) ctr +=1 self.backgroundMesh.serialize(path.join(projectFolder,backgroundMesh)) project['backgroundMesh'] = backgroundMesh if path.exists(self.textureFile): project['texture'] = path.basename(self.textureFile) shutil.copyfile(self.textureFile, path.join(projectFolder,project['texture'])) regionMarker = 'Regions%s.dat' %name ctr = 0 while path.exists(path.join(projectFolder,regionMarker)): regionMarker = 'Regions%s_%d.dat' % (name,ctr) ctr +=1 if self.regionMarkerWidget.saveRegions(path.join(projectFolder,regionMarker)): project['regionMarkers']=regionMarker cellMarker = 'Markers%s.dat' %name ctr = 0 while path.exists(path.join(projectFolder,cellMarker)): cellMarker = 'Markers%s_%d.dat' % (name,ctr) ctr +=1 if self.digitiserView.saveRegions(path.join(projectFolder,cellMarker)): project['cellMarkers']=cellMarker with open(path.join(projectFolder,'%s.ann'%name),'wb') as ser: json.dump(project,ser,2) QtGui.QMessageBox.information(self,"Success","Successfully saved project!") def exitApp(self): self.close() def setupMainModelGraphics(self): self.mainModelView.setViewParameters([0.006591612769376118, -0.28280922217064075, 2.5081264404696726], [0.08671705424785614, 0.029457375407218933, -0.07984980940818787], [0.15726460806804382, 0.9798543449214825, 0.12309876436305625], 0.6981317007977258) self.mainModelInitialized.emit() def setupDigitiserGraphics(self): self.zincDigitizerInitialized.emit() def showProjectDetails(self): if not self.currentProject is None and len(self.currentProject)>0: def changeCurrentProjectRecord(rec): self.currentProject = dict(rec) self.currentProject['texture'] = path.basename(self.textureFile) pdialog = ProjectDetailsEditWindow(self.currentProject) pdialog.changed.connect(changeCurrentProjectRecord) pdialog.show() def showUserDocumentation(self): if hasattr(self, 'helpview'): del self.helpview self.helpview = QtWebKit.QWebView() self.helpview.setWindowTitle("User documentation") url = QtCore.QUrl.fromLocalFile(path.abspath(path.join(dir_path,'./help/help.html'))) self.helpview.load(url) self.helpview.show() if __name__ == '__main__': app = QApplication(sys.argv) ams = ApplicationWindow() ams.show() #data = ProjectDetailsWindow() #data.show() sys.exit(app.exec_())