Esempio n. 1
0
        /// <summary>
        /// Loads an OBJ file from a stream.
        /// </summary>
        /// <param name="stream">A stream with OBJ file data.</param>
        private static TriMesh LoadObjStream(Stream stream)
        {
            TriMesh mesh = new TriMesh();
            mesh.Traits.HasFaceVertexNormals = true;
            mesh.Traits.HasTextureCoordinates = true;

            StreamReader sr = new StreamReader(stream);
            ObjFileProcessorState state = new ObjFileProcessorState();
            string line;

            while ((line = sr.ReadLine()) != null)
            {

                ProcessObjLine(mesh, line, state);

            }

            if (state.VertexTextureCoords.Count == mesh.Vertices.Count)
            {
                for (int i = 0; i < mesh.Vertices.Count; i++)
                {
                    mesh.Vertices[i].Traits.UV = state.VertexTextureCoords[i];
                }
            }
            mesh.TrimExcess();
            return mesh;
        }
Esempio n. 2
0
        /// <summary>
        /// Loads an OBJ file from a stream.
        /// </summary>
        /// <param name="stream">A stream with OBJ file data.</param>
        private static TriMesh LoadObjStream(Stream stream)
        {
            TriMesh mesh = new TriMesh();

            mesh.Traits.HasFaceVertexNormals  = true;
            mesh.Traits.HasTextureCoordinates = true;

            StreamReader          sr    = new StreamReader(stream);
            ObjFileProcessorState state = new ObjFileProcessorState();
            string line;

            while ((line = sr.ReadLine()) != null)
            {
                ProcessObjLine(mesh, line, state);
            }

            if (state.VertexTextureCoords.Count == mesh.Vertices.Count)
            {
                for (int i = 0; i < mesh.Vertices.Count; i++)
                {
                    mesh.Vertices[i].Traits.UV = state.VertexTextureCoords[i];
                }
            }
            mesh.TrimExcess();
            return(mesh);
        }
Esempio n. 3
0
        /// <summary>
        /// Loads an OBJ file from a stream.
        /// </summary>
        /// <param name="stream">A stream with OBJ file data.</param>
        protected void LoadObjStream(Stream stream)
        {
            Traits.HasFaceVertexNormals  = true;
            Traits.HasTextureCoordinates = true;

            StreamReader          sr    = new StreamReader(stream);
            ObjFileProcessorState state = new ObjFileProcessorState();
            string line;

            while ((line = sr.ReadLine()) != null)
            {
                ProcessObjLine(line, state);
            }

            TrimExcess();
        }
Esempio n. 4
0
        /// <summary>
        /// Loads an OBJ file from a stream.
        /// </summary>
        /// <param name="stream">A stream with OBJ file data.</param>
        protected void LoadObjStream(Stream stream, bool hasVertexNormals = true, bool hasTextureCoords = false)
        {
            Traits.HasFaceVertexNormals  = hasVertexNormals;
            Traits.HasTextureCoordinates = hasTextureCoords;

            StreamReader          sr    = new StreamReader(stream);
            ObjFileProcessorState state = new ObjFileProcessorState();
            string line;

            while ((line = sr.ReadLine()) != null)
            {
                ProcessObjLine(line, state);
            }

            // add per-vertex properties
            //if (state.VertexNormals.Count == this.Vertices.Count)
            //{
            //    for (int i = 0; i < this.Vertices.Count; i++)
            //    {
            //        this.Vertices[i].Traits.Normal = state.VertexNormals[i];
            //    }

            //    this.Traits.HasFaceVertexNormals = true;
            //}
            //else
            //{
            //    this.Traits.HasFaceVertexNormals = false;
            //}

            //if (state.VertexTextureCoords.Count == this.Vertices.Count)
            //{
            //    for (int i = 0; i < this.Vertices.Count; i++)
            //    {
            //        this.Vertices[i].Traits.TextureCoordinate = state.VertexTextureCoords[i];
            //    }

            //    this.Traits.HasTextureCoordinates = true;
            //}
            //else
            //{
            //    this.Traits.HasTextureCoordinates = false;
            //}

            TrimExcess();
        }
