From b20a923357b278e94ddb1e860e1dc52e9c8be629 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 8 Oct 2015 02:14:48 -0400 Subject: [PATCH 01/18] STYLE: SliceViewAnnotations: Simplify code --- .../DataProbe/DataProbeLib/SliceViewAnnotations.py | 50 ++++++++-------------- 1 file changed, 18 insertions(+), 32 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index 76536d9f2e..8904aca252 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -323,22 +323,15 @@ def onOrientationMarkerCheckBox(self): self.updateSliceViewFromGUI() def onCornerTextsActivationCheckBox(self): - if self.topLeftCheckBox.checked: - self.topLeft = 1 - else: - self.topLeft = 0 + self.topLeft = int(self.topLeftCheckBox.checked) + self.topRight = int(self.topRightCheckBox.checked) + self.bottomLeft = int(self.bottomLeftCheckBox.checked) - if self.topRightCheckBox.checked: - self.topRight = 1 + if self.topRight: self.scalarBarEnalbeCheckBox.checked = False - else: - self.topRight = 0 - if self.bottomLeftCheckBox.checked: - self.bottomLeft = 1 - else: - self.bottomLeft = 0 self.updateSliceViewFromGUI() + settings = qt.QSettings() settings.setValue('DataProbe/sliceViewAnnotations.topLeft', self.topLeft) @@ -476,16 +469,18 @@ def updateSliceViewFromGUI(self): elif self.level3RadioButton.checked: self.annotationsDisplayAmount = 2 - if self.sliceViewAnnotationsEnabled: - self.cornerTextParametersCollapsibleButton.enabled = True - self.activateCornersGroupBox.enabled = True - self.fontPropertiesGroupBox.enabled = True - self.scalarBarLayerSelectionGroupBox.enabled = True - self.annotationsAmountGroupBox.enabled = True - self.rulerCollapsibleButton.enabled = True - self.scalarBarCollapsibleButton.enabled = True - self.restorDefaultsButton.enabled = True + enabled = self.sliceViewAnnotationsEnabled + + self.cornerTextParametersCollapsibleButton.enabled = enabled + self.activateCornersGroupBox.enabled = enabled + self.fontPropertiesGroupBox.enabled = enabled + self.scalarBarLayerSelectionGroupBox.enabled = enabled + self.annotationsAmountGroupBox.enabled = enabled + self.rulerCollapsibleButton.enabled = enabled + self.scalarBarCollapsibleButton.enabled = enabled + self.restorDefaultsButton.enabled = enabled + if enabled: for sliceViewName in self.sliceViewNames: sliceWidget = self.layoutManager.sliceWidget(sliceViewName) sl = sliceWidget.sliceLogic() @@ -494,14 +489,6 @@ def updateSliceViewFromGUI(self): self.updateScalarBar(sl) self.updateOrientationMarker(sl) else: - self.cornerTextParametersCollapsibleButton.enabled = False - self.activateCornersGroupBox.enabled = False - self.scalarBarLayerSelectionGroupBox.enabled = False - self.fontPropertiesGroupBox.enabled = False - self.annotationsAmountGroupBox.enabled = False - self.rulerCollapsibleButton.enabled = False - self.scalarBarCollapsibleButton.enabled = False - self.restorDefaultsButton.enabled = False # Remove Observers for sliceViewName in self.sliceViewNames: @@ -780,7 +767,7 @@ def createHumanOrientationModel(self): modelPaths = [modulePath + "DataProbeLib/Resources/Models/"+ modelFile for modelFile in modelFiles] for modelPath in modelPaths: successfulLoad = slicer.util.loadModel(modelPath) - if successfulLoad != True: + if not successfulLoad: print 'Warning: Could not load model %s' %modelPath nodes.UnRegister(slicer.mrmlScene) @@ -931,8 +918,7 @@ def makeRuler(self, sliceNode): rulerArea = viewWidth/4 #if self.rulerEnabled and \ - if viewWidth > self.minimumWidthForRuler and\ - rulerArea>0.5 and rulerArea<500 and NUMPY_AVAILABLE: + if viewWidth > self.minimumWidthForRuler and 0.5 < rulerArea < 500 and NUMPY_AVAILABLE: rulerSizesArray = np.array([1,5,10,50,100]) index = np.argmin(np.abs(rulerSizesArray- rulerArea)) From f478c232030062745ac97ee6872bfdb332c92c61 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 8 Oct 2015 02:23:42 -0400 Subject: [PATCH 02/18] STYLE: SliceViewAnnotations: Remove unused variables and fix typo --- .../DataProbe/DataProbeLib/SliceViewAnnotations.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index 8904aca252..0e4c70fef5 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -87,8 +87,6 @@ def __init__(self, layoutManager=None): self.humanActor = None # If there are no user settings load defaults - settings = qt.QSettings() - self.sliceViewAnnotationsEnabled = settingsValue('DataProbe/sliceViewAnnotations.enabled', 1, converter=int) self.bottomLeft = settingsValue('DataProbe/sliceViewAnnotations.bottomLeft', 1, converter=int) @@ -506,7 +504,7 @@ def updateSliceViewFromGUI(self): self.sliceCornerAnnotations[sliceViewName].SetText(3, "") self.sliceViews[sliceViewName].scheduleRender() - # reset golobal variables + # reset global variables self.sliceCornerAnnotations = {} def createGlobalVariables(self): @@ -539,7 +537,6 @@ def addSliceViewObserver(self, sliceViewName): sliceView = sliceWidget.sliceView() renderWindow = sliceView.renderWindow() - renderWindow.GetRenderers() renderer = renderWindow.GetRenderers().GetItemAsObject(0) self.renderers[sliceViewName] = renderer @@ -553,7 +550,6 @@ def addSliceViewObserver(self, sliceViewName): def createActors(self, sliceViewName): sliceWidget = self.layoutManager.sliceWidget(sliceViewName) self.sliceWidgets[sliceViewName] = sliceWidget - sliceView = sliceWidget.sliceView() self.rulerTextActors[sliceViewName] = vtk.vtkTextActor() textActor = self.rulerTextActors[sliceViewName] @@ -611,8 +607,6 @@ def createRuler(self, sliceViewName): actor.SetMapper(mapper) # color actor actor.GetProperty().SetLineWidth(1) - textActor = self.rulerTextActors[sliceViewName] - textProperty = textActor.GetTextProperty() def createScalarBar(self, sliceViewName): if self.hasVTKPVScalarBarActor: @@ -898,13 +892,11 @@ def makeRuler(self, sliceNode): # self.minimumWidthForRuler = 200 viewWidth = self.sliceViews[sliceViewName].width - viewHeight = self.sliceViews[sliceViewName].height rasToXY = vtk.vtkMatrix4x4() m = sliceNode.GetXYToRAS() rasToXY.DeepCopy(m) rasToXY.Invert() - scalingFactorString = " mm" # TODO: The current logic only supports rulers from 1mm to 10cm # add support for other ranges. @@ -998,8 +990,8 @@ def modifyScalarBar(self, sliceLogic): renderer.SetLayer(0) if orientationRenderer != None: orientationRenderer.SetLayer(1) - renderWindow = renderer.GetRenderWindow() - interactor = renderWindow.GetInteractor() + #renderWindow = renderer.GetRenderWindow() + #interactor = renderWindow.GetInteractor() # create the scalarBarWidget #scalarBarWidget = self.scalarBarWidgets[sliceViewName] @@ -1053,7 +1045,6 @@ def makeAnnotationText(self, sliceLogic): sliceViewName = sliceNode.GetLayoutName() self.currentSliceViewName = sliceViewName - renderer = self.renderers[sliceViewName] if self.sliceViews[sliceViewName]: # # Update slice corner annotations @@ -1263,7 +1254,6 @@ def drawCornerAnnotations(self): # adjust maximum text length based on fontsize and view width viewWidth = self.sliceViews[self.currentSliceViewName].width self.maximumTextLength = int((viewWidth - 40) / self.fontSize) - cornerAnnotation = '' for i, cornerText in enumerate(self.cornerTexts): keys = sorted(cornerText.keys()) From 42227527a405e9ba63e0bc43504e087d155af1ea Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 8 Oct 2015 02:30:25 -0400 Subject: [PATCH 03/18] STYLE: SliceViewAnnotations: Explicitly identify static methods --- .../DataProbe/DataProbeLib/SliceViewAnnotations.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index 0e4c70fef5..d7a0c9364d 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -1111,7 +1111,8 @@ def makeAnnotationText(self, sliceLogic): self.drawCornerAnnotations() - def updateScalarBarRange(self, sliceLogic, volumeNode, scalarBar, selectedLayer): + @staticmethod + def updateScalarBarRange(sliceLogic, volumeNode, scalarBar, selectedLayer): vdn = volumeNode.GetDisplayNode() if vdn: vcn = vdn.GetColorNode() @@ -1209,7 +1210,8 @@ def makeDicomAnnotation(self,bgUid,fgUid): self.cornerTexts[3]['6-TR']['text'] = 'TR ' + dicomDic['Repetition Time'] self.cornerTexts[3]['7-TE']['text'] = 'TE ' + dicomDic['Echo Time'] - def makePatientInfo(self,dicomDic): + @staticmethod + def makePatientInfo(dicomDic): # This will give an string of patient's birth date, # patient's age and sex patientInfo = dicomDic['Patient Birth Date' @@ -1217,7 +1219,8 @@ def makePatientInfo(self,dicomDic): ] + ', ' + dicomDic['Patient Sex'] return patientInfo - def formatDICOMDate(self, date): + @staticmethod + def formatDICOMDate(date): standardDate = '' if date != '': date = date.rstrip() @@ -1225,7 +1228,8 @@ def formatDICOMDate(self, date): standardDate = date[:4] + '-' + date[4:6]+ '-' + date[6:] return standardDate - def formatDICOMTime(self, time): + @staticmethod + def formatDICOMTime(time): if time == '': # time field is empty return '' @@ -1240,7 +1244,8 @@ def formatDICOMTime(self, time): studyS = time[4:6] return studyH + ':' + studyM + ':' + studyS +clockTime - def fitText(self,text,textSize): + @staticmethod + def fitText(text,textSize): if len(text) > textSize: preSize = int(textSize/2) postSize = preSize - 3 @@ -1289,7 +1294,8 @@ def resetTexts(self): for key in cornerText.keys(): self.cornerTexts[i][key]['text'] = '' - def extractDICOMValues(self,uid): + @staticmethod + def extractDICOMValues(uid): p ={} tags = { "0008,0021": "Series Date", From 03d9ab268a2c4dc3f65d896d4d8938edd3532226 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 8 Oct 2015 02:55:22 -0400 Subject: [PATCH 04/18] STYLE: SliceViewAnnotations: Remove unused/dead code This commit removes dead code originally introduced in r23612 (ENH: Add Slice Annotations to DataProbe module) --- Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index d7a0c9364d..0abf1ce188 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -416,9 +416,6 @@ def restoreDefaultValues(self): settings.setValue('DataProbe/sliceViewAnnotations.rangeLabelFormat', self.rangeLabelFormat) self.updateSliceViewFromGUI() - def updateMRMLFromGUI(self): - self.parameterNode.SetParameter(self.parameter, str(sliceViewAnnotationsEnabled)) - def updateGUIFromMRML(self,caller,event): if self.parameterNode.GetParameter(self.parameter) == '': # parameter does not exist - probably intializing @@ -847,9 +844,6 @@ def createAxesOrientationModel(self): self.axes.SetUserTransform(transform) - def sliceLogicModifiedEvent(self, caller,event): - self.updateLayersAnnotation(caller) - def updateRuler(self, sliceLogic): sliceCompositeNode = sliceLogic.GetSliceCompositeNode() # Get the layers From b48a529553df6eef4b4745567d05761c88ae6109 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 8 Oct 2015 03:00:57 -0400 Subject: [PATCH 05/18] BUG: SliceViewAnnotations: Ensure 'y' is set in updateOrientationMarker --- Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index 0abf1ce188..49522b475c 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -697,9 +697,8 @@ def updateOrientationMarker(self, sliceLogic): [m.GetElement(2,0),m.GetElement(2,1),m.GetElement(2,2)]]) det = np.linalg.det(v) cameraPositionMultiplier = 100/self.zoomValue - if det > 0: # right hand - y = np.array([0,0,-cameraPositionMultiplier]) - elif det < 0: # left hand + y = np.array([0,0,-cameraPositionMultiplier]) # right hand + if det < 0: # left hand y = np.array([0,0,cameraPositionMultiplier]) x = np.matrix([[m.GetElement(0,0),m.GetElement(0,1),m.GetElement(0,2)], From 71de2f4ccb6cef5cfc62435a46069ab75cb1c997 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 8 Oct 2015 03:05:23 -0400 Subject: [PATCH 06/18] STYLE: SliceViewAnnotations: Fix unused variable checking sliceCompositeNode --- Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index 49522b475c..b4422b313c 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -845,6 +845,9 @@ def createAxesOrientationModel(self): def updateRuler(self, sliceLogic): sliceCompositeNode = sliceLogic.GetSliceCompositeNode() + if not sliceCompositeNode: + return + # Get the layers sliceNode = sliceLogic.GetBackgroundLayer().GetSliceNode() if not sliceNode: @@ -859,6 +862,8 @@ def updateRuler(self, sliceLogic): def updateScalarBar(self, sliceLogic): sliceCompositeNode = sliceLogic.GetSliceCompositeNode() + if not sliceCompositeNode: + return # Get the layers backgroundLayer = sliceLogic.GetBackgroundLayer() @@ -958,6 +963,8 @@ def makeRuler(self, sliceNode): def modifyScalarBar(self, sliceLogic): sliceCompositeNode = sliceLogic.GetSliceCompositeNode() + if not sliceCompositeNode: + return # Get the layers backgroundLayer = sliceLogic.GetBackgroundLayer() From c1f71ef9927a2765f10791a590f7e22d184e7fe6 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 8 Oct 2015 03:22:13 -0400 Subject: [PATCH 07/18] BUG: SliceViewAnnotations: Ensure modifyScalarBar uses a valid scalarBar Before this commit, the code adding/removing the scalarBar actor could have been executed with a non-initialized scalarBar variable. --- .../DataProbe/DataProbeLib/SliceViewAnnotations.py | 30 +++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index b4422b313c..3d4bb8083b 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -1006,21 +1006,21 @@ def modifyScalarBar(self, sliceLogic): scalarBar.SetPosition(0.8,0.1) scalarBar.SetPosition2(0.17,0.8) - # Get the volumes - backgroundVolume = backgroundLayer.GetVolumeNode() - foregroundVolume = foregroundLayer.GetVolumeNode() - - if (backgroundVolume != None and self.scalarBarSelectedLayer == 'background'): - self.updateScalarBarRange(sliceLogic, backgroundVolume, scalarBar, self.scalarBarSelectedLayer) - renderer.AddActor(scalarBar) - #scalarBarWidget.On() - elif (foregroundVolume != None and self.scalarBarSelectedLayer == 'foreground'): - self.updateScalarBarRange(sliceLogic, foregroundVolume, scalarBar, self.scalarBarSelectedLayer) - renderer.AddActor(scalarBar) - #scalarBarWidget.On() - else: - renderer.RemoveActor(scalarBar) - #scalarBarWidget.Off() + # Get the volumes + backgroundVolume = backgroundLayer.GetVolumeNode() + foregroundVolume = foregroundLayer.GetVolumeNode() + + if (backgroundVolume != None and self.scalarBarSelectedLayer == 'background'): + self.updateScalarBarRange(sliceLogic, backgroundVolume, scalarBar, self.scalarBarSelectedLayer) + renderer.AddActor(scalarBar) + #scalarBarWidget.On() + elif (foregroundVolume != None and self.scalarBarSelectedLayer == 'foreground'): + self.updateScalarBarRange(sliceLogic, foregroundVolume, scalarBar, self.scalarBarSelectedLayer) + renderer.AddActor(scalarBar) + #scalarBarWidget.On() + else: + renderer.RemoveActor(scalarBar) + #scalarBarWidget.Off() def makeAnnotationText(self, sliceLogic): self.resetTexts() From 8f01befc87021870605c90dc3e4f66f454f124f1 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 8 Oct 2015 03:45:32 -0400 Subject: [PATCH 08/18] STYLE: SliceViewAnnotations: Simplify removing 'currentSliceViewName' ivar Update API of these methods adding 'sliceViewName' parameter: * drawCornerAnnotations * makeDicomAnnotation --- .../DataProbe/DataProbeLib/SliceViewAnnotations.py | 30 ++++++++++------------ 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index 3d4bb8083b..d86d2fa050 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -882,7 +882,6 @@ def updateScalarBar(self, sliceLogic): def makeRuler(self, sliceNode): sliceViewName = sliceNode.GetLayoutName() - self.currentSliceViewName = sliceViewName renderer = self.renderers[sliceViewName] if self.sliceViews[sliceViewName]: # @@ -973,8 +972,6 @@ def modifyScalarBar(self, sliceLogic): # Get slice view name sliceViewName = backgroundLayer.GetSliceNode().GetLayoutName() - self.currentSliceViewName = sliceViewName - renderer = self.renderers[sliceViewName] orientationRenderer = self.orientationMarkerRenderers[sliceViewName] if self.sliceViews[sliceViewName]: @@ -1043,7 +1040,6 @@ def makeAnnotationText(self, sliceLogic): if not sliceNode: return sliceViewName = sliceNode.GetLayoutName() - self.currentSliceViewName = sliceViewName if self.sliceViews[sliceViewName]: # @@ -1064,11 +1060,11 @@ def makeAnnotationText(self, sliceLogic): bgUid = bgUids.partition(' ')[0] fgUid = fgUids.partition(' ')[0] self.dicomVolumeNode = 1 - self.makeDicomAnnotation(bgUid,fgUid) + self.makeDicomAnnotation(bgUid,fgUid,sliceViewName) elif (bgUids and self.backgroundDICOMAnnotationsPersistence): uid = bgUids.partition(' ')[0] self.dicomVolumeNode = 1 - self.makeDicomAnnotation(uid,None) + self.makeDicomAnnotation(uid,None,sliceViewName) else: for key in self.cornerTexts[2]: self.cornerTexts[2][key]['text'] = '' @@ -1083,7 +1079,7 @@ def makeAnnotationText(self, sliceLogic): uids = backgroundVolume.GetAttribute('DICOM.instanceUIDs') if uids: uid = uids.partition(' ')[0] - self.makeDicomAnnotation(uid,None) + self.makeDicomAnnotation(uid,None,sliceViewName) self.dicomVolumeNode = 1 else: self.dicomVolumeNode = 0 @@ -1098,7 +1094,7 @@ def makeAnnotationText(self, sliceLogic): if uids: uid = uids.partition(' ')[0] # passed UID as bg - self.makeDicomAnnotation(uid,None) + self.makeDicomAnnotation(uid,None,sliceViewName) self.dicomVolumeNode = 1 else: self.dicomVolumeNode = 0 @@ -1109,7 +1105,7 @@ def makeAnnotationText(self, sliceLogic): self.cornerTexts[0]['1-Label']['text'] = 'L: ' + labelVolumeName + ' (' + str( "%d"%(labelOpacity*100)) + '%)' - self.drawCornerAnnotations() + self.drawCornerAnnotations(sliceViewName) @staticmethod def updateScalarBarRange(sliceLogic, volumeNode, scalarBar, selectedLayer): @@ -1130,11 +1126,11 @@ def updateScalarBarRange(sliceLogic, volumeNode, scalarBar, selectedLayer): lut2.SetRange(level-width/2,level+width/2) scalarBar.SetLookupTable(lut2) - def makeDicomAnnotation(self,bgUid,fgUid): + def makeDicomAnnotation(self,bgUid,fgUid,sliceViewName): # Do not attempt to retrieve dicom values if no local database exists if not slicer.dicomDatabase: return - viewHeight = self.sliceViews[self.currentSliceViewName].height + viewHeight = self.sliceViews[sliceViewName].height if fgUid != None and bgUid != None: backgroundDicomDic = self.extractDICOMValues(bgUid) foregroundDicomDic = self.extractDICOMValues(fgUid) @@ -1252,12 +1248,12 @@ def fitText(text,textSize): text = text[:preSize] + "..." + text[-postSize:] return text - def drawCornerAnnotations(self): + def drawCornerAnnotations(self, sliceViewName): if not self.sliceViewAnnotationsEnabled: return # Auto-Adjust # adjust maximum text length based on fontsize and view width - viewWidth = self.sliceViews[self.currentSliceViewName].width + viewWidth = self.sliceViews[sliceViewName].width self.maximumTextLength = int((viewWidth - 40) / self.fontSize) for i, cornerText in enumerate(self.cornerTexts): @@ -1278,16 +1274,16 @@ def drawCornerAnnotations(self): elif self.annotationsDisplayAmount == 2: if (cornerText[key]['category'] == 'A'): cornerAnnotation = cornerAnnotation+ text + '\n' - sliceCornerAnnotation = self.sliceCornerAnnotations[self.currentSliceViewName] + sliceCornerAnnotation = self.sliceCornerAnnotations[sliceViewName] # encode to avoid 'unicode conversion error' for patient names containing international characters cornerAnnotation = slicer.util.toVTKString(cornerAnnotation) sliceCornerAnnotation.SetText(i, cornerAnnotation) textProperty = sliceCornerAnnotation.GetTextProperty() textProperty.SetShadow(1) - self.renderers[self.currentSliceViewName].RemoveActor(sliceCornerAnnotation) - self.renderers[self.currentSliceViewName].AddActor(sliceCornerAnnotation) + self.renderers[sliceViewName].RemoveActor(sliceCornerAnnotation) + self.renderers[sliceViewName].AddActor(sliceCornerAnnotation) - self.sliceViews[self.currentSliceViewName].scheduleRender() + self.sliceViews[sliceViewName].scheduleRender() def resetTexts(self): for i, cornerText in enumerate(self.cornerTexts): From 78419bf7ef61f33d457e7b877b68af9b8531ece8 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 8 Oct 2015 03:55:09 -0400 Subject: [PATCH 09/18] STYLE: SliceViewAnnotations: Re-factor and simplify updateSliceViewFromGUI() --- .../DataProbe/DataProbeLib/SliceViewAnnotations.py | 30 ++++++++-------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index d86d2fa050..7b1af68e59 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -475,32 +475,24 @@ def updateSliceViewFromGUI(self): self.scalarBarCollapsibleButton.enabled = enabled self.restorDefaultsButton.enabled = enabled - if enabled: - for sliceViewName in self.sliceViewNames: - sliceWidget = self.layoutManager.sliceWidget(sliceViewName) - sl = sliceWidget.sliceLogic() - self.makeAnnotationText(sl) - self.updateRuler(sl) - self.updateScalarBar(sl) - self.updateOrientationMarker(sl) - else: - # Remove Observers - - for sliceViewName in self.sliceViewNames: - sliceWidget = self.layoutManager.sliceWidget(sliceViewName) - sl = sliceWidget.sliceLogic() - self.updateRuler(sl) - self.updateScalarBar(sl) - self.updateOrientationMarker(sl) + for sliceViewName in self.sliceViewNames: + sliceWidget = self.layoutManager.sliceWidget(sliceViewName) + sl = sliceWidget.sliceLogic() + self.updateRuler(sl) + self.updateScalarBar(sl) + self.updateOrientationMarker(sl) - # Clear Annotations - for sliceViewName in self.sliceViewNames: + if enabled: + self.makeAnnotationText(sl) + else: + # Clear Annotations self.sliceCornerAnnotations[sliceViewName].SetText(0, "") self.sliceCornerAnnotations[sliceViewName].SetText(1, "") self.sliceCornerAnnotations[sliceViewName].SetText(2, "") self.sliceCornerAnnotations[sliceViewName].SetText(3, "") self.sliceViews[sliceViewName].scheduleRender() + if not enabled: # reset global variables self.sliceCornerAnnotations = {} From 069599c0f6b10eebbf08a9ea48c026dcb5a70e2b Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 8 Oct 2015 04:41:30 -0400 Subject: [PATCH 10/18] STYLE: SliceViewAnnotations: Move ScalarBar font config to modifyScalarBar() --- .../DataProbe/DataProbeLib/SliceViewAnnotations.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index 7b1af68e59..0b2d00013d 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -445,16 +445,10 @@ def updateSliceViewFromGUI(self): cornerAnnotation.SetMinimumFontSize(self.fontSize) cornerAnnotation.SetNonlinearFontScaleFactor(1) textProperty = cornerAnnotation.GetTextProperty() - scalarBar = self.scalarBars[sliceViewName] - scalarBarTextProperty = scalarBar.GetLabelTextProperty() - scalarBarTextProperty.ItalicOff() - scalarBarTextProperty.BoldOff() if self.fontFamily == 'Times': textProperty.SetFontFamilyToTimes() - scalarBarTextProperty.SetFontFamilyToTimes() else: textProperty.SetFontFamilyToArial() - scalarBarTextProperty.SetFontFamilyToArial() # Updating Annotations Amount if self.level1RadioButton.checked: @@ -968,6 +962,15 @@ def modifyScalarBar(self, sliceLogic): orientationRenderer = self.orientationMarkerRenderers[sliceViewName] if self.sliceViews[sliceViewName]: scalarBar = self.scalarBars[sliceViewName] + # Font + scalarBarTextProperty = scalarBar.GetLabelTextProperty() + scalarBarTextProperty.ItalicOff() + scalarBarTextProperty.BoldOff() + if self.fontFamily == 'Times': + scalarBarTextProperty.SetFontFamilyToTimes() + else: + scalarBarTextProperty.SetFontFamilyToArial() + scalarBar.SetTextPositionToPrecedeScalarBar() if self.hasVTKPVScalarBarActor: scalarBar.SetRangeLabelFormat(self.rangeLabelFormat) From ec4a55d6aeef2f8e7227ec10d7ffed70cf4be1ee Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 8 Oct 2015 04:44:20 -0400 Subject: [PATCH 11/18] STYLE: SliceViewAnnotations: Rename function --- Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index 0b2d00013d..7c7a3274ad 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -526,7 +526,7 @@ def addSliceViewObserver(self, sliceViewName): self.sliceViews[sliceViewName] = sliceView self.sliceCornerAnnotations[sliceViewName] = sliceView.cornerAnnotation() sliceLogic = sliceWidget.sliceLogic() - self.addObserver(sliceLogic, vtk.vtkCommand.ModifiedEvent, self.updateCornerAnnotations) + self.addObserver(sliceLogic, vtk.vtkCommand.ModifiedEvent, self.updateViewAnnotations) self.orientationMarkerRenderers[sliceViewName] = vtk.vtkRenderer() @@ -611,7 +611,7 @@ def createScalarBar(self, sliceViewName): ''' return scalarBar - def updateCornerAnnotations(self,caller,event): + def updateViewAnnotations(self,caller,event): layoutManager = self.layoutManager if layoutManager is None: return From efedf284f638ff7c2833c38a9baf9f6be0a6c5b2 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Fri, 9 Oct 2015 00:51:35 -0400 Subject: [PATCH 12/18] STYLE: SliceViewAnnotations: Add updateCornerAnnotation() function --- .../DataProbe/DataProbeLib/SliceViewAnnotations.py | 48 ++++++++++++---------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index 7c7a3274ad..5796c74de8 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -439,17 +439,6 @@ def updateSliceViewFromGUI(self): for slider in [self.zoomSlider,self.widthSlider, self.heightSlider]: slider.enabled = self.orientationMarkerEnableCheckBox.checked - for sliceViewName in self.sliceViewNames: - cornerAnnotation = self.sliceCornerAnnotations[sliceViewName] - cornerAnnotation.SetMaximumFontSize(self.fontSize) - cornerAnnotation.SetMinimumFontSize(self.fontSize) - cornerAnnotation.SetNonlinearFontScaleFactor(1) - textProperty = cornerAnnotation.GetTextProperty() - if self.fontFamily == 'Times': - textProperty.SetFontFamilyToTimes() - else: - textProperty.SetFontFamilyToArial() - # Updating Annotations Amount if self.level1RadioButton.checked: self.annotationsDisplayAmount = 0 @@ -475,16 +464,7 @@ def updateSliceViewFromGUI(self): self.updateRuler(sl) self.updateScalarBar(sl) self.updateOrientationMarker(sl) - - if enabled: - self.makeAnnotationText(sl) - else: - # Clear Annotations - self.sliceCornerAnnotations[sliceViewName].SetText(0, "") - self.sliceCornerAnnotations[sliceViewName].SetText(1, "") - self.sliceCornerAnnotations[sliceViewName].SetText(2, "") - self.sliceCornerAnnotations[sliceViewName].SetText(3, "") - self.sliceViews[sliceViewName].scheduleRender() + self.updateCornerAnnotation(sl) if not enabled: # reset global variables @@ -627,6 +607,32 @@ def updateViewAnnotations(self,caller,event): self.updateScalarBar(caller) self.updateOrientationMarker(caller) + def updateCornerAnnotation(self, sliceLogic): + + sliceNode = sliceLogic.GetBackgroundLayer().GetSliceNode() + sliceViewName = sliceNode.GetLayoutName() + + enabled = self.sliceViewAnnotationsEnabled + + cornerAnnotation = self.sliceCornerAnnotations[sliceViewName] + + if enabled: + # Font + cornerAnnotation.SetMaximumFontSize(self.fontSize) + cornerAnnotation.SetMinimumFontSize(self.fontSize) + cornerAnnotation.SetNonlinearFontScaleFactor(1) + textProperty = cornerAnnotation.GetTextProperty() + if self.fontFamily == 'Times': + textProperty.SetFontFamilyToTimes() + else: + textProperty.SetFontFamilyToArial() + # Text + self.makeAnnotationText(sliceLogic) + else: + # Clear Annotations + for position in range(3): + cornerAnnotation.SetText(position, "") + def updateOrientationMarker(self, sliceLogic): sliceNode = sliceLogic.GetBackgroundLayer().GetSliceNode() sliceViewName = sliceNode.GetLayoutName() From 6653a4549e86a1f4361a047d844659234eb0102a Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Fri, 9 Oct 2015 02:49:10 -0400 Subject: [PATCH 13/18] STYLE: SliceViewAnnotations: Do not remove/re-add slicerCornerAnnotation This commit removes no-op code that was initially introduced in r23981 (ENH: Fix 3943 and other enhancements for slice view annotations) --- Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index 5796c74de8..791cf14154 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -1281,8 +1281,6 @@ def drawCornerAnnotations(self, sliceViewName): sliceCornerAnnotation.SetText(i, cornerAnnotation) textProperty = sliceCornerAnnotation.GetTextProperty() textProperty.SetShadow(1) - self.renderers[sliceViewName].RemoveActor(sliceCornerAnnotation) - self.renderers[sliceViewName].AddActor(sliceCornerAnnotation) self.sliceViews[sliceViewName].scheduleRender() From 70cc96eb6e27fd67fb990005488e26004dcf9ddf Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Fri, 9 Oct 2015 02:51:46 -0400 Subject: [PATCH 14/18] STYLE: SliceViewAnnotations: Remove extra loop in createCornerAnnotations --- Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index 791cf14154..46d7e39326 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -486,10 +486,7 @@ def createGlobalVariables(self): def createCornerAnnotations(self): self.createGlobalVariables() - sliceViewNames = self.layoutManager.sliceViewNames() - - for sliceViewName in sliceViewNames: - self.sliceViewNames.append(sliceViewName) + self.sliceViewNames = self.layoutManager.sliceViewNames() for sliceViewName in self.sliceViewNames: self.addSliceViewObserver(sliceViewName) self.createActors(sliceViewName) From df1edd783f43db1bfbe6fc18bcfeafe2f6406c64 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Fri, 9 Oct 2015 02:59:36 -0400 Subject: [PATCH 15/18] STYLE: SliceViewAnnotations: Remove unused methods openSettingsPopup/close Following r23612 (ENH: Add Slice Annotations to DataProbe module), these method are obsolete. --- Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index 46d7e39326..3ea1fcfcc2 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -423,14 +423,6 @@ def updateGUIFromMRML(self,caller,event): self.sliceViewAnnotationsEnabled = int(self.parameterNode.GetParameter(self.parameter)) self.updateSliceViewFromGUI() - def openSettingsPopup(self): - if not self.window.isVisible(): - self.window.show() - self.window.raise_() - - def close(self): - self.window.hide() - def updateSliceViewFromGUI(self): # Create corner annotations if have not created already if len(self.sliceCornerAnnotations.items()) == 0: From 04d58b814f85ddbd44c79d0303f773b6b9522b34 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Fri, 9 Oct 2015 03:14:16 -0400 Subject: [PATCH 16/18] STYLE: SliceViewAnnotations: Fix spelling mistake --- Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index 3ea1fcfcc2..9d32c5ebf6 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -59,7 +59,7 @@ def __init__(self, layoutManager=None): '8-Bg-SeriesDescription':{'text':'','category':'C'}, '9-Fg-SeriesDescription':{'text':'','category':'C'} }) - # Top Rihgt Corner Text + # Top Right Corner Text self.cornerTexts.append({ '1-Institution-Name':{'text':'','category':'B'}, '2-Referring-Phisycian':{'text':'','category':'B'}, @@ -196,7 +196,7 @@ def create(self): else: self.axesRadioButton.checked = True - self.restorDefaultsButton = find(window, 'restoreDefaultsButton')[0] + self.restoreDefaultsButton = find(window, 'restoreDefaultsButton')[0] # connections self.sliceViewAnnotationsCheckBox.connect('clicked()', self.onSliceViewAnnotationsCheckBox) @@ -230,7 +230,7 @@ def create(self): for radioButton in [self.cubeRadioButton, self.axesRadioButton, self.humanRadioButton]: radioButton.connect('clicked()', self.onOrientationMarkerTypeRadioButton) - self.restorDefaultsButton.connect('clicked()', self.restoreDefaultValues) + self.restoreDefaultsButton.connect('clicked()', self.restoreDefaultValues) def onLayoutManagerDestroyed(self): self.layoutManager = slicer.app.layoutManager() @@ -448,7 +448,7 @@ def updateSliceViewFromGUI(self): self.annotationsAmountGroupBox.enabled = enabled self.rulerCollapsibleButton.enabled = enabled self.scalarBarCollapsibleButton.enabled = enabled - self.restorDefaultsButton.enabled = enabled + self.restoreDefaultsButton.enabled = enabled for sliceViewName in self.sliceViewNames: sliceWidget = self.layoutManager.sliceWidget(sliceViewName) From 2e69c18b49c713d4f7cdda61461f8b7b2fd9f6b9 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Fri, 9 Oct 2015 03:16:57 -0400 Subject: [PATCH 17/18] STYLE: SliceViewAnnotations: Simplify code removing ivar There is no need to keep track of the corner annotation, it can easily be retrieved given a sliceView. --- .../DataProbe/DataProbeLib/SliceViewAnnotations.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index 9d32c5ebf6..c8b14c2098 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -70,8 +70,6 @@ def __init__(self, layoutManager=None): '7-TE':{'text':'','category':'A'} }) - self.sliceCornerAnnotations = {} - self.annotationsDisplayAmount = 0 # @@ -425,7 +423,7 @@ def updateGUIFromMRML(self,caller,event): def updateSliceViewFromGUI(self): # Create corner annotations if have not created already - if len(self.sliceCornerAnnotations.items()) == 0: + if len(self.sliceViewNames) == 0: self.createCornerAnnotations() for slider in [self.zoomSlider,self.widthSlider, self.heightSlider]: @@ -458,16 +456,11 @@ def updateSliceViewFromGUI(self): self.updateOrientationMarker(sl) self.updateCornerAnnotation(sl) - if not enabled: - # reset global variables - self.sliceCornerAnnotations = {} - def createGlobalVariables(self): self.sliceViewNames = [] self.sliceWidgets = {} self.sliceViews = {} self.cameras = {} - self.sliceCornerAnnotations = {} self.renderers = {} self.rulerActors = {} self.points = {} @@ -493,7 +486,6 @@ def addSliceViewObserver(self, sliceViewName): self.renderers[sliceViewName] = renderer self.sliceViews[sliceViewName] = sliceView - self.sliceCornerAnnotations[sliceViewName] = sliceView.cornerAnnotation() sliceLogic = sliceWidget.sliceLogic() self.addObserver(sliceLogic, vtk.vtkCommand.ModifiedEvent, self.updateViewAnnotations) self.orientationMarkerRenderers[sliceViewName] = vtk.vtkRenderer() @@ -603,7 +595,7 @@ def updateCornerAnnotation(self, sliceLogic): enabled = self.sliceViewAnnotationsEnabled - cornerAnnotation = self.sliceCornerAnnotations[sliceViewName] + cornerAnnotation = self.sliceViews[sliceViewName].cornerAnnotation() if enabled: # Font @@ -1264,7 +1256,7 @@ def drawCornerAnnotations(self, sliceViewName): elif self.annotationsDisplayAmount == 2: if (cornerText[key]['category'] == 'A'): cornerAnnotation = cornerAnnotation+ text + '\n' - sliceCornerAnnotation = self.sliceCornerAnnotations[sliceViewName] + sliceCornerAnnotation = self.sliceViews[sliceViewName].cornerAnnotation() # encode to avoid 'unicode conversion error' for patient names containing international characters cornerAnnotation = slicer.util.toVTKString(cornerAnnotation) sliceCornerAnnotation.SetText(i, cornerAnnotation) From dc066d2c5e51c2199bf5a3f0346c4bc59d43f470 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Fri, 9 Oct 2015 10:14:22 -0400 Subject: [PATCH 18/18] BUG: SliceViewAnnotations: Do not show blank when corner annotation is off. Fixes #4043 Note that while setting the text of the corner annotation to a space avoid the blank area from showing up, this doesn't address the root cause. There is probably something wrong in either ctkVTKSliceView or VTK itself. The problem is still reproducible running the following snippet in the Slicer python interactor: v = ctk.ctkVTKSliceView() v.show() v.cornerAnnotationText = "Hello" v.forceRender() v.cornerAnnotationText = "" v.forceRender() --- Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py index c8b14c2098..5f3511de25 100644 --- a/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py +++ b/Modules/Scripted/DataProbe/DataProbeLib/SliceViewAnnotations.py @@ -612,7 +612,7 @@ def updateCornerAnnotation(self, sliceLogic): else: # Clear Annotations for position in range(3): - cornerAnnotation.SetText(position, "") + cornerAnnotation.SetText(position, " ") def updateOrientationMarker(self, sliceLogic): sliceNode = sliceLogic.GetBackgroundLayer().GetSliceNode() @@ -1259,7 +1259,7 @@ def drawCornerAnnotations(self, sliceViewName): sliceCornerAnnotation = self.sliceViews[sliceViewName].cornerAnnotation() # encode to avoid 'unicode conversion error' for patient names containing international characters cornerAnnotation = slicer.util.toVTKString(cornerAnnotation) - sliceCornerAnnotation.SetText(i, cornerAnnotation) + sliceCornerAnnotation.SetText(i, cornerAnnotation if len(cornerAnnotation) else ' ') textProperty = sliceCornerAnnotation.GetTextProperty() textProperty.SetShadow(1)