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"); } } } } }