- Author:
- rjag008 <rjag008@auckland.ac.nz>
- Date:
- 2018-08-18 17:01:42+12:00
- Desc:
- Final Release
- Permanent Source URI:
- https://models.cellml.org/workspace/51d/rawfile/9ea33dda840d259caf68e26d21300bece4eeff3f/gui/annotator.py
'''
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_())