private void ProcessLine(string line, string folderPath)
        {
            string[] parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            if (parts.Length > 0)
            {
                switch (parts[0])
                {
                case "mtllib":
                    Material = ProcessMaterial(parts[1], folderPath);
                    break;

                case "v":
                    Vector3 vertex = ProcessVertex(parts);
                    Vertices.Add(vertex);
                    break;

                case "vt":
                    Vector2 texCoord = ProcessTextureCoordinate(parts);
                    TexCoords.Add(texCoord);
                    break;

                case "vn":
                    Vector3 normal = ProcessVertex(parts);
                    Normals.Add(normal);
                    break;

                case "f":
                    ObjFace face = ProcessFace(parts);
                    Faces.Add(face);
                    break;
                }
            }
        }
            public void BuildFacesFromData()
            {
                List <ObjFace> faces = new List <ObjFace>();

                for (int i = 0; i < Positions.Count; i += 3)
                {
                    ObjFace face         = new ObjFace();
                    bool    hasTexCoords = TexCoords.Count > 0;
                    bool    hasNormal    = Normals.Count > 0;

                    face.Positions = new int[3];
                    for (int j = 0; j < 3; j++)
                    {
                        face.Positions[j] = i + 1;
                    }

                    if (hasTexCoords)
                    {
                        face.TexCoords = new int[3];
                        for (int j = 0; j < 3; j++)
                        {
                            face.TexCoords[j] = i + 1;
                        }
                    }

                    if (hasNormal)
                    {
                        face.Normals = new int[3];
                        for (int j = 0; j < 3; j++)
                        {
                            face.Normals[j] = i + 1;
                        }
                    }
                }
            }
        private static Dictionary <string, List <ObjFace> > ReadObjects(BinaryReader b, int num)
        {
            var d = new Dictionary <string, List <ObjFace> >();

            for (var i = 0; i < num; i++)
            {
                var faces      = new List <ObjFace>();
                var objectName = b.ReadNtString();
                var numFaces   = b.ReadInt32();

                for (var j = 0; j < numFaces; j++)
                {
                    var face     = new ObjFace();
                    var material = (FaceMaterial)b.ReadByte();
                    var numVerts = b.ReadInt32();

                    face.MaterialName = GetMaterialName(material);

                    for (var k = 0; k < numVerts; k++)
                    {
                        var v = b.Read7BitEncodedInt();
                        var n = b.Read7BitEncodedInt();
                        var t = b.Read7BitEncodedInt();

                        face.Vertices.Add(new ObjTriplet(v + 1, t + 1, n + 1));
                    }

                    faces.Add(face);
                }

                d[objectName] = faces;
            }

            return(d);
        }
            public void BuildFacesFromData()
            {
                List<ObjFace> faces = new List<ObjFace>();
                for (int i = 0; i < Positions.Count; i += 3)
                {
                    ObjFace face = new ObjFace();
                    bool hasTexCoords = TexCoords.Count > 0;
                    bool hasNormal = Normals.Count > 0;

                    face.Positions = new int[3];
                    for (int j = 0; j < 3; j++)
                        face.Positions[j] = i + 1;

                    if (hasTexCoords)
                    {
                        face.TexCoords = new int[3];
                        for (int j = 0; j < 3; j++)
                            face.TexCoords[j] = i + 1;
                    }

                    if (hasNormal)
                    {
                        face.Normals = new int[3];
                        for (int j = 0; j < 3; j++)
                            face.Normals[j] = i + 1;
                    }
                }
            }
Example #5
0
        private void GetObjFace(ObjFace face, ObjItem objModel,
                                ref List <float> vertexPositions, ref List <float> vertexNormals, ref List <float> vertexTextureCoordinates, ref List <float> vertexBoneWeights, ref List <float> vertexBoneIndices, ref List <uint> indeces)
        {
            if (face.Count == 3)
            {
                for (var i = 0; i < face.Count; i++)
                {
                    var faceVertex = face[i];
                    ObjLoader.AppendObjTriangle(objModel, faceVertex, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces);
                }
                SetFaceTriangleIndex(face, objModel);
            }
            else if (face.Count == 4)
            {
                var faceVertex0 = face[0];
                var faceVertex1 = face[1];
                var faceVertex2 = face[2];
                var faceVertex3 = face[3];

                ObjLoader.AppendObjTriangle(objModel, faceVertex0, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces);
                ObjLoader.AppendObjTriangle(objModel, faceVertex1, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces);
                ObjLoader.AppendObjTriangle(objModel, faceVertex2, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces);

                ObjLoader.AppendObjTriangle(objModel, faceVertex2, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces);
                ObjLoader.AppendObjTriangle(objModel, faceVertex3, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces);
                ObjLoader.AppendObjTriangle(objModel, faceVertex0, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces);
                SetFaceTriangleIndex(face, objModel);
            }
        }
Example #6
0
        private void SaveObj(string directory, string filename, params string[] meshnames)
        {
            var obj = new ObjFile();

            var referenced_materials = new List <PortableMaterial>();

            foreach (var name in meshnames)
            {
                var pmesh = meshes[name];

                for (int i = 0; i < pmesh.triangles.Count; i++)
                {
                    var triangle = pmesh.triangles[i];
                    var face     = new ObjFace();

                    face.ObjectName = name;

                    foreach (var vertex in triangle.vertices)
                    {
                        obj.Vertices.Add(vertex.position);
                        obj.VertexNormals.Add(vertex.normal);
                        obj.TextureVertices.Add(vertex.uv);

                        var index = obj.Vertices.Count;
                        face.Vertices.Add(new ObjTriplet(index, index, index));
                    }

                    face.MaterialName = triangle.material.name;
                    obj.Faces.Add(face);

                    referenced_materials.Add(triangle.material);
                }
            }

            var mtl = new ObjMaterialFile();

            var materials = referenced_materials.Distinct();

            foreach (var m in materials)
            {
                var material = new ObjMaterial(m.name);
                material.DiffuseColor = new ObjMaterialColor(m.colour.x, m.colour.y, m.colour.z);
                if (m.texture != null)
                {
                    material.DiffuseMap = new ObjMaterialMap(m.texture.filename);
                }
                material.IsAntiAliasingEnabled = false;

                mtl.Materials.Add(material);
            }

            mtl.WriteTo(directory + Path.DirectorySeparatorChar + filename + ".mtl");
            obj.MaterialLibraries.Add(filename + ".mtl");

            obj.WriteTo(directory + Path.DirectorySeparatorChar + filename + ".obj");
        }
Example #7
0
 private void SetFaceTriangleIndex(ObjFace face, ObjItem objModel)
 {
     if (objModel.ObjExport != null && face.ObjExportIndex > -1)
     {
         objModel.ObjExport.Faces[face.ObjExportIndex].TriangleIndex0 = LastTriangleIndex++;
         if (face.Count == 4)
         {
             objModel.ObjExport.Faces[face.ObjExportIndex].TriangleIndex1 = LastTriangleIndex++;
         }
     }
 }
Example #8
0
        public void Element_Face_Valid()
        {
            var obj = new ObjFile();

            obj.Groups.Add(new ObjGroup("b"));
            obj.Vertices.Add(new ObjVertex(0, 0, 0));
            obj.Vertices.Add(new ObjVertex(0, 0, 0));
            obj.Vertices.Add(new ObjVertex(0, 0, 0));
            obj.Vertices.Add(new ObjVertex(0, 0, 0));
            obj.Vertices.Add(new ObjVertex(0, 0, 0));
            obj.Vertices.Add(new ObjVertex(0, 0, 0));
            var face = new ObjFace();

            face.Vertices.Add(new ObjTriplet(2, 0, 0));
            face.Vertices.Add(new ObjTriplet(3, 0, 0));
            face.Vertices.Add(new ObjTriplet(4, 0, 0));
            face.Vertices.Add(new ObjTriplet(5, 0, 0));
            face.Vertices.Add(new ObjTriplet(6, 0, 0));
            obj.Faces.Add(face);
            obj.Groups[0].Faces.Add(face);
            face.ObjectName                     = "a";
            face.LevelOfDetail                  = 2;
            face.MapName                        = "c";
            face.MaterialName                   = "d";
            face.SmoothingGroupNumber           = 10;
            face.IsBevelInterpolationEnabled    = true;
            face.IsColorInterpolationEnabled    = true;
            face.IsDissolveInterpolationEnabled = true;

            string text     = WriteObj(obj);
            string expected =
                @"v 0.000000 0.000000 0.000000
v 0.000000 0.000000 0.000000
v 0.000000 0.000000 0.000000
v 0.000000 0.000000 0.000000
v 0.000000 0.000000 0.000000
v 0.000000 0.000000 0.000000
g b
o a
lod 2
usemap c
usemtl d
s 10
bevel on
c_interp on
d_interp on
f 2 3 4 5 6
";

            AssertExtensions.TextEqual(expected, text);
        }
        private Face CreateFace(Map map, List <Vector3> points, ObjFace objFace)
        {
            var verts = objFace.Vertices.Select(x => points[x]).ToList();

            var f = new Face(map.NumberGenerator.Next("Face"))
            {
                Plane = new Plane(verts[2], verts[1], verts[0])
            };

            verts.Reverse();
            f.Vertices.AddRange(verts);

            return(f);
        }
Example #10
0
        private void ParseFace(string[] data)
        {
            int length = data.Length - 1;

            var face = new ObjFace(3);

            currentFaceGroup.Faces.Add(face);

            for (int i = 0; i < length; i++)
            {
                string[] parts = data[i + 1].Split('/');

                var vert = new ObjFaceVertex();

                vert.VertexIndex = ParseIndex(parts, 0);

                if (parts.Length > 1 && !string.IsNullOrEmpty(parts[1]))
                {
                    vert.UVIndex = ParseIndex(parts, 1);
                }

                if (parts.Length > 2 && !string.IsNullOrEmpty(parts[2]))
                {
                    vert.NormalIndex = ParseIndex(parts, 2);
                }

                if (i < 3)
                {
                    face.Vertices[i] = vert;
                }
                else
                {
                    // polygon > 3 vertices -> triangulate: add new face for every additional polygon
                    var newFace = new ObjFace(3);

                    newFace.Vertices[0] = face.Vertices[0];
                    newFace.Vertices[1] = face.Vertices[2];
                    newFace.Vertices[2] = vert;

                    face = newFace;
                    currentFaceGroup.Faces.Add(face);
                }
            }
        }
