9 from SegmentEditorEffects
import *
13 """ DrawEffect is a LabelEffect implementing the interactive draw 14 tool in the segment editor 18 scriptedEffect.name =
'Draw' 20 AbstractScriptedSegmentEditorLabelEffect.__init__(self, scriptedEffect)
23 import qSlicerSegmentationsEditorEffectsPythonQt
as effects
24 clonedEffect = effects.qSlicerSegmentEditorScriptedLabelEffect(
None)
25 clonedEffect.setPythonSource(__file__.replace(
'\\',
'/'))
29 iconPath = os.path.join(os.path.dirname(__file__),
'Resources/Icons/Draw.png')
30 if os.path.exists(iconPath):
31 return qt.QIcon(iconPath)
35 return """<html>Draw segment outline in slice viewers<br>. 36 <p><ul style="margin: 0"> 37 <li><b>Left-click:</b> add point.</li> 38 <li><b>Left-button drag-and-drop:</b> add multiple points.</li> 39 <li><b>x:</b> delete last point.</li> 40 <li><b>Double-left-click</b> or <b>right-click</b> or <b>a</b> or <b>enter</b>: apply outline.</li> 46 self.scriptedEffect.removeActor2D(sliceWidget, pipeline.actor)
56 if viewWidget.className() !=
"qMRMLSliceWidget":
59 pipeline = self.pipelineForWidget(viewWidget)
63 anyModifierKeyPressed = callerInteractor.GetShiftKey()
or callerInteractor.GetControlKey()
or callerInteractor.GetAltKey()
65 if eventId == vtk.vtkCommand.LeftButtonPressEvent
and not anyModifierKeyPressed:
67 confirmedEditingAllowed = self.scriptedEffect.confirmCurrentSegmentVisible()
68 if confirmedEditingAllowed == self.scriptedEffect.NotConfirmed
or confirmedEditingAllowed == self.scriptedEffect.ConfirmedWithDialog:
73 pipeline.actionState =
"drawing" 74 self.scriptedEffect.cursorOff(viewWidget)
75 xy = callerInteractor.GetEventPosition()
76 ras = self.xyToRas(xy, viewWidget)
77 pipeline.addPoint(ras)
79 elif eventId == vtk.vtkCommand.LeftButtonReleaseEvent:
80 if pipeline.actionState ==
"drawing":
81 pipeline.actionState =
"moving" 82 self.scriptedEffect.cursorOn(viewWidget)
84 elif eventId == vtk.vtkCommand.RightButtonPressEvent
and not anyModifierKeyPressed:
85 pipeline.actionState =
"finishing" 86 sliceNode = viewWidget.sliceLogic().GetSliceNode()
87 pipeline.lastInsertSliceNodeMTime = sliceNode.GetMTime()
89 elif (eventId == vtk.vtkCommand.RightButtonReleaseEvent
and pipeline.actionState ==
"finishing")
or (eventId == vtk.vtkCommand.LeftButtonDoubleClickEvent
and not anyModifierKeyPressed):
90 abortEvent = (pipeline.rasPoints.GetNumberOfPoints() > 1)
91 sliceNode = viewWidget.sliceLogic().GetSliceNode()
92 if abs(pipeline.lastInsertSliceNodeMTime - sliceNode.GetMTime()) < 2:
94 pipeline.actionState =
"" 95 elif eventId == vtk.vtkCommand.MouseMoveEvent:
96 if pipeline.actionState ==
"drawing":
97 xy = callerInteractor.GetEventPosition()
98 ras = self.xyToRas(xy, viewWidget)
99 pipeline.addPoint(ras)
101 elif eventId == vtk.vtkCommand.KeyPressEvent:
102 key = callerInteractor.GetKeySym()
103 if key ==
'a' or key ==
'Return':
107 pipeline.deleteLastPoint()
112 pipeline.positionActors()
116 if callerViewNode
and callerViewNode.IsA(
'vtkMRMLSliceNode'):
120 logging.error(
'processViewNodeEvents: Invalid pipeline')
125 sliceLogic = viewWidget.sliceLogic()
127 currentSliceOffset = sliceLogic.GetSliceOffset()
128 if pipeline.activeSliceOffset:
129 offset = abs(currentSliceOffset - pipeline.activeSliceOffset)
132 pipeline.setLineMode(lineMode)
133 pipeline.positionActors()
140 pipeline =
DrawPipeline(self.scriptedEffect, sliceWidget)
143 renderer = self.scriptedEffect.renderer(sliceWidget)
145 logging.error(
"pipelineForWidget: Failed to get renderer!")
147 self.scriptedEffect.addActor2D(sliceWidget, pipeline.actor)
157 """ Visualization objects and pipeline for each slice view for drawing 172 self.
actor = vtk.vtkTexturedActor2D()
175 actorProperty = self.
actor.GetProperty()
176 actorProperty.SetColor(1, 1, 0)
177 actorProperty.SetLineWidth(1)
186 dimension = 16 * lineStippleRepeat
188 image = vtk.vtkImageData()
189 image.SetDimensions(dimension, 1, 1)
190 image.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 4)
191 image.SetExtent(0, dimension - 1, 0, 0, 0, 0)
195 while i_dim < dimension:
196 for i
in range(0, 16):
198 bit = (lineStipplePattern & mask) >> i
201 for j
in range(0, lineStippleRepeat):
202 image.SetScalarComponentFromFloat(i_dim, 0, 0, 0, on)
203 image.SetScalarComponentFromFloat(i_dim, 0, 0, 1, on)
204 image.SetScalarComponentFromFloat(i_dim, 0, 0, 2, on)
205 image.SetScalarComponentFromFloat(i_dim, 0, 0, 3, off)
208 for j
in range(0, lineStippleRepeat):
209 image.SetScalarComponentFromFloat(i_dim, 0, 0, 0, on)
210 image.SetScalarComponentFromFloat(i_dim, 0, 0, 1, on)
211 image.SetScalarComponentFromFloat(i_dim, 0, 0, 2, on)
212 image.SetScalarComponentFromFloat(i_dim, 0, 0, 3, on)
214 self.
texture.SetInputData(image)
220 polyData = vtk.vtkPolyData()
222 lines = vtk.vtkCellArray()
223 polyData.SetLines(lines)
231 currentSliceOffset = sliceLogic.GetSliceOffset()
242 sliceNode = sliceLogic.GetSliceNode()
247 idList = vtk.vtkIdList()
248 idList.InsertNextId(p - 1)
249 idList.InsertNextId(p)
250 self.
polyData.InsertNextCell(vtk.VTK_LINE, idList)
253 actorProperty = self.
actor.GetProperty()
255 self.
polyData.GetPointData().SetTCoords(
None)
256 self.
actor.SetTexture(
None)
257 elif mode ==
"dashed":
259 self.
tcoords.SetNumberOfComponents(1)
261 for i
in range(0, self.
polyData.GetNumberOfPoints()):
263 self.
tcoords.SetTypedTuple(i, [value])
270 sliceNode = sliceLogic.GetSliceNode()
271 rasToXY = vtk.vtkTransform()
272 rasToXY.SetMatrix(sliceNode.GetXYToRAS())
281 lineExists = lines.GetNumberOfCells() > 0
284 idList = vtk.vtkIdList()
285 idList.InsertNextId(self.
polyData.GetNumberOfPoints() - 1)
286 idList.InsertNextId(0)
287 self.
polyData.InsertNextCell(vtk.VTK_LINE, idList)
293 segmentationNode = self.
scriptedEffect.parameterSetNode().GetSegmentationNode()
299 self.
scriptedEffect.modifySelectedSegmentByLabelmap(modifierLabelmap, slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeAdd)
311 pcount = self.
rasPoints.GetNumberOfPoints()
318 cellCount = self.
polyData.GetNumberOfCells()
320 self.
polyData.DeleteCell(cellCount - 1)
def pipelineForWidget(self, sliceWidget)
def setupOptionsFrame(self)
def __init__(self, scriptedEffect, sliceWidget)
def processViewNodeEvents(self, callerViewNode, eventId, viewWidget)
def createStippleTexture(self, lineStipplePattern, lineStippleRepeat)
def deleteLastPoint(self)
def processInteractionEvents(self, callerInteractor, eventId, viewWidget)
def setLineMode(self, mode="solid")
def __init__(self, scriptedEffect)