#============================================================================== # # Project: SharpImage # Module: VolumeRender.py # Language: IronPython # Author: Dan Mueller # Date: $Date: 2007-07-13 06:30:23 +1000 (Fri, 13 Jul 2007) $ # Revision: $Revision: 8 $ # # Copyright (c) Queensland University of Technology (QUT) 2007. # All rights reserved. # # This software is distributed WITHOUT ANY WARRANTY; without even # the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # PURPOSE. See the above copyright notices for more information. # #============================================================================== # Import the base script class import Script from Script import * clr.AddReference("Tao.OpenGl") from Tao.OpenGl import * from System import String class VolumeRenderScript(ScriptObject): # ------------------------------------------------------------------------- Name = "VolumeRender" Help = """Performs 3D texture-based volume rendering. If image absolute filepaths are provided, the type must be specifed with a trailing #Type (eg. #SS3). Example: VolumeRender Value="C:/temp/Value.mhd#SS3" Gradient="C:/temp/Gradient.mhd#UC3" - or - VolumeRender Value="Value" Gradient="Gradient\"""" Parameters = """(string) Value = the absolute filepath or pattern for the 'value' image. ("Value") (string) Gradient = the absolute filepath or pattern for the 'gradient' image. ("Gradient") (string) Extra1 = the absolute filepath or pattern for the 'extra1' image. (None) (string) Extra2 = the absolute filepath or pattern for the 'extra2' image. (None) (siTransferFunction) Tf = the starting transfer function. (siTransferFunction(size)) (string) TfBackground = the backgound image for the transfer function. ("Histogram")""" Value = "Value" Gradient = "Gradient" Extra1 = None Extra2 = None Tf = None TfBackground = "Histogram" TfEditor = None Renderer = None RendererEditor = None IllustrationEditor = None # ------------------------------------------------------------------------- def Run(self): """ The entry-point for this script. """ try: self.Initialise() self.DoWork() except Exception, ex: self.HandleException( ex ) self.FinishedWork( False ) self.Finalise() def Initialise(self): """ Initialise the environment for running this script. """ """ NOTE: This function is invoked on the main UI thread. """ try: # Initialise the base class ScriptObject.Initialise( self ) except Exception, ex: self.HandleException( ex ) self.FinishedWork( False ) self.Finalise( ) def DoWork(self): """ Perform the main functions of the script. """ """ NOTE: This function is invoked on the main UI thread. """ try: self.StartedWork() # Create the renderer self.Renderer = siVolumeRenderer( self.ParentApplication ) programVert = Path.Combine( Path.GetDirectoryName(self.FilePath), "shader-vm.vert" ) programFrag = Path.Combine( Path.GetDirectoryName(self.FilePath), "shader-vm.frag" ) self.Renderer.Metadata["VertexProgram"] = programVert self.Renderer.Metadata["FragmentProgram"] = programFrag # Get the value image if (self.Value != None and Path.IsPathRooted(self.Value)): self.Value = self.ParentApplication.OpenImage( self.Value ) elif (self.Value != None): self.Value = self.GetOpenImageMatchingPattern( self.Value ) if (self.Value == None): raise ArgumentException( "A value image must be provided." ) else: self.Value.Metadata["Value"] = True self.Value.Metadata["TextureInterpolation"] = Gl.GL_LINEAR self.Renderer.Inputs.Add( self.Value ) # Get the gradient magnitude image if (self.Gradient != None and Path.IsPathRooted(self.Gradient)): self.Gradient = self.ParentApplication.OpenImage( self.Gradient ) elif (self.Gradient != None): self.Gradient = self.GetOpenImageMatchingPattern( self.Gradient ) if (self.Gradient != None): self.Gradient.Metadata["Gradient"] = True self.Gradient.Metadata["TextureInterpolation"] = Gl.GL_LINEAR self.Renderer.Inputs.Add( self.Gradient ) # Get the extra1 image if (self.Extra1 != None and Path.IsPathRooted(self.Extra1)): self.Extra1 = self.ParentApplication.OpenImage( self.Extra1 ) elif (self.Extra1 != None): self.Extra1 = self.GetOpenImageMatchingPattern( self.Extra1 ) if (self.Extra1 != None): self.Extra1.Metadata["Extra1"] = True self.Extra1.Metadata["TextureInterpolation"] = Gl.GL_NEAREST self.Renderer.Inputs.Add( self.Extra1 ) # Get the extra2 image if (self.Extra2 != None and Path.IsPathRooted(self.Extra2)): self.Extra2 = self.ParentApplication.OpenImage( self.Extra2 ) elif (self.Extra2 != None): self.Extra2 = self.GetOpenImageMatchingPattern( self.Extra2 ) if (self.Extra2 != None): self.Extra2.Metadata["Extra2"] = True self.Extra2.Metadata["TextureInterpolation"] = Gl.GL_NEAREST self.Renderer.Inputs.Add( self.Extra2 ) # Setup the transfer function if (self.Tf == None): if (self.Value.PixelType.IsChar): tfSize0 = 256 else: tfSize0 = 512 tfSize1 = 128; if (self.Extra1 == None): self.Tf = siTransferFunction( itkSize(tfSize0,tfSize1) ) else:self.Tf = siTransferFunction( itkSize(tfSize0,tfSize1), "All", "Tag1", "Tag2", "Tag3", "Tag4", "Tag5", "Tag6", "Tag7" ) self.TfEditor = siFormTransferFunctionEditor( self.Tf ) self.Renderer.Metadata["TransferFunction"] = self.Tf self.Renderer.Closed += self.TfEditor.OnRendererClosed # Get the transfer function background image if (self.TfBackground != None and Path.IsPathRooted(self.TfBackground)): self.TfBackground = self.ParentApplication.OpenImage( self.TfBack ) elif (self.TfBackground != None): self.TfBackground = self.GetOpenImageMatchingPattern( self.TfBackground ) if (self.TfBackground != None): self.Tf.BackgroundImage = self.TfBackground # Show the forms self.Renderer.Initialise() self.RendererEditor = siFormRendererEditor( self.Renderer ) self.IllustrationEditor = siFormVariableSlider( self.Value ) self.IllustrationEditor.AddVariable( "Factor1", 0.00, 0.0, 10.0, 0.01 ) self.IllustrationEditor.AddVariable( "Factor2", 0.50, 0.0, 1.0, 0.001 ) self.IllustrationEditor.AddVariable( "Factor3", 0.25, 0.0, 1.0, 0.001 ) self.IllustrationEditor.ValueStringFormat = "00.000" self.IllustrationEditor.Initialise( ) self.IllustrationEditor.VariableChanged += self.VariableChangedHandler self.Renderer.Closed += self.IllustrationEditor.OnRendererClosed self.ParentApplication.AddTool( self.TfEditor ) self.ParentApplication.AddTool( self.RendererEditor ) self.ParentApplication.AddTool( self.IllustrationEditor ) self.ParentApplication.ShowRenderer( self.Renderer ) # Finish self.FinishedWork( True ) self.Finalise( ) except Exception, ex: self.HandleException( ex ) self.FinishedWork( False ) self.Finalise( ) def VariableChangedHandler(self, name, variables): """ Handle the self.IllustrationEditor.VariableChanged event. """ self.Renderer.Properties.Factor1 = variables["Factor1"] self.Renderer.Properties.Factor2 = variables["Factor2"] self.Renderer.Properties.Factor3 = variables["Factor3"]