Example #11
0
        private static void WriteObj(Int32Rect[][] tiles, BitmapSource[][][] imagedata, ConvertOptions options)
        {
            var positions = new Dictionary <Vector3, int>();
            var normals   = new Dictionary <Vector3, int>();
            var uvs       = new Dictionary <Vector2, int>();

            var normal = new Vector3(0, 0, 1);

            var xcount = (options.ImageWidth.Value + options.TileWidth - 1) / options.TileWidth;
            var ycount = (options.ImageHeight.Value + options.TileHeight - 1) / options.TileHeight;

            var folder   = Path.GetDirectoryName(options.InputFileName);
            var filename = Path.GetFileNameWithoutExtension(options.InputFileName);

            var mtl = new ObjMaterialFile();
            var obj = new ObjFile();

            obj.MaterialLibraries.Add($"{filename}.mtl");

            for (var y = 0; y < ycount; y++)
            {
                for (var x = 0; x < xcount; x++)
                {
                    var tile    = tiles[y][x];
                    var texture = imagedata[0][y][x];
                    var encoder = new PngBitmapEncoder();
                    encoder.Frames.Add(BitmapFrame.Create(texture));
                    var matname = $"{filename}_{y:D3}_{x:D3}";
                    using (var outfile = File.Open(Path.Combine(folder, $"{matname}.png"), FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        encoder.Save(outfile);
                    }

                    var material = new ObjMaterial(matname);
                    material.DiffuseMap = new ObjMaterialMap($"{matname}.png");
                    mtl.Materials.Add(material);
                    var face = new ObjFace();
                    face.MaterialName = matname;

                    face.Vertices.Add(new ObjTriplet(
                                          positions.AddUniqueIndex(new Vector3(tile.X, -(tile.Y), 0)),
                                          uvs.AddUniqueIndex(new Vector2(0, (float)tile.Height / texture.PixelHeight)),
                                          normals.AddUniqueIndex(normal)
                                          ));
                    face.Vertices.Add(new ObjTriplet(
                                          positions.AddUniqueIndex(new Vector3(tile.X + tile.Width, -(tile.Y), 0)),
                                          uvs.AddUniqueIndex(new Vector2((float)tile.Width / texture.PixelWidth, (float)tile.Height / texture.PixelHeight)),
                                          normals.AddUniqueIndex(normal)
                                          ));
                    face.Vertices.Add(new ObjTriplet(
                                          positions.AddUniqueIndex(new Vector3(tile.X + tile.Width, -(tile.Y + tile.Height), 0)),
                                          uvs.AddUniqueIndex(new Vector2((float)tile.Width / texture.PixelWidth, 0)),
                                          normals.AddUniqueIndex(normal)
                                          ));
                    face.Vertices.Add(new ObjTriplet(
                                          positions.AddUniqueIndex(new Vector3(tile.X, -(tile.Y + tile.Height), 0)),
                                          uvs.AddUniqueIndex(new Vector2(0, 0)),
                                          normals.AddUniqueIndex(normal)
                                          ));

                    obj.Faces.Add(face);
                }
            }

            (from x in positions orderby x.Value select x.Key).ToList().ForEach(x => obj.Vertices.Add(x.ToObjVertex()));
            (from x in normals orderby x.Value select x.Key).ToList().ForEach(x => obj.VertexNormals.Add(x.ToObjVector3()));
            (from x in uvs orderby x.Value select x.Key).ToList().ForEach(x => obj.TextureVertices.Add(x.ToObjVector3()));

            mtl.WriteTo(Path.Combine(folder, $"{filename}.mtl"));
            obj.WriteTo(Path.Combine(folder, $"{filename}.obj"));
        }
        private void ParseObj(Stream stream)
        {
            ObjMesh    currentMesh    = null;
            ObjPolygon currentPolygon = null;

            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                List <Vector3> Positions = new List <Vector3>();
                List <Vector2> TexCoords = new List <Vector2>();
                List <Vector3> Normals   = new List <Vector3>();

                var    enusculture     = new CultureInfo("en-US");
                string currentMaterial = null;
                while (!reader.EndOfStream)
                {
                    string line = reader.ReadLine();
                    line = line.Replace(",", ".");

                    // Ignore empty lines and comments.
                    if (String.IsNullOrWhiteSpace(line) || line.StartsWith("#"))
                    {
                        continue;
                    }

                    string[] args = line.Split(_argSeparators, StringSplitOptions.RemoveEmptyEntries);
                    if (args.Length == 1)
                    {
                        continue;
                    }

                    switch (args[0])
                    {
                    case "o":
                    case "g":
                        currentMesh = new ObjMesh(args.Length > 1 ? args[1] : $"Mesh{Meshes.Count}");
                        Meshes.Add(currentMesh);
                        continue;

                    case "v":
                        Positions.Add(new Vector3(
                                          Single.Parse(args[1], enusculture),
                                          Single.Parse(args[2], enusculture),
                                          Single.Parse(args[3], enusculture)));
                        continue;

                    case "vt":
                        TexCoords.Add(new Vector2(
                                          Single.Parse(args[1], enusculture),
                                          Single.Parse(args[2], enusculture)));
                        continue;

                    case "vn":
                        Normals.Add(new Vector3(
                                        Single.Parse(args[1], enusculture),
                                        Single.Parse(args[2], enusculture),
                                        Single.Parse(args[3], enusculture)));
                        continue;

                    case "f":
                        // Only support triangles for now.
                        if (args.Length != 4)
                        {
                            throw new Exception("Obj must be trianglulated!");
                        }

                        int[] indices = new int[3 * 2];     //3 faces, position and normal indices

                        if (!currentMesh.Polygons.ContainsKey(currentMaterial))
                        {
                            currentPolygon = new ObjPolygon(currentMaterial);
                            currentMesh.Polygons.Add(currentMaterial, currentPolygon);
                        }

                        ObjFace face = new ObjFace()
                        {
                            Vertices = new ObjVertex[3]
                        };
                        for (int i = 0; i < 3; i++)
                        {
                            string[] vertexArgs    = args[i + 1].Split(_vertexSeparators, StringSplitOptions.None);
                            int      positionIndex = Int32.Parse(vertexArgs[0]) - 1;

                            face.Vertices[i].Position = Positions[positionIndex];

                            currentPolygon.Indices.Add(positionIndex);

                            if (float.IsNaN(face.Vertices[i].Position.X) ||
                                float.IsNaN(face.Vertices[i].Position.Y) ||
                                float.IsNaN(face.Vertices[i].Position.Z))
                            {
                                face.Vertices = null;
                                break;
                            }

                            if (vertexArgs.Length > 1 && vertexArgs[1] != String.Empty)
                            {
                                face.Vertices[i].TexCoord = TexCoords[Int32.Parse(vertexArgs[1]) - 1];
                            }
                            if (vertexArgs.Length > 2 && vertexArgs[2] != String.Empty)
                            {
                                face.Vertices[i].Normal = Normals[Int32.Parse(vertexArgs[2]) - 1];
                            }
                        }
                        currentPolygon.Faces.Add(face);
                        continue;

                    case "usemtl":
                    {
                        if (args.Length < 2)
                        {
                            continue;
                        }
                        currentMaterial = args[1];
                        continue;
                    }
                    }
                }
            }
        }
 public ObjFace(ObjFace face)
 {
     Vertices = face.Vertices;
 }
Example #14
0
        private static ObjFace ParceFace(string line)
        {
            var vertices = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            var face = new ObjFace();

            foreach (var vertexString in vertices)
            {
                var faceVertex = ParseFaceVertex(vertexString);
                face.AddVertex(faceVertex);
            }

            return face;
        }
 private void SetFaceTriangleIndex(ObjFace face, ObjItem objModel)
 {
     if (objModel.ObjExport != null && face.ObjExportIndex > -1)
     {
         objModel.ObjExport.Faces[face.ObjExportIndex].TriangleIndex0 = LastTriangleIndex++;
         if (face.Count == 4)
             objModel.ObjExport.Faces[face.ObjExportIndex].TriangleIndex1 = LastTriangleIndex++;
     }
 }
        private void GetObjFace(ObjFace face, ObjItem objModel,
                                             ref List<float> vertexPositions, ref List<float> vertexNormals, ref List<float> vertexTextureCoordinates, ref List<float> vertexBoneWeights, ref List<float> vertexBoneIndices, ref List<uint> indeces)
        {
            if (face.Count == 3)
            {
                for (var i = 0; i < face.Count; i++)
                {
                    var faceVertex = face[i];
                    ObjLoader.AppendObjTriangle(objModel, faceVertex, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces);
                }
                SetFaceTriangleIndex(face, objModel);
            }
            else if (face.Count == 4)
            {
                var faceVertex0 = face[0];
                var faceVertex1 = face[1];
                var faceVertex2 = face[2];
                var faceVertex3 = face[3];

                ObjLoader.AppendObjTriangle(objModel, faceVertex0, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces);
                ObjLoader.AppendObjTriangle(objModel, faceVertex1, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces);
                ObjLoader.AppendObjTriangle(objModel, faceVertex2, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces);

                ObjLoader.AppendObjTriangle(objModel, faceVertex2, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces);
                ObjLoader.AppendObjTriangle(objModel, faceVertex3, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces);
                ObjLoader.AppendObjTriangle(objModel, faceVertex0, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces);
                SetFaceTriangleIndex(face, objModel);
            }
        }
Example #17
0
 private Face CreateFace(DataStructures.MapObjects.Map map, List<Coordinate> points, ObjFace objFace)
 {
     var verts = objFace.Vertices.Select(x => points[x]).ToList();
     var f = new Face(map.IDGenerator.GetNextFaceID());
     f.Plane = new Plane(verts[2], verts[1], verts[0]);
     f.Vertices.AddRange(verts.Select(x => new Vertex(x, f)).Reverse());
     f.UpdateBoundingBox();
     return f;
 }