Esempio n. 5
0
        /// <summary>
        /// Processes a line from an OBJ file.
        /// </summary>
        /// <param name="line">A line from an OBJ file.</param>
        /// <param name="state">An object that manages state between calls.</param>
        private static void ProcessObjLine(TriMesh mesh, string line, ObjFileProcessorState state)
        {
            // Trim out comments (allow comments trailing on a line)
            int commentStart = line.IndexOf('#');
            if (commentStart != -1)
            {
                line = line.Substring(0, commentStart);
            }

            // Tokenize line
            string[] tokens = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);

            // Process line based on the keyword used
            if (tokens.Length > 0)
            {
                int? v;
                float x, y, z;
                TriMesh.Vertex[] faceVertices;
                int?[] vt, vn;

                switch (tokens[0])
                {
                    case "v":   // Vertex
                        if (tokens.Length != 4)
                        {
                            throw new IOException("Vertices in the OBJ file must have 3 coordinates.");
                        }

                        x = Single.Parse(tokens[1]);
                        y = Single.Parse(tokens[2]);
                        z = Single.Parse(tokens[3]);

                        mesh.Vertices.Add(new VertexTraits(x, y, z));
                        break;

                    case "vt":   // Vertex texture
                        if (tokens.Length != 3 && tokens.Length != 4)
                        {
                            throw new IOException("Texture coordinates in the OBJ file must have 2 or 3 coordinates.");
                        }

                        x = Single.Parse(tokens[1]);
                        y = Single.Parse(tokens[2]);


                        state.VertexTextureCoords.Add(new Vector2D(x, y));
                        break;

                    case "vn":   // Vertex normal
                        if (tokens.Length != 4)
                        {
                            throw new IOException("Vertex normals in the OBJ file must have 3 coordinates.");
                        }

                        x = Single.Parse(tokens[1]);
                        y = Single.Parse(tokens[2]);
                        z = Single.Parse(tokens[3]);

                        state.VertexNormals.Add(new Vector3D(x, y, z));
                        break;

                    case "f":   // Face
                        faceVertices = new TriMesh.Vertex[tokens.Length - 1];
                        vt = new int?[tokens.Length - 1];
                        vn = new int?[tokens.Length - 1];

                        // Parse vertex/texture coordinate/normal indices
                        for (int i = 0; i < faceVertices.Length; ++i)
                        {
                            string[] vertexTokens = tokens[i + 1].Split("/".ToCharArray());

                            v = Int32.Parse(vertexTokens[0]);

                            if (vertexTokens.Length > 1 && vertexTokens[1].Length > 0)
                            {
                                vt[i] = Int32.Parse(vertexTokens[1]);
                            }
                            else
                            {
                                mesh.Traits.HasTextureCoordinates = false;
                            }

                            if (vertexTokens.Length > 2 && vertexTokens[2].Length > 0)
                            {
                                vn[i] = Int32.Parse(vertexTokens[2]);
                            }
                            else
                            {
                                mesh.Traits.HasFaceVertexNormals = false;
                            }

                            faceVertices[i] = mesh.Vertices[v.Value - 1];
                        }

                        try
                        {
                            TriMesh.Face[] addedFaces = mesh.Faces.AddTriangles(faceVertices);

                            // Set texture coordinates and normals if any are given
                            for (int i = 0; i < faceVertices.Length; ++i)
                            {
                                TriMesh.HalfEdge faceVertex;
                                if (vt[i].HasValue || vn[i].HasValue)
                                {
                                    foreach (TriMesh.Face f in addedFaces)
                                    {
                                        faceVertex = f.FindHalfedgeTo(faceVertices[i]);
                                        if (faceVertex != null) // Make sure vertex belongs to face if triangularization is on
                                        {
                                            if (vt[i].HasValue)
                                            {
                                                faceVertex.Traits.TextureCoordinate = state.VertexTextureCoords[vt[i].Value - 1];
                                            }
                                            if (vn[i].HasValue)
                                            {
                                                faceVertex.Traits.Normal = state.VertexNormals[vn[i].Value - 1];
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        catch { }

                        break;
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Processes a line from an OBJ file.
        /// </summary>
        /// <param name="line">A line from an OBJ file.</param>
        /// <param name="state">An object that manages state between calls.</param>
        private void ProcessObjLine(string line, ObjFileProcessorState state)
        {
            // Trim out comments (allow comments trailing on a line)
            int commentStart = line.IndexOf('#');

            if (commentStart != -1)
            {
                line = line.Substring(0, commentStart);
            }

            // Tokenize line
            string[] tokens = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);

            // Process line based on the keyword used
            if (tokens.Length > 0)
            {
                int?     v;
                float    x, y, z;
                Vertex[] faceVertices;
                int?[]   vt, vn;

                switch (tokens[0])
                {
                case "v":       // Vertex
                    if (tokens.Length != 4)
                    {
                        throw new IOException("Vertices in the OBJ file must have 3 coordinates.");
                    }

                    x = Single.Parse(tokens[1], CultureInfo.InvariantCulture);
                    y = Single.Parse(tokens[2], CultureInfo.InvariantCulture);
                    z = Single.Parse(tokens[3], CultureInfo.InvariantCulture);

                    Vertices.Add(new VertexTraits(x, y, z));
                    break;

                case "vt":       // Vertex texture
                    if (tokens.Length != 3 && tokens.Length != 4)
                    {
                        throw new IOException("Texture coordinates in the OBJ file must have 2 or 3 coordinates.");
                    }

                    x = Single.Parse(tokens[1], CultureInfo.InvariantCulture);
                    y = Single.Parse(tokens[2], CultureInfo.InvariantCulture);

                    state.VertexTextureCoords.Add(new Point(x, y));
                    break;

                case "vn":       // Vertex normal
                    if (tokens.Length != 4)
                    {
                        throw new IOException("Vertex normals in the OBJ file must have 3 coordinates.");
                    }

                    x = Single.Parse(tokens[1], CultureInfo.InvariantCulture);
                    y = Single.Parse(tokens[2], CultureInfo.InvariantCulture);
                    z = Single.Parse(tokens[3], CultureInfo.InvariantCulture);

                    state.VertexNormals.Add(new Vector3D(x, y, z));
                    break;

                case "f":       // Face
                    faceVertices = new Vertex[tokens.Length - 1];
                    vt           = new int?[tokens.Length - 1];
                    vn           = new int?[tokens.Length - 1];

                    // Parse vertex/texture coordinate/normal indices
                    for (int i = 0; i < faceVertices.Length; ++i)
                    {
                        string[] vertexTokens = tokens[i + 1].Split("/".ToCharArray());

                        v = Int32.Parse(vertexTokens[0]);

                        if (vertexTokens.Length > 1 && vertexTokens[1].Length > 0)
                        {
                            vt[i] = Int32.Parse(vertexTokens[1]);
                        }
                        else
                        {
                            Traits.HasTextureCoordinates = false;
                        }

                        if (vertexTokens.Length > 2 && vertexTokens[2].Length > 0)
                        {
                            vn[i] = Int32.Parse(vertexTokens[2]);
                        }
                        else
                        {
                            Traits.HasFaceVertexNormals = false;
                        }

                        faceVertices[i] = Vertices[v.Value - 1];
                    }

                    Face[] addedFaces = Faces.AddTriangles(faceVertices);

                    // Set texture coordinates and normals if any are given
                    for (int i = 0; i < faceVertices.Length; ++i)
                    {
                        Halfedge faceVertex;
                        if (vt[i].HasValue || vn[i].HasValue)
                        {
                            foreach (Face f in addedFaces)
                            {
                                faceVertex = f.FindHalfedgeTo(faceVertices[i]);
                                if (faceVertex != null)     // Make sure vertex belongs to face if triangularization is on
                                {
                                    if (vt[i].HasValue)
                                    {
                                        faceVertex.Traits.TextureCoordinate = state.VertexTextureCoords[vt[i].Value - 1];
                                    }
                                    if (vn[i].HasValue)
                                    {
                                        faceVertex.Traits.Normal = state.VertexNormals[vn[i].Value - 1];
                                    }
                                }
                            }
                        }
                    }
                    break;
                }
            }
        }