/*=============================================================================
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
}
}