Esempio n. 1
0
        public static (int[], int[]) FillPolygon(IMeshBuilder meshBuilder, IList <Vector3d> newPolygon, Vector3f normal)
        {
            if (meshBuilder == null || newPolygon == null)
            {
                return(null, null);
            }
            var triangulation = Geometry.Triangulate(newPolygon, normal);

            if (triangulation == null)
            {
                return(null, null);
            }
            //add vertices and triangles of basement to mesh
            var vertexToIndex    = new Dictionary <Vector3d, int>();
            var addedTriangles   = new int[triangulation.Count];
            int addedTriangleIdx = 0;

            foreach (var triangle in triangulation)
            {
                int a0 = AddDistinctVertex3d(meshBuilder, vertexToIndex, triangle[0], normal);
                int b0 = AddDistinctVertex3d(meshBuilder, vertexToIndex, triangle[1], normal);
                int c0 = AddDistinctVertex3d(meshBuilder, vertexToIndex, triangle[2], normal);

                addedTriangles[addedTriangleIdx] = meshBuilder.AppendTriangle(a0, b0, c0);
                addedTriangleIdx++;
            }
            int[] newVertices = vertexToIndex.Values.ToArray();
            return(newVertices, addedTriangles);
        }
        public IOReadResult Read(TextReader reader, ReadOptions options, IMeshBuilder builder)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Model));
            Model         model;

            try {
                model = (Model)serializer.Deserialize(reader);
            } catch (Exception e) {
                return(new IOReadResult(IOCode.FileParsingError, $"XML parsing error: {e}"));
            }

            foreach (var @object in model.resources.objects)
            {
                var mesh   = @object.mesh;
                int meshId = builder.AppendNewMesh(false, false, false, true);
                var mapV   = new int[mesh.vertices.vertices.Length];
                for (int k = 0; k < mesh.vertices.vertices.Length; ++k)
                {
                    var vertex = mesh.vertices.vertices[k];
                    mapV[k] = builder.AppendVertex(vertex.x, vertex.y, vertex.z);
                }
                for (int j = 0; j < mesh.triangles.triangles.Length; ++j)
                {
                    var triangle = mesh.triangles.triangles[j];
                    builder.AppendTriangle(mapV[triangle.v1], mapV[triangle.v2], mapV[triangle.v3]);
                }
            }

            return(IOReadResult.Ok);
        }
Esempio n. 3
0
        public IOReadResult Read(TextReader reader, ReadOptions options, IMeshBuilder builder)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(AMF));
            AMF           amf;

            try {
                amf = (AMF)serializer.Deserialize(reader);
            } catch (Exception e) {
                return(new IOReadResult(IOCode.FileParsingError, $"XML parsing error: {e}"));
            }

            foreach (var @object in amf.objects)
            {
                foreach (var mesh in @object.meshes)
                {
                    int meshId = builder.AppendNewMesh(false, false, false, true);
                    var mapV   = new int[mesh.vertices.vertices.Length];
                    for (int k = 0; k < mesh.vertices.vertices.Length; ++k)
                    {
                        var coordinates = mesh.vertices.vertices[k].coordinates;
                        mapV[k] = builder.AppendVertex(coordinates.x, coordinates.y, coordinates.z);
                    }
                    for (int i = 0; i < mesh.volumes.Length; ++i)
                    {
                        for (int j = 0; j < mesh.volumes[i].triangles.Length; ++j)
                        {
                            var triangle = mesh.volumes[i].triangles[j];
                            builder.AppendTriangle(mapV[triangle.v1], mapV[triangle.v2], mapV[triangle.v3], i);
                        }
                    }
                }
            }

            return(IOReadResult.Ok);
        }
Esempio n. 4
0
 unsafe int append_triangle(IMeshBuilder builder, Triangle t)
 {
     if (t.vIndices[0] < 0 || t.vIndices[1] < 0 || t.vIndices[2] < 0)
     {
         emit_warning(string.Format("[OBJReader] invalid triangle:  {0} {1} {2}",
                                    t.vIndices[0], t.vIndices[1], t.vIndices[2]));
         return(-1);
     }
     return(builder.AppendTriangle(t.vIndices[0], t.vIndices[1], t.vIndices[2]));
 }
