11import ctk , qt , slicer , vtk
22
3- class displayModel ():
3+ class displayModel (object ):
44 def __init__ (self , modelNode , imageSize = None , orientation = None , zoom = None , showFeatureEdges = False ):
55 self .modelNode = modelNode
66 # rollPitchYawDeg
@@ -90,7 +90,7 @@ def displayMarkups(markupsNode):
9090 """Display markups node by converting to pandas dataframe object"""
9191 return slicer .util .dataframeFromMarkups (markupsNode )
9292
93- class displayTransform ():
93+ class displayTransform (object ):
9494 """This class displays information about a transform in a Jupyter notebook cell.
9595 """
9696 def __init__ (self , transform ):
@@ -130,7 +130,7 @@ def displayNode(node):
130130 return None
131131
132132
133- class displayViews :
133+ class displayViews ( object ) :
134134 """This class captures current views and makes it available
135135 for display in the output of a Jupyter notebook cell.
136136 :param viewLayout: FourUp, Conventional, OneUp3D, OneUpRedSlice,
@@ -167,7 +167,7 @@ def _repr_mimebundle_(self, include=None, exclude=None):
167167 dataType = "image/png"
168168 return { dataType : dataValue }
169169
170- class displaySliceView ():
170+ class displaySliceView (object ):
171171 """This class captures a slice view and makes it available
172172 for display in the output of a Jupyter notebook cell.
173173 """
@@ -198,7 +198,7 @@ def _repr_mimebundle_(self, include=None, exclude=None):
198198 dataType = "image/jpeg"
199199 return { dataType : dataValue }
200200
201- class display3DView ():
201+ class display3DView (object ):
202202 """This class captures a 3D view and makes it available
203203 for display in the output of a Jupyter notebook cell.
204204 """
@@ -237,19 +237,28 @@ def _repr_mimebundle_(self, include=None, exclude=None):
237237 dataType = "image/jpeg"
238238 return { dataType : dataValue }
239239
240- def showVolumeRendering (volumeNode , presetName = None ):
240+ def showVolumeRendering (volumeNode , show = True , presetName = None ):
241241 volRenLogic = slicer .modules .volumerendering .logic ()
242- displayNode = volRenLogic .CreateDefaultVolumeRenderingNodes (volumeNode )
243- displayNode .SetVisibility (True )
244- scalarRange = volumeNode .GetImageData ().GetScalarRange ()
245- if not presetName :
246- if scalarRange [1 ]- scalarRange [0 ] < 1500 :
247- # small dynamic range, probably MRI
248- presetName = 'MR-Default'
249- else :
250- # larger dynamic range, probably CT
251- presetName = 'CT-Chest-Contrast-Enhanced'
252- displayNode .GetVolumePropertyNode ().Copy (volRenLogic .GetPresetByName (presetName ))
242+ if show :
243+ displayNode = volRenLogic .GetFirstVolumeRenderingDisplayNode (volumeNode )
244+ if not displayNode :
245+ displayNode = volRenLogic .CreateDefaultVolumeRenderingNodes (volumeNode )
246+ displayNode .SetVisibility (True )
247+ scalarRange = volumeNode .GetImageData ().GetScalarRange ()
248+ if not presetName :
249+ if scalarRange [1 ]- scalarRange [0 ] < 1500 :
250+ # small dynamic range, probably MRI
251+ presetName = 'MR-Default'
252+ else :
253+ # larger dynamic range, probably CT
254+ presetName = 'CT-Chest-Contrast-Enhanced'
255+ displayNode .GetVolumePropertyNode ().Copy (volRenLogic .GetPresetByName (presetName ))
256+ else :
257+ # hide
258+ volRenLogic = slicer .modules .volumerendering .logic ()
259+ displayNode = volRenLogic .GetFirstVolumeRenderingDisplayNode (volumeNode )
260+ if displayNode :
261+ displayNode .SetVisibility (False )
253262
254263def reset3DView (viewID = 0 ):
255264 threeDWidget = slicer .app .layoutManager ().threeDWidget (viewID )
@@ -259,3 +268,64 @@ def reset3DView(viewID=0):
259268def setViewLayout (layoutName ):
260269 layoutId = eval ("slicer.vtkMRMLLayoutNode.SlicerLayout" + layoutName + "View" )
261270 slicer .app .layoutManager ().setLayout (layoutId )
271+
272+ def showSliceViewAnnotations (show ):
273+ # Disable slice annotations immediately
274+ slicer .modules .DataProbeInstance .infoWidget .sliceAnnotations .sliceViewAnnotationsEnabled = show
275+ slicer .modules .DataProbeInstance .infoWidget .sliceAnnotations .updateSliceViewFromGUI ()
276+ # Disable slice annotations persistently (after Slicer restarts)
277+ settings = qt .QSettings ()
278+ settings .setValue ('DataProbe/sliceViewAnnotations.enabled' , 1 if show else 0 )
279+
280+ class displayViewLightbox (object ):
281+
282+ def __init__ (self , viewName = None , rows = None , columns = None , filename = None , positionRange = None , rangeShrink = None ):
283+ viewName = viewName if viewName else "Red"
284+ rows = rows if rows else 4
285+ columns = columns if columns else 6
286+
287+ sliceWidget = slicer .app .layoutManager ().sliceWidget (viewName )
288+
289+ if positionRange is None :
290+ sliceBounds = [0 ,0 ,0 ,0 ,0 ,0 ]
291+ sliceWidget .sliceLogic ().GetLowestVolumeSliceBounds (sliceBounds )
292+ slicePositionRange = [sliceBounds [0 ], sliceBounds [1 ]]
293+ else :
294+ slicePositionRange = [positionRange [0 ], positionRange [1 ]]
295+
296+ if rangeShrink :
297+ slicePositionRange [0 ] += rangeShrink [0 ]
298+ slicePositionRange [1 ] -= rangeShrink [1 ]
299+
300+ # Capture red slice view, 30 images, from position -125.0 to 75.0
301+ # into current folder, with name image_00001.png, image_00002.png, ...
302+ import ScreenCapture
303+ screenCaptureLogic = ScreenCapture .ScreenCaptureLogic ()
304+ viewNodeID = 'vtkMRMLSliceNodeRed'
305+ destinationFolder = 'outputs/Capture-SliceSweep'
306+ numberOfFrames = rows * columns
307+ filenamePattern = "_lightbox_tmp_image_%05d.png"
308+ viewNode = sliceWidget .mrmlSliceNode ()
309+ # Suppress log messages
310+ def noLog (msg ):
311+ pass
312+ screenCaptureLogic .addLog = noLog
313+ # Capture images
314+ screenCaptureLogic .captureSliceSweep (viewNode , slicePositionRange [0 ], slicePositionRange [1 ],
315+ numberOfFrames , destinationFolder , filenamePattern )
316+ # Create lightbox image
317+ resultImageFilename = filename if filename else filenamePattern % numberOfFrames
318+ screenCaptureLogic .createLightboxImage (columns , destinationFolder , filenamePattern , numberOfFrames , resultImageFilename )
319+
320+ # Save result
321+ with open (destinationFolder + "/" + resultImageFilename , "rb" ) as file :
322+ self .dataValue = file .read ()
323+ self .dataType = "image/png"
324+ # This could be used to create an image widget: img = Image(value=image, format='png')
325+
326+ # Clean up
327+ screenCaptureLogic .deleteTemporaryFiles (destinationFolder , filenamePattern , numberOfFrames if filename else numberOfFrames + 1 )
328+
329+ def _repr_mimebundle_ (self , include = None , exclude = None ):
330+ import base64
331+ return { self .dataType : base64 .b64encode (self .dataValue ) }
0 commit comments