Example #18
0
        private void loadModel(string fileName)
        {
            treeView1.Nodes.Clear();
            m = new WavefrontOBJ();
            m.loadObjModel(fileName);

            TreeNode nodeObjects = new TreeNode("Objects (" + m.getNumObjects() + ")");

            for (int i = 0; i < m.getNumObjects(); i++)
            {
                ObjObject o          = m.getObject(i);
                TreeNode  nodeObject = new TreeNode("Object " + i + " - \"" + o.getName() + "\"");
                // object name
                TreeNode nodeObjectName      = new TreeNode("Name");
                TreeNode nodeObjectNameValue = new TreeNode(o.getName());
                nodeObjectNameValue.Tag = o;
                nodeObjectName.Nodes.Add(nodeObjectNameValue);
                nodeObject.Nodes.Add(nodeObjectName);
                // first face
                TreeNode nodeObjectFirstFace      = new TreeNode("First face");
                TreeNode nodeObjectFirstFaceValue = new TreeNode(o.getFirstFace().ToString());
                nodeObjectFirstFace.Nodes.Add(nodeObjectFirstFaceValue);
                nodeObject.Nodes.Add(nodeObjectFirstFace);
                // face count
                TreeNode nodeObjectNumFaces      = new TreeNode("Faces count");
                TreeNode nodeObjectNumFacesValue = new TreeNode(o.getNumFaces().ToString());
                nodeObjectNumFaces.Nodes.Add(nodeObjectNumFacesValue);
                nodeObject.Nodes.Add(nodeObjectNumFaces);

                nodeObjects.Nodes.Add(nodeObject);
            }
            treeView1.Nodes.Add(nodeObjects);
            TreeNode nodeGroups = new TreeNode("Groups (" + m.getNumGroups() + ")");

            for (int i = 0; i < m.getNumGroups(); i++)
            {
                ObjGroup o         = m.getGroup(i);
                TreeNode nodeGroup = new TreeNode("Group " + i + " - \"" + o.getName() + "\"");
                // object name
                TreeNode nodeGroupName      = new TreeNode("Name");
                TreeNode nodeGroupNameValue = new TreeNode(o.getName());
                nodeGroupNameValue.Tag = o;
                nodeGroupName.Nodes.Add(nodeGroupNameValue);
                nodeGroup.Nodes.Add(nodeGroupName);
                // first face
                TreeNode nodeGroupFirstFace      = new TreeNode("First face");
                TreeNode nodeGroupFirstFaceValue = new TreeNode(o.getFirstFace().ToString());
                nodeGroupFirstFace.Nodes.Add(nodeGroupFirstFaceValue);
                nodeGroup.Nodes.Add(nodeGroupFirstFace);
                // face count
                TreeNode nodeGroupNumFaces      = new TreeNode("Faces count");
                TreeNode nodeGroupNumFacesValue = new TreeNode(o.getNumFaces().ToString());
                nodeGroupNumFaces.Nodes.Add(nodeGroupNumFacesValue);
                nodeGroup.Nodes.Add(nodeGroupNumFaces);

                nodeGroups.Nodes.Add(nodeGroup);
            }
            treeView1.Nodes.Add(nodeGroups);
            TreeNode nodeFaces = new TreeNode("Faces (" + m.getNumFaces() + ")");

            for (int i = 0; i < m.getNumFaces(); i++)
            {
                ObjFace  f        = m.getFace(i);
                TreeNode nodeFace = new TreeNode("Face " + i);
                // number of vertices

                /*TreeNode nodeFaceNumFaceVerts = new TreeNode("FaceVerts count");
                 * TreeNode nodeFaceNumFaceVertsValue = new TreeNode(f.getNumVerts().ToString());
                 * nodeFaceNumFaceVerts.Nodes.Add(nodeFaceNumFaceVertsValue);
                 * nodeFace.Nodes.Add(nodeFaceNumFaceVerts);*/
                // vertices
                TreeNode nodeFaceFaceVerts = new TreeNode("FaceVerts (" + f.getNumVerts() + ")");
                for (int j = 0; j < f.getNumVerts(); j++)
                {
                    TreeNode nodeFaceFaceVert = new TreeNode("FaceVert " + j + " (abs " + (j + f.getFirstVert()) + ")");
                    nodeFaceFaceVerts.Nodes.Add(nodeFaceFaceVert);
                }
                nodeFace.Nodes.Add(nodeFaceFaceVerts);

                nodeFaces.Nodes.Add(nodeFace);
            }
            treeView1.Nodes.Add(nodeFaces);
            TreeNode nodePositions = new TreeNode("XYZs (" + m.getNumXYZs() + ")");

            for (int i = 0; i < m.getNumXYZs(); i++)
            {
                TreeNode nodePosition      = new TreeNode("XYZ " + i);
                TreeNode nodePositionValue = new TreeNode(m.getXYZ(i).ToString());
                nodePosition.Nodes.Add(nodePositionValue);
                nodePositions.Nodes.Add(nodePosition);
            }
            treeView1.Nodes.Add(nodePositions);
            if (m.getNumTexCoords() > 0)
            {
                TreeNode nodeTexCoords = new TreeNode("TexCoords (" + m.getNumTexCoords() + ")");
                for (int i = 0; i < m.getNumTexCoords(); i++)
                {
                    TreeNode nodeTexCoord      = new TreeNode("TexCoord " + i);
                    TreeNode nodeTexCoordValue = new TreeNode(m.getTexCoord(i).ToString());
                    nodeTexCoord.Nodes.Add(nodeTexCoordValue);
                    nodeTexCoords.Nodes.Add(nodeTexCoord);
                }
                treeView1.Nodes.Add(nodeTexCoords);
            }
            ;
            if (m.getNumNormals() > 0)
            {
                TreeNode nodeNormals = new TreeNode("Normals (" + m.getNumNormals() + ")");
                for (int i = 0; i < m.getNumNormals(); i++)
                {
                    TreeNode nodeNormal      = new TreeNode("Normal " + i);
                    TreeNode nodeNormalValue = new TreeNode(m.getNormal(i).ToString());
                    nodeNormal.Nodes.Add(nodeNormalValue);
                    nodeNormals.Nodes.Add(nodeNormal);
                }
                treeView1.Nodes.Add(nodeNormals);
            }
        }
Example #19
0
        public static GameObject LoadOBJFile(string FilePath, List <Texture2D> LoadedTextures)
        {
            string meshName = Path.GetFileNameWithoutExtension(FilePath);

            bool hasNormals = false;
            //OBJ LISTS
            List <Vector3> vertices = new List <Vector3>();
            List <Vector3> normals  = new List <Vector3>();
            List <Vector2> uvs      = new List <Vector2>();
            //UMESH LISTS
            List <Vector3> uvertices = new List <Vector3>();
            List <Vector3> unormals  = new List <Vector3>();
            List <Vector2> uuvs      = new List <Vector2>();
            //MESH CONSTRUCTION
            List <string>            materialNames = new List <string>();
            List <string>            objectNames   = new List <string>();
            Dictionary <string, int> hashtable     = new Dictionary <string, int>();
            List <ObjFace>           faceList      = new List <ObjFace>();
            string cmaterial = "";
            string cmesh     = "default";

            //CACHE
            Material[] materialCache = null;
            //save this info for later
            FileInfo OBJFileInfo = new FileInfo(FilePath);

            foreach (string ln in File.ReadAllLines(FilePath))
            {
                if (ln.Length > 0 && ln[0] != '#')
                {
                    string   l    = ln.Trim().Replace("  ", " ");
                    string[] cmps = l.Split(' ');
                    string   data = l.Remove(0, l.IndexOf(' ') + 1);

                    if (cmps[0] == "mtllib")
                    {
                        //load cache
                        string pth = OBJGetFilePath(data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, meshName);
                        if (pth != null)
                        {
                            materialCache = LoadMTLFile(pth, LoadedTextures);
                        }
                    }
                    else if ((cmps[0] == "g" || cmps[0] == "o") && SplitByMaterial == false)
                    {
                        cmesh = data;
                        if (!objectNames.Contains(cmesh))
                        {
                            objectNames.Add(cmesh);
                        }
                    }
                    else if (cmps[0] == "usemtl")
                    {
                        cmaterial = data;
                        if (!materialNames.Contains(cmaterial))
                        {
                            materialNames.Add(cmaterial);
                        }

                        if (SplitByMaterial)
                        {
                            if (!objectNames.Contains(cmaterial))
                            {
                                objectNames.Add(cmaterial);
                            }
                        }
                    }
                    else if (cmps[0] == "v")
                    {
                        //VERTEX
                        vertices.Add(ParseVectorFromCMPS(cmps));
                    }
                    else if (cmps[0] == "vn")
                    {
                        //VERTEX NORMAL
                        normals.Add(ParseVectorFromCMPS(cmps));
                    }
                    else if (cmps[0] == "vt")
                    {
                        //VERTEX UV
                        uvs.Add(ParseVectorFromCMPS(cmps));
                    }
                    else if (cmps[0] == "f")
                    {
                        int[] indexes = new int[cmps.Length - 1];
                        for (int i = 1; i < cmps.Length; i++)
                        {
                            string felement    = cmps[i];
                            int    vertexIndex = -1;
                            int    normalIndex = -1;
                            int    uvIndex     = -1;
                            if (felement.Contains("//"))
                            {
                                //doubleslash, no UVS.
                                string[] elementComps = felement.Split('/');
                                vertexIndex = int.Parse(elementComps[0]) - 1;
                                normalIndex = int.Parse(elementComps[2]) - 1;
                            }
                            else if (felement.Split('/').Length == 3)
                            {
                                //contains everything
                                string[] elementComps = felement.Split('/');
                                vertexIndex = int.Parse(elementComps[0]) - 1;
                                uvIndex     = int.Parse(elementComps[1]) - 1;
                                normalIndex = int.Parse(elementComps[2]) - 1;
                            }
                            else if (!felement.Contains("/"))
                            {
                                //just vertex inedx
                                vertexIndex = int.Parse(felement) - 1;
                            }
                            else
                            {
                                //vertex and uv
                                string[] elementComps = felement.Split('/');
                                vertexIndex = int.Parse(elementComps[0]) - 1;
                                uvIndex     = int.Parse(elementComps[1]) - 1;
                            }
                            string hashEntry = vertexIndex + "|" + normalIndex + "|" + uvIndex;
                            if (hashtable.ContainsKey(hashEntry))
                            {
                                indexes[i - 1] = hashtable[hashEntry];
                            }
                            else
                            {
                                //create a new hash entry
                                indexes[i - 1]       = hashtable.Count;
                                hashtable[hashEntry] = hashtable.Count;
                                uvertices.Add(vertices[vertexIndex]);
                                if (normalIndex < 0 || (normalIndex > (normals.Count - 1)))
                                {
                                    unormals.Add(Vector3.zero);
                                }
                                else
                                {
                                    hasNormals = true;
                                    unormals.Add(normals[normalIndex]);
                                }
                                if (uvIndex < 0 || (uvIndex > (uvs.Count - 1)))
                                {
                                    uuvs.Add(Vector2.zero);
                                }
                                else
                                {
                                    uuvs.Add(uvs[uvIndex]);
                                }
                            }
                        }
                        if (indexes.Length < 5 && indexes.Length >= 3)
                        {
                            ObjFace f1 = new ObjFace();
                            f1.MaterialName = cmaterial;
                            f1.Indexes      = new int[] { indexes[0], indexes[1], indexes[2] };
                            f1.MeshName     = (SplitByMaterial) ? cmaterial : cmesh;
                            faceList.Add(f1);
                            if (indexes.Length > 3)
                            {
                                ObjFace f2 = new ObjFace();
                                f2.MaterialName = cmaterial;
                                f2.MeshName     = (SplitByMaterial) ? cmaterial : cmesh;
                                f2.Indexes      = new int[] { indexes[2], indexes[3], indexes[0] };
                                faceList.Add(f2);
                            }
                        }
                    }
                }
            }

            if (objectNames.Count == 0)
            {
                objectNames.Add("default");
            }

            //build objects
            GameObject parentObject = new GameObject(meshName);


            foreach (string obj in objectNames)
            {
                GameObject subObject = new GameObject(obj);
                subObject.transform.parent     = parentObject.transform;
                subObject.transform.localScale = new Vector3(-1, 1, 1); //IIRC I did this to correct for some rotation issues? TODO review this
                //Create mesh
                Mesh m = new Mesh();
                m.name = obj;
                //LISTS FOR REORDERING
                List <Vector3>        processedVertices = new List <Vector3>();
                List <Vector3>        processedNormals  = new List <Vector3>();
                List <Vector2>        processedUVs      = new List <Vector2>();
                List <int[]>          processedIndexes  = new List <int[]>();
                Dictionary <int, int> remapTable        = new Dictionary <int, int>();
                //POPULATE MESH
                List <string> meshMaterialNames = new List <string>();

                List <ObjFace> ofaces = faceList.FindAll(x => x.MeshName == obj);
                foreach (string mn in materialNames)
                {
                    ObjFace[] faces = ofaces.FindAll(x => x.MaterialName == mn).ToArray();
                    if (faces.Length > 0)
                    {
                        int[] indexes = new int[0];
                        foreach (ObjFace f in faces)
                        {
                            int l = indexes.Length;
                            Array.Resize(ref indexes, l + f.Indexes.Length);
                            Array.Copy(f.Indexes, 0, indexes, l, f.Indexes.Length);
                        }
                        meshMaterialNames.Add(mn);
                        if (m.subMeshCount != meshMaterialNames.Count)
                        {
                            m.subMeshCount = meshMaterialNames.Count;
                        }

                        for (int i = 0; i < indexes.Length; i++)
                        {
                            int idx = indexes[i];
                            //build remap table
                            if (remapTable.ContainsKey(idx))
                            {
                                //ezpz
                                indexes[i] = remapTable[idx];
                            }
                            else
                            {
                                processedVertices.Add(uvertices[idx]);
                                processedNormals.Add(unormals[idx]);
                                processedUVs.Add(uuvs[idx]);
                                remapTable[idx] = processedVertices.Count - 1;
                                indexes[i]      = remapTable[idx];
                            }
                        }

                        processedIndexes.Add(indexes);
                    }
                    else
                    {
                    }
                }

                //apply stuff
                m.vertices = processedVertices.ToArray();
                m.normals  = processedNormals.ToArray();
                m.uv       = processedUVs.ToArray();

                for (int i = 0; i < processedIndexes.Count; i++)
                {
                    m.SetTriangles(processedIndexes[i], i);
                }

                if (!hasNormals)
                {
                    m.RecalculateNormals();
                }
                m.RecalculateBounds();
                ;

                MeshFilter   mf = subObject.AddComponent <MeshFilter>();
                MeshRenderer mr = subObject.AddComponent <MeshRenderer>();

                Material[] processedMaterials = new Material[meshMaterialNames.Count];
                for (int i = 0; i < meshMaterialNames.Count; i++)
                {
                    if (materialCache == null)
                    {
                        processedMaterials[i] = new Material(Shader.Find("Standard (Specular setup)"));
                    }
                    else
                    {
                        Material mfn = Array.Find(materialCache, x => x.name == meshMaterialNames[i]);;
                        if (mfn == null)
                        {
                            processedMaterials[i] = new Material(Shader.Find("Standard (Specular setup)"));
                        }
                        else
                        {
                            processedMaterials[i] = mfn;
                        }
                    }
                    processedMaterials[i].name = meshMaterialNames[i];
                }

                mr.materials      = processedMaterials;
                mr.enabled        = true;
                mr.useLightProbes = false;
                mf.mesh           = m;
            }

            return(parentObject);
        }
