/*=============================================================================
Project: SharpImage
Module: siVolumeProperties.cs
Language: C#
Author: Dan Mueller
Date: $Date: 2008-01-09 16:23:10 +1000 (Wed, 09 Jan 2008) $
Revision: $Revision: 29 $
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.
=============================================================================*/
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.ComponentModel;
using System.Xml.Serialization;
using Tao.OpenGl;
using Tao.FreeGlut;
using Tao.Platform.Windows;
using SharpImage.Main;
using SharpImage.Forms;
namespace SharpImage.Rendering
{
///
/// Describes the different blending options.
///
public enum siVolumeBlendEnum
{
BackToFront,
MaximumProjection,
MinimumProjection,
}
///
/// Describes the different texture mapping geometry options.
///
public enum siVolumeGeometryEnum
{
ViewAlignedFill,
ViewAlignedSingle,
ViewAlignedSlab,
Orthogonal
}
///
/// Encapsulates properties for volume rendering.
///
public class siVolumeProperties
{
#region Instance Variables
//============================================================================
private siVolumeRenderer m_Renderer;
//============================================================================
#endregion
#region Construction and Disposal
//============================================================================
///
/// Constructor for serialization.
///
protected siVolumeProperties()
{
}
///
/// Default constructor.
///
public siVolumeProperties(siVolumeRenderer renderer)
{
this.m_Renderer = renderer;
this.UpdateToRenderer();
}
//============================================================================
#endregion
#region Properties
//============================================================================
#region Renderer
//=====================================================================
///
/// Get the renderer these properties are attached.
///
[System.Xml.Serialization.XmlIgnore]
protected siVolumeRenderer Renderer
{
get { return this.m_Renderer; }
}
//=====================================================================
#endregion
#region RepaintRenderer
//=====================================================================
private bool m_RepaintRenderer = true;
///
/// Get/set if the renderer is repainted when a property is changed.
///
[System.Xml.Serialization.XmlIgnore]
public bool RepaintRenderer
{
get { return this.Renderer != null && this.m_RepaintRenderer; }
set
{
this.m_RepaintRenderer = value;
if (value && this.Renderer != null)
this.Renderer.Repaint();
}
}
//=====================================================================
#endregion
#region BackColor
//=====================================================================
private Color m_BackColor = Color.White;
///
/// Gets/sets the background color of the Renderer window.
///
[Browsable(true)]
[Category("Color")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[System.Xml.Serialization.XmlIgnore]
public Color BackColor
{
get { return this.Renderer.BackColor; }
set
{
this.m_BackColor = value;
if (this.Renderer != null)
{
float[] back = siColorHelper.To4fv(value);
Gl.glClearColor(back[0], back[1], back[2], back[3]);
this.Renderer.BackColor = value;
}
if (this.RepaintRenderer)
{
this.Renderer.Repaint();
}
}
}
//=====================================================================
#endregion
#region ViewportSize
//=====================================================================
private Size m_ViewportSize = new Size(350, 350);
///
/// Gets/sets the viewport size.
///
[Browsable(true)]
[Category("Size and Transform")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public Size ViewportSize
{
get { return this.Renderer.ViewportSize; }
set
{
this.m_ViewportSize = value;
if (this.Renderer != null) this.Renderer.ViewportSize = value;
}
}
//=====================================================================
#endregion
#region BoxOutline
//=====================================================================
private bool m_BoxOutlineEnabled = true;
private Color m_BoxOutlineColor = Color.FromArgb(60, Color.Gray);
///
/// Gets/sets the RGB color of the outline box drawn around the the volume.
/// This property is used for user interaction. Use BoxOutlineColor to
/// set the RGBA color.
///
[Browsable(true)]
[Category("BoxOutline")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public bool BoxOutlineEnabled
{
get { return this.m_BoxOutlineEnabled; }
set
{
this.m_BoxOutlineEnabled = value;
if (this.RepaintRenderer) this.Renderer.Repaint();
}
}
///
/// Gets/sets the color of the outline box drawn around the the volume.
///
[Browsable(false)]
[System.Xml.Serialization.XmlIgnore]
public Color BoxOutlineColor
{
get { return this.m_BoxOutlineColor; }
set
{
this.m_BoxOutlineColor = value;
if (this.RepaintRenderer) this.Renderer.Repaint();
}
}
///
/// Gets/sets the RGB color of the outline box drawn around the the volume.
/// This property is used for user interaction. Use BoxOutlineColor to
/// set the RGBA color.
///
[Browsable(true)]
[Category("BoxOutline")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[System.Xml.Serialization.XmlIgnore]
public Color BoxOutlineColorRGB
{
get { return siColorHelper.ColorFromRgb(this.BoxOutlineColor); }
set { this.BoxOutlineColor = Color.FromArgb(this.BoxOutlineColor.A, value); }
}
///
/// Gets/sets the Alpha component of the outline box drawn around the the volume.
/// This property is used for user interaction. Use BoxOutlineColor to
/// set the RGBA color.
///
[Browsable(true)]
[Category("BoxOutline")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[System.Xml.Serialization.XmlIgnore]
public int BoxOutlineColorA
{
get { return this.BoxOutlineColor.A; }
set { this.BoxOutlineColor = Color.FromArgb(value, this.BoxOutlineColor); }
}
//=====================================================================
#endregion
#region gluLookAt
//=====================================================================
private double m_EyeX = 0.0;
private double m_EyeY = 0.0;
private double m_EyeZ = -7.5;
private double m_CenterX = 0.0;
private double m_CenterY = 0.0;
private double m_CenterZ = 0.0;
private double m_UpX = 0.0;
private double m_UpY = 1.0;
private double m_UpZ = 0.0;
///
/// Gets/sets the x-position to look at using Glu.gluLookAt.
///
[Browsable(false)]
public double EyeX
{
get { return this.m_EyeX; }
set { this.m_EyeX = value; }
}
///
/// Gets/sets the y-position to look at using Glu.gluLookAt.
///
[Browsable(false)]
public double EyeY
{
get { return this.m_EyeY; }
set { this.m_EyeY = value; }
}
///
/// Gets/sets the z-position to look at using Glu.gluLookAt.
///
[Browsable(false)]
public double EyeZ
{
get { return this.m_EyeZ; }
set { this.m_EyeZ = value; }
}
///
/// Gets/sets the Center x-position to look at using Glu.gluLookAt.
///
[Browsable(false)]
public double CenterX
{
get { return this.m_CenterX; }
set { this.m_CenterX = value; }
}
///
/// Gets/sets the Center y-position to look at using Glu.gluLookAt.
///
[Browsable(false)]
public double CenterY
{
get { return this.m_CenterY; }
set { this.m_CenterY = value; }
}
///
/// Gets/sets the Center z-position to look at using Glu.gluLookAt.
///
[Browsable(false)]
public double CenterZ
{
get { return this.m_CenterZ; }
set { this.m_CenterZ = value; }
}
///
/// Gets/sets the Up x-position to look at using Glu.gluLookAt.
///
[Browsable(false)]
public double UpX
{
get { return this.m_UpX; }
set { this.m_UpX = value; }
}
///
/// Gets/sets the Up y-position to look at using Glu.gluLookAt.
///
[Browsable(false)]
public double UpY
{
get { return this.m_UpY; }
set { this.m_UpY = value; }
}
///
/// Gets/sets the Up z-position to look at using Glu.gluLookAt.
///
[Browsable(false)]
public double UpZ
{
get { return this.m_UpZ; }
set { this.m_UpZ = value; }
}
//=====================================================================
#endregion
#region Frustrum
//=====================================================================
private double m_FrustrumLeft = 0.2;
private double m_FrustrumRight = -0.2;
private double m_FrustrumTop = 0.2;
private double m_FrustrumBottom = -0.2;
private double m_FrustrumFront = 1.0;
private double m_FrustrumBack = 20.0;
///
/// Gets/sets the left limit of the Frustrum.
///
[Browsable(true)]
[Category("Frustrum")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public double FrustrumLeft
{
get { return this.m_FrustrumLeft; }
set
{
if (this.Renderer != null) this.Renderer.Metadata["FrustrumLeft"] = value;
this.m_FrustrumLeft = value;
}
}
///
/// Gets/sets the right limit of the Frustrum.
///
[Browsable(true)]
[Category("Frustrum")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public double FrustrumRight
{
get { return this.m_FrustrumRight; }
set
{
if (this.Renderer != null) this.Renderer.Metadata["FrustrumRight"] = value;
this.m_FrustrumRight = value;
}
}
///
/// Gets/sets the top limit of the Frustrum.
///
[Browsable(true)]
[Category("Frustrum")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public double FrustrumTop
{
get { return this.m_FrustrumTop; }
set
{
if (this.Renderer != null) this.Renderer.Metadata["FrustrumTop"] = value;
this.m_FrustrumTop = value;
}
}
///
/// Gets/sets the bottom limit of the Frustrum.
///
[Browsable(true)]
[Category("Frustrum")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public double FrustrumBottom
{
get { return this.m_FrustrumBottom; }
set
{
if (this.Renderer != null) this.Renderer.Metadata["FrustrumBottom"] = value;
this.m_FrustrumBottom = value;
}
}
///
/// Gets/sets the front limit of the Frustrum.
///
[Browsable(true)]
[Category("Frustrum")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public double FrustrumFront
{
get { return this.m_FrustrumFront; }
set
{
if (this.Renderer != null) this.Renderer.Metadata["FrustrumFront"] = value;
this.m_FrustrumFront = value;
}
}
///
/// Gets/sets the back limit of the Frustrum.
///
[Browsable(true)]
[Category("Frustrum")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public double FrustrumBack
{
get { return this.m_FrustrumBack; }
set
{
if (this.Renderer != null) this.Renderer.Metadata["FrustrumBack"] = value;
this.m_FrustrumBack = value;
}
}
//=====================================================================
#endregion
#region Transforms
//=====================================================================
private itk.itkVector m_TransformTranslate = new itk.itkVector(0.0, 0.0, 0.0);
private siTrackBall m_TrackBall = new siTrackBall();
///
/// Gets/sets the translation vector.
///
[ReadOnly(true)]
[Browsable(true)]
[Category("Size and Transform")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[System.Xml.Serialization.XmlIgnore]
public itk.itkVector TransformTranslate
{
get { return this.m_TransformTranslate; }
set { this.m_TransformTranslate = value; }
}
///
/// Gets/sets the trackball.
///
[Browsable(false)]
[System.Xml.Serialization.XmlIgnore]
public siTrackBall TrackBall
{
get { return this.m_TrackBall; }
set { this.m_TrackBall = value; }
}
///
/// Gets the rotation transform.
/// This property is used for user interaction.
///
//[ReadOnly(true)]
[Browsable(true)]
[Category("Size and Transform")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[TypeConverter(typeof(itkVectorTypeConverter))]
[System.Xml.Serialization.XmlIgnore]
public itk.itkVector TransformRotation
{
get { return new itk.itkVector(this.TrackBall.GetRotationMatrixAsArray()); }
set
{
itk.itkMatrix matrix = new itk.itkMatrix(3, 3);
for (uint r = 0; r < 3; r++)
for (uint c = 0; c < 3; c++)
matrix[r, c] = value[(int)(r * 4 + c)];
this.TrackBall.RotationMatrix = matrix;
if (this.RepaintRenderer) this.Renderer.Repaint();
}
}
//=====================================================================
#endregion
#region ModelSize
//=====================================================================
private itk.itkArray m_ModelSize = new itk.itkArray(1.0,1.0,1.0);
///
/// Gets/sets the size of the model in model space.
/// The model size would be [1.0, 1.0, 1.0] for an image with
/// spacing equalling [1.0, 1.0, 1.0].
///
[ReadOnly(true)]
[Browsable(true)]
[Category("Size and Transform")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[System.Xml.Serialization.XmlIgnore]
public itk.itkArray ModelSize
{
get { return this.m_ModelSize; }
set { this.m_ModelSize = value; }
}
//=====================================================================
#endregion
#region FragmentProgramPath
//=====================================================================
private string m_FragmentProgramPath = String.Empty;
[Browsable(true)]
[Category("Rendering")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[Editor(typeof(siOpenFilenameEditor), typeof(UITypeEditor))]
[TypeConverter(typeof(siOpenFilenameTypeConverter))]
[siFilenameEditorFilter("Fragment Shader Program Files (*.frag)|*.frag")]
[System.Xml.Serialization.XmlIgnore]
public String FragmentProgramPath
{
get
{
if (this.Renderer != null && this.Renderer.Shader != null)
return this.Renderer.Shader.FragmentProgramPath;
else
return string.Empty;
}
set
{
this.m_FragmentProgramPath = value;
if (this.Renderer != null &&
value != null &&
value.Length > 0 &&
File.Exists(value))
this.Renderer.SetShader(value);
if (this.RepaintRenderer) this.Renderer.Repaint();
}
}
//=====================================================================
#endregion
#region WireFrame
//=====================================================================
private bool m_WireFrame = false;
///
/// Gets/sets if the texture geometry is rendered as a wire frame.
///
[Browsable(true)]
[Category("Rendering")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public bool WireFrame
{
get { return this.m_WireFrame; }
set
{
this.m_WireFrame = value;
if (this.RepaintRenderer) this.Renderer.Repaint();
}
}
//=====================================================================
#endregion
#region Lighting
//=====================================================================
private Color m_LightColorAmbient = Color.White;
private Color m_LightColorDiffuse = Color.White;
private Color m_LightColorSpecular = Color.White;
private float m_LightColorSpecularExponent = 2.0f;
private float m_NormalOffset = 0.0396f;
///
/// Gets/sets the ambient color of Light0.
///
[Browsable(false)]
[Category("Lighting")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[System.Xml.Serialization.XmlIgnore]
public Color LightColorAmbient
{
get { return this.m_LightColorAmbient; }
set { this.m_LightColorAmbient = value; }
}
///
/// Gets/sets the ambient color.A of Light0.
///
[Browsable(true)]
[Category("Lighting")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[System.Xml.Serialization.XmlIgnore]
public int LightColorAmbientA
{
get { return this.m_LightColorAmbient.A; }
set
{
Color colorOld = this.m_LightColorAmbient;
Color colorNew = Color.FromArgb(value, colorOld);
this.m_LightColorAmbient = colorNew;
if (this.RepaintRenderer) this.Renderer.Repaint();
}
}
///
/// Gets/sets the ambient color.RGB of Light0.
///
[Browsable(true)]
[Category("Lighting")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[System.Xml.Serialization.XmlIgnore]
public Color LightColorAmbientRGB
{
get { return siColorHelper.ColorFromRgb(this.m_LightColorAmbient); }
set
{
Color colorNew = Color.FromArgb(this.LightColorAmbientA, value);
this.m_LightColorAmbient = colorNew;
if (this.RepaintRenderer) this.Renderer.Repaint();
}
}
///
/// Gets/sets the diffuse color of Light0.
///
[Browsable(false)]
[Category("Lighting")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[System.Xml.Serialization.XmlIgnore]
public Color LightColorDiffuse
{
get { return this.m_LightColorDiffuse; }
set
{
this.m_LightColorDiffuse = value;
if (this.RepaintRenderer) this.Renderer.Repaint();
}
}
///
/// Gets/sets the diffuse color.A of Light0.
///
[Browsable(true)]
[Category("Lighting")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[System.Xml.Serialization.XmlIgnore]
public int LightColorDiffuseA
{
get { return this.m_LightColorDiffuse.A; }
set
{
Color colorOld = this.m_LightColorDiffuse;
Color colorNew = Color.FromArgb(value, colorOld);
this.m_LightColorDiffuse = colorNew;
if (this.RepaintRenderer) this.Renderer.Repaint();
}
}
///
/// Gets/sets the diffuse color.RGB of Light0.
///
[Browsable(true)]
[Category("Lighting")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[System.Xml.Serialization.XmlIgnore]
public Color LightColorDiffuseRGB
{
get { return siColorHelper.ColorFromRgb(this.m_LightColorDiffuse); }
set
{
Color colorNew = Color.FromArgb(this.LightColorDiffuseA, value);
this.m_LightColorDiffuse = colorNew;
if (this.RepaintRenderer) this.Renderer.Repaint();
}
}
///
/// Gets/sets the specular color of Light0.
///
[Browsable(false)]
[Category("Lighting")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[System.Xml.Serialization.XmlIgnore]
public Color LightColorSpecular
{
get { return this.m_LightColorSpecular; }
set
{
this.m_LightColorSpecular = value;
if (this.RepaintRenderer) this.Renderer.Repaint();
}
}
///
/// Gets/sets the specular color.A of Light0.
///
[Browsable(true)]
[Category("Lighting")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[System.Xml.Serialization.XmlIgnore]
public int LightColorSpecularA
{
get { return this.m_LightColorSpecular.A; }
set
{
Color colorOld = this.m_LightColorSpecular;
Color colorNew = Color.FromArgb(value, colorOld);
this.m_LightColorSpecular = colorNew;
if (this.RepaintRenderer) this.Renderer.Repaint();
}
}
///
/// Gets/sets the specular color.RGB of Light0.
///
[Browsable(true)]
[Category("Lighting")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[System.Xml.Serialization.XmlIgnore]
public Color LightColorSpecularRGB
{
get { return siColorHelper.ColorFromRgb(this.m_LightColorSpecular); }
set
{
Color colorNew = Color.FromArgb(this.LightColorSpecularA, value);
this.m_LightColorSpecular = colorNew;
if (this.RepaintRenderer) this.Renderer.Repaint();
}
}
///
/// Gets/sets the specular exponent.
///
[Browsable(true)]
[Category("Lighting")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public float LightColorSpecularExponent
{
get { return this.m_LightColorSpecularExponent; }
set
{
this.m_LightColorSpecularExponent = value;
if (this.RepaintRenderer) this.Renderer.Repaint();
}
}
///
/// Gets/sets the offset for computing the normal.
///
[Browsable(true)]
[Category("Lighting")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public float NormalOffset
{
get { return this.m_NormalOffset; }
set
{
// Save the value
this.m_NormalOffset = value;
// Set the value in the sahder
if (this.Renderer != null && this.Renderer.ContainsMetadata("Shader"))
this.Renderer.Shader.SetUniformFloat("fNormalOffset", value);
if (this.RepaintRenderer)
this.Renderer.Repaint();
}
}
//=====================================================================
#endregion
#region Factors
//=====================================================================
private float m_Factor1 = 0.0f;
private float m_Factor2 = 0.0f;
private float m_Factor3 = 0.0f;
///
/// Gets/sets the factor.
///
[Browsable(true)]
[Category("Enhancement")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public float Factor1
{
get { return this.m_Factor1; }
set
{
// Save the value
this.m_Factor1 = value;
// Set the value in the sahder
if (this.Renderer != null && this.Renderer.ContainsMetadata("Shader"))
{
this.Renderer.Shader.SetUniformFloat("fFactor1", value);
}
// Repaint
if (this.RepaintRenderer)
{
this.Renderer.RaiseModified();
this.Renderer.Repaint();
}
}
}
///
/// Gets/sets the factor.
///
[Browsable(true)]
[Category("Enhancement")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public float Factor2
{
get { return this.m_Factor2; }
set
{
// Save the value
this.m_Factor2 = value;
// Set the value in the sahder
if (this.Renderer != null && this.Renderer.ContainsMetadata("Shader"))
{
this.Renderer.Shader.SetUniformFloat("fFactor2", value);
}
// Repaint
if (this.RepaintRenderer)
{
this.Renderer.RaiseModified();
this.Renderer.Repaint();
}
}
}
///
/// Gets/sets the factor.
///
[Browsable(true)]
[Category("Enhancement")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public float Factor3
{
get { return this.m_Factor3; }
set
{
// Save the value
this.m_Factor3 = value;
// Set the value in the sahder
if (this.Renderer != null && this.Renderer.ContainsMetadata("Shader"))
{
this.Renderer.Shader.SetUniformFloat("fFactor3", value);
}
// Repaint
if (this.RepaintRenderer)
{
this.Renderer.RaiseModified();
this.Renderer.Repaint();
}
}
}
//=====================================================================
#endregion
#region SamplingRate
//=====================================================================
private siSamplingRate m_SamplingRate = new siSamplingRate(0.5F, 1.5F);
///
/// Gets/sets the volume sampling rate. A value of 1.0 means that one
/// texture-geometry polygon will pass through each voxel.
///
[ReadOnly(true)]
[Browsable(true)]
[Category("Rendering")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
[TypeConverter(typeof(ExpandableObjectConverter))]
public siSamplingRate SamplingRate
{
get { return this.m_SamplingRate; }
set { this.m_SamplingRate = value; }
}
//=====================================================================
#endregion
#region Blending
//=====================================================================
private siVolumeBlendEnum m_Blending = siVolumeBlendEnum.BackToFront;
///
/// Gets/sets the blending type.
///
[Browsable(true)]
[Category("Rendering")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public siVolumeBlendEnum Blending
{
get { return this.m_Blending; }
set
{
// Set the value
this.m_Blending = value;
// Force the background colour
if (value == siVolumeBlendEnum.MaximumProjection)
this.BackColor = Color.Black;
else if (value == siVolumeBlendEnum.MinimumProjection)
this.BackColor = Color.White;
// Repaint
if (this.RepaintRenderer) this.Renderer.Repaint();
}
}
//=====================================================================
#endregion
#region Geometry
//=====================================================================
private siVolumeGeometryEnum m_GeometryType = siVolumeGeometryEnum.ViewAlignedFill;
///
/// Gets/sets the blending type.
///
[Browsable(true)]
[Category("Rendering")]
[ParenthesizePropertyName(false)]
[RefreshProperties(RefreshProperties.All)]
public siVolumeGeometryEnum GeometryType
{
get
{
if (this.Renderer.GeometryGenerator != null)
return this.Renderer.GeometryGenerator.GeometryType;
else
return siVolumeGeometryEnum.ViewAlignedFill;
}
set
{
this.m_GeometryType = value;
if (this.Renderer != null && this.Renderer.GeometryGenerator != null)
this.Renderer.GeometryGenerator.GeometryType = value;
if (this.RepaintRenderer)
this.Renderer.Repaint();
}
}
//=====================================================================
#endregion
//============================================================================
#endregion
#region Serialization Properties
//============================================================================
///
/// This method is needed for serialization.
/// It is not intended for general use.
///
[System.ComponentModel.Browsable(false)]
public virtual string SerializableBackColor
{
get { return siColorHelper.SerializeColor(this.BackColor); }
set { this.BackColor = siColorHelper.DeserializeColor(value); }
}
///
/// This method is needed for serialization.
/// It is not intended for general use.
///
[System.ComponentModel.Browsable(false)]
public virtual string SerializableBoxOutlineColor
{
get { return siColorHelper.SerializeColor(this.BoxOutlineColor); }
set { this.BoxOutlineColor = siColorHelper.DeserializeColor(value); }
}
///
/// This method is needed for serialization.
/// It is not intended for general use.
///
[System.ComponentModel.Browsable(false)]
public virtual string SerializableLightColorAmbient
{
get { return siColorHelper.SerializeColor(this.LightColorAmbient); }
set { this.LightColorAmbient = siColorHelper.DeserializeColor(value); }
}
///
/// This method is needed for serialization.
/// It is not intended for general use.
///
[System.ComponentModel.Browsable(false)]
public virtual string SerializableLightColorDiffuse
{
get { return siColorHelper.SerializeColor(this.LightColorDiffuse); }
set { this.LightColorDiffuse = siColorHelper.DeserializeColor(value); }
}
///
/// This method is needed for serialization.
/// It is not intended for general use.
///
[System.ComponentModel.Browsable(false)]
public virtual string SerializableLightColorSpecular
{
get { return siColorHelper.SerializeColor(this.LightColorSpecular); }
set { this.LightColorSpecular = siColorHelper.DeserializeColor(value); }
}
///
/// This method is needed for serialization.
/// It is not intended for general use.
///
[System.ComponentModel.Browsable(false)]
public virtual string SerializableTransformTranslate
{
get { return this.SerializeVector(this.TransformTranslate); }
set { this.TransformTranslate = this.DeserializeVector(value); }
}
///
/// This method is needed for serialization.
/// It is not intended for general use.
///
[System.ComponentModel.Browsable(false)]
public virtual string SerializableTransformRotation
{
get { return this.SerializeVector(this.TransformRotation); }
set { this.TransformRotation = this.DeserializeVector(value); }
}
///
/// This method is needed for serialization.
/// It is not intended for general use.
///
[System.ComponentModel.Browsable(false)]
public virtual string SerializableFragmentProgramPath
{
get
{
string shortpath = this.FragmentProgramPath.Replace(Application.StartupPath, "");
return shortpath.Trim(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
}
set { this.FragmentProgramPath = Path.Combine(Application.StartupPath, value); }
}
//============================================================================
#endregion
#region Serialization Methods
//=====================================================================
///
/// Serializes this object to the given path.
///
/// The absolute path and name of the file to create with the serialized object.
public void ToXmlFile(string filePath)
{
// Ensure the filePath is valid
if (filePath == null || filePath.Length == 0)
throw new ArgumentNullException("filePath", "The file path to serialize the Volume Properties can not be null or empty.");
// Ensure the directory exists
if (!Directory.Exists(Path.GetDirectoryName(filePath)))
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
// Serialize
XmlSerializer serializer = new XmlSerializer(typeof(siVolumeProperties));
FileStream stream = File.Create(filePath);
serializer.Serialize(stream, this);
stream.Flush();
stream.Close();
stream.Dispose();
}
///
/// Deserializes this object from the given path.
///
/// The absolute path and name of the file to deserialize the object from.
///
public static siVolumeProperties FromXmlFile(siVolumeRenderer renderer, string filePath)
{
// Ensure the filePath is valid
if (filePath == null || filePath.Length == 0)
throw new ArgumentNullException("filePath", "The file path to serialize the Volume Properties can not be null or empty.");
if (!File.Exists(filePath))
throw new FileNotFoundException("The file path to deserialize the Volume Properties was not found.", filePath);
// Deserialize
XmlSerializer serializer = new XmlSerializer(typeof(siVolumeProperties));
FileStream stream = File.OpenRead(filePath);
siVolumeProperties result = (siVolumeProperties)serializer.Deserialize(stream);
// Finish
result.m_Renderer = renderer;
result.UpdateToRenderer();
// Clean up
stream.Flush();
stream.Close();
stream.Dispose();
// Return
return result;
}
//=====================================================================
#endregion
#region Public Methods
//============================================================================
///
/// Computes the size of the model from the first input object.
///
///
public void ComputeModelSize()
{
// Create result
this.m_ModelSize = new itk.itkArray(3U);
// Check if the renderer has an input
if (this.Renderer == null ||
this.Renderer.Inputs.Count == 0)
{
return;
}
// Get the input
itk.itkDataObject data = this.Renderer.Inputs[0];
// Compute the model size different for images and spatial objects
if (data is itk.itkImageBase)
{
// Input is image
itk.itkImageBase dataAsImage = data as itk.itkImageBase;
if (dataAsImage.Spacing[0] == dataAsImage.Spacing[1])
{
m_ModelSize[0] = 1.0;
m_ModelSize[1] = 1.0;
m_ModelSize[2] = dataAsImage.PhysicalSize[2] / dataAsImage.PhysicalSize[0];
}
else if (dataAsImage.Spacing[1] == dataAsImage.Spacing[2])
{
m_ModelSize[0] = dataAsImage.PhysicalSize[0] / dataAsImage.PhysicalSize[1];
m_ModelSize[1] = 1.0;
m_ModelSize[2] = 1.0;
}
else if (dataAsImage.Spacing[0] == dataAsImage.Spacing[2])
{
m_ModelSize[0] = 1.0;
m_ModelSize[1] = dataAsImage.PhysicalSize[1] / dataAsImage.PhysicalSize[0];
m_ModelSize[2] = 1.0;
}
else
{
// Assume dimension 0 is the master dimension
m_ModelSize[0] = 1.0;
m_ModelSize[1] = dataAsImage.PhysicalSize[1] / dataAsImage.PhysicalSize[0];
m_ModelSize[2] = dataAsImage.PhysicalSize[2] / dataAsImage.PhysicalSize[0];
}
}
else if (data is itk.itkSpatialObjectBase)
{
// Input is spatial object
itk.itkSpatialObjectBase sobject = data as itk.itkSpatialObjectBase;
if (sobject.Spacing[0] == sobject.Spacing[1])
{
m_ModelSize[0] = 1.0;
m_ModelSize[1] = 1.0;
m_ModelSize[2] = sobject.Spacing[2] / sobject.Spacing[0];
}
else if (sobject.Spacing[1] == sobject.Spacing[2])
{
m_ModelSize[0] = sobject.Spacing[0] / sobject.Spacing[1];
m_ModelSize[1] = 1.0;
m_ModelSize[2] = 1.0;
}
else if (sobject.Spacing[0] == sobject.Spacing[2])
{
m_ModelSize[0] = 1.0;
m_ModelSize[1] = sobject.Spacing[1] / sobject.Spacing[0];
m_ModelSize[2] = 1.0;
}
else
{
// Assume dimension 0 is the master dimension
m_ModelSize[0] = 1.0;
m_ModelSize[1] = sobject.Spacing[1] / sobject.Spacing[0];
m_ModelSize[2] = sobject.Spacing[2] / sobject.Spacing[0];
}
}
else if (data is siDataObjectDecorator)
{
// Input is spatial object
siDataObjectDecorator decorator = data as siDataObjectDecorator;
if (decorator.Spacing[0] == decorator.Spacing[1])
{
m_ModelSize[0] = 1.0;
m_ModelSize[1] = 1.0;
m_ModelSize[2] = decorator.Spacing[2] / decorator.Spacing[0];
}
else if (decorator.Spacing[1] == decorator.Spacing[2])
{
m_ModelSize[0] = decorator.Spacing[0] / decorator.Spacing[1];
m_ModelSize[1] = 1.0;
m_ModelSize[2] = 1.0;
}
else if (decorator.Spacing[0] == decorator.Spacing[2])
{
m_ModelSize[0] = 1.0;
m_ModelSize[1] = decorator.Spacing[1] / decorator.Spacing[0];
m_ModelSize[2] = 1.0;
}
else
{
// Assume dimension 0 is the master dimension
m_ModelSize[0] = 1.0;
m_ModelSize[1] = decorator.Spacing[1] / decorator.Spacing[0];
m_ModelSize[2] = decorator.Spacing[2] / decorator.Spacing[0];
}
}
}
//============================================================================
#endregion
#region Private Methods
//============================================================================
private void UpdateToRenderer()
{
this.BackColor = this.m_BackColor;
this.FrustrumLeft = this.m_FrustrumLeft;
this.FrustrumRight = this.m_FrustrumRight;
this.FrustrumTop = this.m_FrustrumTop;
this.FrustrumBottom = this.m_FrustrumBottom;
this.FrustrumFront = this.m_FrustrumFront;
this.FrustrumBack = this.m_FrustrumBack;
if (this.m_FragmentProgramPath != null && this.m_FragmentProgramPath.Length > 0)
this.FragmentProgramPath = this.m_FragmentProgramPath;
this.NormalOffset = this.m_NormalOffset;
this.Factor1 = this.m_Factor1;
this.Factor2 = this.m_Factor2;
this.Factor3 = this.m_Factor3;
this.GeometryType = this.m_GeometryType;
this.ViewportSize = this.m_ViewportSize;
this.SamplingRate.Changed += new siSamplingRate.siSamplingRateHandler(this.Renderer.SamplingRateChanged);
this.ComputeModelSize();
this.Renderer.Repaint();
}
private itk.itkVector DeserializeVector(string vector)
{
vector = vector.Trim('[', ']');
string[] split = vector.Split(new char[] { ',' });
itk.itkVector result = new itk.itkVector((uint)split.Length);
for (int i = 0; i < split.Length; i++)
result[i] = Double.Parse(split[i]);
return result;
}
private string SerializeVector(itk.itkVector vector)
{
string result = string.Empty;
for (int i = 0; i < vector.Length; i++)
result += vector[i].ToString("0.0###") + ", ";
return result.TrimEnd(' ', ',');
}
//============================================================================
#endregion
}
}