Browse files

COMP: Remove SWidget tcl related code

Keep the Slicer3Adapter.tcl around since it's still required by EMSegment

Later on should also remove the slicer.sliceWidet* object since these
ones can be accessed using the slicer.app.layoutManager() object.

See http://na-mic.org/Mantis/view.php?id=2735
Fixes #2735

git-svn-id: http://svn.slicer.org/Slicer4/trunk@21407 3bd1e089-480b-0410-8dfb-8563597acbee
  • Loading branch information...
1 parent e655074 commit fd51c47a437bf0f5db627283362c7e0fb1d1b829 @jcfr jcfr committed Nov 14, 2012
View
304 Base/GUI/Tcl/GridSWidget.tcl
@@ -1,304 +0,0 @@
-
-#########################################################
-#
-if {0} { ;# comment
-
- GridSWidget - manages slice plane interactions
-
-# TODO :
-
-}
-#
-#########################################################
-# ------------------------------------------------------------------
-# GridSWidget
-# ------------------------------------------------------------------
-#
-# The class definition - define if needed (not when re-sourcing)
-#
-if { [itcl::find class GridSWidget] == "" } {
-
- itcl::class GridSWidget {
-
- inherit SWidget
-
- constructor {args} {}
- destructor {}
-
- public variable layer "label" ;# which slice layer to show the grid for
- public variable rgba ".5 .5 1 .3" ;# grid color
- public variable cutoff "5" ;# don't show grid if it's less than 'cutoff' screen pixels
-
- # methods
- method processEvent {{caller ""} {event ""}} {}
- method updateGrid { } {}
- method resetGrid { } {}
- method addGridLine { startPoint endPoint } {}
- }
-}
-
-# ------------------------------------------------------------------
-# CONSTRUCTOR/DESTRUCTOR
-# ------------------------------------------------------------------
-itcl::body GridSWidget::constructor {sliceGUI} {
-
- $this configure -sliceGUI $sliceGUI
-
- # create grid display parts
- set o(gridPolyData) [vtkNew vtkPolyData]
- set o(gridLines) [vtkNew vtkCellArray]
- $o(gridPolyData) SetLines $o(gridLines)
- set o(gridPoints) [vtkNew vtkPoints]
- $o(gridPolyData) SetPoints $o(gridPoints)
-
- set o(gridMapper) [vtkNew vtkPolyDataMapper2D]
- set o(gridActor) [vtkNew vtkActor2D]
- $o(gridMapper) SetInput $o(gridPolyData)
- $o(gridActor) SetMapper $o(gridMapper)
- eval [$o(gridActor) GetProperty] SetColor [lrange $rgba 0 2]
- eval [$o(gridActor) GetProperty] SetOpacity [lindex $rgba 3]
- after idle [$_renderWidget GetRenderer] AddActor2D $o(gridActor)
- lappend _actors $o(gridActor)
-
- #
- # set up observers on sliceGUI and on sliceNode
- #
- $::slicer3::Broker AddObservation $sliceGUI DeleteEvent "::SWidget::ProtectedDelete $this"
-
- set events { "MouseMoveEvent" "UserEvent" }
- foreach event $events {
- $::slicer3::Broker AddObservation $sliceGUI $event "::SWidget::ProtectedCallback $this processEvent $sliceGUI $event"
- }
-
- set node [[$sliceGUI GetLogic] GetSliceNode]
- $::slicer3::Broker AddObservation $node DeleteEvent "::SWidget::ProtectedDelete $this"
- $::slicer3::Broker AddObservation $node AnyEvent "::SWidget::ProtectedCallback $this processEvent $node AnyEvent"
-
- set node [[$sliceGUI GetLogic] GetSliceCompositeNode]
- $::slicer3::Broker AddObservation $node DeleteEvent "::SWidget::ProtectedDelete $this"
- $::slicer3::Broker AddObservation $node AnyEvent "::SWidget::ProtectedCallback $this processEvent $node AnyEvent"
-
- after idle $this processEvent $node
-}
-
-
-itcl::body GridSWidget::destructor {} {
-
- if { [info command $_renderer] != "" } {
- foreach a $_actors {
- $_renderer RemoveActor2D $a
- }
- }
-}
-
-
-
-# ------------------------------------------------------------------
-# METHODS
-# ------------------------------------------------------------------
-
-#
-# handle interactor events
-#
-itcl::body GridSWidget::processEvent { {caller ""} {event ""} } {
-
- if { $enabled != "true" } {
- return
- }
-
- if { [info command $sliceGUI] == "" || [$sliceGUI GetLogic] == "" } {
- # the sliceGUI was deleted behind our back, so we need to
- # self destruct
- ::SWidget::ProtectedDelete $this
- return
- }
-
- if { ![$_sliceCompositeNode GetLabelGrid] || [$_sliceCompositeNode GetLabelVolumeID] == "" } {
- # avoid any computation if we are not currently visible
- $o(gridActor) SetVisibility 0
- [$sliceGUI GetSliceViewer] RequestRender
- return
- }
-
- foreach {x y} [$_interactor GetEventPosition] {}
- $this queryLayers $x $y
- set xyToRAS [$_sliceNode GetXYToRAS]
- set ras [$xyToRAS MultiplyPoint $x $y 0 1]
- foreach {r a s t} $ras {}
-
- set node [[$sliceGUI GetLogic] GetSliceNode]
- if { $caller == $node } {
- $this updateGrid
- return
- }
-
- set node [[$sliceGUI GetLogic] GetSliceCompositeNode]
- if { $caller == $node } {
- $this updateGrid
- return
- }
-
- if { $caller == $sliceGUI } {
-
- switch $event {
-
- "MouseMoveEvent" {
- #
- # highlight the current grid cell
- #
-
- # update the actors...
- }
- }
-
- return
- }
-
-}
-
-itcl::body GridSWidget::resetGrid { } {
-
- set idArray [$o(gridLines) GetData]
- $idArray Reset
- $idArray InsertNextTuple1 0
- $o(gridPoints) Reset
- $o(gridLines) SetNumberOfCells 0
-
-}
-
-itcl::body GridSWidget::addGridLine { startPoint endPoint } {
-
- set startPoint [lrange $startPoint 0 2]
- set endPoint [lrange $endPoint 0 2]
- set startIndex [eval $o(gridPoints) InsertNextPoint $startPoint]
- set endIndex [eval $o(gridPoints) InsertNextPoint $endPoint]
-
- set cellCount [$o(gridLines) GetNumberOfCells]
- set idArray [$o(gridLines) GetData]
- $idArray InsertNextTuple1 2
- $idArray InsertNextTuple1 $startIndex
- $idArray InsertNextTuple1 $endIndex
- $o(gridLines) SetNumberOfCells [expr $cellCount + 1]
-
-}
-
-
-#
-# make the grid object
-#
-itcl::body GridSWidget::updateGrid { } {
-
-
- if { ![$_sliceCompositeNode GetLabelGrid] || [$_sliceCompositeNode GetLabelVolumeID] == "" } {
- $o(gridActor) SetVisibility 0
- [$sliceGUI GetSliceViewer] RequestRender
- return
- }
-
- $this resetGrid
-
- #
- # check the size cutoff
- # - map a single pixel from IJK to XY and check the size
- # - if the grid won't be visible, don't show it.
- # - also don't so if image data doesn't exist
- #
- set ijkToXY [vtkMatrix4x4 New]
- $ijkToXY DeepCopy [[$_layers($layer,logic) GetXYToIJKTransform] GetMatrix]
- $ijkToXY SetElement 0 3 0
- $ijkToXY SetElement 1 3 0
- $ijkToXY SetElement 2 3 0
- $ijkToXY Invert
- foreach {x y z w} [$ijkToXY MultiplyPoint 1 1 1 0] {}
- if { [expr abs($x)] < $cutoff && [expr abs($y)] < $cutoff || $_layers($layer,image) == "" } {
- $o(gridActor) SetVisibility 0
- $ijkToXY Delete
- return
- } else {
- if { [$o(gridActor) GetVisibility] } {
- # put the actor at the top of the display list
- [$_renderWidget GetRenderer] RemoveActor2D $o(gridActor)
- [$_renderWidget GetRenderer] AddActor2D $o(gridActor)
- }
- $o(gridActor) SetVisibility 1
- }
-
-
- #
- # determine which slice plane to display
- # - since this is an orthogonal projection, all slices will look the same,
- # so once we know which to draw, we only need to draw a single one
- # - choose the two indices that have the largest change with respect to XY
- # - make two sets of lines, one along the rows and one along the columns
- #
- set xyToIJK [vtkMatrix4x4 New]
- $xyToIJK DeepCopy [[$_layers($layer,logic) GetXYToIJKTransform] GetMatrix]
- $xyToIJK SetElement 0 3 0
- $xyToIJK SetElement 1 3 0
- $xyToIJK SetElement 2 3 0
- foreach {i j k l} [$xyToIJK MultiplyPoint 1 1 0 0] {}
- foreach v {i j k l} { set $v [expr abs([set $v])] }
-
- if { $i < $j && $i < $k } { set rowAxis 1; set colAxis 2 }
- if { $j < $i && $j < $k } { set rowAxis 0; set colAxis 2 }
- if { $k < $i && $k < $j } { set rowAxis 0; set colAxis 1 }
-
- set dims [$_layers($layer,image) GetDimensions]
- set rowDims [lindex $dims $rowAxis]
- set colDims [lindex $dims $colAxis]
-
- $ijkToXY DeepCopy [[$_layers($layer,logic) GetXYToIJKTransform] GetMatrix]
- $ijkToXY Invert
-
- set startPoint "-0.5 -0.5 -0.5 1"
- set endPoint "-0.5 -0.5 -0.5 1"
- set endPoint [lreplace $endPoint $colAxis $colAxis [expr $colDims - 0.5]]
-
- for {set row -0.5} {$row <= $rowDims} {set row [expr $row + 1.0]} {
- set startPoint [lreplace $startPoint $rowAxis $rowAxis $row]
- set endPoint [lreplace $endPoint $rowAxis $rowAxis $row]
- set xyStartPoint [eval $ijkToXY MultiplyPoint $startPoint]
- set xyEndPoint [eval $ijkToXY MultiplyPoint $endPoint]
- $this addGridLine $xyStartPoint $xyEndPoint
- }
-
- set startPoint "-0.5 -0.5 -0.5 1"
- set endPoint "-0.5 -0.5 -0.5 1"
- set endPoint [lreplace $endPoint $rowAxis $rowAxis [expr $rowDims - 0.5]]
-
- for {set col -0.5} {$col <= $colDims} {set col [expr $col + 1.0]} {
- set startPoint [lreplace $startPoint $colAxis $colAxis $col]
- set endPoint [lreplace $endPoint $colAxis $colAxis $col]
- set xyStartPoint [eval $ijkToXY MultiplyPoint $startPoint]
- set xyEndPoint [eval $ijkToXY MultiplyPoint $endPoint]
- $this addGridLine $xyStartPoint $xyEndPoint
- }
-
- $ijkToXY Delete
- $xyToIJK Delete
-
- [$sliceGUI GetSliceViewer] RequestRender
-}
-
-proc GridSWidget::AddGrid {} {
- foreach sw [itcl::find objects -class SliceSWidget] {
- set sliceGUI [$sw cget -sliceGUI]
- if { [info command $sliceGUI] != "" } {
- GridSWidget #auto [$sw cget -sliceGUI]
- }
- }
-}
-
-proc GridSWidget::RemoveGrid {} {
- foreach pw [itcl::find objects -class GridSWidget] {
- itcl::delete object $pw
- }
-}
-
-proc GridSWidget::ToggleGrid {} {
- if { [itcl::find objects -class GridSWidget] == "" } {
- GridSWidget::AddGrid
- } else {
- GridSWidget::RemoveGrid
- }
-}
View
429 Base/GUI/Tcl/ModelSWidget.tcl
@@ -1,429 +0,0 @@
-package require Itcl
-
-#########################################################
-#
-if {0} { ;# comment
-
- ModelSWidget a class for slicer fiducials in 2D
-
-
-# TODO :
-
-}
-#
-#########################################################
-
-#
-#########################################################
-# ------------------------------------------------------------------
-# ModelSWidget
-# ------------------------------------------------------------------
-#
-# The class definition - define if needed (not when re-sourcing)
-#
-if { [itcl::find class ModelSWidget] == "" } {
-
- itcl::class ModelSWidget {
-
- inherit SWidget
-
- constructor {args} {}
- destructor {}
-
- public variable modelID ""
- public variable opacity "0.5"
- public variable visibility "1"
-
- variable _modelNode ""
- variable _modelDisplayNode ""
- variable _modelNodeObservation ""
- variable _modelDisplayNodeObservation ""
- variable _sliceCompositeNode ""
-
- # methods
- method updateModelNode {} {}
- method processEvent {{caller ""} {event ""}} {}
- method positionActors {} {}
- method highlight {} {}
- }
-}
-
-# ------------------------------------------------------------------
-# CONSTRUCTOR/DESTRUCTOR
-# ------------------------------------------------------------------
-itcl::body ModelSWidget::constructor {sliceGUI} {
-
- $this configure -sliceGUI $sliceGUI
-
- set o(cutter) [vtkNew vtkCutter]
- set o(plane) [vtkNew vtkPlane]
- $o(cutter) SetCutFunction $o(plane)
- $o(cutter) SetGenerateCutScalars 0 ;# these would be value of the plane at 0, not cut input scalars
- set o(cutTransform) [vtkNew vtkTransform]
- set o(cutTransformFilter) [vtkNew vtkTransformPolyDataFilter]
- $o(cutTransformFilter) SetInputConnection [$o(cutter) GetOutputPort]
- $o(cutTransformFilter) SetTransform $o(cutTransform)
-
- set o(mapper) [vtkNew vtkPolyDataMapper2D]
- set o(actor) [vtkNew vtkActor2D]
- $o(mapper) SetInputConnection [$o(cutTransformFilter) GetOutputPort]
- $o(actor) SetMapper $o(mapper)
- set _renderer [$_renderWidget GetRenderer]
- $_renderer AddActor2D $o(actor)
- lappend _actors $o(actor)
-
- set _sliceCompositeNode [[$sliceGUI GetLogic] GetSliceCompositeNode]
- $this configure -visibility [$_sliceCompositeNode GetSliceIntersectionVisibility]
-
- $this processEvent
-
- # observe the slice GUI for user input events
- # TODO: no mouse events until we start interacting with the slice nodes
- $::slicer3::Broker AddObservation $sliceGUI DeleteEvent "::SWidget::ProtectedDelete $this"
-
- # observe the slice node for direct manipulations of MRML
- set node [[$sliceGUI GetLogic] GetSliceNode]
- $::slicer3::Broker AddObservation $node DeleteEvent "::SWidget::ProtectedDelete $this"
- $::slicer3::Broker AddObservation $node AnyEvent "::SWidget::ProtectedCallback $this processEvent $node AnyEvent"
-
- # observe the composite node for slice plane visibility requests
- $::slicer3::Broker AddObservation $_sliceCompositeNode DeleteEvent "::SWidget::ProtectedDelete $this"
- $::slicer3::Broker AddObservation $_sliceCompositeNode AnyEvent "::SWidget::ProtectedCallback $this processEvent $_sliceCompositeNode AnyEvent"
-
-}
-
-itcl::body ModelSWidget::destructor {} {
-
- $o(cutTransformFilter) SetInput ""
- $o(cutTransformFilter) SetTransform ""
-
- if { [info command $_renderer] != "" } {
- foreach a $_actors {
- $_renderer RemoveActor2D $a
- }
- }
-
-}
-
-#
-# when told what model to observe...
-#
-itcl::configbody ModelSWidget::modelID {
- if { $modelID == "" } {
- return
- }
-
- $this updateModelNode
-}
-
-
-itcl::configbody ModelSWidget::opacity {
- $this highlight
- [$sliceGUI GetSliceViewer] RequestRender
-}
-
-itcl::configbody ModelSWidget::visibility {
- $this highlight
- [$sliceGUI GetSliceViewer] RequestRender
-}
-
-# ------------------------------------------------------------------
-# METHODS
-# ------------------------------------------------------------------
-
-
-# since the model node may be changing, provide this method
-# to update the internal representation when, for example, the
-# polydata or display node structures update
-itcl::body ModelSWidget::updateModelNode {} {
-
- # find the model node
- set modelNode [$::slicer3::MRMLScene GetNodeByID $modelID]
- if { $modelNode == "" } {
- #error "no node for id $modelID"
- return
- }
-
- # remove observation from old node and add to new node
- # then set input to pipeline
- if { $modelNode != $_modelNode } {
- if { $_modelNodeObservation != "" } {
- $::slicer3::Broker RemoveObservation $_modelNodeObservation
- }
- set _modelNode $modelNode
- if { $_modelNode != "" } {
- $o(cutter) SetInput [$_modelNode GetPolyData]
- set _modelNodeObservation [$::slicer3::Broker AddObservation $_modelNode AnyEvent "::SWidget::ProtectedCallback $this processEvent $_modelNode AnyEvent"]
- }
- }
-
-
- # remove observation from old node and add to new node
- # then set input to pipeline
-
- # TODO: this is a special case (hack) for Fiber Bundles
- # since we actually want to see their tube output, not the
- # original streamlines (which would be dots)
- if { [$_modelNode IsA "vtkMRMLFiberBundleNode"] } {
- set displayNode [$modelNode GetTubeDisplayNode]
- } else {
- set displayNode [$modelNode GetDisplayNode]
- }
- if { $displayNode != $_modelDisplayNode } {
- if { $_modelDisplayNodeObservation != "" } {
- $::slicer3::Broker RemoveObservation $_modelDisplayNodeObservation
- }
- set _modelDisplayNode $displayNode
- if { $_modelDisplayNode != "" } {
- set _modelDisplayNodeObservation [$::slicer3::Broker AddObservation $displayNode AnyEvent "::SWidget::ProtectedCallback $this processEvent $displayNode AnyEvent"]
- }
- }
-
- $this highlight
- [$sliceGUI GetSliceViewer] RequestRender
-}
-
-itcl::body ModelSWidget::positionActors { } {
-
- $o(actor) SetPosition 0 0
- return
-}
-
-itcl::body ModelSWidget::highlight { } {
-
- if { $modelID == "" } {
- $o(actor) SetVisibility 0
- return
- }
-
- $o(actor) SetVisibility $visibility
-
- if { !$visibility } {
- return
- }
-
- set property [$o(actor) GetProperty]
-
- #
- # set color (extracted from the display node)
- #
- set color "0.5 0.5 0.5"
- set modelNode [$::slicer3::MRMLScene GetNodeByID $modelID]
- if { $modelNode != "" } {
- if { $_modelDisplayNode != "" } {
- set color [$_modelDisplayNode GetColor]
- $o(mapper) SetScalarVisibility 0
-
-
- #
- # code below follows vtkSlicerViewerWidget::SetModelDisplayProperty
- # - it cannot be used, because vtkCutter does not generate
- # cut versions of the scalar fields of the polydata
- # - also vtkTransformPolyDataFilter may interfere with the scalars
- # (not investigated)
- # - even if the scalars were preserved, for point data there would be a problem with
- # discrete values (label maps) since they would be interpolated
- # before being mapped through the color lookup table
- #
- if { 0 } {
- $o(mapper) SetScalarVisibility [$_modelDisplayNode GetScalarVisibility]
- set colorNode [$_modelDisplayNode GetColorNode]
- if { $colorNode != "" } {
- set lut [$colorNode GetLookupTable]
- $o(mapper) SetLookupTable $lut
- }
- set polyData [$modelNode GetPolyData]
- set scalarName [$_modelDisplayNode GetActiveScalarName]
- if { $scalarName != "" } {
- set pointData [$polyData GetPointData]
- set pointScalars [$pointData GetScalars $scalarName]
- set cellData [$polyData GetCellData]
- set cellScalars [$cellData GetScalars $scalarName]
- if { $pointScalars != "" } {
- $o(mapper) SetScalarModeToUsePointData
- $o(mapper) SetColorModeToMapScalars
- $o(mapper) UseLookupTableScalarRangeOff
- eval $o(mapper) SetScalarRange [$_modelDisplayNode GetScalarRange]
- } elseif { $cellScalars != "" } {
- $o(mapper) SetScalarModeToUseCellData
- $o(mapper) SetColorModeToDefault
- $o(mapper) UseLookupTableScalarRangeOff
- eval $o(mapper) SetScalarRange [$_modelDisplayNode GetScalarRange]
- } else {
- $o(mapper) SetScalarModeToDefault
- }
- }
- }
- }
- }
-
- eval $property SetColor $color
- $property SetLineWidth 3
- $property SetOpacity $opacity
-
- return
-}
-
-itcl::body ModelSWidget::processEvent { {caller ""} {event ""} } {
-
- if { $enabled != "true" } {
- return
- }
-
- if { [info command $sliceGUI] == "" || [$sliceGUI GetLogic] == "" } {
- # the sliceGUI was deleted behind our back, so we need to
- # self destruct
- itcl::delete object $this
- return
- }
-
- $this updateModelNode
- if { $_modelDisplayNode == "" } {
- # no display node, do nothing
- $this configure -visibility 0
- return
- }
-
- if { [info command $_modelNode] == "" || [$_modelNode GetPolyData] == "" } {
- # the model was deleted behind our back,
- # or if there is no poly data, turn off our display and do nothing
- $this configure -visibility 0
- return
- }
-
- if { $_modelDisplayNode != "" } {
- $this configure -visibility [$_modelDisplayNode GetSliceIntersectionVisibility]
- }
-
- if { !$visibility } {
- # we're not visible, there's no reason to do the calculations...
- return
- }
-
- set transformToWorld [vtkMatrix4x4 New]
- $transformToWorld Identity
-
- # control visibility based on ModelDisplayNode and
- # transform based on transform node
- if { $_modelNode != "" && [$_modelNode GetPolyData] != "" } {
- # TODO: this is a special case (hack) for Fiber Bundles
- # since we actually want to see their tube output, not the
- # original streamlines (which would be dots)
- if { [$_modelNode IsA "vtkMRMLFiberBundleNode"] } {
- if { $_modelDisplayNode != "" } {
- $o(cutter) SetInput [$_modelDisplayNode GetPolyData]
- }
- } else {
- $o(cutter) SetInput [$_modelNode GetPolyData]
- }
-
- # handle model transform to world space
- set tnode [$_modelNode GetParentTransformNode]
- if { $tnode != "" } {
- $tnode GetMatrixTransformToWorld $transformToWorld
- }
- }
-
-
- #
- # update the transform from world to screen space
- # for the extracted cut plane
- #
- $this queryLayers 0 0 0
- set rasToXY [vtkMatrix4x4 New]
- $rasToXY DeepCopy [$_sliceNode GetXYToRAS]
- $rasToXY Invert
-
- set mat [vtkMatrix4x4 New]
- $mat Identity
- $mat Multiply4x4 $rasToXY $transformToWorld $mat
- $rasToXY DeepCopy $mat
-
- $o(cutTransform) SetMatrix $rasToXY
-
- $transformToWorld Invert
- #
- # update the plane equation for the current slice cutting plane
- # - extract from the slice matrix
- # - normalize the normal
- #
-
- $rasToXY DeepCopy [$_sliceNode GetXYToRAS]
-
- if { $_modelNode != "" } {
- $mat Identity
- $mat Multiply4x4 $transformToWorld $rasToXY $mat
- $rasToXY DeepCopy $mat
- }
-
- foreach row {0 1 2} {
- lappend normal [$rasToXY GetElement $row 2]
- lappend origin [$rasToXY GetElement $row 3]
- }
-
- $transformToWorld Delete
- $rasToXY Delete
- $mat Delete
-
-
- set sum 0.
- foreach ele $normal {
- set sum [expr $sum + $ele * $ele]
- }
- set lenInv [expr 1./sqrt($sum)]
- foreach ele $normal {
- lappend norm [expr $ele * $lenInv]
- }
- eval $o(plane) SetNormal $norm
- eval $o(plane) SetOrigin $origin
-
- set grabID [$sliceGUI GetGrabID]
- if { ! ($grabID == "" || $grabID == $this) } {
- # some other widget wants these events
- # -- we can position wrt the current slice node
- $this positionActors
- $o(cutter) Modified
- [$sliceGUI GetSliceViewer] RequestRender
- return
- }
-
- set _actionState ""
- $sliceGUI SetGrabID ""
-
- $this highlight
- $this positionActors
- $o(cutter) Modified
- [$sliceGUI GetSliceViewer] RequestRender
-
-}
-
-#
-# The Rasterize proc is an experiment for creating label maps
-# from models. This works well for simple shapes, but unfortunately
-# does not work for more complex shapes (i.e. with multple contours
-# intersecting the slice plane)
-#
-namespace eval ModelSWidget {
- proc Rasterize { modelSW } {
-
- set sliceGUI [$modelSW cget -sliceGUI]
- set labeler [Labeler #auto $sliceGUI]
- array set o [$modelSW getObjects]
-
- set stripper [vtkStripper New]
- set cleaner [vtkCleanPolyData New]
- $stripper SetInput [$o(cutTransformFilter) GetOutput]
- $cleaner SetInput [$stripper GetOutput]
- set polyData [$cleaner GetOutput]
- $polyData Update
-
- set maskResult [$labeler makeMaskImage $polyData]
- foreach {maskIJKToRAS mask} $maskResult {}
- [$polyData GetPoints] Modified
- set bounds [$polyData GetBounds]
- $labeler applyImageMask $maskIJKToRAS $mask $bounds
-
- itcl::delete object $labeler
- }
-}
-
View
292 Base/GUI/Tcl/RulerSWidget.tcl
@@ -1,292 +0,0 @@
-package require Itcl
-
-#########################################################
-#
-if {0} { ;# comment
-
- RulerSWidget a class for slicer rulers in 2D
-
-
-# TODO :
-
-}
-#
-#########################################################
-
-#
-#########################################################
-# ------------------------------------------------------------------
-# RulerSWidget
-# ------------------------------------------------------------------
-#
-# The class definition - define if needed (not when re-sourcing)
-#
-if { [itcl::find class RulerSWidget] == "" } {
-
- itcl::class RulerSWidget {
-
- inherit SWidget
-
- constructor {args} {}
- destructor {}
-
- public variable rulerID ""
-
- variable _rulerNode ""
- variable _rulerNodeObservation ""
- variable _updating 0
-
- # methods
- method processEvent {{caller ""} {event ""}} {}
- method updateMRMLFromWidget {} {}
- method updateWidgetFromMRML {} {}
- method updateAnnotation {} {}
- method lockWidget { lockFlag } {}
- }
-}
-
-# ------------------------------------------------------------------
-# CONSTRUCTOR/DESTRUCTOR
-# ------------------------------------------------------------------
-itcl::body RulerSWidget::constructor {sliceGUI} {
-
- $this configure -sliceGUI $sliceGUI
-
- set o(lineWidget) [vtkNew vtkLineWidget2]
- $o(lineWidget) SetInteractor [$_renderWidget GetRenderWindowInteractor]
- [$o(lineWidget) GetRepresentation] PlaceWidget 0 1 0 1 0 1
- $o(lineWidget) On
-
- # observe the slice GUI for user input events
- # TODO: no mouse events until we start interacting with the slice nodes
- $::slicer3::Broker AddObservation $sliceGUI DeleteEvent "::SWidget::ProtectedDelete $this"
-
- # observe the slice node for direct manipulations of MRML
- set sliceNode [[$sliceGUI GetLogic] GetSliceNode]
- $::slicer3::Broker AddObservation $sliceNode DeleteEvent "::SWidget::ProtectedDelete $this"
- $::slicer3::Broker AddObservation $sliceNode AnyEvent "::SWidget::ProtectedCallback $this processEvent $sliceNode AnyEvent"
-
- # observe the widget for interaction
- $::slicer3::Broker AddObservation $o(lineWidget) StartInteractionEvent "::SWidget::ProtectedCallback $this processEvent $o(lineWidget) StartInteractionEvent"
- $::slicer3::Broker AddObservation $o(lineWidget) EndInteractionEvent "::SWidget::ProtectedCallback $this processEvent $o(lineWidget) EndInteractionEvent"
- $::slicer3::Broker AddObservation $o(lineWidget) InteractionEvent "::SWidget::ProtectedCallback $this processEvent $o(lineWidget) InteractionEvent"
-
-}
-
-itcl::body RulerSWidget::destructor {} {
- $o(lineWidget) Off
- if {[info command $sliceGUI] != ""} {
- [$sliceGUI GetSliceViewer] RequestRender
- }
-}
-
-#
-# when told what ruler to observe...
-#
-itcl::configbody RulerSWidget::rulerID {
- # find the ruler node
- set rulerNode [$::slicer3::MRMLScene GetNodeByID $rulerID]
- if { $rulerNode == "" } {
- #error "no node for id $rulerID"
- return
- }
-
- # remove observation from old node and add to new node
- # then set input to pipeline
- if { $rulerNode != $_rulerNode } {
- if { $_rulerNodeObservation != "" } {
- $::slicer3::Broker RemoveObservation $_rulerNodeObservation
- }
- set _rulerNode $rulerNode
- if { $_rulerNode != "" } {
- set _rulerNodeObservation [$::slicer3::Broker AddObservation $_rulerNode AnyEvent "::SWidget::ProtectedCallback $this processEvent $_rulerNode AnyEvent"]
- }
- }
-
- $this updateWidgetFromMRML
- if {[info command $sliceGUI] != ""} {
- [$sliceGUI GetSliceViewer] RequestRender
- }
-}
-
-# ------------------------------------------------------------------
-# METHODS
-# ------------------------------------------------------------------
-
-itcl::body RulerSWidget::updateWidgetFromMRML { } {
-
- if { $_rulerNode == "" } {
- return
- }
-
- if { $_updating } {
- return
- }
-
- #
- # set the two endpoints in screen space
- #
-
- $this queryLayers 0 0 0
- set lineRep [$o(lineWidget) GetRepresentation]
- set ras1 [$_rulerNode GetPosition1]
- set ras2 [$_rulerNode GetPosition2]
- set xyz1 [$this rasToXYZ $ras1]
- set xyz2 [$this rasToXYZ $ras2]
-
- set onSlice 1
- # only show widget if on the correct slice
- $o(lineWidget) On
- foreach xyz [list $xyz1 $xyz2] {
- foreach {x y z} $xyz {}
- if { [expr abs($z)] > 0.5 } {
- set onSlice 0
- }
- }
-
- eval $lineRep SetPoint1DisplayPosition $xyz1
- eval $lineRep SetPoint2DisplayPosition $xyz2
-
- #
- # set up the colours and annotation
- #
- eval [[$lineRep GetPoint1Representation] GetProperty] SetColor [$_rulerNode GetPointColour]
- eval [[$lineRep GetPoint2Representation] GetProperty] SetColor [$_rulerNode GetPoint2Colour]
- eval [$lineRep GetLineProperty] SetColor [$_rulerNode GetLineColour]
- eval [[$lineRep GetTextActor] GetProperty] SetColor [$_rulerNode GetDistanceAnnotationTextColour]
-
- if { [$_rulerNode GetVisibility] && $onSlice } {
- $o(lineWidget) On
- } else {
- $o(lineWidget) Off
- }
-
- $this updateAnnotation
-}
-
-
-itcl::body RulerSWidget::updateMRMLFromWidget { } {
-
- if { $_rulerNode == "" } {
- return
- }
-
- set _updating 1
-
- #
- # set the two endpoints in screen space
- #
- $this queryLayers 0 0 0
- set lineRep [$o(lineWidget) GetRepresentation]
- $_rulerNode DisableModifiedEventOn
- $lineRep GetPoint1DisplayPosition 0 0 0
- $lineRep GetPoint2DisplayPosition 0 0 0
- set xyzpos1 [$lineRep GetPoint1DisplayPosition]
- set xyzpos2 [$lineRep GetPoint2DisplayPosition]
- set pos1 [$this xyzToRAS $xyzpos1]
- set pos2 [$this xyzToRAS $xyzpos2]
- eval $_rulerNode SetPosition1 $pos1
- eval $_rulerNode SetPosition2 $pos2
- $_rulerNode DisableModifiedEventOff
- $_rulerNode InvokePendingModifiedEvent
-
- $this updateAnnotation
- set _updating 0
-}
-
-itcl::body RulerSWidget::updateAnnotation {} {
-
- set lineRep [$o(lineWidget) GetRepresentation]
- $_rulerNode UpdateCurrentDistanceAnnotation
- $lineRep SetDistanceAnnotationFormat [$_rulerNode GetCurrentDistanceAnnotation]
- $lineRep SetDistanceAnnotationVisibility [$_rulerNode GetDistanceAnnotationVisibility]
- $lineRep SetDistanceAnnotationScale .02 .02 .02
-}
-
-itcl::body RulerSWidget::processEvent { {caller ""} {event ""} } {
-
- if { $enabled != "true" } {
- return
- }
-
- if { [info command $sliceGUI] == "" || [$sliceGUI GetLogic] == "" } {
- # the sliceGUI was deleted behind our back, so we need to
- # self destruct
- itcl::delete object $this
- return
- }
- set sliceNode [[$sliceGUI GetLogic] GetSliceNode]
- if { $caller == $_rulerNode || $caller == $sliceNode } {
- $this updateWidgetFromMRML
- if {[info command $sliceGUI] != ""} {
- [$sliceGUI GetSliceViewer] RequestRender
- }
- }
-
- set grabID [$sliceGUI GetGrabID]
- if { ! ($grabID == "" || $grabID == $this) } {
- # some other widget wants these events
- # -- we can position wrt the current slice node
- $this updateWidgetFromMRML
- if {[info command $sliceGUI] != ""} {
- [$sliceGUI GetSliceViewer] RequestRender
- }
- return
- }
-
- $sliceGUI SetGrabID ""
-
- if { $caller == $o(lineWidget) } {
-
- $this requestDelayedAnnotation
-
- if { $event == "StartInteractionEvent" } {
- $this requestDelayedAnnotation
- #--- now adjust the interactionMode.
- #--- This implementation of mouse modes turns on
- #--- 'pick' mode when a ruler endpoint is picked.
- set interactionNode [ $::slicer3::MRMLScene GetNthNodeByClass 0 vtkMRMLInteractionNode ]
- if { $interactionNode != "" } {
- set mode [$interactionNode GetCurrentInteractionMode]
- set modeString [$interactionNode GetInteractionModeAsString $mode]
- set pickPersistence [ $interactionNode GetPickModePersistence]
- if { $pickPersistence == 0 } {
- $interactionNode SetLastInteractionMode $mode
- }
- $interactionNode SetCurrentInteractionMode [ $interactionNode GetInteractionModeByString "PickManipulate" ]
- }
- }
-
- if { $event == "EndInteractionEvent" } {
- #--- now adjust the interactionMode.
- set interactionNode [$::slicer3::MRMLScene GetNthNodeByClass 0 vtkMRMLInteractionNode]
- # Reset interaction mode to default viewtransform
- # mode if user has not selected a persistent pick or place.
- if { $interactionNode != "" } {
- if { [$interactionNode GetCurrentInteractionMode] != [$interactionNode GetInteractionModeByString "ViewTransform"] } {
- set pickPersistence [ $interactionNode GetPickModePersistence]
- set placePersistence [ $interactionNode GetPlaceModePersistence ]
- if { $pickPersistence == 0 && $placePersistence == 0 } {
- $interactionNode SetCurrentInteractionMode [ $interactionNode GetInteractionModeByString "ViewTransform" ]
- $interactionNode SetPickModePersistence 0
- $interactionNode SetPlaceModePersistence 0
- }
- }
- }
- }
-
- $this updateMRMLFromWidget
- if {[info command $sliceGUI] != ""} {
- [$sliceGUI GetSliceViewer] RequestRender
- }
- }
-}
-
-itcl::body RulerSWidget::lockWidget { lockFlag } {
-
- if {$lockFlag == 1} {
- $o(lineWidget) ProcessEventsOff
- } else {
- $o(lineWidget) ProcessEventsOn
- }
-}
View
506 Base/GUI/Tcl/SWidget.tcl
@@ -1,506 +0,0 @@
-
-package require Itcl
-
-package provide SlicerBaseGUITcl 3.0
-
-#
-# utility to only delete an instance if it hasn't already been deleted
-# (this is useful in event handling)
-#
-namespace eval SWidget {
- proc ProtectedDelete {instance} {
- if { [info command $instance] != "" } {
- itcl::delete object $instance
- }
- }
-}
-
-#
-# utility to run method only if instance hasn't already been deleted
-# (this is useful in event handling)
-#
-namespace eval SWidget set CALLBACK_LEVEL 0
-namespace eval SWidget set VERBOSE_CALLBACKS 0
-namespace eval SWidget set DEBUG_CALLBACKS 1
-namespace eval SWidget set TIME_CALLBACKS 0
-namespace eval SWidget set DISABLE_CALLBACKS 0
-namespace eval SWidget set EXCLUDE "__instance_name_pattern__"
-namespace eval SWidget {
- proc ProtectedCallback {instance args} {
- if { $::SWidget::DISABLE_CALLBACKS } {
- return
- }
- if { [string match $::SWidget::EXCLUDE $instance] ||
- [string match $::SWidget::EXCLUDE $args] } {
- return
- }
- if { $::SWidget::VERBOSE_CALLBACKS } {
- for {set sp 0} {$sp < $::SWidget::CALLBACK_LEVEL} {incr sp} {
- puts -nonewline " "
- }
- puts "callback for $instance with $args"
- }
- incr ::SWidget::CALLBACK_LEVEL
- if { [info command $instance] != "" } {
- if { $::SWidget::TIME_CALLBACKS } {
- puts -nonewline "($instance $args: "
- puts "[time "eval $instance $args" 1])"
- } else {
- if { $::SWidget::DEBUG_CALLBACKS } {
- eval $instance $args
- } else {
- if { [catch "eval $instance $args" res] } {
- catch "puts $res"
- catch "puts $::errorInfo"
- if { [string match "*bad alloc*" $res] } {
- ::bgerror $res
- }
- }
- }
- }
- }
- incr ::SWidget::CALLBACK_LEVEL -1
- }
-}
-
-#########################################################
-#
-if {0} { ;# comment
-
- SWidget a class for collecting information about a slicer widget
- including it's vtk class instances and it's interaction
- state.
-
- Parent class of other SWidgets
-
-# TODO :
-
-}
-#
-#########################################################
-
-
-#
-# The partent class definition - define if needed (not when re-sourcing)
-#
-if { [itcl::find class SWidget] == "" } {
-
- itcl::class SWidget {
-
- constructor {} {
- }
-
- destructor {
- vtkDelete
- }
-
- # configure options
- public variable state "" ;# the interaction state of the SWidget
- public variable description "" ;# a status string describing the current state
- public variable sliceGUI "" ;# the sliceGUI on which the SWidget lives
-
- public variable enabled "true" ;# if not enabled, subclasses should not process events
-
- public variable forceAnnotationsOff 1 ;# don't show annotations at all
-
- variable _vtkObjects ""
- variable _pickState "outside"
- variable _actionState ""
- variable _glyphScale 10
-
- variable o ;# array of the objects for this widget, for convenient access
- variable _actors "" ;# list of actors for removing from the renderer
- variable _guiObserverTags ;# save so destructor can remove observer
- variable _nodeObserverTags ;# save so destructor can remove observer
-
- # parts of the sliceGUI saved for easy access
- variable _renderWidget ""
- variable _renderer ""
- variable _interactor ""
- variable _annotation ""
- variable _sliceNode ""
- variable _sliceCompositeNode ""
- variable _layers
-
- # flag to indicate that there is an update pending (in after idle)
- variable _updatePending 0
- # annotation update requested
- variable _annotationTaskID ""
-
- # methods
- method rasToXY {rasPoint} {}
- method rasToXYZ {rasPoint} {}
- method xyToRAS {xyPoint} {}
- method xyzToRAS {xyPoint} {}
- method dcToXYZ { x y } {}
- method queryLayers { x y {z 0} } {}
- method getLayers {} {return [array get _layers]}
- method getObjects {} {return [array get o]}
- method processEvent {{caller ""} {event ""}} {}
- method pick {} {}
- method highlight {} {}
- method place {x y z} {}
- method getPixel {image i j k} {}
- method getTensorPixel {node i j k} {}
- method setPixel {image i j k value} {}
- method setPixelBlock {image i j k size value} {}
- method requestUpdate {} {}
- method processUpdate {} {}
- method requestDelayedAnnotation {} {}
- method processDelayedAnnotation {} {}
- method cancelDelayedAnnotation {} {}
- method getInAnySliceSWidget {} {}
-
- # make a new instance of a class and add it to the list for cleanup
- method vtkNew {class} {
- set object [$class New]
- set _vtkObjects "$object $_vtkObjects"
- return $object
- }
-
- # clean up the vtk classes instanced by this SWidget
- method vtkDelete {} {
- foreach object $_vtkObjects {
- catch "$object Delete"
- }
- set _vtkObjects ""
- }
-
- # generic useful routine
- method superclass {} {
- return [lindex [$this info heritage] 1]
- }
-
- # interact with the status line on the main window
- method statusText {msg} {
- [$::slicer3::ApplicationGUI GetMainSlicerWindow] SetStatusText $msg
- }
-
- # for debugging
- method log {msg} {
- set fp [open "swidget.log" "a"]
- puts $fp "$this: $msg"
- close $fp
- }
- }
-}
-
-#
-# called on 'widget configure -sliceGUI gui'
-# - caches handles to useful objects
-#
-itcl::configbody SWidget::sliceGUI {
- set _renderWidget [[$sliceGUI GetSliceViewer] GetRenderWidget]
-
- set _interactor [$_renderWidget GetRenderWindowInteractor]
- set _annotation [$_renderWidget GetCornerAnnotation]
- set _sliceNode [[$sliceGUI GetLogic] GetSliceNode]
- set _sliceCompositeNode [[$sliceGUI GetLogic] GetSliceCompositeNode]
-}
-
-# return x y for a give r a s
-itcl::body SWidget::rasToXY { rasPoint } {
- set rasToXY [vtkMatrix4x4 New]
- $rasToXY DeepCopy [$_sliceNode GetXYToRAS]
- $rasToXY Invert
- set xyzw [eval $rasToXY MultiplyPoint $rasPoint 1]
- $rasToXY Delete
- return [lrange $xyzw 0 1]
-}
-
-# return x y z for a give r a s
-itcl::body SWidget::rasToXYZ { rasPoint } {
- set rasToXY [vtkMatrix4x4 New]
- $rasToXY DeepCopy [$_sliceNode GetXYToRAS]
- $rasToXY Invert
- set xyzw [eval $rasToXY MultiplyPoint $rasPoint 1]
- $rasToXY Delete
- return [lrange $xyzw 0 2]
-}
-
-# return r a s for a given x y
-itcl::body SWidget::xyToRAS { xyPoint } {
- set rast [eval [$_sliceNode GetXYToRAS] MultiplyPoint $xyPoint 0 1]
- return [lrange $rast 0 2]
-}
-
-# return r a s for a given x y z
-itcl::body SWidget::xyzToRAS { xyPoint } {
- set rast [eval [$_sliceNode GetXYToRAS] MultiplyPoint $xyPoint 1]
- return [lrange $rast 0 2]
-}
-
-# return xyz for a given device coordinate (x y). THe device coordinate (xy)
-# is a position in the window, the returned xyz is a position in a viewport,
-# with z corresonding to a slice in the slice volume
-itcl::body SWidget::dcToXYZ { wx wy } {
- set wx [expr int($wx)]
- set wy [expr int($wy)]
-
- foreach {windoww windowh} [[$_interactor GetRenderWindow] GetSize] {}
- set numRows [$_sliceNode GetLayoutGridRows]
- set numCols [$_sliceNode GetLayoutGridColumns]
-
- if { $windoww == 0 || $windowh == 0 } {
- # degenerate case, return gracefully
- return "0 0 0"
- }
-
- set tx [expr $wx / double($windoww)]
- set ty [expr ($windowh - $wy) / double($windowh)]
-
- set z [expr (floor($ty*$numRows)*$numCols + floor($tx*$numCols))]
-
- set pokedRenderer [$_interactor FindPokedRenderer $wx $wy]
- foreach {rox roy} [$pokedRenderer GetOrigin] {}
- set x [expr $wx - $rox]
- set y [expr $wy - $roy]
-
- return "$x $y $z"
-}
-
-itcl::body SWidget::queryLayers { x y {z 0} } {
- #
- # get the logic, node, image, ijk coords, and pixel for each layer
- # - store these in a layers array for easy access
- #
-
- # determine which renderer based on z position
- # - ignore if z is not define (as when there is just one slice)
- if { [catch "expr $z" res] } {
- # puts "bad z: $res"
- set lightboxK 0
- } else {
- set lightboxK [expr int($z + 0.5)]
- }
-
- foreach layer {background foreground label} {
- set _layers($layer,logic) [[$sliceGUI GetLogic] Get[string totitle $layer]Layer]
- set _layers($layer,node) [$_layers($layer,logic) GetVolumeNode]
- if { $_layers($layer,node) == "" } {
- set _layers($layer,image) ""
- set _layers($layer,xyToIJK) ""
- foreach v {i j k} {
- set _layers($layer,$v) 0
- }
- set _layers($layer,pixel) "None"
- } elseif { $lightboxK < 0 || $lightboxK >= [$_renderWidget GetNumberOfRenderers] } {
- # RAS position in not a visible slice, don't report pixel information
- set _layers($layer,image) ""
- set _layers($layer,xyToIJK) ""
- foreach v {i j k} {
- set _layers($layer,$v) "-"
- }
- set _layers($layer,pixel) "Slice not shown"
- } else {
- set _layers($layer,image) [$_layers($layer,node) GetImageData]
- set _layers($layer,xyToIJK) [[$_layers($layer,logic) GetXYToIJKTransform] GetMatrix]
- foreach {i j k l} [$_layers($layer,xyToIJK) MultiplyPoint $x $y $z 1] {}
- foreach v {i j k} { ;# cast to integer
- if { ![string is double [set $v]] } {
- set _layers($layer,$v) 0
- } else {
- set _layers($layer,$v) [expr int(round([set $v]))]
- }
- }
- if { [$_layers($layer,node) GetClassName] == "vtkMRMLDiffusionTensorVolumeNode" } {
- set _layers($layer,pixel) [$this getTensorPixel $_layers($layer,node) \
- $_layers($layer,i) $_layers($layer,j) $_layers($layer,k)]
- } else {
- set _layers($layer,pixel) [$this getPixel $_layers($layer,image) \
- $_layers($layer,i) $_layers($layer,j) $_layers($layer,k)]
- }
- }
- }
-}
-
-namespace eval SWidget set getTensorPixelWarning 0
-
-itcl::body SWidget::getTensorPixel { node i j k } {
-
- # TODO: in slicer4 this code is not needed
- return
-
- if { ![info exists o(dtiMath)] } {
- if { [info command vtkDiffusionTensorMathematics] == "" } {
- if { !$::SWidget::getTensorPixelWarning } {
- puts "$this: TODO: in slicer4 vtkDiffusionTensorMathematics class is not available - need to figure out why..."
- set ::SWidget::getTensorPixelWarning 1
- }
- return
- }
- set o(dtiMath) [vtkNew vtkDiffusionTensorMathematics]
- set o(dtiPixelImage) [vtkNew vtkImageData]
- set o(dtiPixelTensors) [vtkNew vtkDoubleArray]
- $o(dtiPixelImage) SetDimensions 1 1 1
- $o(dtiPixelImage) AllocateScalars
- $o(dtiPixelTensors) SetNumberOfComponents 9
- $o(dtiPixelTensors) SetNumberOfTuples 1
- $o(dtiPixelTensors) Allocate 9 0
- [$o(dtiPixelImage) GetPointData] SetTensors $o(dtiPixelTensors)
- $o(dtiMath) SetInput $o(dtiPixelImage)
- }
-
- set tensorImage [$node GetImageData]
- if { $tensorImage == "" } {
- return "No Image Data"
- }
- set tensors [[$tensorImage GetPointData] GetTensors]
- if { $tensors == "" } {
- return "No Tensors"
- }
- set displayNode [$node GetDisplayNode]
- if { $displayNode == "" } {
- return "No Display Node"
- }
-
- foreach "w h d" [$tensorImage GetDimensions] {}
- set sliceSize [expr $w * $h]
- set volSize [expr $d * $sliceSize]
- set idx [expr $i + $j*$w + $k*$sliceSize]
-
- if { $idx < 0 || $idx >= $volSize } {
- return "Out of Frame"
- }
-
- set tensor [$tensors GetTuple9 $idx]
- eval $o(dtiPixelTensors) SetTuple9 0 $tensor
-
- $o(dtiPixelImage) Modified
- $o(dtiMath) SetOperation [$displayNode GetScalarInvariant]
- $o(dtiMath) Update
- set outImage [$o(dtiMath) GetOutput]
- set numComps [$outImage GetNumberOfScalarComponents]
- set pixel ""
- if { $numComps == 1 } {
- lappend pixel [$outImage GetScalarComponentAsDouble 0 0 0 0]
- }
- lappend pixel [$o(dtiMath) GetOperationAsAbbreviatedString]
- return $pixel
-}
-
-itcl::body SWidget::getPixel { image i j k } {
- if { $image == "" } { return "" }
- foreach index "i j k" dimension [$image GetDimensions] {
- set ind [set $index]
- if { $ind < 0 || $ind >= $dimension } {return "Out of Frame"}
- }
- set n [$image GetNumberOfScalarComponents]
-
- if { 0 } {
- ### BUG IN vtkImageData GetScalarComponentAsDouble ???
- for {set c 0} {$c < $n} {incr c} {
- lappend pixel [$image GetScalarComponentAsDouble $i $j $k $c]
- }
- } else {
- # directly access the scalars to get pixel value
- # - need to compensate because the increments already include the pixel size
- set scalars [[$image GetPointData] GetScalars]
- if { $scalars == "" } {
- set scalars [[$image GetPointData] GetTensors]
- }
- foreach "w h d" [$image GetDimensions] {}
- set sliceSize [expr $w * $h]
- set idx [expr $i + $j*$w + $k*$sliceSize]
- if { $scalars != "" && $n <= 3 } {
- set pixel [$scalars GetTuple$n $idx]
- } else {
- if { $scalars != "" } {
- set pixel "$n Components"
- } else {
- set pixel "Unknown"
- }
- }
- }
- if { [string is double $pixel] && $pixel == [expr int($pixel)] } {
- set pixel [expr int($pixel)]
- }
- return $pixel
-}
-
-itcl::body SWidget::setPixelBlock { image i j k size value } {
- for {set ii [expr $i - $size]} {$ii <= [expr $i + $size]} {incr ii} {
- for {set jj [expr $j - $size]} {$jj <= [expr $j + $size]} {incr jj} {
- for {set kk [expr $k - $size]} {$kk <= [expr $k + $size]} {incr kk} {
- SliceViewerSetPixel $image $ii $jj $kk $value
- }
- }
- }
-}
-
-itcl::body SWidget::setPixel { image i j k value } {
- foreach index "i j k" dimension [$image GetDimensions] {
- set ind [set $index]
- if { $ind < 0 || $ind >= $dimension } {return -1}
- }
- set n [$image GetNumberOfScalarComponents]
- for {set c 0} {$c < $n} {incr c} {
- set v [lindex $value $c]
- if { $v != "" } {
- $image SetScalarComponentFromDouble $i $j $k $c $v
- $image Modified
- }
- }
- return 0
-}
-
-itcl::body SWidget::requestUpdate {} {
- if { $_updatePending } {
- return
- }
- set _updatePending 1
- after idle $this processUpdate
-}
-
-itcl::body SWidget::processUpdate {} {
- set _updatePending 0
-}
-
-itcl::body SWidget::requestDelayedAnnotation { } {
- $this cancelDelayedAnnotation
- set _annotationTaskID [after 300 ::SWidget::ProtectedCallback $this processDelayedAnnotation]
-}
-
-itcl::body SWidget::processDelayedAnnotation { } {
- if { [$this getInAnySliceSWidget] && !$forceAnnotationsOff } {
- $_renderWidget CornerAnnotationVisibilityOn
- [$sliceGUI GetSliceViewer] RequestRender
- } else {
- $_renderWidget CornerAnnotationVisibilityOff
- [$sliceGUI GetSliceViewer] RequestRender
- }
-}
-
-itcl::body SWidget::cancelDelayedAnnotation { } {
- $_renderWidget CornerAnnotationVisibilityOff
- if {$_annotationTaskID != ""} {
- after cancel $_annotationTaskID
- set _annotationTaskID ""
- [$sliceGUI GetSliceViewer] RequestRender
- }
-}
-
-itcl::body SWidget::getInAnySliceSWidget { } {
- if { [itcl::find class ::SliceSWidget] == "::SliceSWidget"} {
- set swidgets [itcl::find objects -class ::SliceSWidget]
- foreach sw $swidgets {
- if { [$sw getInWidget] } {
- return 1
- }
- }
- }
- return 0
-}
-
-#
-# TODO: this little helper reloads the swidget functionality
-#
-proc sssss {} {
- itcl::delete class SWidget
-
- set dir $::env(SLICER_HOME)/$::env(SLICER_SHARE_DIR)/Tcl
- source $dir/SWidget.tcl
- foreach sw [glob $dir/*SWidget.tcl] {
- source $sw
- }
-}
View
1,513 Base/GUI/Tcl/SliceSWidget.tcl
@@ -1,1513 +0,0 @@
-
-#########################################################
-#
-if {0} { ;# comment
-
- SliceSWidget - manages slice plane interactions
-
-# TODO :
-
-}
-#
-#########################################################
-# ------------------------------------------------------------------
-# SliceSWidget
-# ------------------------------------------------------------------
-#
-# The class definition - define if needed (not when re-sourcing)
-#
-if { [itcl::find class SliceSWidget] == "" } {
-
- itcl::class SliceSWidget {
-
- inherit SWidget
-
- constructor {args} {}
- destructor {}
-
- public variable sliceStep 1 ;# the size of the slice increment/decrement
- public variable calculateAnnotations 1 ;# include annotation calculation (turned off for slicer4)
- #
- # These are widgets that track the state of a node in the MRML Scene
- # - for each of these we update things each time a node or scene is added
- #
- public variable swidgetTypes {
- { ModelSWidget -modelID vtkMRMLModelNode }
- { RulerSWidget -rulerID vtkMRMLMeasurementsRulerNode }
- }
-
- variable _actionStartRAS "0 0 0"
- variable _actionStartXY "0 0"
- variable _actionStartViewportOrigin "0 0"
- variable _actionStartWindowXY "0 0"
- variable _actionStartFOV "250 250 250"
- variable _actionStartOrientation ""
- variable _actionModifier ""
- variable _swidgets ""
- variable _inWidget 0
- variable _lastLabelOpacity 1.0
- variable _lastForegroundOpacity 1.0
-
- # methods
- method updateSWidgets {} {}
- method resizeSliceNode {} {}
- method processEvent {{caller ""} {event ""}} {}
- method updateAnnotationCallback {r a s} {}
- method updateAnnotationsCallback {r a s} {}
- method updateAnnotation {r a s} {}
- method updateAnnotations {r a s} {}
- method updateStatusAnnotation {r a s} {}
- method incrementSlice {} {}
- method decrementSlice {} {}
- method moveSlice { delta } {}
- method jumpSlice { r a s } {}
- method jumpOtherSlices { r a s } {}
- method getLinkedSliceGUIs {} {}
- method addSliceModelSWidgets {} {}
- method isCompareViewer {} {}
- method isCompareViewMode {} {}
- method getSliceSWidgetForGUI { gui } {}
- method getInWidget {} {}
- method startTranslate { x y windowx windowy rox roy ras } {}
- method endTranslate {} {}
- }
-}
-
-# ------------------------------------------------------------------
-# CONSTRUCTOR/DESTRUCTOR
-# ------------------------------------------------------------------
-itcl::body SliceSWidget::constructor {sliceGUI} {
-
- $this configure -sliceGUI $sliceGUI
-
- # create matrices to store transform state
- set o(storeXYToRAS) [$this vtkNew vtkMatrix4x4]
- set o(storeSliceToRAS) [$this vtkNew vtkMatrix4x4]
- set o(scratchMatrix) [$this vtkNew vtkMatrix4x4]
-
- # set the annotation property
- # but have the actual text be off by default
- [$_annotation GetTextProperty] SetColor 1 1 1
- [$_annotation GetTextProperty] SetShadow 1
- $_renderWidget CornerAnnotationVisibilityOff
-
- # TODO:
- # create text actors for L/R, I/S, P/A
-
- # setup the layers structure
- foreach layer {background foreground label} {
- set _layers($layer,logic) [[$sliceGUI GetLogic] Get[string totitle $layer]Layer]
- set _layers($layer,node) [$_layers($layer,logic) GetVolumeNode]
- if { $_layers($layer,node) == "" } {
- set _layers($layer,image) ""
- set _layers($layer,xyToIJK) ""
- foreach v {i j k} {
- set _layers($layer,$v) 0
- }
- set _layers($layer,pixel) "None"
- }
- }
-
- $this processEvent
-
- #
- # set up observers on sliceGUI and on sliceNode
- #
-
- $::slicer3::Broker AddObservation $sliceGUI DeleteEvent "::SWidget::ProtectedDelete $this"
-
- # events to catch (currently not catching KeyReleaseEvent, UserEvent)
- # We catch CharEvent (KeyPressEvent would have been enough) in order to prevent
- # the default vtkInteractorStyle::OnChar() to be called.
- set events { "MouseMoveEvent" "RightButtonPressEvent" "RightButtonReleaseEvent"
- "LeftButtonPressEvent" "LeftButtonReleaseEvent" "MiddleButtonPressEvent"
- "MiddleButtonReleaseEvent" "MouseWheelForwardEvent" "MouseWheelBackwardEvent"
- "ExposeEvent" "ConfigureEvent" "EnterEvent" "LeaveEvent"
- "TimerEvent" "KeyPressEvent" "ExitEvent" "CharEvent" }
- foreach event $events {
- $::slicer3::Broker AddObservation $sliceGUI $event "::SWidget::ProtectedCallback $this processEvent $sliceGUI $event"
- }
-
- # BUG: expose events are not passed through the vtk/kw layer so we need to explicitly handle them here
- [[[$sliceGUI GetSliceViewer] GetRenderWidget] GetVTKWidget] AddBinding "<Expose>" "::SWidget::ProtectedCallback $this processEvent $sliceGUI ExposeEvent"
-
- set node [[$sliceGUI GetLogic] GetSliceNode]
- $::slicer3::Broker AddObservation $node DeleteEvent "::SWidget::ProtectedDelete $this"
- $::slicer3::Broker AddObservation $node AnyEvent "::SWidget::ProtectedCallback $this processEvent $node AnyEvent"
-
- # observe NodeAdded events from the MRML scene to create
- # model intersection displays as needed
- set NodeAddedEvent 66000
- set NodeRemovedEvent 66001
- set SceneClosedEvent 66003
- set SceneAboutToBeClosedEvent 66004
- set SceneImportedEvent 66011
- $::slicer3::Broker AddObservation $::slicer3::MRMLScene $NodeAddedEvent "::SWidget::ProtectedCallback $this processEvent $::slicer3::MRMLScene NodeAddedEvent"
- $::slicer3::Broker AddObservation $::slicer3::MRMLScene $NodeRemovedEvent "::SWidget::ProtectedCallback $this processEvent $::slicer3::MRMLScene NodeRemovedEvent"
- $::slicer3::Broker AddObservation $::slicer3::MRMLScene $SceneClosedEvent "::SWidget::ProtectedCallback $this processEvent $::slicer3::MRMLScene SceneClosedEvent"
- $::slicer3::Broker AddObservation $::slicer3::MRMLScene $SceneAboutToBeClosedEvent "::SWidget::ProtectedCallback $this processEvent $::slicer3::MRMLScene SceneAboutToBeClosedEvent"
- $::slicer3::Broker AddObservation $::slicer3::MRMLScene $SceneImportedEvent "::SWidget::ProtectedCallback $this processEvent $::slicer3::MRMLScene SceneImportedEvent"
-
- # put the other widgets last the events in this widget get natural
- # priority over the same event to a child widget
-
-# lappend _swidgets [FiducialsSWidget #auto $sliceGUI]
- set gridSWidget [GridSWidget #auto $sliceGUI]
- $gridSWidget configure -layer "label"
- lappend _swidgets $gridSWidget
-# lappend _swidgets [CrosshairSWidget #auto $sliceGUI]
-# lappend _swidgets [VolumeDisplaySWidget #auto $sliceGUI]
-
- #lappend _swidgets [RegionsSWidget #auto $sliceGUI] ;# not used
-}
-
-
-itcl::body SliceSWidget::destructor {} {
-
- foreach sw $_swidgets {
- if { [info command $sw] != "" } {
- itcl::delete object $sw
- }
- }
-
- $_renderWidget RemoveAllRenderers
-}
-
-
-
-# ------------------------------------------------------------------
-# METHODS
-# ------------------------------------------------------------------
-
-#
-# create a slice widget for every node that does
-# not already have one. Also delete old ones.
-#
-itcl::body SliceSWidget::updateSWidgets {} {
- # this part is generic, based on the types configured for this class to manage
- foreach swidgetType $swidgetTypes {
- foreach {swidgetClass configVar nodeClass} $swidgetType {}
- array set sws ""
- # build look up table for current nodes
- set swidgets [itcl::find objects -class $swidgetClass]
- foreach sw $swidgets {
- set id [$sw cget $configVar]
- set gui [$sw cget -sliceGUI]
- set sws($gui,$id) $sw
- }
-
- # loop through nodes and create any needed new widgets
- # - special case: skip the slice model that corresponds to our slice GUI
- # - also keep track of used ones so we know which ones to delete later
- set usedSWidgets ""
- set nNodes [$::slicer3::MRMLScene GetNumberOfNodesByClass $nodeClass]
- for {set n 0} {$n < $nNodes} {incr n} {
- set node [$::slicer3::MRMLScene GetNthNodeByClass $n $nodeClass]
- set id [$node GetID]
- set layoutName [$_sliceNode GetName]
- set name [$node GetName]
- if { ![string match ${layoutName}* $name] } {
- if { ![info exists sws($sliceGUI,$id)] } {
- set swidget [$swidgetClass #auto $sliceGUI]
- $swidget configure $configVar $id
- lappend _swidgets $swidget
- } else {
- lappend usedSWidgets $sws($sliceGUI,$id)
- }
- }
- }
-
- # delete any of the widgets that no longer correspond to a node that is in the scene
- # - only the ones which correspond to 'our' sliceGUI instance
- foreach sw $swidgets {
- if { [lsearch $usedSWidgets $sw] == -1 } {
- if { [$sw cget -sliceGUI] == $sliceGUI } {
- set _swidgets [lremove -all $_swidgets $sw]
- itcl::delete object $sw
- }
- }
- }
- }
-}
-
-#
-# make sure the size of the slice matches the window size of the widget
-#
-itcl::body SliceSWidget::resizeSliceNode {} {
- set epsilon 1.0e-6
-
- if { $_layers(background,node) != "" } {
- set logic [$sliceGUI GetLogic]
- set sliceSpacing [lindex [$logic GetLowestVolumeSliceSpacing] 2]
- if { [catch "expr $sliceSpacing"] } {
- set sliceSpacing 1.0
- }
- $this configure -sliceStep $sliceSpacing
- }
-
- foreach {windoww windowh} [[$_interactor GetRenderWindow] GetSize] {}
- foreach {windowx windowy} [$_interactor GetEventPosition] {}
- # We should really use the pokedrenderer's size for these calculations.
- # However, viewerports in the LightBox can differ in size by a pixel. So
- # set the image size based on the size of renderer zero.
- #
- ###set pokedRenderer [$_interactor FindPokedRenderer $windowx $windowy]
- #set pokedRenderer [$_renderWidget GetRenderer]
- # Get the last renderer since the first corresponds to the overlay
- set nr [$_renderWidget GetNumberOfRenderers]
- set renderedid [expr $nr - 1]
- set pokedRenderer [$_renderWidget GetNthRenderer $renderedid]
- foreach {w h} [$pokedRenderer GetSize] {}
-
-
- foreach {nodeW nodeH nodeD} [$_sliceNode GetDimensions] {}
- foreach {nodefovx nodefovy nodefovz} [$_sliceNode GetFieldOfView] {}
- if { [catch "expr $nodefovx"] } {
- set nodefovx 1.0
- }
- if { [catch "expr $nodefovy"] } {
- set nodefovy 1.0
- }
- if { [catch "expr $nodefovz"] } {
- set nodefovz 1.0
- }
-
- if { $windoww < 1 || $windowh < 1 ||
- $w < 1 || $h < 1 || $nodeW < 1 || $nodeH < 1 ||
- $nodefovx == 0. || $nodefovx == 0.} {
- #puts "ignoring bogus resize"
- } else {
- set scaling0 [expr $w / (1. * $nodeW)]
- set scaling1 [expr $h / (1. * $nodeH)]
-
- set sMagnitude0 $scaling0
- if { $sMagnitude0 < 1.0 } {
- set sMagnitude0 [expr 1. / $sMagnitude0]
- }
-
- set sMagnitude1 $scaling1
- if { $sMagnitude1 < 1.0 } {
- set sMagnitude1 [expr 1. / $sMagnitude1]
- }
-
- if {$sMagnitude0 < $sMagnitude1} {
- # keep x fov the same, adjust y
- set fovx $nodefovx
- set fovy [expr $nodefovy * $scaling1 / $scaling0]
- set fovz [expr $sliceStep * $nodeD]
- } else {
- # keep y fov the same, adjust x
- set fovx [expr $nodefovx * $scaling0 / $scaling1]
- set fovy $nodefovy
- set fovz [expr $sliceStep * $nodeD]
- }
-
- set windowAspect [expr $h / (1. * $w)]
- set planeAspect [expr $fovy / (1. * $fovx)]
- if { [expr $windowAspect != $planeAspect] } {
- set fovx [expr $fovy / $windowAspect]
- }
-
- if { $fovx == $nodefovx && $fovy == $nodefovy && $fovz == $nodefovz &&
- $w == $nodeW && $h == $nodeH && [expr abs($sliceStep - ($nodefovz / (1. * $nodeD)))] < $epsilon} {
- return
- }
- set disabled [$_sliceNode GetDisableModifiedEvent]
- $_sliceNode DisableModifiedEventOn
- $_sliceNode SetDimensions $w $h $nodeD
- $_sliceNode SetFieldOfView $fovx $fovy $fovz
- $_sliceNode SetDisableModifiedEvent $disabled
- if { $disabled == 0 } {
- $_sliceNode InvokePendingModifiedEvent
- $_sliceNode DisableModifiedEventOff
- }
- }
-}
-
-#
-# handle interactor events
-#
-itcl::body SliceSWidget::processEvent { {caller ""} {event ""} } {
-
- if { $enabled != "true" } {
- return
- }
-
- if { [info command $sliceGUI] == "" || [$sliceGUI GetLogic] == "" } {
- # the sliceGUI was deleted behind our back, so we need to
- # self destruct
- ::SWidget::ProtectedDelete $this
- return
- }
-
- if { [info command $_sliceNode] == "" } {
- # somehow our slice node is corrupted - we need to bail out
- return
- }
-
- #if { $caller == $_sliceNode &&
- # $event == "AnyEvent"} {
- # return
- #}
-
- if { [$::slicer3::MRMLScene IsBatchProcessing] } {
- return
- }
-
- # MRML Scene update probably means we need to create a new model intersection SWidget
- if { $caller == $::slicer3::MRMLScene &&
- ((($event == "NodeAddedEvent" || $event == "NodeRemovedEvent") && ![$::slicer3::MRMLScene GetIsUpdating]) ||
- $event == "SceneClosedEvent" || $event == "SceneAboutToBeClosedEvent" ||
- $event == "SceneImportedEvent") } {
- $this updateSWidgets
- }
-
- #
- # get the current event info
- # - the event type
- # - check to see if another widget is grabbing
- # (we'll process some events even if we don't have grab)
- # - the actual x y location of the event
- # - fill the layers info with local info
- # - get the RAS space location of the event
- #
- if { $event != "ConfigureEvent" } {
- set tkwindow [$_renderWidget GetWidgetName]
- if { $tkwindow != "" } {
- $_interactor UpdateSize [winfo width $tkwindow] [winfo height $tkwindow]
- }
- }
-
- # To support the LightBox, the event locations sometimes need to be
- # relative to a renderer (or viewport or pane of the lightbox).
- # Currently, these are relative to the viewport of the "start" action.
- # We may need to change this in some cases to be relative to an "active"
- # viewport.
-
-
- #
- # get the event position and make it relative to a renderer/viewport
- #
- foreach {windowx windowy} [$_interactor GetEventPosition] {}
- foreach {lastwindowx lastwindowy} [$_interactor GetLastEventPosition] {}
- foreach {windoww windowh} [[$_interactor GetRenderWindow] GetSize] {}
-
- set pokedRenderer [$_interactor FindPokedRenderer $windowx $windowy]
- #set renderer0 [$_renderWidget GetRenderer]
- # Get the last renderer since the first corresponds to the overlay
- set nr [$_renderWidget GetNumberOfRenderers]
- set renderedid [expr $nr - 1]
- set renderer0 [$_renderWidget GetNthRenderer $renderedid]
-
- foreach {x y z} [$this dcToXYZ $windowx $windowy] {}
-
- if { $x < 0 } {
- set x 0
- }
- if { $y < 0 } {
- set y 0
- }
- # We should really use the pokedrenderer's size for these calculations.
- # However, viewports in the LightBox can differ in size by a pixel. So
- # set the image size based on the size of renderer zero.
- #
- ###foreach {w h} [$pokedRenderer GetSize] {}
- foreach {w h} [$renderer0 GetSize] {}
- foreach {rox roy} [$pokedRenderer GetOrigin] {}
-
- set xyToRAS [$_sliceNode GetXYToRAS]
- set ras [$xyToRAS MultiplyPoint $x $y $z 1]
-
- foreach {r a s t} $ras {}
-
- #
- # check that the window size is correct for the node and resize if needed
- #
- if { $caller != $_sliceNode } {
- $this resizeSliceNode
- }
-
- if { $calculateAnnotations && $_actionState == "" } {
-
- # TODO: the annotations seem to be very time consuming to calculate
- # but most of the time they will not be displayed - instead we should
- # move the calculation into the DelayedAnnotation method
-
- #
- # cancel any scheduled annotations
- #
- if { [itcl::find class ::SliceSWidget] == "::SliceSWidget"} {
- set swidgets [itcl::find objects -class ::SliceSWidget]
- foreach sw $swidgets {
- $sw cancelDelayedAnnotation
- }
- }
-
- #
- # update the annotations even if they aren't currently visible
- # - this way the values will be correct when the corner annotation
- # are eventually made visible
- #
- set link [$_sliceCompositeNode GetLinkedControl]
- if { $link == 1 && [$this isCompareViewMode] == 1 &&
- ([$this isCompareViewer] == 1 || [$_sliceNode GetSingletonTag] == "Red") } {
- $this updateAnnotations $r $a $s
- } else {
- $this updateAnnotation $r $a $s
- }
- } else {
- $_renderWidget CornerAnnotationVisibilityOff
- }
-
- if { $forceAnnotationsOff } {
- $_renderWidget CornerAnnotationVisibilityOff
- }
-
- #
- # if another widget has the grab, let this go unless
- # it is a focus event, in which case we want to update
- # our display icon
- #
- set grabID [$sliceGUI GetGrabID]
- if { ($grabID != "" && $grabID != $this) } {
- if { ![string match "Focus*Event" $event] } {
- if { [info command $grabID] != $grabID } {
- # the widget with the grab doesn't exist any more (probably deleted while grabbing)
- # reset the grabID and continue
- $sliceGUI SetGrabID ""
- } else {
- return ;# some other widget wants these events
- }
- }
- }
-
- if { $_actionState == "Translate" && $_actionModifier == "Shift" } {
- # need to check if the user has stopped doing a shift-drag
- if { (![$_interactor GetShiftKey] && ![$_interactor GetControlKey]) || $event == "LeftButtonReleaseEvent" } {
- $this endTranslate
- set _actionModifier ""
- }
- }
-
- switch $event {
-
- "MouseMoveEvent" {
- #
- # Mouse move behavior governed by _actionState mode
- # - handle modifying the view
- #
- if { [$_interactor GetShiftKey] && $_actionState != "Translate" } {
- $this jumpOtherSlices $r $a $s
- # need to render to show the annotation
- [$sliceGUI GetSliceViewer] RequestRender
- } else {
- switch $_actionState {
- "Translate" {
- #
- # Translate
- # TODO: move calculation to vtkMRMLSliceLogic
- $sliceGUI SetCurrentGUIEvent "" ;# reset event so we don't respond again
- set tx [expr $windowx - [lindex $_actionStartViewportOrigin 0]]
- set ty [expr $windowy - [lindex $_actionStartViewportOrigin 1]]
-
- set currentRAS [$o(storeXYToRAS) MultiplyPoint $tx $ty 0 1]
- foreach d {dr da ds} start $_actionStartRAS current $currentRAS {
- set $d [expr $current - $start]
- }
- $o(scratchMatrix) DeepCopy $o(storeSliceToRAS)
- foreach d {dr da ds} i {0 1 2} {
- set v [$o(scratchMatrix) GetElement $i 3]
- $o(scratchMatrix) SetElement $i 3 [expr $v - [set $d]]
- }
-
- [$_sliceNode GetSliceToRAS] DeepCopy $o(scratchMatrix)
- $_sliceNode UpdateMatrices
-
- $sliceGUI SetGUICommandAbortFlag 1
- $sliceGUI SetCurrentGUIEvent "" ;# reset event so we don't respond again
- }
- "Zoom" {
- #
- # Zoom
- # TODO: move calculation to vtkMRMLSliceLogic
- $sliceGUI SetCurrentGUIEvent "" ;# reset event so we don't respond again
- set deltay [expr $windowy - [lindex $_actionStartWindowXY 1]]
-
- set percent [expr ($windowh + $deltay) / (1.0 * $windowh)]
-
- # the factor operation is so 'z' isn't changed and the
- # slider can still move through the full range
- if { $percent > 0. } {
- set newFOV ""
- foreach f $_actionStartFOV factor "$percent $percent 1" {
- lappend newFOV [expr $f * $factor]
- }
-
- foreach {nfx nfy nfz} $newFOV {}
- $_sliceNode SetFieldOfView $nfx $nfy $nfz
- }
- $sliceGUI SetGUICommandAbortFlag 1
- }
- "Rotate" {
- #
- # Rotate
- # TODO: move calculation to vtkMRMLSliceLogic
- $sliceGUI SetCurrentGUIEvent "" ;# reset event so we don't respond again
- set dx [expr $windowx - $lastwindowx]
- set dy [expr $windowy - $lastwindowy]
-
- set dazimuth [expr 20.0 / $w]
- set delevation [expr 20.0 / $h]
-
- set rx [expr $dx * $dazimuth * 10.0]
- set ry [expr $dy * $delevation * 10.0]
-
- set tfm [$this vtkNew vtkTransform]
- $tfm PreMultiply
- $tfm Identity
- $tfm SetMatrix [$_sliceNode GetSliceToRAS]
- $tfm RotateX $ry
- $tfm RotateY $rx
-
- [$_sliceNode GetSliceToRAS] DeepCopy [$tfm GetMatrix]
- $_sliceNode UpdateMatrices
-
- $tfm Delete
-
- $sliceGUI SetGUICommandAbortFlag 1
- }
- default {
- # need to render to show the annotation
- [$sliceGUI GetSliceViewer] RequestRender
- }
- }
- }
- }
-
- "RightButtonPressEvent" {
- $::slicer3::MRMLScene SaveStateForUndo $_sliceNode
-
- $this requestDelayedAnnotation
- if { [$_interactor GetControlKey] } {
- set _actionState "Rotate"
- } else {
- set _actionState "Zoom"
- }
- set _actionStartXY "$x $y"
- set _actionStartWindowXY "$windowx $windowy"
- set _actionStartViewportOrigin "$rox $roy"
- set _actionStartRAS $ras
- set _actionStartOrientation [$_sliceNode GetOrientationString]
-
- # 2 = FieldOfView
- [$sliceGUI GetLogic] StartSliceNodeInteraction 2
-
- $sliceGUI SetGrabID $this
- $sliceGUI SetGUICommandAbortFlag 1
- set _actionStartFOV [$_sliceNode GetFieldOfView]
- }
- "RightButtonReleaseEvent" {
- [$sliceGUI GetLogic] EndSliceNodeInteraction
-
- $this requestDelayedAnnotation
- set _actionState ""
- set _actionStartOrientation ""
- $sliceGUI SetGrabID ""
- $sliceGUI SetGUICommandAbortFlag 1
- }
- "LeftButtonPressEvent" {
- if { [info command SeedSWidget] != "" } {
- # seed widget is disabled, annotation module takes care of fiducials
- set interactionNode [$::slicer3::MRMLScene GetNthNodeByClass 0 vtkMRMLInteractionNode]
- set modeString ""
- if { $interactionNode != "" } {
- set mode [$interactionNode GetCurrentInteractionMode]
- set modeString [$interactionNode GetInteractionModeAsString $mode]
- }
- if { $modeString == "Place" } {
- # AND PLACE FIDUCIAL.
- # don't place a fiducial in slicer4 - let this mode by handled by the Annotations module
- # FiducialsSWidget::AddFiducial $r $a $s
- } else {
- if { [$_interactor GetShiftKey] || [$_interactor GetControlKey] } {
- # shift-left-button is alias for middle mouse button to support
- # machines with no middle mouse button (e.g. macs)
- # - shift+mouse move will also do jump all slices if no left button
- # is pressed. This is unfortunate, but we use shift to be compatible
- # with the 3D viewer convention for pan
- # - control key is also a translate modifier to make it easier
- # to avoid the jump slice issue.
- $this startTranslate $x $y $windowx $windowy $rox $roy $ras
- set _actionModifier "Shift"
- }
- }
- }
- }
- "LeftButtonReleaseEvent" {
- # let the annotation module handle pick/place/view transform
- }
- "MiddleButtonPressEvent" {
- $this startTranslate $x $y $windowx $windowy $rox $roy $ras
- }
- "MiddleButtonReleaseEvent" {
- $this endTranslate
- }
- "MouseWheelForwardEvent" {
- $sliceGUI SetCurrentGUIEvent "" ;# reset event so we don't respond again
- $this incrementSlice
- }
- "MouseWheelBackwardEvent" {
- $sliceGUI SetCurrentGUIEvent "" ;# reset event so we don't respond again
- $this decrementSlice
- }
- "ExposeEvent" {
- [$sliceGUI GetSliceViewer] RequestRender
- }
- "ConfigureEvent" {
- $this resizeSliceNode
- }
- "EnterEvent" {
- set _inWidget 1
- if { !$forceAnnotationsOff } {
- $_renderWidget CornerAnnotationVisibilityOn
- }
- [$::slicer3::ApplicationGUI GetMainSlicerWindow] SetStatusText "Middle Button: Pan; Right Button: Zoom"
-
- set sliceGUIs [$this getLinkedSliceGUIs]
- # find the slice spacing to use
- set thisSliceSpacing [[$sliceGUI GetLogic] GetLowestVolumeSliceSpacing]
- foreach gui $sliceGUIs {
- set snode [$gui GetSliceNode]
- if { $_sliceNode != $snode } {
- set sliceSpacing [[$gui GetLogic] GetLowestVolumeSliceSpacing]
- if { [lindex $sliceSpacing 2] < [lindex $thisSliceSpacing 2] } {
- set thisSliceSpacing $sliceSpacing
- }
- }
- }
- # disable modifieds
- foreach gui $sliceGUIs {
- set snode [$gui GetSliceNode]
- $snode DisableModifiedEventOn
- }
- # modify each slice node
- #puts "Current node $_sliceNode Current gui $sliceGUI Current SliceWidget $this"
- if { $sliceGUIs != $sliceGUI } {
- # only adjust the spacing mode if there is something
- # linked to us
- $_sliceNode SetSliceSpacingModeToAutomatic
- foreach gui $sliceGUIs {
- set snode [$gui GetSliceNode]
-
- # prescribe spacing for all guis
- eval $snode SetPrescribedSliceSpacing $thisSliceSpacing
- $snode SetSliceSpacingModeToPrescribed
-
- # then tell them to reslice
- set that [$this getSliceSWidgetForGUI $gui]
- $that resizeSliceNode
- }
- }
- # enable modifieds, don't invoke the pending events,
- # request a render on each
- foreach gui $sliceGUIs {
- set snode [$gui GetSliceNode]
- #$snode InvokePendingModifiedEvent
- $snode DisableModifiedEventOff
- [$gui GetSliceViewer] RequestRender
- }
- }
- "LeaveEvent" {
- #puts "Leave"
- set _inWidget 0
-
- set sliceGUIs [$this getLinkedSliceGUIs]
- # cancel annotation requests before doing anything else
- foreach gui $sliceGUIs {
- set sw [$this getSliceSWidgetForGUI $gui]
- $sw cancelDelayedAnnotation
- }
- # now turn do whatever else is needed
- foreach gui $sliceGUIs {
- [[$gui GetSliceViewer] GetRenderWidget] CornerAnnotationVisibilityOff
- set snode [$gui GetSliceNode]
- if { [$this isCompareViewMode] == 1 } {
- # for now, don't switch back to automatic (maybe when we switch
- # out of compare view mode turn automatic back on)
- # $snode SetSliceSpacingModeToAutomatic
- }
- [$gui GetSliceViewer] RequestRender
- }
- [$::slicer3::ApplicationGUI GetMainSlicerWindow] SetStatusText ""
- }
- "TimerEvent" { }
- "KeyPressEvent" {
- set key [$_interactor GetKeySym]
- if { [lsearch "space Up Down Left Right" $key] != -1 } {
- $sliceGUI SetCurrentGUIEvent "" ;# reset event so we don't respond again
- $sliceGUI SetGUICommandAbortFlag 1
- switch [$_interactor GetKeySym] {
- "Left" - "Down" {
- $this decrementSlice
- }
- "Right" - "Up" {
- $this incrementSlice
- }
- "space" {
- ::Box::ShowDialog EditBox
- }
- default {
- set capture 0
- }
- }
- }
- }
- "CharEvent" {
- set key [$_interactor GetKeySym]
- if { [lsearch "v V r b f g G T c e s S" $key] != -1 } {
- $sliceGUI SetCurrentGUIEvent "" ;# reset event so we don't respond again
- $sliceGUI SetGUICommandAbortFlag 1
- switch [$_interactor GetKeySym] {
- "v" {
- $_sliceNode SetSliceVisible [expr ![$_sliceNode GetSliceVisible]]
- }
- "V" {
- # toggle all slices visibility
- puts "Toggling all slices visibility not implemented yet"
- }
- "r" {
- # figure out the new field of view for the current slice
- # node, then set that field of view on the linked slice
- # nodes
- set logic [$sliceGUI GetLogic]
-
- # 8 = ResetFieldOfViewFlag
- $logic StartSliceNodeInteraction 8
- $logic FitSliceToAll
- $_sliceNode UpdateMatrices
- $logic EndSliceNodeInteraction
- }
- "g" {
- # toggle the label opacity via the slice compoiste node
- set opacity [$_sliceCompositeNode GetLabelOpacity]
- if {$opacity != 0.0} {
- set _lastLabelOpacity $opacity
- }
- if { $opacity == 0.0 } {
- $_sliceCompositeNode SetLabelOpacity $_lastLabelOpacity
- } else {
- $_sliceCompositeNode SetLabelOpacity 0.0
- }
- }
- "G" {
- puts "Toggling label opacity for all slices not implemented yet"
- }
- "T" {
- # toggle opacity of foreground overlay
- set opacity [$_sliceCompositeNode GetForegroundOpacity]
- if {$opacity != 0.0} {
- set _lastForegroundOpacity $opacity
- }
- if { $opacity == 0.0 } {
- $_sliceCompositeNode SetForegroundOpacity $_lastForegroundOpacity
- } else {
- $_sliceCompositeNode SetForegroundOpacity 0.0
- }
- }
- "b" {
- $this decrementSlice
- }
- "f" {
- $this incrementSlice
- }
- "e" {
- EditorToggleErasePaintLabel
- }
- "s" {
- # set the active slice. if in compare view put this slice in
- # the background of the red viewer
- set k [expr int($z + 0.5)]
- if { $k >= 0 && $k < [lindex [$_sliceNode GetDimensions] 2] } {
- $_sliceNode SetActiveSlice $k
- if { [$this isCompareViewer] == 1 } {
- # set the volume on the red viewer
- set redGUI [$::slicer3::ApplicationGUI GetMainSliceGUI Red]
- set redLogic [$redGUI GetLogic]
- set redNode [$redGUI GetSliceNode]
- set redCNode [$redLogic GetSliceCompositeNode]
-
- $redCNode SetReferenceBackgroundVolumeID [$_sliceCompositeNode GetBackgroundVolumeID]
-
- # set the slice offset on the red viewer (translate to
- # active slice)
- # offset to first slice in viewer
- set offset [[$sliceGUI GetLogic] GetSliceOffset]
- # offset to the active slice
- set offset2 [expr $offset + [$_sliceNode GetActiveSlice] * [lindex [[$sliceGUI GetLogic] GetLowestVolumeSliceSpacing] 2] ]
- # offset needed for the active slice in red viewer
- set offset3 [expr $offset2 - [$redNode GetActiveSlice] * [lindex [[$redGUI GetLogic] GetLowestVolumeSliceSpacing] 2] ]
- $redLogic SetSliceOffset $offset3
-
- # force the red viewer to recalculate its matrices
- set that [$this getSliceSWidgetForGUI $redGUI]
- $that resizeSliceNode
- }
- }
- }
- "S" {
- # set the active slice. if in compare view put this slice in
- # the foreground of the red viewer
- set k [expr int($z + 0.5)]
- if { $k >= 0 && $k < [lindex [$_sliceNode GetDimensions] 2] } {
- $_sliceNode SetActiveSlice $k
- if { [$this isCompareViewer] == 1 } {
- # set the volume on the red viewer
- set redGUI [$::slicer3::ApplicationGUI GetMainSliceGUI Red]
- set redLogic [$redGUI GetLogic]
- set redNode [$redGUI GetSliceNode]
- set redCNode [$redLogic GetSliceCompositeNode]
-
- $redCNode SetReferenceForegroundVolumeID [$_sliceCompositeNode GetBackgroundVolumeID]
-
- # set the slice offset on the red viewer (translate to
- # active slice)
- # offset to first slice in viewer
- set offset [[$sliceGUI GetLogic] GetSliceOffset]
- # offset to the active slice
- set offset2 [expr $offset + [$_sliceNode GetActiveSlice] * [lindex [[$sliceGUI GetLogic] GetLowestVolumeSliceSpacing] 2] ]
- # offset needed for the active slice in red viewer
- set offset3 [expr $offset2 - [$redNode GetActiveSlice] * [lindex [[$redGUI GetLogic] GetLowestVolumeSliceSpacing] 2] ]
- $redLogic SetSliceOffset $offset3
-
- # force the red viewer to recalculate its matrices
- set that [$this getSliceSWidgetForGUI $redGUI]
- $that resizeSliceNode
- }
- }
- }
- default {
- set capture 0
- }
- }
- } else {
- # puts "slice ignoring $key"
- }
- }
- "KeyReleaseEvent" {
- }
- "FocusInEvent" {
- #puts "focusin. prescribing spacing"
- #need to do the same as EnterEvent?
- }
- "FocusOutEvent" {
- #puts "focusout. automatic spacing"
- #need to do the same as EnterEvent?
- }
- "ExitEvent" { }
- }
-}
-
-#
-# Defer actual calculation of the annotation text until the
-# it is time to render the text
-#
-itcl::body SliceSWidget::updateAnnotation {r a s} {
- after idle $this updateAnnotationCallback $r $a $s
-}
-
-itcl::body SliceSWidget::updateAnnotations {r a s} {
- after idle $this updateAnnotationsCallback $r $a $s
-}
-
-itcl::body SliceSWidget::updateAnnotationsCallback {r a s} {
-
- # check arguments - if they are, for example, nan, just bail out
- foreach v "r a s" {
- if { [scan [set $v] %g scanvar] == 0 } {
- return
- }
- }
-
- $this updateStatusAnnotation $r $a $s
-
- foreach {x y z} [$this rasToXYZ "$r $a $s"] {}
- $this queryLayers $x $y $z
-
- set ssgui [[$::slicer3::ApplicationGUI GetApplication] GetModuleGUIByName "Slices"]
- if { $ssgui == "" } {
- return
- }
- set numsgui [$ssgui GetNumberOfSliceGUI]
- for { set i 0 } { $i < $numsgui } { incr i } {
- if { $i == 0} {
- set sgui [$ssgui GetFirstSliceGUI]
- set lname [$ssgui GetFirstSliceGUILayoutName]
- } else {
- set sgui [$ssgui GetNextSliceGUI $lname]
- set lname [$ssgui GetNextSliceGUILayoutName $lname]
- }
- set sNode [$sgui GetSliceNode]
- set logic [$sgui GetLogic]
- set sliceCompositeNode [$logic GetSliceCompositeNode]
-
- if { $sliceCompositeNode == "" } {
- # need a composite node to be able to do anything
- return
- }
-
- if { $lname != "Red" && [string first "Compare" $lname] != 0 } {
- continue
- }
-
- set laybelText ""
- set voxelText ""
- set ijkText ""
- set xyText ""
- set rasText ""
- set foregroundname "None"
- set backgroundname "None"
- set labelname "None"
- set reformation ""