示例#1
0
        public static ObjFile FromFile(string fileName)
        {
            ObjFile obj = new ObjFile();

            obj.FileName = fileName;

            using (StreamReader file = new StreamReader(fileName))
            {
                string line;

                string materialName = null;

                ObjMesh mesh = new ObjMesh("unnamed");
                obj.Meshes.Add(mesh);

                ObjFaceGroup faceGroup = new ObjFaceGroup();
                mesh.FaceGroups.Add(faceGroup);

                while ((line = file.ReadLine()) != null)
                {
                    if (string.IsNullOrWhiteSpace(line))
                    {
                        continue;
                    }

                    line = line.Trim();

                    if (line.StartsWith("#", StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    string[] values = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);

                    switch (values[0].ToUpperInvariant())
                    {
                    case "MTLLIB":
                        if (values.Length != 2)
                        {
                            throw new InvalidDataException("missing mtllib name");
                        }

                        if (obj.Materials.Count > 0)
                        {
                            throw new InvalidDataException("multiple mtllib");
                        }

                        obj.Materials = ObjMaterialDictionary.FromFile(Path.Combine(Path.GetDirectoryName(fileName), values[1]));
                        break;

                    case "V":
                        if (values.Length < 4)
                        {
                            throw new InvalidDataException("v must be x y z");
                        }

                        obj.Vertices.Add(new ObjVector3(
                                             float.Parse(values[1], CultureInfo.InvariantCulture),
                                             float.Parse(values[2], CultureInfo.InvariantCulture),
                                             float.Parse(values[3], CultureInfo.InvariantCulture)));
                        break;

                    case "VT":
                        if (values.Length < 3)
                        {
                            throw new InvalidDataException("vt must be u v");
                        }

                        obj.VertexTexCoords.Add(new ObjVector2(
                                                    float.Parse(values[1], CultureInfo.InvariantCulture),
                                                    float.Parse(values[2], CultureInfo.InvariantCulture)));
                        break;

                    case "VN":
                        if (values.Length < 4)
                        {
                            throw new InvalidDataException("vn must be x y z");
                        }

                        obj.VertexNormals.Add(new ObjVector3(
                                                  float.Parse(values[1], CultureInfo.InvariantCulture),
                                                  float.Parse(values[2], CultureInfo.InvariantCulture),
                                                  float.Parse(values[3], CultureInfo.InvariantCulture)));
                        break;

                    case "O":
                    case "G":
                        if (values.Length < 2)
                        {
                            throw new InvalidDataException("missing object name");
                        }

                        if (faceGroup.Faces.Count == 0)
                        {
                            mesh.Name = values[1];
                        }
                        else
                        {
                            mesh = new ObjMesh(values[1]);
                            obj.Meshes.Add(mesh);

                            faceGroup = new ObjFaceGroup();
                            faceGroup.MaterialName = materialName;
                            mesh.FaceGroups.Add(faceGroup);
                        }
                        break;

                    case "USEMTL":
                        if (values.Length != 2)
                        {
                            throw new InvalidDataException("missing material name");
                        }

                        materialName = values[1];

                        if (faceGroup.Faces.Count == 0)
                        {
                            faceGroup.MaterialName = materialName;
                        }
                        else
                        {
                            faceGroup = new ObjFaceGroup();
                            faceGroup.MaterialName = materialName;
                            mesh.FaceGroups.Add(faceGroup);
                        }
                        break;

                    case "F":
                        if (values.Length == 4)
                        {
                            var v1 = ParseFaceVertex(values[1]);
                            var v2 = ParseFaceVertex(values[2]);
                            var v3 = ParseFaceVertex(values[3]);

                            var face = new ObjFace();
                            face.VerticesIndex        = new ObjIndex(v1.Item1, v2.Item1, v3.Item1);
                            face.VertexTexCoordsIndex = new ObjIndex(v1.Item2, v2.Item2, v3.Item2);
                            face.VertexNormalsIndex   = new ObjIndex(v1.Item3, v2.Item3, v3.Item3);

                            faceGroup.Faces.Add(face);
                        }
                        else if (values.Length == 5)
                        {
                            var v1 = ParseFaceVertex(values[1]);
                            var v2 = ParseFaceVertex(values[2]);
                            var v3 = ParseFaceVertex(values[3]);
                            var v4 = ParseFaceVertex(values[4]);

                            var face = new ObjFace();
                            face.VerticesIndex        = new ObjIndex(v1.Item1, v2.Item1, v3.Item1, v4.Item1);
                            face.VertexTexCoordsIndex = new ObjIndex(v1.Item2, v2.Item2, v3.Item2, v4.Item2);
                            face.VertexNormalsIndex   = new ObjIndex(v1.Item3, v2.Item3, v3.Item3, v4.Item3);

                            faceGroup.Faces.Add(face);
                        }
                        else
                        {
                            throw new InvalidDataException("invalid face");
                        }
                        break;
                    }
                }
            }

            return(obj);
        }
示例#2
0
        public static ObjFile FromFile(string fileName)
        {
            ObjFile obj = new ObjFile();

            obj.FileName = fileName;

            using (StreamReader file = new StreamReader(fileName))
            {
                string line;

                string materialName = null;

                ObjMesh mesh = new ObjMesh("unnamed");
                obj.Meshes.Add(mesh);

                ObjFaceGroup faceGroup = new ObjFaceGroup();
                mesh.FaceGroups.Add(faceGroup);

                while ((line = file.ReadLine()) != null)
                {
                    if (string.IsNullOrWhiteSpace(line))
                    {
                        continue;
                    }

                    line = line.Trim();

                    if (line.StartsWith("#", StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    string[] values = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);

                    switch (values[0].ToUpperInvariant())
                    {
                        case "MTLLIB":
                            if (values.Length != 2)
                            {
                                throw new InvalidDataException("missing mtllib name");
                            }

                            if (obj.Materials.Count > 0)
                            {
                                throw new InvalidDataException("multiple mtllib");
                            }

                            obj.Materials = ObjMaterialDictionary.FromFile(Path.Combine(Path.GetDirectoryName(fileName), values[1]));
                            break;

                        case "V":
                            if (values.Length < 4)
                            {
                                throw new InvalidDataException("v must be x y z");
                            }

                            obj.Vertices.Add(new ObjVector3(
                                float.Parse(values[1], CultureInfo.InvariantCulture),
                                float.Parse(values[2], CultureInfo.InvariantCulture),
                                float.Parse(values[3], CultureInfo.InvariantCulture)));
                            break;

                        case "VT":
                            if (values.Length < 3)
                            {
                                throw new InvalidDataException("vt must be u v");
                            }

                            obj.VertexTexCoords.Add(new ObjVector2(
                                float.Parse(values[1], CultureInfo.InvariantCulture),
                                float.Parse(values[2], CultureInfo.InvariantCulture)));
                            break;

                        case "VN":
                            if (values.Length < 4)
                            {
                                throw new InvalidDataException("vn must be x y z");
                            }

                            obj.VertexNormals.Add(new ObjVector3(
                                float.Parse(values[1], CultureInfo.InvariantCulture),
                                float.Parse(values[2], CultureInfo.InvariantCulture),
                                float.Parse(values[3], CultureInfo.InvariantCulture)));
                            break;

                        case "O":
                        case "G":
                            if (values.Length < 2)
                            {
                                throw new InvalidDataException("missing object name");
                            }

                            if (faceGroup.Faces.Count == 0)
                            {
                                mesh.Name = values[1];
                            }
                            else
                            {
                                mesh = new ObjMesh(values[1]);
                                obj.Meshes.Add(mesh);

                                faceGroup = new ObjFaceGroup();
                                faceGroup.MaterialName = materialName;
                                mesh.FaceGroups.Add(faceGroup);
                            }
                            break;

                        case "USEMTL":
                            if (values.Length != 2)
                            {
                                throw new InvalidDataException("missing material name");
                            }

                            materialName = values[1];

                            if (faceGroup.Faces.Count == 0)
                            {
                                faceGroup.MaterialName = materialName;
                            }
                            else
                            {
                                faceGroup = new ObjFaceGroup();
                                faceGroup.MaterialName = materialName;
                                mesh.FaceGroups.Add(faceGroup);
                            }
                            break;

                        case "F":
                            if (values.Length == 4)
                            {
                                var v1 = ParseFaceVertex(values[1]);
                                var v2 = ParseFaceVertex(values[2]);
                                var v3 = ParseFaceVertex(values[3]);

                                var face = new ObjFace();
                                face.VerticesIndex = new ObjIndex(v1.Item1, v2.Item1, v3.Item1);
                                face.VertexTexCoordsIndex = new ObjIndex(v1.Item2, v2.Item2, v3.Item2);
                                face.VertexNormalsIndex = new ObjIndex(v1.Item3, v2.Item3, v3.Item3);

                                faceGroup.Faces.Add(face);
                            }
                            else if (values.Length == 5)
                            {
                                var v1 = ParseFaceVertex(values[1]);
                                var v2 = ParseFaceVertex(values[2]);
                                var v3 = ParseFaceVertex(values[3]);
                                var v4 = ParseFaceVertex(values[4]);

                                var face = new ObjFace();
                                face.VerticesIndex = new ObjIndex(v1.Item1, v2.Item1, v3.Item1, v4.Item1);
                                face.VertexTexCoordsIndex = new ObjIndex(v1.Item2, v2.Item2, v3.Item2, v4.Item2);
                                face.VertexNormalsIndex = new ObjIndex(v1.Item3, v2.Item3, v3.Item3, v4.Item3);

                                faceGroup.Faces.Add(face);
                            }
                            else
                            {
                                throw new InvalidDataException("invalid face");
                            }
                            break;
                    }
                }
            }

            return obj;
        }