Esempio n. 5
0
 int append_triangle(IMeshBuilder builder, Index3i tri)
 {
     if (tri.a < 0 || tri.b < 0 || tri.c < 0)
     {
         emit_warning(string.Format("[PLYReader] invalid triangle:  {0} {1} {2}",
                                    tri.a, tri.b, tri.c));
         return(-1);
     }
     return(builder.AppendTriangle(tri.a, tri.b, tri.c));
 }
Esempio n. 6
0
        int append_triangle(IMeshBuilder builder, Triangle t)
        {
            if (t.vIndices[0] < 0 || t.vIndices[1] < 0 || t.vIndices[2] < 0)
            {
                emit_warning(string.Format("[OBJReader] invalid triangle:  {0} {1} {2}",
                                           t.vIndices[0], t.vIndices[1], t.vIndices[2]));
                return(-1);
            }
            int gid = (t.nGroupID == Triangle.InvalidGroupID) ?
                      m_nSetInvalidGroupsTo : t.nGroupID;

            return(builder.AppendTriangle(t.vIndices[0], t.vIndices[1], t.vIndices[2], gid));
        }
Esempio n. 7
0
        unsafe int append_triangle(IMeshBuilder builder, int nTri, int[] mapV)
        {
            Triangle t  = vTriangles[nTri];
            int      v0 = mapV[t.vIndices[0] - 1];
            int      v1 = mapV[t.vIndices[1] - 1];
            int      v2 = mapV[t.vIndices[2] - 1];

            if (v0 == -1 || v1 == -1 || v2 == -1)
            {
                emit_warning(string.Format("[OBJReader] invalid triangle:  {0} {1} {2}  mapped to {3} {4} {5}",
                                           t.vIndices[0], t.vIndices[1], t.vIndices[2], v0, v1, v2));
                return(-1);
            }
            return(builder.AppendTriangle(v0, v1, v2));
        }
Esempio n. 8
0
        int append_triangle(IMeshBuilder builder, int nTri, int[] mapV)
        {
            Triangle t  = vTriangles[nTri];
            int      v0 = mapV[t.vIndices[0] - 1];
            int      v1 = mapV[t.vIndices[1] - 1];
            int      v2 = mapV[t.vIndices[2] - 1];

            if (v0 == -1 || v1 == -1 || v2 == -1)
            {
                emit_warning(string.Format("[OBJReader] invalid triangle:  {0} {1} {2}  mapped to {3} {4} {5}",
                                           t.vIndices[0], t.vIndices[1], t.vIndices[2], v0, v1, v2));
                return(-1);
            }
            int gid = (vTriangles[nTri].nGroupID == Triangle.InvalidGroupID) ?
                      m_nSetInvalidGroupsTo : vTriangles[nTri].nGroupID;

            return(builder.AppendTriangle(v0, v1, v2, gid));
        }
Esempio n. 9
0
        protected virtual void BuildMesh_NoMerge(STLSolid solid, IMeshBuilder builder)
        {
            /*int meshID = */ builder.AppendNewMesh(false, false, false, false);

            DVectorArray3f vertices = solid.Vertices;
            int            nTris    = vertices.Count / 3;

            for (int ti = 0; ti < nTris; ++ti)
            {
                Vector3f va = vertices[3 * ti];
                int      a  = builder.AppendVertex(va.x, va.y, va.z);
                Vector3f vb = vertices[3 * ti + 1];
                int      b  = builder.AppendVertex(vb.x, vb.y, vb.z);
                Vector3f vc = vertices[3 * ti + 2];
                int      c  = builder.AppendVertex(vc.x, vc.y, vc.z);

                builder.AppendTriangle(a, b, c);
            }
        }