Example #20
0
        private Face CreateFace(DataStructures.MapObjects.Map map, List <Coordinate> points, ObjFace objFace)
        {
            var verts = objFace.Vertices.Select(x => points[x]).ToList();
            var f     = new Face(map.IDGenerator.GetNextFaceID());

            f.Plane = new Plane(verts[2], verts[1], verts[0]);
            f.Vertices.AddRange(verts.Select(x => new Vertex(x, f)).Reverse());
            f.UpdateBoundingBox();
            return(f);
        }
Example #21
0
        static void Main(string[] args)
        {
            void ShowInfo()
            {
                AdvConsole.WriteLine(ConsoleColor.Cyan,
                                     "PlaneBorder\n" +
                                     "by Zach Combs\n" +
                                     "\n" +
                                     "<sourceOBJ> <destOBJ> <borderWidth> <borderHeight>\n" +
                                     "     Maps textures for a VVVVVV Circuit style track.\n" +
                                     "     sourceOBJ      The source OBJ file\n" +
                                     "     destOBj        The destination OBJ file\n" +
                                     "     borderWidth    The width of borders\n" +
                                     "     borderHeight   The height of borders");
            }

            void WriteError(string s)
            {
                AdvConsole.WriteLine(ConsoleColor.Red, "ERROR: " + s);
            }

            Rect2d[] CalculateVerticesOfRect(float width, float height, float cornerwidth, float cornerheight)
            {
                //coords[0] = topleft corner
                //coords[1] = topright corner
                //coords[2] = bottomleft corner
                //coords[3] = bottomright corner
                //coords[4] = left side
                //coords[5] = right side
                //coords[6] = bottom side
                //coords[7] = top side
                //coords[8] = center
                Rect2d[] coords = new Rect2d[9];

                Rect2d corner_topleft     = new Rect2d();
                Rect2d corner_topright    = new Rect2d();
                Rect2d corner_bottomleft  = new Rect2d();
                Rect2d corner_bottomright = new Rect2d();
                Rect2d side_left          = new Rect2d();
                Rect2d side_right         = new Rect2d();
                Rect2d side_bottom        = new Rect2d();
                Rect2d side_top           = new Rect2d();
                Rect2d center             = new Rect2d();

                ObjVector2 in_topleft     = new ObjVector2();
                ObjVector2 in_bottomright = new ObjVector2();

                if (width < (cornerwidth * 2))
                {
                    in_topleft.X = width / 2;
                }
                else
                {
                    in_topleft.X = cornerwidth;
                }
                if (height < (cornerheight * 2))
                {
                    in_topleft.Y = height / 2;
                }
                else
                {
                    in_topleft.Y = cornerheight;
                }
                if (width < (cornerwidth * 2))
                {
                    in_bottomright.X = width / 2;
                }
                else
                {
                    in_bottomright.X = width - cornerwidth;
                }
                if (height < (cornerheight * 2))
                {
                    in_bottomright.Y = height / 2;
                }
                else
                {
                    in_bottomright.Y = height - cornerheight;
                }

                corner_topleft = new Rect2d(
                    new ObjVector2(0, 0),
                    new ObjVector2(in_topleft.X, in_topleft.Y));
                corner_topright = new Rect2d(
                    new ObjVector2(in_bottomright.X, 0),
                    new ObjVector2(width, in_topleft.Y));
                corner_bottomleft = new Rect2d(
                    new ObjVector2(0, in_bottomright.Y),
                    new ObjVector2(in_topleft.X, height));
                corner_bottomright = new Rect2d(
                    new ObjVector2(in_bottomright.X, in_bottomright.Y),
                    new ObjVector2(width, height));

                side_left = new Rect2d(
                    new ObjVector2(0, in_topleft.Y),
                    new ObjVector2(in_topleft.X, in_bottomright.Y));
                side_right = new Rect2d(
                    new ObjVector2(in_bottomright.X, in_topleft.Y),
                    new ObjVector2(width, in_bottomright.Y));
                side_bottom = new Rect2d(
                    new ObjVector2(in_topleft.X, in_bottomright.Y),
                    new ObjVector2(in_bottomright.X, height));
                side_top = new Rect2d(
                    new ObjVector2(in_topleft.X, 0),
                    new ObjVector2(in_bottomright.X, in_topleft.Y));

                center = new Rect2d(
                    new ObjVector2(in_topleft.X, in_topleft.Y),
                    new ObjVector2(in_bottomright.X, in_bottomright.Y));

                coords[0] = corner_topleft;
                coords[1] = corner_topright;
                coords[2] = corner_bottomleft;
                coords[3] = corner_bottomright;
                coords[4] = side_left;
                coords[5] = side_right;
                coords[6] = side_bottom;
                coords[7] = side_top;
                coords[8] = center;
                return(coords);
            }

            Rect2d[] CalculateTexCoordsOfRect(float width, float height, float cornerwidth, float cornerheight)
            {
                //coords[0] = topleft corner
                //coords[1] = topright corner
                //coords[2] = bottomleft corner
                //coords[3] = bottomright corner
                //coords[4] = left side
                //coords[5] = right side
                //coords[6] = bottom side
                //coords[7] = top side
                //coords[8] = center
                Rect2d[] coords = new Rect2d[9];

                coords[0] = new Rect2d(
                    new ObjVector2(0.125F, 0F),
                    new ObjVector2(0.25F, 0.5F));
                coords[1] = new Rect2d(
                    new ObjVector2(0.25F, 0F),
                    new ObjVector2(0.375F, 0.5F));
                coords[2] = new Rect2d(
                    new ObjVector2(0.125F, 0.5F),
                    new ObjVector2(0.25F, 1F));
                coords[3] = new Rect2d(
                    new ObjVector2(0.25F, 0.5F),
                    new ObjVector2(0.375F, 1F));

                float in_width    = ((width < (cornerwidth * 2)) ? 0f : (width - (cornerwidth * 2)));
                float in_height   = ((height < (cornerheight * 2)) ? 0f : (height - (cornerheight * 2)));
                float uv_in_width = ((in_width == 0) ? 0f : (
                                         ((in_width / (cornerwidth * 2)) < 0.5f) ? 0.5f :
                                         ((float)Math2.Round(in_width / (cornerwidth * 2), 0.5, Math2.RoundTechnique.ToNearest))
                                         ));
                float uv_in_height = ((in_height == 0) ? 0f : (
                                          ((in_height / (cornerheight * 2)) < 0.5f) ? 0.5f :
                                          ((float)Math2.Round(in_height / (cornerheight * 2), 0.5, Math2.RoundTechnique.ToNearest))
                                          ));
                Rect2d side_left = new Rect2d(
                    new ObjVector2(0.375F, 0F),
                    new ObjVector2(0.5F, uv_in_height));
                Rect2d side_right = new Rect2d(
                    new ObjVector2(0.5F, 0F),
                    new ObjVector2(0.625F, uv_in_height));
                Rect2d side_bottom = new Rect2d(
                    new ObjVector2(0.625F, 0F),
                    new ObjVector2(0.75F, uv_in_width));//This will be rotated counter-clockwise
                Rect2d side_top = new Rect2d(
                    new ObjVector2(0.75F, 0F),
                    new ObjVector2(0.875F, uv_in_width));//This will be rotated counter-clockwise
                Rect2d center = new Rect2d(
                    new ObjVector2(0F, 0F),
                    new ObjVector2(uv_in_width, uv_in_height));



                coords[4] = side_left;
                coords[5] = side_right;
                coords[6] = side_bottom;
                coords[7] = side_top;
                coords[8] = center;
                return(coords);
            }

            bool IsARectangle(ObjVector2 v1, ObjVector2 v2, ObjVector2 v3, ObjVector2 v4, out ObjVector2[] outpoints, out int[] oldindexes, out bool isclockwise)
            {
                //Returns whether or not v1, v2, v3, v4 make a rectangle
                //The vertices need to be in the order of building a rectangle
                //If v1, v2, v3, v4 make a rectangle, it makes an array of the vertices where the top-left vertex is first
                //The order of the vertices in the array depends on whether or not the rectangle the built clockwise or counter-clockwise
                int   topleft   = -1;
                float mincoordx = Math.Min(Math.Min(v1.X, v2.X), Math.Min(v3.X, v4.X));
                float mincoordy = Math.Min(Math.Min(v1.Y, v2.Y), Math.Min(v3.Y, v4.Y));

                if (v1.X == mincoordx & v1.Y == mincoordy)
                {
                    topleft = 0;
                }
                if (v2.X == mincoordx & v2.Y == mincoordy)
                {
                    topleft = 1;
                }
                if (v3.X == mincoordx & v3.Y == mincoordy)
                {
                    topleft = 2;
                }
                if (v4.X == mincoordx & v4.Y == mincoordy)
                {
                    topleft = 3;
                }
                if (topleft == -1)
                {
                    outpoints   = null;
                    oldindexes  = null;
                    isclockwise = false;
                    return(false);
                }
                else
                {
                    ObjVector2 newv1   = null;
                    ObjVector2 newv2   = null;
                    ObjVector2 newv3   = null;
                    ObjVector2 newv4   = null;
                    int        oldind1 = -1;
                    int        oldind2 = -1;
                    int        oldind3 = -1;
                    int        oldind4 = -1;
                    if (topleft == 0)
                    {
                        newv1   = new ObjVector2(v1.X, v1.Y);
                        newv2   = new ObjVector2(v2.X, v2.Y);
                        newv3   = new ObjVector2(v3.X, v3.Y);
                        newv4   = new ObjVector2(v4.X, v4.Y);
                        oldind1 = 0;
                        oldind2 = 1;
                        oldind3 = 2;
                        oldind4 = 3;
                    }
                    else if (topleft == 1)
                    {
                        newv1   = new ObjVector2(v2.X, v2.Y);
                        newv2   = new ObjVector2(v3.X, v3.Y);
                        newv3   = new ObjVector2(v4.X, v4.Y);
                        newv4   = new ObjVector2(v1.X, v1.Y);
                        oldind1 = 1;
                        oldind2 = 2;
                        oldind3 = 3;
                        oldind4 = 0;
                    }
                    else if (topleft == 2)
                    {
                        newv1   = new ObjVector2(v3.X, v3.Y);
                        newv2   = new ObjVector2(v4.X, v4.Y);
                        newv3   = new ObjVector2(v1.X, v1.Y);
                        newv4   = new ObjVector2(v2.X, v2.Y);
                        oldind1 = 2;
                        oldind2 = 3;
                        oldind3 = 0;
                        oldind4 = 1;
                    }
                    else if (topleft == 3)
                    {
                        newv1   = new ObjVector2(v4.X, v4.Y);
                        newv2   = new ObjVector2(v1.X, v1.Y);
                        newv3   = new ObjVector2(v2.X, v2.Y);
                        newv4   = new ObjVector2(v3.X, v3.Y);
                        oldind1 = 3;
                        oldind2 = 0;
                        oldind3 = 1;
                        oldind4 = 2;
                    }
                    bool isrectccw = (newv1.X == newv2.X & newv2.Y == newv3.Y & newv3.X == newv4.X & newv4.Y == newv1.Y);
                    bool isrectcw  = (newv1.Y == newv2.Y & newv2.X == newv3.X & newv3.Y == newv4.Y & newv4.X == newv1.X);
                    if (isrectccw | isrectcw)
                    {
                        outpoints     = new ObjVector2[4];
                        outpoints[0]  = newv1;
                        outpoints[1]  = newv2;
                        outpoints[2]  = newv3;
                        outpoints[3]  = newv4;
                        oldindexes    = new int[4];
                        oldindexes[0] = oldind1;
                        oldindexes[1] = oldind2;
                        oldindexes[2] = oldind3;
                        oldindexes[3] = oldind4;
                        isclockwise   = isrectcw;
                        return(true);
                    }
                    else
                    {
                        outpoints   = null;
                        oldindexes  = null;
                        isclockwise = false;
                        return(false);
                    }
                }
            }

            double PointDirection(ObjVector2 pnt1, ObjVector2 pnt2)
            {
                double xxx = pnt2.X - pnt1.X;
                double yyy = pnt2.Y - pnt1.Y;

                if (xxx == 0)
                {
                    if (yyy < 0)
                    {
                        return(Math.PI * 1.5D);
                    }
                    else
                    {
                        return(Math.PI * 0.5D);
                    }
                }
                else if (xxx < 0)
                {
                    return(Math.Atan(yyy / xxx) + Math.PI);
                }
                else
                {
                    return(Math.Atan(yyy / xxx));
                }
            }

            const int reqargs = 4;

            if (args == null)
            {
                ShowInfo();
                return;
            }
            if (args.Length == 0)
            {
                ShowInfo();
                return;
            }

            if (args.Length < reqargs)
            {
                WriteError(
                    "You must specify source obj, dest obj, corner width, and corner height"
                    );
                return;
            }

            string file_source   = args[0];
            string file_dest     = args[1];
            float  corner_width  = 0f; //borderWidth
            float  corner_height = 0f; //borderHeight

            if (!File.Exists(file_source))
            {
                WriteError(String.Format(
                               "\"{0}\" does not exist"
                               , file_source));
                return;
            }
            if (File.Exists(file_dest))
            {
                WriteError(String.Format(
                               "\"{0}\" already exists"
                               , file_dest));
                return;
            }
            if (!float.TryParse(args[2], out corner_width))
            {
                WriteError(String.Format(
                               "\"{0}\" is not valid"
                               , args[2]));
                return;
            }
            if (!float.TryParse(args[3], out corner_height))
            {
                WriteError(String.Format(
                               "\"{0}\" is not valid"
                               , args[3]));
                return;
            }

            try
            {
                Obj obj = new Obj();
                obj.Load(file_source, ObjLoadMode.IgnoreGroups, false);
                ObjGroup group = obj.Groups.Groups[0];

                ObjGroup newgroup = new ObjGroup();
                int AddVertex(ObjVector3 vertex)
                {
                    int index = -1;
                    int n     = 0;

                    while (n < newgroup.Vertexes.Count & index == -1)
                    {
                        ObjVector3 vector = newgroup.Vertexes.Item(n);
                        if (
                            vertex.X == vector.X &
                            vertex.Y == vector.Y &
                            vertex.Z == vector.Z)
                        {
                            index = n;
                        }
                        n += 1;
                    }
                    if (index == -1)
                    {
                        index = newgroup.Vertexes.Count;
                        newgroup.Vertexes.Add(vertex);
                    }
                    return(index);
                }
                void AddRectangle(
                    ObjVector3 topleftpos,
                    int coordplane,
                    Rect2d[] Vertices, Rect2d[] TexCoords)
                {
                    //coordplane==0: +X+Z plane
                    //coordplane==1: -X+Z plane
                    //coordplane==2: +X-Y plane
                    //coordplane==3: -X-Y plane
                    //coordplane==4: +Z-Y plane
                    //coordplane==5: -Z-Y plane

                    ObjVector3 DeterminePosition(float vx, float vy)
                    {
                        ObjVector3 vector = new ObjVector3(
                            topleftpos.X,
                            topleftpos.Y,
                            topleftpos.Z);

                        if (coordplane == 0)
                        {
                            vector.X += vx;
                            vector.Z += vy;
                        }
                        else if (coordplane == 1)
                        {
                            vector.X += -vx;
                            vector.Z += vy;
                        }
                        else if (coordplane == 2)
                        {
                            vector.X += vx;
                            vector.Y += -vy;
                        }
                        else if (coordplane == 3)
                        {
                            vector.X += -vx;
                            vector.Y += -vy;
                        }
                        else if (coordplane == 4)
                        {
                            vector.Z += vx;
                            vector.Y += -vy;
                        }
                        else if (coordplane == 5)
                        {
                            vector.Z += -vx;
                            vector.Y += -vy;
                        }

                        return(vector);
                    }
                    ObjFacePoint NewFacePoint(int v, int vt)
                    {
                        ObjFacePoint facepoint = new ObjFacePoint();

                        facepoint.Vertex_Index   = v;
                        facepoint.TexCoord_Index = vt;
                        return(facepoint);
                    }
                    for (int n = 0; n < Math.Min(
                             Vertices.Length, TexCoords.Length
                             ); n += 1)
                    {
                        Rect2d rect_v  = Vertices[n];
                        Rect2d rect_tc = TexCoords[n];

                        if (
                            (rect_v.Pos_TopLeft.X != rect_v.Pos_BottomRight.X) &
                            (rect_v.Pos_TopLeft.Y != rect_v.Pos_BottomRight.Y)
                            )
                        {
                            ObjVector2 newtexcoord_tl = new ObjVector2(
                                rect_tc.Pos_TopLeft.X,
                                rect_tc.Pos_TopLeft.Y);
                            ObjVector2 newtexcoord_tr = new ObjVector2(
                                rect_tc.Pos_BottomRight.X,
                                rect_tc.Pos_TopLeft.Y);
                            ObjVector2 newtexcoord_bl = new ObjVector2(
                                rect_tc.Pos_TopLeft.X,
                                rect_tc.Pos_BottomRight.Y);
                            ObjVector2 newtexcoord_br = new ObjVector2(
                                rect_tc.Pos_BottomRight.X,
                                rect_tc.Pos_BottomRight.Y);
                            if (n == 6 | n == 7)
                            {
                                //These are the top/bottom rectangles
                                newtexcoord_tl.X = rect_tc.Pos_BottomRight.X;
                                newtexcoord_tl.Y = rect_tc.Pos_TopLeft.Y;
                                newtexcoord_tr.X = rect_tc.Pos_BottomRight.X;
                                newtexcoord_tr.Y = rect_tc.Pos_BottomRight.Y;
                                newtexcoord_bl.X = rect_tc.Pos_TopLeft.X;
                                newtexcoord_bl.Y = rect_tc.Pos_TopLeft.Y;
                                newtexcoord_br.X = rect_tc.Pos_TopLeft.X;
                                newtexcoord_br.Y = rect_tc.Pos_BottomRight.Y;
                            }

                            ObjVector3 newvertex_tl = DeterminePosition(
                                rect_v.Pos_TopLeft.X,
                                rect_v.Pos_TopLeft.Y);
                            ObjVector3 newvertex_tr = DeterminePosition(
                                rect_v.Pos_BottomRight.X,
                                rect_v.Pos_TopLeft.Y);
                            ObjVector3 newvertex_bl = DeterminePosition(
                                rect_v.Pos_TopLeft.X,
                                rect_v.Pos_BottomRight.Y);
                            ObjVector3 newvertex_br = DeterminePosition(
                                rect_v.Pos_BottomRight.X,
                                rect_v.Pos_BottomRight.Y);

                            int v_index_tl  = AddVertex(newvertex_tl);
                            int v_index_tr  = AddVertex(newvertex_tr);
                            int v_index_bl  = AddVertex(newvertex_bl);
                            int v_index_br  = AddVertex(newvertex_br);
                            int tc_index_tl = newgroup.TexCoords.Count;
                            newgroup.TexCoords.Add(newtexcoord_tl);
                            int tc_index_tr = newgroup.TexCoords.Count;
                            newgroup.TexCoords.Add(newtexcoord_tr);
                            int tc_index_bl = newgroup.TexCoords.Count;
                            newgroup.TexCoords.Add(newtexcoord_bl);
                            int tc_index_br = newgroup.TexCoords.Count;
                            newgroup.TexCoords.Add(newtexcoord_br);

                            ObjFace newface = new ObjFace();
                            newface.UsesNormals   = false;
                            newface.UsesTexCoords = true;
                            newface.Points.Add(NewFacePoint(
                                                   v_index_tl, tc_index_tl
                                                   ));
                            newface.Points.Add(NewFacePoint(
                                                   v_index_bl, tc_index_bl
                                                   ));
                            newface.Points.Add(NewFacePoint(
                                                   v_index_br, tc_index_br
                                                   ));
                            newface.Points.Add(NewFacePoint(
                                                   v_index_tr, tc_index_tr
                                                   ));
                            newgroup.Faces.Add(newface);
                        }
                    }
                }

                #region Create rectangles
                //Create rectangles
                //Create vertices and textures
                AdvConsole.WriteLine(ConsoleColor.Green,
                                     "Creating rectangles"
                                     );
                for (int n = 0; n < group.Faces.Count; n += 1)
                {
                    ObjFace face = group.Faces.Item(n);
                    ObjFacePointCollection points   = face.Points;
                    List <ObjVector3>      vertexes = new List <ObjVector3>();
                    for (int m = 0; m < points.Count; m += 1)
                    {
                        int prev = m - 1; if (prev < 0)
                        {
                            prev = points.Count - 1;
                        }
                        int next = m + 1; if (next >= points.Count)
                        {
                            next = 0;
                        }
                        int        index    = points.Item(m).Vertex_Index;
                        int        index_p  = points.Item(prev).Vertex_Index;
                        int        index_n  = points.Item(next).Vertex_Index;
                        ObjVector3 vertex   = group.Vertexes.Item(index);
                        ObjVector3 vertex_p = group.Vertexes.Item(index_p);
                        ObjVector3 vertex_n = group.Vertexes.Item(index_n);
                        bool       xsame    = (vertex.X == vertex_p.X & vertex.X == vertex_n.X);
                        bool       ysame    = (vertex.Y == vertex_p.Y & vertex.Y == vertex_n.Y);
                        bool       zsame    = (vertex.Z == vertex_p.Z & vertex.Z == vertex_n.Z);
                        if (!((xsame & zsame) |
                              (xsame & ysame) |
                              (zsame & ysame)))
                        {
                            vertexes.Add(vertex);
                        }
                    }
                    if (vertexes.Count == 4)
                    {
                        ObjVector3 v1    = vertexes[0];
                        ObjVector3 v2    = vertexes[1];
                        ObjVector3 v3    = vertexes[2];
                        ObjVector3 v4    = vertexes[3];
                        bool       isonx = (v1.X == v2.X & v2.X == v3.X & v3.X == v4.X);
                        bool       isony = (v1.Y == v2.Y & v2.Y == v3.Y & v3.Y == v4.Y);
                        bool       isonz = (v1.Z == v2.Z & v2.Z == v3.Z & v3.Z == v4.Z);
                        if (isonx | isony | isonz)
                        {
                            //coordplane==0: +X+Z plane
                            //coordplane==1: -X+Z plane
                            //coordplane==2: +X-Y plane
                            //coordplane==3: -X-Y plane
                            //coordplane==4: +Z-Y plane
                            //coordplane==5: -Z-Y plane

                            int          coordplane;
                            bool         isclockwise;
                            ObjVector2[] rectpoints;
                            int[]        oldindexes;
                            int          axis = -1; //0=X; 1=Y; 2=Z;
                            if (isonx)
                            {
                                axis = 0;
                            }
                            if (isony)
                            {
                                axis = 1;
                            }
                            if (isonz)
                            {
                                axis = 2;
                            }
                            ObjVector2 v1_2 = null;
                            ObjVector2 v2_2 = null;
                            ObjVector2 v3_2 = null;
                            ObjVector2 v4_2 = null;
                            if (axis == 0)
                            {
                                v1_2 = new ObjVector2(
                                    v1.Z, -v1.Y
                                    );
                                v2_2 = new ObjVector2(
                                    v2.Z, -v2.Y
                                    );
                                v3_2 = new ObjVector2(
                                    v3.Z, -v3.Y
                                    );
                                v4_2 = new ObjVector2(
                                    v4.Z, -v4.Y
                                    );
                            }
                            if (axis == 1)
                            {
                                v1_2 = new ObjVector2(
                                    v1.X, v1.Z
                                    );
                                v2_2 = new ObjVector2(
                                    v2.X, v2.Z
                                    );
                                v3_2 = new ObjVector2(
                                    v3.X, v3.Z
                                    );
                                v4_2 = new ObjVector2(
                                    v4.X, v4.Z
                                    );
                            }
                            if (axis == 2)
                            {
                                v1_2 = new ObjVector2(
                                    v1.X, -v1.Y
                                    );
                                v2_2 = new ObjVector2(
                                    v2.X, -v2.Y
                                    );
                                v3_2 = new ObjVector2(
                                    v3.X, -v3.Y
                                    );
                                v4_2 = new ObjVector2(
                                    v4.X, -v4.Y
                                    );
                            }
                            if (IsARectangle(v1_2, v2_2, v3_2, v4_2, out rectpoints, out oldindexes, out isclockwise))
                            {
                                float width;
                                float height;
                                int   topleftindex;
                                if (isclockwise)
                                {
                                    ObjVector2 tl = rectpoints[1];
                                    ObjVector2 br = rectpoints[3];
                                    topleftindex = oldindexes[1];
                                    width        = -(br.X - tl.X);
                                    height       = br.Y - tl.Y;
                                }
                                else
                                {
                                    ObjVector2 tl = rectpoints[0];
                                    ObjVector2 br = rectpoints[2];
                                    topleftindex = oldindexes[0];
                                    width        = br.X - tl.X;
                                    height       = br.Y - tl.Y;
                                }
                                Rect2d[] rects_v = CalculateVerticesOfRect(
                                    width, height, corner_width, corner_height
                                    );
                                Rect2d[] rects_vt = CalculateTexCoordsOfRect(
                                    width, height, corner_width, corner_height
                                    );
                                if (axis == 1 & !isclockwise)
                                {
                                    coordplane = 0;
                                }
                                else if (axis == 1 & isclockwise)
                                {
                                    coordplane = 1;
                                }
                                else if (axis == 2 & !isclockwise)
                                {
                                    coordplane = 2;
                                }
                                else if (axis == 2 & isclockwise)
                                {
                                    coordplane = 3;
                                }
                                else if (axis == 0 & !isclockwise)
                                {
                                    coordplane = 4;
                                }
                                else
                                {
                                    coordplane = 5;
                                }
                                AddRectangle(vertexes[topleftindex], coordplane, rects_v, rects_vt);
                            }
                        }
                    }
                }
                #endregion

                #region Finalize faces
                AdvConsole.Write(ConsoleColor.Green,
                                 "Finalizing faces "
                                 );
                int cursorleft = Console.CursorLeft;
                int cursortop  = Console.CursorTop;
                for (int n = 0; n <= newgroup.Faces.Count; n += 1)
                {
                    Console.CursorLeft = cursorleft;
                    Console.CursorTop  = cursortop;
                    AdvConsole.WriteLine(ConsoleColor.Green,
                                         "({0}/{1})"
                                         , n, newgroup.Faces.Count);
                    if (n < newgroup.Faces.Count)
                    {
                        int     index = newgroup.Faces.Count - 1 - n;
                        ObjFace face  = newgroup.Faces.Item(index);
                        ObjFacePointCollection newpoints = new ObjFacePointCollection();
                        for (int m = 0; m < 4; m += 1)
                        {
                            int next = m + 1; if (next >= 4)
                            {
                                next = 0;
                            }
                            ObjFacePoint pnt           = face.Points.Item(m);
                            ObjFacePoint pnt_next      = face.Points.Item(next);
                            int          ind           = pnt.Vertex_Index;
                            int          ind_next      = pnt_next.Vertex_Index;
                            int          ind_t         = pnt.TexCoord_Index;
                            int          ind_t_next    = pnt_next.TexCoord_Index;
                            ObjVector3   v             = newgroup.Vertexes.Item(ind);
                            ObjVector3   v_next        = newgroup.Vertexes.Item(ind_next);
                            ObjVector2   vt            = newgroup.TexCoords.Item(ind_t);
                            ObjVector2   vt_next       = newgroup.TexCoords.Item(ind_t_next);
                            double       distanceapart = Math.Sqrt(
                                Math.Pow(v_next.X - v.X, 2) +
                                Math.Pow(v_next.Y - v.Y, 2) +
                                Math.Pow(v_next.Z - v.Z, 2)
                                );
                            double t_distanceapart = Math.Sqrt(
                                Math.Pow(vt_next.X - vt.X, 2) +
                                Math.Pow(vt_next.Y - vt.Y, 2)
                                );
                            double t_direction = PointDirection(
                                vt, vt_next
                                );

                            int axis = -1;//0=X different; 1=Y different; 2=Z different
                            if (v.Y == v_next.Y & v.Z == v_next.Z)
                            {
                                axis = 0;
                            }
                            if (v.X == v_next.X & v.Z == v_next.Z)
                            {
                                axis = 1;
                            }
                            if (v.X == v_next.X & v.Y == v_next.Y)
                            {
                                axis = 2;
                            }

                            ObjFacePoint point_first = new ObjFacePoint();
                            point_first.Vertex_Index   = ind;
                            point_first.TexCoord_Index = ind_t;
                            newpoints.Add(point_first);

                            Dictionary <int, float> newinpoints = new Dictionary <int, float>();//int=vertex index
                            float val;
                            float val_next;
                            if (axis == 0)
                            {
                                val      = v.X;
                                val_next = v_next.X;
                            }
                            else if (axis == 1)
                            {
                                val      = v.Y;
                                val_next = v_next.Y;
                            }
                            else
                            {
                                val      = v.Z;
                                val_next = v_next.Z;
                            }
                            for (int o = 0; o < newgroup.Vertexes.Count; o += 1)
                            {
                                if (o != ind & o != ind_next)
                                {
                                    ObjVector3 vector = newgroup.Vertexes.Item(o);
                                    if (
                                        (axis == 0 & vector.Y == v.Y & vector.Z == v.Z &
                                         vector.X > Math.Min(val, val_next) &
                                         vector.X < Math.Max(val, val_next)) |
                                        (axis == 1 & vector.X == v.X & vector.Z == v.Z &
                                         vector.Y > Math.Min(val, val_next) &
                                         vector.Y < Math.Max(val, val_next)) |
                                        (axis == 2 & vector.X == v.X & vector.Y == v.Y &
                                         vector.Z > Math.Min(val, val_next) &
                                         vector.Z < Math.Max(val, val_next))
                                        )
                                    {
                                        float val_in;
                                        if (axis == 0)
                                        {
                                            val_in = vector.X;
                                        }
                                        else if (axis == 1)
                                        {
                                            val_in = vector.Y;
                                        }
                                        else
                                        {
                                            val_in = vector.Z;
                                        }
                                        newinpoints.Add(o, val_in);
                                    }
                                }
                            }
                            int[]   nip_keys   = newinpoints.Keys.ToArray();
                            float[] nip_values = newinpoints.Values.ToArray();
                            Array.Sort(nip_values, nip_keys);
                            if (val > val_next)
                            {
                                Array.Reverse(nip_keys);
                                Array.Reverse(nip_values);
                            }
                            for (int o = 0; o < nip_keys.Length; o += 1)
                            {
                                int        nip_key      = nip_keys[o];
                                ObjVector3 inpnt        = newgroup.Vertexes.Item(nip_key);
                                double     fromstrt2pnt = Math.Sqrt(
                                    Math.Pow(inpnt.X - v.X, 2) +
                                    Math.Pow(inpnt.Y - v.Y, 2) +
                                    Math.Pow(inpnt.Z - v.Z, 2)
                                    );
                                double xx   = vt.X + Math.Cos(t_direction) * (fromstrt2pnt / distanceapart) * t_distanceapart;
                                double yy   = vt.Y + Math.Sin(t_direction) * (fromstrt2pnt / distanceapart) * t_distanceapart;
                                int    tind = newgroup.TexCoords.Count; newgroup.TexCoords.Add(
                                    new ObjVector2((float)xx, (float)yy));

                                ObjFacePoint point_in = new ObjFacePoint();
                                point_in.Vertex_Index   = nip_key;
                                point_in.TexCoord_Index = tind;
                                newpoints.Add(point_in);
                            }
                        }
                        face.Points = newpoints;
                    }
                }
                #endregion

                #region Save OBJ
                AdvConsole.WriteLine(ConsoleColor.Green,
                                     "Saving OBJ"
                                     );
                string DetermineMTLSaveName()
                {
                    string filewithoutext = Path.GetDirectoryName(
                        Path.GetFullPath(file_source)) +
                                            Path.GetFileNameWithoutExtension(
                        file_source);
                    string mtlfilename = filewithoutext + ".mtl";
                    int    i           = 0;

                    while (File.Exists(mtlfilename))
                    {
                        mtlfilename = filewithoutext + i.ToString() + ".mtl";
                        i          += 1;
                    }
                    return(mtlfilename);
                }
                Obj newobj = new Obj();
                newobj.Groups.Add("newgroup", newgroup);
                newobj.Save(file_dest, DetermineMTLSaveName());
                #endregion
            }
            catch (Exception ex)
            {
                WriteError("Could not complete program\n" +
                           ex.Message);
            }
        }
        private ObjFace ProcessFace(string[] data)
        {
            ObjFace face = new ObjFace();

            for (int i = 0; i < 3; i++)
            {
                string[] faceData = data[i + 1].Split(new[] { '/' });

                // Ensure we've allocated arrays for this type of data.
                if (faceData.Length >= 1) // Position only
                {
                    if (face.Positions == null)
                    {
                        face.Positions = new int[3];
                    }
                }
                if (faceData.Length >= 2 && faceData[1] != "") // Potentially no Texcoord
                {
                    if (face.TexCoords == null)
                    {
                        face.TexCoords = new int[3];
                    }
                }
                if (faceData.Length >= 3) // Position + Normal, Potentially no Texcoord
                {
                    if (face.Normals == null)
                    {
                        face.Normals = new int[3];
                    }
                }

                if (faceData.Length >= 1)
                {
                    int  posIndex;
                    bool bHasPos = int.TryParse(faceData[0], out posIndex);
                    if (bHasPos)
                    {
                        face.Positions[i] = posIndex - 1;
                    }
                }
                if (faceData.Length >= 2)
                {
                    int  texCoordIndex;
                    bool bHasTexcoord = int.TryParse(faceData[1], out texCoordIndex);
                    if (bHasTexcoord)
                    {
                        face.TexCoords[i] = texCoordIndex - 1;
                    }
                }
                if (faceData.Length >= 3)
                {
                    int  normalIndex;
                    bool bHasNormal = int.TryParse(faceData[2], out normalIndex);
                    if (bHasNormal)
                    {
                        face.Normals[i] = normalIndex - 1;
                    }
                }
            }

            return(face);
        }
