2 import vtk, qt, ctk, slicer
4 from SegmentEditorEffects
import *
7 """ DrawEffect is a LabelEffect implementing the interactive draw 8 tool in the segment editor 12 scriptedEffect.name =
'Draw' 14 AbstractScriptedSegmentEditorLabelEffect.__init__(self, scriptedEffect)
17 import qSlicerSegmentationsEditorEffectsPythonQt
as effects
18 clonedEffect = effects.qSlicerSegmentEditorScriptedLabelEffect(
None)
19 clonedEffect.setPythonSource(__file__.replace(
'\\',
'/'))
23 iconPath = os.path.join(os.path.dirname(__file__),
'Resources/Icons/Draw.png')
24 if os.path.exists(iconPath):
25 return qt.QIcon(iconPath)
29 return """<html>Draw segment outline in slice viewers<br>. 30 <p><ul style="margin: 0"> 31 <li><b>Left-click:</b> add point.</li> 32 <li><b>Left-button drag-and-drop:</b> add multiple points.</li> 33 <li><b>x:</b> delete last point.</li> 34 <li><b>Right-click</b> or <b>a</b> or <b>enter:</b> apply outline.</li> 40 self.scriptedEffect.removeActor2D(sliceWidget, pipeline.actor)
50 if viewWidget.className() !=
"qMRMLSliceWidget":
53 pipeline = self.pipelineForWidget(viewWidget)
57 if eventId == vtk.vtkCommand.LeftButtonPressEvent:
58 pipeline.actionState =
"drawing" 59 self.scriptedEffect.cursorOff(viewWidget)
60 xy = callerInteractor.GetEventPosition()
61 ras = self.xyToRas(xy, viewWidget)
62 pipeline.addPoint(ras)
64 elif eventId == vtk.vtkCommand.LeftButtonReleaseEvent:
65 pipeline.actionState =
"" 66 self.scriptedEffect.cursorOn(viewWidget)
67 elif eventId == vtk.vtkCommand.RightButtonPressEvent:
68 sliceNode = viewWidget.sliceLogic().GetSliceNode()
69 pipeline.lastInsertSliceNodeMTime = sliceNode.GetMTime()
70 elif eventId == vtk.vtkCommand.RightButtonReleaseEvent:
71 sliceNode = viewWidget.sliceLogic().GetSliceNode()
72 if abs(pipeline.lastInsertSliceNodeMTime - sliceNode.GetMTime()) < 2:
74 pipeline.actionState =
None 75 elif eventId == vtk.vtkCommand.MouseMoveEvent:
76 if pipeline.actionState ==
"drawing":
77 xy = callerInteractor.GetEventPosition()
78 ras = self.xyToRas(xy, viewWidget)
79 pipeline.addPoint(ras)
81 elif eventId == vtk.vtkCommand.KeyPressEvent:
82 key = callerInteractor.GetKeySym()
83 if key ==
'a' or key ==
'Return':
87 pipeline.deleteLastPoint()
92 pipeline.positionActors()
96 if callerViewNode
and callerViewNode.IsA(
'vtkMRMLSliceNode'):
100 logging.error(
'processViewNodeEvents: Invalid pipeline')
105 sliceLogic = viewWidget.sliceLogic()
107 currentSlice = sliceLogic.GetSliceOffset()
108 if pipeline.activeSlice:
109 offset = abs(currentSlice - pipeline.activeSlice)
112 pipeline.setLineMode(lineMode)
113 pipeline.positionActors()
120 pipeline =
DrawPipeline(self.scriptedEffect, sliceWidget)
123 renderer = self.scriptedEffect.renderer(sliceWidget)
125 logging.error(
"pipelineForWidget: Failed to get renderer!")
127 self.scriptedEffect.addActor2D(sliceWidget, pipeline.actor)
136 """ Visualization objects and pipeline for each slice view for drawing 153 actorProperty = self.
actor.GetProperty()
154 actorProperty.SetColor(1,1,0)
155 actorProperty.SetLineWidth(1)
159 polyData = vtk.vtkPolyData()
162 lines = vtk.vtkCellArray()
163 polyData.SetLines(lines)
164 idArray = lines.GetData()
166 idArray.InsertNextTuple1(0)
168 polygons = vtk.vtkCellArray()
169 polyData.SetPolys(polygons)
170 idArray = polygons.GetData()
172 idArray.InsertNextTuple1(0)
181 currentSlice = sliceLogic.GetSliceOffset()
191 sliceNode = sliceLogic.GetSliceNode()
196 idArray = lines.GetData()
197 idArray.InsertNextTuple1(p)
198 idArray.SetTuple1(0, idArray.GetNumberOfTuples()-1)
199 lines.SetNumberOfCells(1)
202 actorProperty = self.
actor.GetProperty()
204 actorProperty.SetLineStipplePattern(0xffff)
205 elif mode ==
"dashed":
206 actorProperty.SetLineStipplePattern(0xff00)
211 sliceNode = sliceLogic.GetSliceNode()
212 rasToXY = vtk.vtkTransform()
213 rasToXY.SetMatrix(sliceNode.GetXYToRAS())
222 if lines.GetNumberOfCells() == 0:
return 225 idArray = lines.GetData()
226 p = idArray.GetTuple1(1)
227 idArray.InsertNextTuple1(p)
228 idArray.SetTuple1(0, idArray.GetNumberOfTuples() - 1)
233 import vtkSegmentationCorePython
as vtkSegmentationCore
239 self.
scriptedEffect.modifySelectedSegmentByLabelmap(modifierLabelmap, slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeAdd)
244 idArray = lines.GetData()
246 idArray.InsertNextTuple1(0)
249 lines.SetNumberOfCells(0)
254 pcount = self.
rasPoints.GetNumberOfPoints()
255 if pcount <= 0:
return 261 idArray = lines.GetData()
262 idArray.SetTuple1(0, pcount)
263 idArray.SetNumberOfTuples(pcount+1)
def pipelineForWidget(self, sliceWidget)
def setupOptionsFrame(self)
def __init__(self, scriptedEffect, sliceWidget)
def processViewNodeEvents(self, callerViewNode, eventId, viewWidget)
def deleteLastPoint(self)
def processInteractionEvents(self, callerInteractor, eventId, viewWidget)
def setLineMode(self, mode="solid")
def __init__(self, scriptedEffect)