Esempio n. 10
0
        protected virtual void BuildMesh_IdenticalWeld(STLSolid solid, IMeshBuilder builder)
        {
            /*int meshID = */ builder.AppendNewMesh(false, false, false, false);

            DVectorArray3f vertices = solid.Vertices;
            int            N        = vertices.Count;

            int[] mapV = new int[N];

            Dictionary <Vector3f, int> uniqueV = new Dictionary <Vector3f, int>();

            for (int vi = 0; vi < N; ++vi)
            {
                Vector3f v = vertices[vi];
                int      existing_idx;
                if (uniqueV.TryGetValue(v, out existing_idx))
                {
                    mapV[vi] = existing_idx;
                }
                else
                {
                    int vid = builder.AppendVertex(v.x, v.y, v.z);
                    uniqueV[v] = vid;
                    mapV[vi]   = vid;
                }
            }


            int nTris = N / 3;

            for (int ti = 0; ti < nTris; ++ti)
            {
                int a = mapV[3 * ti];
                int b = mapV[3 * ti + 1];
                int c = mapV[3 * ti + 2];
                if (a == b || a == c || b == c)     // don't try to add degenerate triangles
                {
                    continue;
                }
                builder.AppendTriangle(a, b, c);
            }
        }
Esempio n. 11
0
        public IOReadResult Read(TextReader reader, ReadOptions options, IMeshBuilder builder)
        {
            // format is:
            //
            // OFF
            // VCOUNT TCOUNT     (2 ints)
            // x y z
            // ...
            // 3 va vb vc
            // ...
            //

            string first_line = reader.ReadLine();

            if (first_line.StartsWith("OFF") == false)
            {
                return(new IOReadResult(IOCode.FileParsingError, "ascii OFF file must start with OFF header"));
            }

            int nVertexCount   = 0;
            int nTriangleCount = 0;

            int nLines = 0;

            while (reader.Peek() >= 0)
            {
                string line = reader.ReadLine();
                nLines++;
                string[] tokens = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
                if (tokens.Length == 0)
                {
                    continue;
                }

                if (tokens[0].StartsWith("#"))
                {
                    continue;
                }

                if (tokens.Length != 3)
                {
                    return(new IOReadResult(IOCode.FileParsingError, "first non-comment line of OFF must be vertex/tri/edge counts, found: " + line));
                }
                nVertexCount   = int.Parse(tokens[0]);
                nTriangleCount = int.Parse(tokens[1]);
                //int nEdgeCount = int.Parse(tokens[2]);
                break;
            }


            builder.AppendNewMesh(false, false, false, false);

            int vi = 0;

            while (vi < nVertexCount && reader.Peek() > 0)
            {
                string line = reader.ReadLine();
                nLines++;
                string[] tokens = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
                if (tokens.Length == 0)
                {
                    continue;
                }

                if (tokens[0].StartsWith("#"))
                {
                    continue;
                }

                if (tokens.Length != 3)
                {
                    emit_warning("found invalid OFF vertex line: " + line);
                }

                double x = Double.Parse(tokens[0]);
                double y = Double.Parse(tokens[1]);
                double z = Double.Parse(tokens[2]);
                builder.AppendVertex(x, y, z);
                vi++;
            }
            if (vi < nVertexCount)
            {
                return(new IOReadResult(IOCode.FileParsingError,
                                        string.Format("File specified {0} vertices but only found {1}", nVertexCount, vi)));
            }


            int ti = 0;

            while (ti < nTriangleCount && reader.Peek() > 0)
            {
                string line = reader.ReadLine();
                nLines++;
                string[] tokens = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
                if (tokens.Length == 0)
                {
                    continue;
                }

                if (tokens[0].StartsWith("#"))
                {
                    continue;
                }

                if (tokens.Length < 4)
                {
                    emit_warning("found invalid OFF triangle line: " + line);
                }

                int nV = int.Parse(tokens[0]);
                if (nV != 3)
                {
                    emit_warning("found non-triangle polygon in OFF, currently unsupported: " + line);
                }

                int a = int.Parse(tokens[1]);
                int b = int.Parse(tokens[2]);
                int c = int.Parse(tokens[3]);

                builder.AppendTriangle(a, b, c);
                ti++;
            }
            if (ti < nTriangleCount)
            {
                emit_warning(string.Format("File specified {0} triangles but only found {1}", nTriangleCount, ti));
            }

            return(new IOReadResult(IOCode.Ok, ""));
        }