Example #23
0
        private static void ParseFace(ObjContext objContext, string[] token)
        {
            if (objContext == null)
            {
                throw new ArgumentNullException("objContext");
            }
            if (token == null)
            {
                throw new ArgumentNullException("token");
            }
            if (token.Length < 3)
            {
                throw new ArgumentException("wrong array length", "token");
            }

            if (objContext.Groups.Count == 0)
            {
                throw new InvalidOperationException("no group");
            }
            ObjGroup objGroup = objContext.Groups[objContext.Groups.Count - 1];

            if (objGroup.Geometries.Count == 0)
            {
                throw new InvalidOperationException("no geometry");
            }
            ObjGeometry objGeometry = objGroup.Geometries[objGroup.Geometries.Count - 1];

            ObjFace objFace = new ObjFace();

            foreach (string values in token)
            {
                string[] indices       = Regex.Split(values, "/");
                int[]    indicesValues = Array.ConvertAll(indices, delegate(string item) {
                    if (String.IsNullOrEmpty(item) == false)
                    {
                        return(Int32.Parse(item, NumberFormatInfo.InvariantInfo));
                    }
                    else
                    {
                        return(Int32.MinValue);
                    }
                });

                int indexVertex   = indicesValues[0];
                int indexNormal   = indicesValues[2];
                int indexTexCoord = indicesValues[1];

                ObjFaceCoord objFaceCoord = new ObjFaceCoord();

                // Position
                if (indexVertex < 0)
                {
                    indexVertex = objContext.Vertices.Count + indexVertex + 1;
                }
                objFaceCoord.VertexIndex = indexVertex - 1;

                // Normal (optional)
                if (indexNormal != Int32.MinValue)
                {
                    if (indexNormal < 0)
                    {
                        indexNormal = objContext.Normals.Count + indexNormal + 1;
                    }
                    objFaceCoord.NormalIndex = indexNormal - 1;
                }

                // Tex coord (optional)
                if (indexTexCoord != Int32.MinValue)
                {
                    if (indexTexCoord < 0)
                    {
                        indexTexCoord = objContext.TextureCoords.Count + indexTexCoord + 1;
                    }
                    objFaceCoord.TexCoordIndex = indexTexCoord - 1;
                }

                objFace.Coords.Add(objFaceCoord);
            }

            objGeometry.Faces.Add(objFace);
        }
