# Avizo-Script-Object V3.0 # NO DEPRECATION WARNING ############################################################## # Mother script for Avizo Fire action based workflow. # Each action is defined with: # - a procedure name # - an information string to be displayed before execution # - a procedure called to initalize ports # - a procedure called at action initialisation # - a procedure called if the Back button is pressed in this action # - a procedure called if action is skipped # - a procedure called when action is executed # # # In order to "inherit" from this scro, source it in your script: # - source "$AMIRA_ROOT/share/script-objects/ActionStep.scro" # - declare a procedure called defineActions that will add each action with the following syntax: # addAction initPorts onPortUpdate initAction onBackAction onSkipAction onApplyAction # # Ports created in the initPorts procedure will automatically be shown when corresponding action is the current one, hidden otherwise. # # Additionnaly this script declare : # # - an Orthoslice named MainOrthoslice # for further created Orthoslices, use port interconnection so that all slices are synchronized: # sliceNumber connect MainOrthoSlice # Reconnect the MainOrthoslice to another data with the convenience function attachMainOrthoSlice # # - dimX, dimY, dimZ are the dimensions of the input # - dataIs2D variable is equal to 1 if the connected data is 2D # # # See example GradientThresholding2.scro in AMIRA_ROOT/share/script-objects # # If you use the script you CANNOT redefine the function update(). # If you redefine the update() function the update of the ActionStep # won't be called and this will lead to unwanted behaviour. # # authors: Gwenole Tallec (gtallec@fei.com) # Daniel Lichau (dlichau@fei.com) # # (C) copyright 2011, FEI SAS # ############################################################# # ######################################################################### # Constructor is called when script module is instantiated # ######################################################################### "$this" proc constructor {} { if { [lsearch script ["$this" allPorts]] >= 0 } { "$this" script hide } # These are just default supported types. # To override them, declare valid types in the script resource "-proc" before the first "fire". if { [ "$this" data getValidTypes ] == "HxData" } { "$this" data clearTypes "$this" data addType HxUniformScalarField3 } # Initialize variables "$this" initCommonVar # A procedure initVar must be define in script which using this script. # In this procedure, tcl variable must be initialized "$this" initVar if { ! [__isProduct "PerGeos"] } { # data port can't be manually changed "$this" data allowEditing 0 } # Define slice number and slice orientation ports "$this" newPortIntSlider sliceNumber "$this" sliceNumber setLabel "Slice Number" "$this" newPortRadioBox sliceOrientation 3 "$this" sliceOrientation setLabel "Slice Orientation" "$this" sliceOrientation setLabel 0 "xy" "$this" sliceOrientation setLabel 1 "xz" "$this" sliceOrientation setLabel 2 "yz" # Create info port to indicate current step "$this" newPortInfo info "$this" info setLabel Info # Create action port "$this" newPortButtonList action 3 "$this" action setLabel Action "$this" action setLabel 0 "Back" "$this" action setSensitivity 0 0 "$this" action setLabel 1 "Skip" "$this" action setLabel 2 "Apply" # Create no back port "$this" newPortToggleList portNoBack 1 "$this" portNoBack setLabel "Memory Consumption" "$this" portNoBack setLabel 0 "Remove intermediate data" "$this" portNoBack setValue 0 0 if { !["$this" getVar hasNoBackOption] } { "$this" portNoBack hideMaskIncrease } # Get image dimensions if { ["$this" getVar currentData] != "" } { set dimX [lindex [["$this" getVar currentData] getDims] 0] set dimY [lindex [["$this" getVar currentData] getDims] 1] set dimZ [lindex [["$this" getVar currentData] getDims] 2] # check if data is 2D "$this" setVar dataIs2D 0 if { ($dimX == 1) || ($dimY == 1) || ($dimZ == 1) } { "$this" setVar dataIs2D 1 } } # Create an OrthoSlice an attach it to currentData if { ["$this" getVar "mainOrthoSlice"] == "" } { "$this" createMainSlice "$this" setVar isNetworkLoading false } else { "$this" setVar isNetworkLoading true } "$this" masterDefineActions "$this" select "$this" setVar isNetworkLoading false } # ######################################################################### # Create main slice and colorwash # ######################################################################### "$this" proc createMainSlice {} { set data ["$this" data source] if {$data == ""} { return } # Create main orthoslice set type [$data getTypeId] #LDA data case if {"$type" == "HxVolumeDataObject"} { set mainOrthoSlice [create HxOrthoSliceLDM {MainOrthoSlice}] } else { set mainOrthoSlice [create HxOrthoSlice {MainOrthoSlice}] } if { ["$this" getVar currentData] != "" } { "$mainOrthoSlice" data connect ["$this" getVar currentData] } "$mainOrthoSlice" setNoRename 1 "$mainOrthoSlice" fire "$this" setVar mainOrthoSlice "$mainOrthoSlice" # Create colorwash # If data is not a LDA if {"$type" != "HxVolumeDataObject"} { set colorwash [create HxColorwash {Colorwash} ] "$colorwash" alpha setValue 0.5 "$colorwash" mode setValue 7 "$colorwash" module connect "$mainOrthoSlice" "$colorwash" setNoRename 1 "$colorwash" fire "$this" setVar colorwash "$colorwash" if { !["$this" getVar isColorwashVisible] } { "$colorwash" hideIcon } } # Interconnect port sliceNumber and sliceOrientation "$this" sliceNumber connect "$mainOrthoSlice" sliceNumber "$this" sliceOrientation connect "$mainOrthoSlice" sliceOrientation } # ######################################################################### # Attach main slice # ######################################################################### "$this" proc attachMainOrthoSlice {args} { if { ["$this" data source] == "" } { return } set mainOrthoSlice ["$this" getVar mainOrthoSlice] set colorwash ["$this" getVar colorwash] if { !["$this" getVar isNetworkLoading] } { "$mainOrthoSlice" data connect [lindex $args 0] "$mainOrthoSlice" fire if {[llength $args]>1} { "$colorwash" alpha setValue 0.5 "$colorwash" mode setValue 7 "$colorwash" data connect [lindex $args 1] } else { "$colorwash" data disconnect } "$colorwash" fire } } # ######################################################################### # Declare the actions of your script # ######################################################################### "$this" proc masterDefineActions {} { # Close connection editor "$this" closeConnectionEditor "$this" defineActions if { ["$this" getVar isFinishActionAvailable] } { "$this" defineFinishAction } "$this" setCurrentAction ["$this" getVar currentActionId] } # ######################################################################### # Delete all actions from specified action # ######################################################################### "$this" proc deleteAllActionsFrom { actionID } { set newNumActions $actionID #remove all ports related to the actions for {set id $actionID} {$id < ["$this" getVar numActions] } {incr id 1} { set procName [lindex ["$this" getVar procNames] $id] foreach port ["$this" getVar "portList $procName"] { "$this" deletePort $port } } #remove all items after actionID "$this" setVar procNames [lreplace ["$this" getVar procNames] $newNumActions ["$this" getVar numActions]] "$this" setVar infoList [lreplace ["$this" getVar infoList] $newNumActions ["$this" getVar numActions]] "$this" setVar skipEnabled [lreplace ["$this" getVar skipEnabled] $newNumActions ["$this" getVar numActions]] "$this" setVar numActions $newNumActions } # ######################################################################### # Add action of your script. Prototype is the following: # # addAction # # initPorts # onPortUpdate # initAction # onBackAction # onSkipAction # onApplyAction # ######################################################################### "$this" proc addAction { args } { set argIndex 0 set procName [lindex $args $argIndex]; incr argIndex; set info [lindex $args $argIndex]; incr argIndex; set initPorts_body {} set initAction_body {} set onBackAction_body {} set onSkipAction_body {} set onApplyAction_body {} set onPortUpdate_body {} while { $argIndex < [llength $args] } { set bodyId [lindex $args $argIndex] incr argIndex set body [lindex $args $argIndex] switch $bodyId { initPorts { set initPorts_body $body } onPortUpdate { set onPortUpdate_body $body } initAction { set initAction_body $body } onBackAction { set onBackAction_body $body } onSkipAction { set onSkipAction_body $body } onApplyAction { set onApplyAction_body $body } } incr argIndex } set actionId ["$this" getVar numActions] # Initialize ports set lastNumPorts [llength ["$this" allPorts]] eval $initPorts_body "$this" setVar "portList $procName" [lrange ["$this" allPorts] $lastNumPorts end] foreach port ["$this" getVar "portList $procName"] { "$this" $port hide } "$this" proc "initAction\"$procName\"" {} $initAction_body "$this" proc "onBackAction\"$procName\"" {} $onBackAction_body "$this" proc "onSkipAction\"$procName\"" {} $onSkipAction_body "$this" proc "onApplyAction\"$procName\"" {} $onApplyAction_body "$this" proc "onPortUpdate\"$procName\"" {} $onPortUpdate_body "$this" setVar procNames($actionId) "$procName" "$this" setVar infoList($actionId) $info "$this" setVar skipEnabled($actionId) 0 # Fill procedure name array set tempList ["$this" getVar procNames] lappend tempList "$procName" "$this" setVar procNames "$tempList" # Fill skip enabled state set tempList ["$this" getVar skipEnabled] # If skip action body is empty, will disable skip button if { [string is space $onSkipAction_body] } { lappend tempList 0 } else { lappend tempList 1 } "$this" setVar skipEnabled $tempList # Fill info list set tempList ["$this" getVar infoList] lappend tempList $info "$this" setVar infoList $tempList if { !["$this" getVar isNetworkLoading] } { # Fill number of actions "$this" setVar numActions [incr actionId] } } # ######################################################################### # Action called when hitting back button # ######################################################################### "$this" proc backProc { actionId } { if { $actionId < ["$this" getVar numActions] } { set proc [lindex ["$this" getVar procNames] $actionId] foreach port ["$this" getVar "portList $proc"] { "$this" $port hide } "$this" "onBackAction\"$proc\""; } "$this" setCurrentAction [expr $actionId - 1] } # ######################################################################### # Set the current action # ######################################################################### "$this" proc setCurrentAction { actionId } { "$this" setVar currentActionId $actionId "$this" setInfoTooltip "$this" setInfoValue # Connect Back button "$this" connectBackButton if { ["$this" hasDefinedActionAssociated $actionId] } { # Connect Apply button "$this" connectApplyButton # Connect Skip button "$this" connectSkipButton set nextProcName [lindex ["$this" getVar procNames] $actionId] # Show current action ports foreach port ["$this" getVar "portList $nextProcName"] { "$this" $port show } "$this" "onPortUpdate\"$nextProcName\"" # Call initAction of next action "$this" "initAction\"$nextProcName\"" } else { "$this" action setSensitivity 2 0 "$this" action setSensitivity 1 0 } } # ######################################################################### # Return false if specified action is not a "real" action # When finish action is not available, last step (end of step) is not a "real" action # ######################################################################### "$this" proc hasDefinedActionAssociated { actionId } { set numOfNumerotedActions ["$this" getNumOfNumerotedActions] if { $actionId >= $numOfNumerotedActions } { if { ["$this" getVar isFinishActionAvailable] } { return true } else { return false } } else { return true } } # ######################################################################### # Return total number of numeroted actions # ######################################################################### "$this" proc getNumOfNumerotedActions {} { # Number of numeroted actions: # Finish action is a special step (Finish) which must not be numeroted. # consequently, total number of steps to display is (numActions-1) if { ["$this" getVar isFinishActionAvailable] } { set numOfNumerotedActions [expr ["$this" getVar numActions] -1] } else { set numOfNumerotedActions ["$this" getVar numActions] } return $numOfNumerotedActions } # ######################################################################### # Connect Apply button to correct action (using currentActionId) # ######################################################################### "$this" proc connectApplyButton {} { set actionId ["$this" getVar currentActionId] "$this" action setLabel 2 "Apply" "$this" action setSensitivity 2 1 # Connect Apply button "$this" action setCmd 2 "\"$this\" applyProc $actionId" "$this" action setSensitivity 2 1 } # ######################################################################### # Connect Skip button to correct action (using currentActionId) # ######################################################################### "$this" proc connectSkipButton {} { set actionId ["$this" getVar currentActionId] # Connect skip button only if skip method is defined set connectSkip [lindex ["$this" getVar skipEnabled] $actionId] if {$connectSkip == 0} { "$this" action setSensitivity 1 0 } else { set procName [lindex ["$this" getVar procNames] $actionId] set procName skip$procName "$this" action setCmd 1 "\"$this\" skipProc $actionId" "$this" action setSensitivity 1 1 } } # ######################################################################### # Connect Back button to correct action (using currentActionId) # ######################################################################### "$this" proc connectBackButton {} { set actionId ["$this" getVar currentActionId] # Connect Back button to actionId-1 if {$actionId > 0} { "$this" action setCmd 0 "\"$this\" backProc $actionId" "$this" action setSensitivity 0 1 } else { "$this" action setSensitivity 0 0 } } # ######################################################################### # Action called when hitting apply button # ######################################################################### "$this" proc applyProc { actionId } { set procName [lindex ["$this" getVar procNames] $actionId] "$this" "onApplyAction\"$procName\"" if { [exists "$this"] } { "$this" goToNextStep $actionId } } # ######################################################################### # Go to next step of specified action # ######################################################################### "$this" proc goToNextStep { actionId } { set procName [lindex ["$this" getVar procNames] $actionId] # Hide actions ports foreach port ["$this" getVar "portList $procName"] { "$this" $port hide } if { ["$this" getVar isFinishActionAvailable] } { # actionId is comprised between 0 and numAction-1 set actionId [expr min([incr actionId], [expr ["$this" getVar numActions] - 1])] } else { incr actionId } "$this" setCurrentAction $actionId # No back port management if { ["$this" portNoBack getValue 0] == 1 } { "$this" portNoBack setSensitivity 0 0 "$this" action setSensitivity 0 0 if { ["$this" getVar hasNoBackOption] } { "$this" cleanupIntermediateData } } } # ######################################################################### # Action called when hitting skip button # ######################################################################### "$this" proc skipProc { actionId } { set procName [lindex ["$this" getVar procNames] $actionId] "$this" "onSkipAction\"$procName\"" "$this" goToNextStep $actionId } # ######################################################################### # Update procedure # ######################################################################### "$this" proc update {} { # No back port management "$this" updateNoBack set actionId ["$this" getVar currentActionId] if {$actionId < ["$this" getVar numActions]} { set procName [lindex ["$this" getVar procNames] $actionId] # Call onPortUpdate procedure of current step "$this" "onPortUpdate\"$procName\"" } # Test if the script must be restarted. # This is the case when the port data has a new source (NEW_SOURCE flag equals 1) # and this source is different than the currently edited data. # This 2nd test has been added to prevent the script from being uselessly restarted # at its creation (its port data has a new source at its 1st connection). if { ["$this" data isNew 1] && ["$this" getVar currentData] != ["$this" data source] } { "$this" restart } } # ######################################################################### # # ######################################################################### "$this" proc updateNoBack {} { set actionId ["$this" getVar currentActionId] # No back port management if { ["$this" portNoBack getValue 0] == 0 } { if { $actionId > 0 } { "$this" action setSensitivity 0 1 } } elseif { ["$this" portNoBack getValue 0] == 1 } { "$this" action setSensitivity 0 0 } } # ######################################################################### # Define finish action # ######################################################################### "$this" proc defineFinishAction {} { "$this" addAction "Finish" "End of steps" initPorts { "$this" newPortGeneric portSavingOptions "$this" portSavingOptions setLabel "Save Options" "$this" portSavingOptions insertCheckBox 0 "Save:" 0 "$this" portSavingOptions insertRadioGroup 1 2 "Result data only" "Full project" 1 "$this" portSavingOptions setValue 0 1 "$this" newPortFilename portDataname "$this" portDataname setLabel Filename "$this" portDataname registerFileType "Avizo binary" am "$this" portDataname hideMaskIncrease "$this" newPortFilename portProjectname "$this" portProjectname setLabel Filename "$this" portProjectname registerFileType "Avizo project" hx "$this" portProjectname hideMaskIncrease } onPortUpdate { # Radio buttons and port filename are enabled # only if checkbox is checked set isChecked ["$this" portSavingOptions getValue 0] "$this" portSavingOptions setSensitivity 1 $isChecked } initAction { "$this" action setLabel 2 "Finish" } onBackAction { } onSkipAction { } onApplyAction { if { ["$this" portSavingOptions getValue 0] == 1 } { if { ["$this" portSavingOptions getValue 1] == "Result data only" } { # Save data set dataToSave [["$this" getVar mainOrthoSlice] data source] # Set default filename if { ["$this" portDataname getValue] == "" } { "$this" portDataname setValue "$dataToSave" } # Display file dialog if { ["$this" portDataname exec] == 0 } { # Cancel pressed return } set dataFilename ["$this" portDataname getValue] if { [file exists $dataFilename] == 1 } { # Display warning (file exists) if { [theMsg overwrite $dataFilename] == 1 } { # Overwrite pressed file delete -force $dataFilename } else { # Cancel pressed return } } set format "Avizo binary" "$dataToSave" save $format $dataFilename } else { # Save project # Set default filename if { ["$this" portProjectname getValue] == "" } { "$this" portProjectname setValue [theObjectPool getProjectName] } if { ["$this" portProjectname exec] == 0 } { # Cancel pressed return } set projectFilename ["$this" portProjectname getValue] if { [file exists $projectFilename] == 1 } { # Display warning (file exists) if { [theMsg overwrite $projectFilename] == 1 } { # Overwrite pressed file delete -force $projectFilename } else { # Cancel pressed return } } # Save project saveProjectAs -includeInvisible -forceAutoSave $projectFilename } } elseif { ["$this" portSavingOptions getValue 0] == 0 } { # No save option, display an info dialog set infoMsg "Save option was not set. This wizard will be removed without saving.\n Result will have to be saved later using \"File>Save Project\" menu" if { [theMsg info -enableDoNotShowAgain $infoMsg "OK" "Cancel"] == 1 } { # Cancel return } } # Call destructor "$this" destructor remove "$this" } } # ######################################################################### # Set value on port info # ######################################################################### "$this" proc setInfoValue {} { set actionId ["$this" getVar currentActionId] # Fill info set infoStr [lindex ["$this" getVar infoList] $actionId] if { $actionId >= ["$this" getNumOfNumerotedActions] } { if { ["$this" getVar isFinishActionAvailable] } { "$this" info setValue "$infoStr" } else { "$this" info setValue "End of steps" } } else { "$this" info setValue "Step [expr $actionId +1] of ["$this" getNumOfNumerotedActions]: $infoStr" } } # ######################################################################### # Set tooltip on port info # ######################################################################### "$this" proc setInfoTooltip {} { set tooltipValue "" set actionId ["$this" getVar currentActionId] for { set i 0 } { $i < ["$this" getVar numActions] } { incr i } { # Current step in bold with arrow if { $i == $actionId } { set tooltipValue [concat $tooltipValue ""] set tooltipValue [concat $tooltipValue "⇒ "] } if { !["$this" getVar isFinishActionAvailable] || ($i != [expr ["$this" getVar numActions] -1]) } { set tooltipValue [concat $tooltipValue "Step [expr $i + 1]: "] } set tooltipValue [concat $tooltipValue [lindex ["$this" getVar infoList] $i]] # Current step in bold if { $i == $actionId } { set tooltipValue [concat $tooltipValue ""] } # New line before next step set tooltipValue [concat $tooltipValue "
"] } "$this" info setTooltip $tooltipValue } # ######################################################################### # Initialize common variables # ######################################################################### "$this" proc initCommonVar {} { if { !["$this" hasVar currentData] } {"$this" setVar currentData ["$this" data source]} if { !["$this" hasVar currentActionId] } {"$this" setVar currentActionId 0} if { !["$this" hasVar colorwash] } {"$this" setVar colorwash {}} if { !["$this" hasVar mainOrthoSlice] } {"$this" setVar mainOrthoSlice {}} if { !["$this" hasVar numActions] } {"$this" setVar numActions 0} if { !["$this" hasVar dataIs2D] } {"$this" setVar dataIs2D 1} if { !["$this" hasVar isFinishActionAvailable] } {"$this" setVar isFinishActionAvailable false} if { !["$this" hasVar hasNoBackOption] } {"$this" setVar hasNoBackOption false} if { !["$this" hasVar isColorwashVisible] } {"$this" setVar isColorwashVisible true} # Variable storing textual information "$this" setVar infoList [list] # Variable storing procedure names "$this" setVar procNames [list] # Variable storing skip enabled state, because skip feature can be disabled "$this" setVar skipEnabled [list] } # ######################################################################### # React on object renaming to update currentData Tcl variable if needed. # ######################################################################### "$this" proc objectRenamed {object oldName} { "$this" currentDataRenamed $object $oldName } "$this" proc currentDataRenamed {object oldName} { if { ["$this" hasVar currentData] && [string equal ["$this" getVar currentData] $oldName] } { "$this" setVar currentData $object } }