/*============================================================================= Project: SharpImage Module: siSceneSpatialObject.cs Language: C# Author: Dan Mueller Date: $Date: 2007-07-06 10:57:00 +1000 (Fri, 06 Jul 2007) $ Revision: $Revision: 2 $ 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.Collections.Generic; using System.Text; using SharpImage.Rendering; namespace SharpImage.SpatialObject { public class siSceneSpatialObject : siSpatialObject { #region Constants //===================================================================== private const string MET_SCENE_OBJECT_TYPE = MET_OBJECT_TYPE + "Scene"; private const string MET_NUM_OBJECTS = "NObjects = "; //===================================================================== #endregion #region Instance Variables //===================================================================== private int m_ExpectedNumberOfObjects = 0; private int m_CurrentObject = 0; //===================================================================== #endregion #region Construction and Disposal //===================================================================== /// /// Protected constructor. /// protected siSceneSpatialObject() { } /// /// Static factory constructor. /// /// public static siSceneSpatialObject New() { return new siSceneSpatialObject(); } //===================================================================== #endregion #region Properties //===================================================================== #region CurrentLine //===================================================================== private int m_CurrentLine = 0; private int CurrentLine { get { return this.m_CurrentLine; } } //===================================================================== #endregion #region MetaLines //===================================================================== private string[] m_MetaLines; private string[] MetaLines { get { return this.m_MetaLines; } } //===================================================================== #endregion //===================================================================== #endregion #region Public Methods //===================================================================== /// /// Read the scene spatial object from a meta file (*.mhd). /// /// public override void Read(string filename) { // Check filename is valid if (filename != null && filename.Length > 0 && File.Exists(filename)) { // Set the name this.Name = filename; // Read the file as lines this.m_MetaLines = File.ReadAllLines(filename); // Read header info this.ReadSceneObjectType(); this.ReadNumDims(); this.ReadNumObjects(); while (this.m_CurrentObject < this.m_ExpectedNumberOfObjects) { string objectType = this.ParseObjectType(this.PeekCurrentLine()); if (objectType == "Group") this.ReadGroup(); else if (objectType == "Tube") this.ReadTube(); else if (objectType == null) // Reached the end of the file, stop reading this.m_CurrentObject = this.m_ExpectedNumberOfObjects; else throw new FileLoadException("Unknown object type: " + objectType); this.m_CurrentObject++; } } else { throw new FileNotFoundException("The given meta filename is not valid.", filename); } } /// /// Write the scene spatial object to a meta file (*.mhd). /// /// public override void Write(string filename) { // Check filename is valid if (filename != null && filename.Length > 0 && File.Exists(filename)) { // Set the name this.Name = filename; // Write to the file // TODO: throw new NotImplementedException("siSpatialObject.Write() is not yet implemented!"); } else { throw new FileNotFoundException("The given meta filename is not valid.", filename); } } /// /// Renders the spatial object using OpenGL. /// /// The renderer this spatial object is being renderered to. public override void Render(siRenderer renderer) { foreach (siSpatialObject child in this.Children) child.Render(renderer); } /// /// Initialises the spatial object for rendering. /// public override void Initialise(siRenderer renderer) { foreach (siSpatialObject child in this.Children) child.Initialise(renderer); } /// /// Return a string reprentation of the scene spatial object. /// /// public override string ToString() { string result = "GroupSpatialObject: NObjects = " + this.Children.Count.ToString() + Environment.NewLine; foreach (siSpatialObject child in this.Children) result += child.ToString() + Environment.NewLine; return result; } //===================================================================== #endregion #region Private Methods //===================================================================== private string ReadCurrentLine() { if (this.CurrentLine < this.MetaLines.Length) { string result = this.MetaLines[this.CurrentLine]; this.m_CurrentLine++; return result; } else return null; } private string PeekCurrentLine() { if (this.CurrentLine < this.MetaLines.Length) return this.MetaLines[this.CurrentLine]; else return null; } private void ReadSceneObjectType() { string line = this.ReadCurrentLine(); if (line != MET_SCENE_OBJECT_TYPE) throw new FileLoadException("Could not find scene object type: expecting '" + MET_SCENE_OBJECT_TYPE + "', found '" + line + "'."); } private void ReadNumDims() { string line = this.ReadCurrentLine(); if (line != MET_NUM_DIMS + "3") throw new FileLoadException("Could not read number of dimensions: expecting '" + MET_NUM_DIMS + "3" + "', found '" + line + "'."); } private void ReadNumObjects() { string line = this.ReadCurrentLine(); if (!line.StartsWith(MET_NUM_OBJECTS)) throw new FileLoadException("Could not read number of objects: expecting '" + MET_NUM_OBJECTS + "X" + "', but found '" + line + "'."); try { this.m_ExpectedNumberOfObjects = Int32.Parse(line.Replace(MET_NUM_OBJECTS, "")); this.m_CurrentObject = 0; } catch (Exception ex) { throw new FileLoadException("Could not read number of objects: expecting '" + MET_NUM_OBJECTS + "X" + "', but found '" + line + "'.", ex); } } private string ParseObjectType(string line) { if (line != null && line.Length > 0) return line.Replace(MET_OBJECT_TYPE, ""); else return null; } private void ReadGroup() { // Consume all group objects - we don't want them string line = this.ReadCurrentLine(); while (!line.StartsWith("EndGroup =") && line != null) line = this.ReadCurrentLine(); } private void ReadTube() { List tubeLines = new List(); string line = this.ReadCurrentLine(); // Read the object type line = this.ReadCurrentLine(); // Read the next line tubeLines.Add(line); while (line != null && !line.StartsWith(MET_OBJECT_TYPE)) { line = this.ReadCurrentLine(); tubeLines.Add(line); } // Back track to have the current line point to the object type if (line != null) this.m_CurrentLine--; // Parse the tube siTubeSpatialObject tube = siTubeSpatialObject.Parse(tubeLines.ToArray()); if (tube != null) this.Children.Add(tube); // Copy the scene metadata to the tube foreach (string key in this.Metadata.Keys) tube.Metadata[key] = this.Metadata[key]; } //===================================================================== #endregion } }