Example #24
0
    private Mesh GetMesh(ObjModel model)
    {
        Mesh m = new Mesh
        {
            name = Name
        };
        int            count        = FaceList.Count * 3;
        List <Vector3> verticesList = new List <Vector3>();
        List <Vector3> normalList   = new List <Vector3>();
        List <Vector2> uvList       = new List <Vector2>();
        bool           hasNormal    = false;
        List <int[]>   triangleList = new List <int[]>();
        //用于保存顶点索引(全局) 与当前mesh中 顶点的索引
        Dictionary <string, int> indexDict = new Dictionary <string, int>();

        //按照材质去找面
        foreach (string matName in MatsList)
        {
            List <ObjFace> faces = FaceList.FindAll((ObjFace o) =>
            {
                if (o.MatName == matName)
                {
                    return(true);
                }
                return(false);
            });

            int[] triangles = new int[faces.Count * 3];
            int   idx       = 0;
            //
            for (int i = 0; i < faces.Count; i++)
            {
                ObjFace  face = faces[i];
                string[] f    = face.FaceStr;

                for (int j = 0; j < f.Length; j++)
                {
                    string[] indexs = f[j].Split('/');
                    int      vIndex = int.Parse(indexs[0]);
                    int      nIndex = -1;
                    int      uIndex = -1;

                    if (indexs.Length > 2 && indexs[2] != "")
                    {
                        nIndex    = int.Parse(indexs[2]);
                        hasNormal = true;
                    }

                    //法线索引
                    if (indexs.Length > 1 && indexs[1] != "")
                    {
                        uIndex = int.Parse(indexs[1]);
                    }

                    string key = vIndex + "|" + uIndex + "|" + nIndex;
                    if (indexDict.ContainsKey(key))
                    {
                        triangles[idx] = indexDict[key];
                    }
                    else
                    {
                        triangles[idx] = verticesList.Count;
                        indexDict[key] = verticesList.Count;
                        verticesList.Add(model.VertexList[vIndex - 1]);
                        normalList.Add(nIndex == -1 ? Vector3.zero : model.NormalList[nIndex - 1]);
                        uvList.Add(uIndex == -1 ? Vector2.zero : model.UVList[uIndex - 1]);
                    }
                    idx++;
                }
            }
            triangleList.Add(triangles);
        }

        m.vertices     = verticesList.ToArray();
        m.normals      = normalList.ToArray();
        m.uv           = uvList.ToArray();
        m.subMeshCount = triangleList.Count;
        for (int i = 0; i < triangleList.Count; i++)
        {
            m.SetTriangles(triangleList[i], i);
        }

        if (!hasNormal)
        {
            m.RecalculateNormals();
        }
        m.RecalculateBounds();
        return(m);
    }
