using System;
namespace ObjReader
{
///
/// dummy class
///
class Class1
{
///
/// demonstrates usage of the .OBJ reading routine
///
[STAThread]
static void Main(string[] args)
{
float[][] vertices;
int[][] faces;
ReadObj(@"..\..\test.obj", out vertices, out faces);
int numV = vertices.Length;
int numF = faces.Length;
Console.Out.WriteLine("Found " + numV + " Vertices and " + numF + " faces.");
Console.Out.WriteLine("The first vertex is (" + vertices[0][0] + ", " + vertices[0][1] + ", " + vertices[0][2] + ")." );
Console.Out.WriteLine("The last vertex is (" + vertices[numV-1][0] + ", " + vertices[numV-1][1] + ", " + vertices[numV-1][2] + ")." );
Console.Out.Write("The first polygon contains the vertices");
bool comma = false;
foreach(int i in faces[0])
{
Console.Out.Write((comma?", ":" ") + i);
comma = true;
}
Console.Out.WriteLine(".");
Console.Out.Write("The last polygon contains the vertices");
comma = false;
foreach(int i in faces[numF-1])
{
Console.Out.Write((comma?", ":" ") + i);
comma = true;
}
Console.Out.WriteLine(".");
Console.In.ReadLine();
}
///
/// reads in an .OBJ file
///
/// Jörn Loviscach
/// file name including path
/// vertex positions
/// vertex indices for faces
static private void ReadObj(string file, out float[][] vertices, out int[][] faces)
{
System.Collections.Queue vQueue = new System.Collections.Queue();
System.Collections.Queue fQueue = new System.Collections.Queue();
System.IO.StreamReader reader = new System.IO.StreamReader(file);
bool firstObjectStarted = false;
while(true)
{
string line = reader.ReadLine();
if(line == null)
break;
if(line.StartsWith("g")) // an object starts
{
if(firstObjectStarted)
{
break; // we only want the first object
}
firstObjectStarted = true;
continue;
}
if(!firstObjectStarted)
continue;
string[] s = line.Split(new char[]{' '}, 50);
if(s[0].Equals("v"))
{
if(s.Length != 1+3)
throw new Exception("wrong number of components in vertex");
float[] v = new float[3];
for(int i = 0; i < 3; i++)
{
v[i] = (float)System.Double.Parse(s[i+1], System.Globalization.CultureInfo.InvariantCulture);
}
vQueue.Enqueue(v);
}
else if(s[0].Equals("f"))
{
int n = s.Length - 1; // number of vertices
int[] f = new int[n];
for(int i = 0; i < n; i++)
{
string[] fs = s[i+1].Split(new char[]{'/'}, 2);
if(fs == null)
throw new Exception("error in face description");
f[i] = Int32.Parse(fs[0]);
}
fQueue.Enqueue(f);
}
}
reader.Close();
int numVertices = vQueue.Count;
object[] vArray = vQueue.ToArray();
vertices = new float[numVertices][];
for(int i = 0; i < numVertices; i++)
{
vertices[i] = (float[])vArray[i];
}
int numFaces = fQueue.Count;
object[] fArray = fQueue.ToArray();
faces = new int[numFaces][];
for(int i = 0; i < numFaces; i++)
{
int[] f = (int[])fArray[i];
int n = f.Length;
faces[i] = new int[n];
for(int j = 0; j < n; j++)
{
faces[i][j] = f[j]-1; // .obj starts vertex numbering at 1, not at 0
if(faces[i][j] >= numVertices) // jl 2004-04-14: bug corrected
throw new Exception("vertex index too large");
}
}
}
}
}