def createUI(self): self.ui = Ui_DialogVolumeManualSkeletonization() self.ui.setupUi(self) self.connect(self.ui.horizontalSliderStartingDensity,QtCore.SIGNAL("valueChanged(int)"),self.startingDensityChanged) self.connect(self.ui.pushButtonStart,QtCore.SIGNAL("pressed ()"),self.startSkeletonization) self.connect(self.ui.pushButtonClose, QtCore.SIGNAL("pressed ()"), self.endSkeletonization) self.connect(self.ui.pushButtonClear, QtCore.SIGNAL("pressed ()"), self.clearSkeleton) self.connect(self.app, QtCore.SIGNAL("keyReleased(QKeyEvent)"), self.keyReleased) self.connect(self.app, QtCore.SIGNAL("keyPressed(QKeyEvent)"), self.keyPressed)
class CAlphaInteractiveLoopBuilder(VolumeManualSkeletonizationForm): def __init__(self, main, chain, parent=None): QtGui.QWidget.__init__(self, parent) self.app = main self.chain = chain self.app.themes.addDefaultRGB("InteractiveLoopBuilder:StartingPoint", 0, 0, 255, 150) self.app.themes.addDefaultRGB("InteractiveLoopBuilder:EndingPoint", 0, 255, 0, 150) self.app.themes.addDefaultRGB("InteractiveLoopBuilder:Sketch", 0, 128, 0, 255) self.started = False self.sketchStarted = False self.viewer = self.app.viewers['volume'] self.skeletonViewer = self.app.viewers["skeleton"] self.calphaViewer = self.app.viewers["calpha"] self.connect(self.viewer, QtCore.SIGNAL("modelLoaded()"), self.modelLoaded) self.connect(self.viewer, QtCore.SIGNAL("modelChanged()"), self.modelChanged) self.connect(self.viewer, QtCore.SIGNAL("modelUnloaded()"), self.modelUnloaded) self.isSkeletonClicked = False self.createUI() self.oldSkeletonViewerMouseMoveEnabledRay = self.skeletonViewer.mouseMoveEnabledRay self.connect( self.skeletonViewer, QtCore.SIGNAL( "mouseClickRay(PyQt_PyObject, float, PyQt_PyObject, QMouseEvent)" ), self.processClickRay) self.connect( self.skeletonViewer, QtCore.SIGNAL( "mouseOverRay(PyQt_PyObject, float, PyQt_PyObject, QMouseEvent)" ), self.processMouseOverRay) self.connect(self.skeletonViewer, QtCore.SIGNAL("modelChanged()"), self.skeletonChanged) maxDensity = self.viewer.renderer.getMaxDensity() minDensity = self.viewer.renderer.getMinDensity() self.ui.horizontalSliderStartingDensity.setMinimum( int(minDensity * 100)) self.ui.horizontalSliderStartingDensity.setMaximum( int(maxDensity * 100)) defaultDensity = (int(minDensity * 100) + int(maxDensity * 100.0)) / 2 self.ui.horizontalSliderStartingDensity.setValue(defaultDensity) self.startIndex = 0 self.endIndex = 0 self.startSkeletonization() def __del__(self): self.engine.finishLoopBuilding() self.skeletonViewer.unloadData() self.endSkeletonization() def endSkeletonization(self): self.startEndSkeletonization(False) def createUI(self): self.ui = Ui_DialogVolumeManualSkeletonization() self.ui.setupUi(self) self.connect(self.ui.horizontalSliderStartingDensity, QtCore.SIGNAL("valueChanged(int)"), self.startingDensityChanged) self.connect(self.ui.pushButtonStart, QtCore.SIGNAL("pressed ()"), self.startSkeletonization) self.connect(self.ui.pushButtonClose, QtCore.SIGNAL("pressed ()"), self.endSkeletonization) self.connect(self.ui.pushButtonClear, QtCore.SIGNAL("pressed ()"), self.clearSkeleton) self.connect(self.app, QtCore.SIGNAL("keyReleased(QKeyEvent)"), self.keyReleased) self.connect(self.app, QtCore.SIGNAL("keyPressed(QKeyEvent)"), self.keyPressed) def initializeEngine(self, medialnessScoringFunction): self.engine = InteractiveLoopBuilderEngine(self.volume, self.mesh, self.calphaViewer.renderer, self.getStartingDensity(), self.getStepCount(), self.getCurveRadius(), self.getMinCurveLength(), medialnessScoringFunction) self.engine.setTranslation(self.viewer.renderer.getOriginX(), self.viewer.renderer.getOriginY(), self.viewer.renderer.getOriginZ()) self.engine.setScaling(self.viewer.renderer.getSpacingX(), self.viewer.renderer.getSpacingY(), self.viewer.renderer.getSpacingZ()) def modelLoaded(self): pass def skeletonChanged(self): self.calphaViewer.emitModelChanged() def processClickRay(self, rayWorld, rayWidth, eyeWorld, event): ray = self.viewer.worldVectorToObjectCoordinates(rayWorld) eye = self.viewer.worldToObjectCoordinates(eyeWorld) divisor = float(self.getMedialness()) + float(self.getSmoothness()) medialnessRatio = float(self.getMedialness()) / divisor smoothnessRatio = float(self.getSmoothness()) / divisor sketchPriority = float(self.getSketchPriority()) if (self.started): if ((event.modifiers() & QtCore.Qt.CTRL) and (event.modifiers() & QtCore.Qt.ALT)): self.engine.selectRootRay(ray[0], ray[1], ray[2], eye[0], eye[1], eye[2], rayWidth, medialnessRatio, smoothnessRatio) elif (event.modifiers() & QtCore.Qt.CTRL): self.engine.selectEndSeed(medialnessRatio, smoothnessRatio) self.engine.selectStartSeedRay(ray[0], ray[1], ray[2], eye[0], eye[1], eye[2], rayWidth, medialnessRatio, smoothnessRatio) self.skeletonViewer.emitModelChanged() elif (event.modifiers() & QtCore.Qt.ALT): self.engine.selectEndSeed(medialnessRatio, smoothnessRatio) self.skeletonViewer.emitModelChanged() def setLoopAtoms(self, startIndex, endIndex): self.engine.clearAtomList() self.engine.clearCurrentPath() for i in range(startIndex, endIndex + 1): if (i in self.chain.residueRange()): atom = self.chain[i].getAtom('CA') if (not atom): raw = PDBAtom(self.chain.getPdbID(), self.chain.getChainID(), i, 'CA') raw.setPosition(Vector3DFloat(0, 0, 0)) atom = self.calphaViewer.renderer.addAtom(raw) atom.setVisible(False) print atom self.chain[i].addAtomObject(atom) self.chain[i].setCAlphaColorToDefault() bondBefore = None bondAfter = None if i - 1 in self.chain.residueRange(): prevCAlpha = self.chain[i - 1].getAtom('CA') if prevCAlpha: print "adding a bond before" bondBefore = PDBBond() bondBefore.setAtom0Ix(prevCAlpha.getHashKey()) bondBefore.setAtom1Ix(atom.getHashKey()) if i + 1 in self.chain.residueRange(): nextCAlpha = self.chain[i + 1].getAtom('CA') if nextCAlpha: print "adding a bond after" bondAfter = PDBBond() bondAfter.setAtom0Ix(nextCAlpha.getHashKey()) bondAfter.setAtom1Ix(atom.getHashKey()) if bondBefore: self.calphaViewer.renderer.addBond(bondBefore) if bondAfter: self.calphaViewer.renderer.addBond(bondAfter) self.engine.addAtom(atom.getHashKey()) if not self.calphaViewer.loaded: self.calphaViewer.loaded = True self.calphaViewer.emitModelLoaded() else: self.calphaViewer.emitModelChanged() def drawOverlay(self): if self.started: manualColors = [ self.app.themes.getColor( "InteractiveLoopBuilder:StartingPoint"), self.app.themes.getColor("InteractiveLoopBuilder:EndingPoint"), self.app.themes.getColor("InteractiveLoopBuilder:Sketch") ] for i in range(3): glPushAttrib(GL_LIGHTING_BIT) self.skeletonViewer.setMaterials(manualColors[i]) self.engine.draw(i) glPopAttrib()
class VolumeManualSkeletonizationForm(BaseDockWidget): MedialnessScoringFunctionBinary, MedialnessScoringFunctionGlobalRank, MedialnessScoringFunctionLocalRank = range(3) def __init__(self, main, viewer, parent=None): BaseDockWidget.__init__(self, main, "&Interactive Skeletonization", "Perform interactive skeletonization", "perform_VolumeManualSkeletonization", "actions-volume-skeletonization-manual", "actions-volume-skeletonization", QtCore.Qt.LeftDockWidgetArea | QtCore.Qt.RightDockWidgetArea | QtCore.Qt.BottomDockWidgetArea, QtCore.Qt.BottomDockWidgetArea, parent) self.app = main self.app.themes.addDefaultRGB("InteractiveSkeletonizer:StartingPoint", 0, 0, 255, 255) self.app.themes.addDefaultRGB("InteractiveSkeletonizer:EndingPoint", 0, 255, 0, 255) self.app.themes.addDefaultRGB("InteractiveSkeletonizer:Sketch", 0, 128, 0, 255) self.app.themes.addDefaultRGB("InteractiveSkeletonizer:UnconfirmedCurve", 255, 255, 0, 255) self.app.themes.addDefaultRGB("InteractiveSkeletonizer:RemovableCurve", 100, 255, 100, 255) self.started = False self.sketchStarted = False self.viewer = viewer self.connect(self.viewer, QtCore.SIGNAL("modelLoaded()"), self.modelLoaded) self.connect(self.viewer, QtCore.SIGNAL("modelChanged()"), self.modelChanged) self.connect(self.viewer, QtCore.SIGNAL("modelUnloaded()"), self.modelUnloaded) self.isSkeletonClicked = False; self.createUI() self.createActions() def createUI(self): self.ui = Ui_DialogVolumeManualSkeletonization() self.ui.setupUi(self) self.connect(self.ui.horizontalSliderStartingDensity,QtCore.SIGNAL("valueChanged(int)"),self.startingDensityChanged) self.connect(self.ui.pushButtonStart,QtCore.SIGNAL("pressed ()"),self.startSkeletonization) self.connect(self.ui.pushButtonClose, QtCore.SIGNAL("pressed ()"), self.endSkeletonization) self.connect(self.ui.pushButtonClear, QtCore.SIGNAL("pressed ()"), self.clearSkeleton) self.connect(self.app, QtCore.SIGNAL("keyReleased(QKeyEvent)"), self.keyReleased) self.connect(self.app, QtCore.SIGNAL("keyPressed(QKeyEvent)"), self.keyPressed) def createActions(self): self.skeletonizeAct = self.displayAct self.skeletonizeAct.setEnabled(False) def showWidget(self, show): BaseDockWidget.showWidget(self, show) if(not show): self.setSkeletonViewerProperties(False) self.ui.pushButtonStart.setEnabled(True) self.ui.pushButtonClose.setEnabled(False) def startSkeletonization(self): self.startEndSkeletonization(True) def endSkeletonization(self): self.startEndSkeletonization(False) self.dock.close() def initializeEngine(self, medialnessScoringFunction): self.engine = InteractiveSkeletonEngine(self.volume, self.mesh, self.getStartingDensity(), self.getStepCount(), self.getCurveRadius(), self.getMinCurveLength(), medialnessScoringFunction) def startEndSkeletonization(self, start): if(start): self.volume = self.viewer.renderer.getVolume() if self.skeletonViewer.loaded: self.skeletonViewer.unloadData() self.mesh = self.skeletonViewer.renderer.getMesh() self.skeletonViewer.setScale(self.viewer.renderer.getSpacingX(), self.viewer.renderer.getSpacingY(), self.viewer.renderer.getSpacingZ()) self.skeletonViewer.setLocation(self.viewer.renderer.getOriginX(), self.viewer.renderer.getOriginY(), self.viewer.renderer.getOriginZ()) if self.ui.radioButtonBinary.isChecked(): medialnessScoringFunction = self.MedialnessScoringFunctionBinary elif self.ui.radioButtonGlobalRank.isChecked(): medialnessScoringFunction = self.MedialnessScoringFunctionGlobalRank else : medialnessScoringFunction = self.MedialnessScoringFunctionLocalRank self.initializeEngine(medialnessScoringFunction) self.engine.setIsoValue(self.viewer.renderer.getSurfaceValue()) self.connect(self.app.viewers["skeleton"], QtCore.SIGNAL("elementSelected (int, int, int, int, int, int, QMouseEvent)"), self.skeletonClicked) self.connect(self.app.mainCamera, QtCore.SIGNAL("cameraChanged()"), self.processCameraChanged) self.connect(self.app.viewers["skeleton"], QtCore.SIGNAL("thicknessChanged(int)"), self.thicknessChanged) self.connect(self.app.viewers["skeleton"], QtCore.SIGNAL("modelDrawing()"), self.drawOverlay) self.engine.setLineThickness(self.skeletonViewer.lineThickness) self.setSkeletonViewerProperties(True) self.skeletonViewer.loaded = True self.ui.pushButtonStart.setEnabled(False) self.ui.pushButtonClose.setEnabled(True) self.skeletonViewer.emitModelLoaded() else: self.disconnect(self.app.viewers["skeleton"], QtCore.SIGNAL("elementSelected (int, int, int, int, int, int, QMouseEvent)"), self.skeletonClicked) self.disconnect(self.app.mainCamera, QtCore.SIGNAL("cameraChanged()"), self.processCameraChanged) self.disconnect(self.app.viewers["skeleton"], QtCore.SIGNAL("thicknessChanged(int)"), self.thicknessChanged) self.disconnect(self.app.viewers["skeleton"], QtCore.SIGNAL("modelDrawing()"), self.drawOverlay) self.engine.finalizeSkeleton() del self.engine self.setSkeletonViewerProperties(False) self.ui.pushButtonStart.setEnabled(True) self.ui.pushButtonClose.setEnabled(False) self.started = start self.skeletonViewer.emitModelChanged() def startingDensityChanged(self, newLevel): self.ui.labelStartingDensityDisplay.setNum(newLevel/100.0) def getStartingDensity(self): return self.ui.horizontalSliderStartingDensity.value()/100.0 def getMedialness(self): return self.ui.horizontalSliderMedialness.value() def getSmoothness(self): return self.ui.horizontalSliderSmoothness.value() def getSketchPriority(self): return self.ui.horizontalSliderSketchPriority.value() def getStepCount(self): return self.ui.horizontalSliderStepCount.value() def getCurveRadius(self): return self.ui.spinBoxCurveRadius.value() def getMinCurveLength(self): return self.ui.spinBoxMinCurve.value() def setSkeletonViewerProperties(self, opening): if(opening): #self.oldSkeletonViewerSelectEnabled = self.skeletonViewer.selectEnabled #self.oldSkeletonViewerMouseMoveEnabled = self.skeletonViewer.mouseMoveEnabled self.oldSkeletonViewerMouseMoveEnabledRay = self.skeletonViewer.mouseMoveEnabledRay self.skeletonViewer.setViewerAutonomy(False); if self.skeletonViewer.loaded: self.skeletonViewer.unloadData() self.skeletonViewer.setSelectEnabled(True) self.skeletonViewer.setMouseMoveEnabledRay(True) color = self.app.themes.getColor("Volume:Model:0") color.setAlpha(150) self.viewer.setModelColor(color) #self.skeletonViewer.setMouseMoveEnabled(True) else: self.skeletonViewer.setViewerAutonomy(True); #self.skeletonViewer.setSelectEnabled(self.oldSkeletonViewerSelectEnabled) self.skeletonViewer.setMouseMoveEnabledRay(self.oldSkeletonViewerMouseMoveEnabledRay) #self.skeletonViewer.setMouseMoveEnabled(self.oldSkeletonViewerMouseMoveEnabled) def filterMouseHits(self, mouseHits): hits = list() for hit_record in mouseHits: minDepth, maxDepth, names = hit_record names = list(names) if(names[0] == self.skeletonViewer.sceneIndex): names.pop(0) for i in range(2-len(names)): names.append(-1) hits.append(names) return hits def processClickRay(self, rayWorld, rayWidth, eyeWorld, event): ray = self.viewer.worldVectorToObjectCoordinates(rayWorld) eye = self.viewer.worldToObjectCoordinates(eyeWorld) divisor = float(self.getMedialness()) + float(self.getSmoothness()); medialnessRatio = float(self.getMedialness()) / divisor; smoothnessRatio = float(self.getSmoothness()) / divisor; sketchPriority = float(self.getSketchPriority()); if(self.started): if((event.modifiers() & QtCore.Qt.CTRL) and (event.modifiers() & QtCore.Qt.ALT)): self.engine.selectRootRay(ray[0], ray[1], ray[2], eye[0], eye[1], eye[2], rayWidth, medialnessRatio, smoothnessRatio) elif(event.modifiers() & QtCore.Qt.CTRL): self.engine.selectEndSeed(medialnessRatio, smoothnessRatio) self.engine.selectStartSeedRay(ray[0], ray[1], ray[2], eye[0], eye[1], eye[2], rayWidth, medialnessRatio, smoothnessRatio) self.skeletonViewer.emitModelChanged() elif (event.modifiers() & QtCore.Qt.ALT): self.engine.selectEndSeed(medialnessRatio, smoothnessRatio) self.skeletonViewer.emitModelChanged() def processMouseOverRay(self, rayWorld, rayWidth, eyeWorld, event): ray = self.viewer.worldVectorToObjectCoordinates(rayWorld) eye = self.viewer.worldToObjectCoordinates(eyeWorld) if(self.started and event.modifiers() & QtCore.Qt.CTRL ): self.engine.browseStartSeedRay(ray[0], ray[1], ray[2], eye[0], eye[1], eye[2], rayWidth) self.engine.analyzePathRay(ray[0], ray[1], ray[2], eye[0], eye[1], eye[2], rayWidth) self.skeletonViewer.emitModelChanged() elif(self.started and event.modifiers() & QtCore.Qt.ALT ): self.engine.analyzePathRay(ray[0], ray[1], ray[2], eye[0], eye[1], eye[2], rayWidth) self.skeletonViewer.emitModelChanged() elif(self.started and event.modifiers() & QtCore.Qt.SHIFT): self.engine.setSketch2D(self.app.mainCamera.width(), self.app.mainCamera.height(), event.x(), event.y()) self.engine.setSketchRay(ray[0], ray[1], ray[2], eye[0], eye[1], eye[2], rayWidth) self.skeletonViewer.emitModelChanged() def processCameraChanged(self): if(self.engine.clearSketch2D()) : self.skeletonViewer.emitModelChanged() def modelLoaded(self): self.skeletonViewer = self.app.viewers["skeleton"]; #self.oldSkeletonViewerSelectEnabled = self.skeletonViewer.selectEnabled #self.oldSkeletonViewerMouseMoveEnabled = self.skeletonViewer.mouseMoveEnabled self.oldSkeletonViewerMouseMoveEnabledRay = self.skeletonViewer.mouseMoveEnabledRay #self.connect(self.app.mainCamera, QtCore.SIGNAL("mouseMovedRAW(PyQt_PyObject, QMouseEvent)"), self.processMouseOverMultiple) #self.connect(self.app.mainCamera, QtCore.SIGNAL("mouseClickedRAW(PyQt_PyObject, QMouseEvent)"), self.processClickMultiple) #self.connect(self.skeletonViewer, QtCore.SIGNAL("elementSelected (int, int, int, int, int, int, QMouseEvent)"), self.processClick) #self.connect(self.skeletonViewer, QtCore.SIGNAL("elementMouseOver (int, int, int, int, int, int, QMouseEvent)"), self.processMouseOver) self.connect(self.skeletonViewer, QtCore.SIGNAL("mouseClickRay(PyQt_PyObject, float, PyQt_PyObject, QMouseEvent)"), self.processClickRay) self.connect(self.skeletonViewer, QtCore.SIGNAL("mouseOverRay(PyQt_PyObject, float, PyQt_PyObject, QMouseEvent)"), self.processMouseOverRay) self.skeletonizeAct.setEnabled(True) self.showWidget(False) maxDensity = self.viewer.renderer.getMaxDensity() minDensity = self.viewer.renderer.getMinDensity() self.ui.horizontalSliderStartingDensity.setMinimum(int(minDensity*100)) self.ui.horizontalSliderStartingDensity.setMaximum(int(maxDensity*100)) defaultDensity = (int(minDensity*100) + int(maxDensity*100.0)) / 2 self.ui.horizontalSliderStartingDensity.setValue(defaultDensity) if(self.started): self.engine.setIsoValue(self.viewer.renderer.getSurfaceValue()) def modelUnloaded(self): self.skeletonizeAct.setEnabled(False) self.showWidget(False) def modelChanged(self): if(self.started): self.engine.setIsoValue(self.viewer.renderer.getSurfaceValue()) self.skeletonViewer.emitModelChanged() def clearSkeleton(self): self.engine.clearSkeleton() self.skeletonViewer.emitModelChanged() def skeletonClicked(self, hit0, hit1, hit2, hit3, hit4, hit5, event): self.engine.addSelectionPoint(hit0, hit1) self.skeletonViewer.emitModelChanged() def keyPressed(self, event): if self.started: if(event.key() == QtCore.Qt.Key_Control): self.engine.startEndPolyLineMode(True) self.skeletonViewer.emitModelChanged() elif(event.key() == QtCore.Qt.Key_Alt): self.engine.startEndSingleRootMode(True) self.skeletonViewer.emitModelChanged() def keyReleased(self, event): if self.started: divisor = float(self.getMedialness()) + float(self.getSmoothness()); medialnessRatio = float(self.getMedialness()) / divisor; smoothnessRatio = float(self.getSmoothness()) / divisor; sketchPriority = float(self.getSketchPriority()); if(event.key() == QtCore.Qt.Key_Control): self.engine.startEndPolyLineMode(False) self.skeletonViewer.emitModelChanged() elif(event.key() == QtCore.Qt.Key_Alt): self.engine.startEndSingleRootMode(False) self.skeletonViewer.emitModelChanged() elif(event.key() == QtCore.Qt.Key_Escape): self.engine.clearCurrentPath(); self.skeletonViewer.emitModelChanged() elif(event.key() == QtCore.Qt.Key_Shift): self.engine.endSketchRay(medialnessRatio, smoothnessRatio, 1.0, sketchPriority) self.skeletonViewer.emitModelChanged() elif(event.key() == QtCore.Qt.Key_Plus): self.engine.selectEndSeed(medialnessRatio, smoothnessRatio) self.skeletonViewer.emitModelChanged() elif(event.key() == QtCore.Qt.Key_Delete): self.engine.deleteSelection(); self.skeletonViewer.emitModelChanged() def thicknessChanged(self, value): self.engine.setLineThickness(value) def drawOverlay(self): if self.started: manualColors = [self.app.themes.getColor("InteractiveSkeletonizer:StartingPoint"), self.app.themes.getColor("InteractiveSkeletonizer:EndingPoint"), self.app.themes.getColor("InteractiveSkeletonizer:Sketch"), self.app.themes.getColor("InteractiveSkeletonizer:UnconfirmedCurve"), self.app.themes.getColor("InteractiveSkeletonizer:RemovableCurve")] for i in range(5): glPushAttrib(GL_LIGHTING_BIT) self.skeletonViewer.setMaterials(manualColors[i]) self.engine.draw(i) glPopAttrib()