Example #25
0
 public void AddFace(ObjFace face)
 {
     _faces.Add(face);
 }
Example #26
0
    /// <summary>
    /// 解析obj文件
    /// </summary>
    /// <param name="objPath"></param>
    /// <returns></returns>
    public static ObjModel ParseObj(string objContent, string objName = "obj")
    {
        if (string.IsNullOrEmpty(objContent))
        {
            return(null);
        }

        ObjModel model   = new ObjModel(objName);
        string   matName = "Standard";

        string[] allLines = objContent.Split('\n');
        //将文本化后的obj文件内容按行分割
        foreach (string line in allLines)
        {
            if (string.IsNullOrEmpty(line) || line[0] == '#' || string.IsNullOrEmpty(line))
            {
                continue;
            }

            //去掉多余的空格 有的中间会是2个空格
            string   temp  = line.Trim().Replace("  ", " ");
            string[] chars = temp.Split(' ');
            if (chars.Length <= 1)
            {
                continue;
            }

            //移除第一个空格前的字符   如 v f vt vn
            string data = temp.Remove(0, temp.IndexOf(' ') + 1);
            //根据第一个字符来判断数据的类型
            switch (chars[0])
            {
            case "mtllib":
                model.MtlName = data;
                break;

            //处理顶点
            case "v":
                model.VertexList.Add(StringToVector3(chars));
                break;

            //处理法线
            case "vn":
                model.NormalList.Add(StringToVector3(chars));
                break;

            //处理UV
            case "vt":
                model.UVList.Add(StringToVector3(chars));
                break;

            case "g":
            case "o":
                model.AddObjPart(data);
                break;

            //使用的材质球名字
            case "usemtl":
                matName = data;
                break;

            //处理面
            case "f":
                if (model.LastPart == null)
                {
                    continue;
                }

                //3个点
                if (chars.Length >= 4)
                {
                    string[] faceStr = new string[] { chars[1], chars[2], chars[3] };
                    ObjFace  face    = new ObjFace(matName, faceStr);
                    model.LastPart.FaceList.Add(face);
                }
                //4个点  相当于2个面
                if (chars.Length >= 5)
                {
                    string[] faceStr = new string[] { chars[3], chars[4], chars[1] };
                    ObjFace  face    = new ObjFace(matName, faceStr);
                    model.LastPart.FaceList.Add(face);
                }

                if (model.LastPart.MatsList.Contains(matName) == false)
                {
                    model.LastPart.MatsList.Add(matName);
                }
                break;
            }
        }

        return(model);
    }
        private ObjFace ProcessFace(string[] data)
        {
            ObjFace face = new ObjFace();

            for (int i = 0; i < 3; i++)
            {
                string[] faceData = data[i + 1].Split(new[] { '/' });

                // Ensure we've allocated arrays for this type of data.
                if (faceData.Length >= 1) // Position only
                    if (face.Positions == null) face.Positions = new int[3];
                if (faceData.Length >= 2 && faceData[1] != "") // Potentially no Texcoord
                    if (face.TexCoords == null) face.TexCoords = new int[3];
                if (faceData.Length >= 3) // Position + Normal, Potentially no Texcoord
                    if (face.Normals == null) face.Normals = new int[3];

                if (faceData.Length >= 1)
                {
                    int posIndex;
                    bool bHasPos = int.TryParse(faceData[0], out posIndex);
                    if (bHasPos) face.Positions[i] = posIndex - 1;
                }
                if (faceData.Length >= 2)
                {
                    int texCoordIndex;
                    bool bHasTexcoord = int.TryParse(faceData[1], out texCoordIndex);
                    if (bHasTexcoord) face.TexCoords[i] = texCoordIndex - 1;
                }
                if (faceData.Length >= 3)
                {
                    int normalIndex;
                    bool bHasNormal = int.TryParse(faceData[2], out normalIndex);
                    if (bHasNormal) face.Normals[i] = normalIndex - 1;
                }
            }

            return face;
        }