Esempio n. 12
0
        private bool is3ds;      // usd to shwo that the 4D4D magic number has been found


        public IOReadResult Read(BinaryReader reader, ReadOptions options, IMeshBuilder builder)
        {
            ushort ChunkID;
            String ChnkID = "";
            UInt32 Clength;

            MeshName = "";
            hasMesh  = false;
            is3ds    = false;

            // Process the file - fails very politely when there is no more data
            while (true)
            {
                //Get the Id of the next Chunk
                try {
                    ChunkID = reader.ReadUInt16();
                } catch {
                    break;
                }
                ChnkID = ChunkID.ToString("X");

                //Get the size of the next chunk in chars
                Clength = reader.ReadUInt32();

                //Process based on Chunk ID
                switch (ChnkID)
                {
                case "4D4D":
                    //This is a new file header
                    is3ds = true;
                    reader.ReadChars(10);
                    break;

                case "3D3D":
                    //This is a new Object Header
                    reader.ReadChars(10);
                    break;

                case "4000":
                    //This is an object Block. Store the name temporarily in case it is a mesh
                    List <char> name = new List <char>();
                    while (true)
                    {
                        char next = reader.ReadChar();
                        if (next == 0)
                        {
                            break;
                        }
                        name.Add(next);
                    }
                    MeshName = new String(name.ToArray <char>());
                    break;

                case "4100":
                    // This is a new Mesh. Retrieve the name and add if the builder supports Metadata
                    builder.AppendNewMesh(false, false, false, false);
                    if (builder.SupportsMetaData)
                    {
                        builder.AppendMetaData("name", MeshName);
                    }
                    break;

                case "4110":
                    // List of Vertexes
                    ushort VertexCount = reader.ReadUInt16();
                    for (int x = 0; x < VertexCount; x++)
                    {
                        double X = reader.ReadSingle();
                        double Y = reader.ReadSingle();
                        double Z = reader.ReadSingle();
                        builder.AppendVertex(X, Y, Z);
                    }
                    break;

                case "4120":
                    // List of Triangles
                    ushort PolygonCount = reader.ReadUInt16();
                    for (int j = 0; j < PolygonCount; j++)
                    {
                        int a     = reader.ReadInt16();
                        int b     = reader.ReadInt16();
                        int c     = reader.ReadInt16();
                        int flags = reader.ReadUInt16();
                        builder.AppendTriangle(a, b, c);
                    }
                    break;

                case "4130":
                    // Mapping from Vertex to Material - retrieved but not currently used
                    List <char> mname = new List <char>();
                    while (true)
                    {
                        char next = reader.ReadChar();
                        if (next == 0)
                        {
                            break;
                        }
                        mname.Add(next);
                    }
                    string MatName = new String(mname.ToArray <char>());
                    ushort entries = reader.ReadUInt16();
                    for (int i = 0; i < entries; i++)
                    {
                        ushort face = reader.ReadUInt16();
                    }
                    break;

                case "4140":
                    // List of UVs per vertex
                    ushort uvCount = reader.ReadUInt16();
                    for (ushort y = 0; y < uvCount; y++)
                    {
                        Vector2f UV = new Vector2f(reader.ReadSingle(), reader.ReadSingle());
                        builder.SetVertexUV(y, UV);
                    }
                    break;

                default:
                    // Any other chunk - retrieved and not used - held in dump temporarily for debug
                    char[] dump = reader.ReadChars((int)Clength - 6);
                    break;
                }
            }
            if (!is3ds)
            {
                return(new IOReadResult(IOCode.FileAccessError, "File is not in .3DS format"));
            }
            else if (!hasMesh)
            {
                return(new IOReadResult(IOCode.FileParsingError, "no mesh found in file"));
            }
            else
            {
                return(new IOReadResult(IOCode.Ok, ""));
            }
        }