Example #28
0
        // Read the obj file.
        private void ReadObjFile(string dir, string objfile)
        {
            char[]        whitespace = { ' ', '\t' };
            List <string> unknown    = new List <string>();

            // The current smoothing group.
            int smoothingGroup = 0;

            // The current material name.
            string curMatName = "";

            // Read the file.
            using (StreamReader file = new System.IO.StreamReader(dir + objfile))
            {
                while (!file.EndOfStream)
                {
                    // Read the next line.
                    string line = CleanLine(file.ReadLine());
                    if (line.Length == 0)
                    {
                        continue;
                    }

                    string[] fields = line.Split(whitespace, StringSplitOptions.RemoveEmptyEntries);
                    switch (fields[0])
                    {
                    case "o":           // Object model.
                    case "g":           // Group.
                        // Only create a new one if the current one isn't empty.
                        if ((NewObjectModel == null) || (NewObjectModel.Faces.Count > 0))
                        {
                            NewObjectModel = new ObjModel();
                            AllObjectModels.Add(NewObjectModel);
                        }
                        NewObjectModel.MaterialName = curMatName;
                        if (fields.Length > 1)
                        {
                            NewObjectModel.Name = fields[1];
                        }
                        smoothingGroup = 0;
                        break;

                    case "v":           // Vertex.
                        double x = double.Parse(fields[1]);
                        double y = double.Parse(fields[2]);
                        double z = double.Parse(fields[3]);
                        AllVertices.Add(new Point3D(x, y, z));
                        break;

                    case "vt":          // Texture coordinates.
                        double u = double.Parse(fields[1]);
                        double v = double.Parse(fields[2]);
                        AllTextureCoordinates.Add(new Point(u, v));
                        break;

                    case "vn":          // Normal.
                        double nx = double.Parse(fields[1]);
                        double ny = double.Parse(fields[2]);
                        double nz = double.Parse(fields[3]);
                        AllNormals.Add(new Vector3D(nx, ny, nz));
                        break;

                    case "f":           // Face.
                        ObjFace face = new ObjFace(
                            AllVertices, AllNormals, AllTextureCoordinates, line);
                        face.SmoothingGroup = smoothingGroup;
                        NewObjectModel.Faces.Add(face);
                        NewObjectModel.MaterialName = curMatName;
                        break;

                    case "s":           // Smoothing.
                        if (fields.Length == 0)
                        {
                            smoothingGroup = 0;
                        }
                        else if (fields[1] == "off")
                        {
                            smoothingGroup = 0;
                        }
                        else if (fields[1] == "on")
                        {
                            smoothingGroup = 1;
                        }
                        else if (!int.TryParse(fields[1], out smoothingGroup))
                        {
                            smoothingGroup = 0;
                        }
                        break;

                    case "usemtl":           // Material.
                        if (fields.Length > 1)
                        {
                            curMatName = fields[1];
                        }
                        break;

                    case "mtllib":          // Material file.
                        string mtlfile = line.Substring(6).Trim();
                        ReadMtlFile(dir, mtlfile);
                        break;

                    default:
                        if (!unknown.Contains(fields[0]))
                        {
                            unknown.Add(fields[0]);
                        }
                        break;
                    }
                }
            }

            // If the final model is empty, remove it.
            if (AllObjectModels[AllObjectModels.Count - 1].Faces.Count == 0)
            {
                AllObjectModels.RemoveAt(AllObjectModels.Count - 1);
            }

            // List unknown tokens.
            if (unknown.Count > 0)
            {
                Console.WriteLine("Unknown obj tokens:");
                foreach (string token in unknown)
                {
                    Console.WriteLine("    " + token);
                }
            }
        }
        public ObjFile Import(string modelPath)
        {
            try
            {
                buffer = File.ReadAllBytes(modelPath);
            }
            catch
            {
                Console.WriteLine("Could not find model: " + modelPath);
                return(null);
            }

            int[][] sections = ParseFile();
            Dictionary <int, object[]> parsedSections = new Dictionary <int, object[]>();

            foreach (int[] section in sections)
            {
                switch (section[1])
                {
                case AnimationDataTag:
                    //Debug.Log("animation data");
                    parsedSections[section[2]] = ParseAnimationData(section[0] + 12, section[3], section[2]);
                    break;

                case AuthorTag:
                    //Debug.Log("author tag");
                    parsedSections[section[2]] = ParseAuthor(section[0] + 12, section[3], section[2]);
                    break;

                case MaterialGroupTag:
                    //Debug.Log("material group tag");
                    parsedSections[section[2]] = ParseMaterialGroup(section[0] + 12, section[3], section[2]);
                    break;

                case MaterialTag:
                    //Debug.Log("material tag");
                    parsedSections[section[2]] = ParseMaterial(section[0] + 12, section[3], section[2]);
                    break;

                case Object3DTag:
                    //Debug.Log("object3d tag");
                    parsedSections[section[2]] = ParseObject3D(section[0] + 12, section[3], section[2]);
                    break;

                case ModelDataTag:
                    //Debug.Log("model data tag");
                    parsedSections[section[2]] = ParseModelData(section[0] + 12, section[3], section[2]);
                    break;

                case GeometryTag:
                    //Debug.Log("geometry tag");
                    parsedSections[section[2]] = ParseGeometry(section[0] + 12, section[3], section[2]);
                    break;

                case TopologyTag:
                    //Debug.Log("topology tag");
                    parsedSections[section[2]] = ParseTopology(section[0] + 12, section[3], section[2]);
                    break;

                case TopologyIpTag:
                    //Debug.Log("topologyIP tag");
                    parsedSections[section[2]] = ParseTopologyIp(section[0] + 12, section[3], section[2]);
                    break;
                }

                if ((uint)section[1] == PassthroughTag)
                {
                    parsedSections[section[2]] = ParsePassthroughGp(section[0] + 12, section[3], section[2]);
                }
            }

            ObjFile obj = new ObjFile();

            foreach (int[] section in sections)
            {
                if (section[1] == ModelDataTag)
                {
                    object[] modelData = parsedSections[section[2]];
                    if ((int)modelData[3] == 6)
                    {
                        continue;
                    }
                    string         modelId  = "model-" + ((object[])modelData[2])[1];
                    object[]       geometry = parsedSections[(int)parsedSections[(int)modelData[4]][2]];
                    object[]       topology = parsedSections[(int)parsedSections[(int)modelData[4]][3]];
                    List <short[]> faces    = (List <short[]>)topology[4];
                    List <float[]> vertices = (List <float[]>)geometry[6];
                    List <float[]> uvs      = (List <float[]>)geometry[7];
                    List <float[]> normals  = (List <float[]>)geometry[8];
                    float[]        position = (float[])((object[])modelData[2])[5];

                    foreach (short[] face in faces)
                    {
                        ObjFace objFace = new ObjFace();
                        objFace.Vertices.Add(new ObjTriplet(face[0] + 1, face[0] + 1, face[0] + 1));
                        objFace.Vertices.Add(new ObjTriplet(face[1] + 1, face[1] + 1, face[1] + 1));
                        objFace.Vertices.Add(new ObjTriplet(face[2] + 1, face[2] + 1, face[2] + 1));
                        obj.Faces.Add(objFace);
                    }

                    foreach (float[] vertex in vertices)
                    {
                        obj.Vertices.Add(new ObjVertex(vertex[0] + position[0], vertex[1] + position[1],
                                                       vertex[2] + position[2]));
                    }

                    foreach (float[] uv in uvs)
                    {
                        obj.TextureVertices.Add(new ObjVector3(uv[0], -uv[1], 0));
                    }

                    foreach (float[] normal in normals)
                    {
                        obj.VertexNormals.Add(new ObjVector3(normal[0], normal[1], normal[2]));
                    }
                }
            }

            return(obj);
        }