Exemple #1
0
        public static void Load(string filepath, TriangleMesh triMesh, float scale)
        {
            using (System.IO.TextReader reader = File.OpenText(filepath))
            {
                XmlSerializer ser = new XmlSerializer(typeof(Collada));
                Collada c = (Collada)ser.Deserialize(reader);
                foreach (Geometry g in c.library_geometries)
                {
                    float[] floats = g.mesh.PositionFloats();
                    int[] indices = g.mesh.TrianglePositionIndices();

                    List<Vector3> vertices = new List<Vector3>();

                    for (int i = 0; i < floats.Count(); i += 3)
                    {
                        Vector3 v = new Vector3(floats[i], floats[i + 1], floats[i + 2]);
                        vertices.Add(v * scale);
                    }

                    for (int i = 0; i < indices.Count(); i += 3)
                    {
                        triMesh.AddTriangle(vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]]);
                    }
                }
            }
            triMesh.Clean();
        }
 public AnalyzedTriangleMesh(TriangleMesh mesh)
 {
     foreach (Triangle t in mesh.Triangles)
     {
         this.AddTriangle(t);
     }
 }
Exemple #3
0
        public Slice(TriangleMesh mesh, Plane plane)
        {
            //GL.Disable(EnableCap.Lighting);
            //GL.LineWidth(2);
            //GL.Begin(PrimitiveType.Lines);
            //float height = 0;

            // Slice at 3 levels and combine all segments - this obviates dealing with triangles that are exactly on the plane.
            for (int i = -1; i <= 1; i++)
            {
                Vector3 offset = plane.Normal * 0.0001f * (float)i;
                LineHandler lineHandler = new LineHandler(0.0f);
                Plane testPlane = new Plane(plane.Normal, plane.Point + offset);
                foreach (Triangle t in mesh.Triangles)
                {
                    var intersect = new TrianglePlaneIntersect(t, testPlane);
                    if (intersect.Intersects)
                    {
                        lineHandler.AddSegment(intersect.PointA, intersect.PointB);
                        //GL.Color3(Color.Blue);
                        //GL.Vertex3(intersect.PointA + new Vector3(0, 0, height + .01f));
                        //GL.Color3(Color.Red);
                        //GL.Vertex3(intersect.PointB + new Vector3(0, 0, height + .01f));
                    }
                    else if (intersect.all_intersect && Vector3.Dot(t.Plane.Normal, testPlane.Normal) > 0.5f)
                    {
                        // Entire triangle intersects
                        // Add all the triangle edges (TODO: clean this up...)
                        List<Vector3> vertices = new List<Vector3>(t.Vertices);
                        for (int a = 0; a < 3; a++)
                        {
                            Vector3 v1 = vertices[a];
                            Vector3 v2 = vertices[(a + 1) % 3];
                            lineHandler.AddSegment(v1, v2);
                        }
                    }
                }
                if (this.polyTree == null)
                {
                    Init(lineHandler.GetOuterLoops(), plane);
                }
                else
                {
                    Slice s = new Slice(lineHandler.GetOuterLoops(), plane);
                    this.Union(s);
                }
            }
            //GL.End();
            //GL.Enable(EnableCap.Lighting);
            //GL.LineWidth(1);
        }
Exemple #4
0
        public static void Load(string filepath, TriangleMesh triMesh, float scale)
        {
            STLDocument stl = null;

            using (Stream filestream = File.OpenRead(filepath))
            {
                stl = STLDocument.Read(filestream);
            }

            foreach (var facet in stl.Facets)
            {
                List <Vector3> vertices = new List <Vector3>();
                foreach (var vertex in facet.Vertices)
                {
                    Vector3 v = new Vector3((float)vertex.X, (float)vertex.Y, (float)vertex.Z);
                    vertices.Add(v * scale);
                }
                triMesh.AddTriangle(new Triangle(vertices[0], vertices[1], vertices[2]));
            }
            triMesh.Clean();
        }
Exemple #5
0
        /// <summary>
        /// Split a mesh into meshes of connected triangles
        /// </summary>
        /// <returns></returns>
        public List <TriangleMesh> SplitDisconnected()
        {
            List <TriangleMesh> meshes = new List <TriangleMesh>();

            List <TriangleIndices> tempTriangles = new List <TriangleIndices>();

            tempTriangles = triangles.ToList();

            while (tempTriangles.Count > 0)
            {
                var mesh      = new TriangleMesh();
                var first     = tempTriangles[0];
                var connected = GetConnected(ref tempTriangles, first);
                foreach (var indices in connected)
                {
                    mesh.AddTriangle(new Triangle(vertices[indices.a], vertices[indices.b], vertices[indices.c]));
                }
                meshes.Add(mesh);
            }

            return(meshes);
        }
Exemple #6
0
 public Edge(TriangleMesh parent)
 {
     this.parentMesh = parent;
 }
Exemple #7
0
        public static void Load(string filepath, TriangleMesh triMesh, float scale)
        {
            List<Vector3> vertices = new List<Vector3>();
            string[] strings = System.IO.File.ReadAllLines(filepath);

            // Lines starting with v are a vertex:
            // "v 10.2426 4.5e-013 -31.7638"
            Regex vertexRegex = new Regex(@"^v\s+(?<x>\S+)\s+(?<y>\S+)\s+(?<z>\S+)", RegexOptions.IgnoreCase);

            // Lines starting with f are a face.  The indices are <vertex>/<texture>/<normal>, where texture and normal are optional.
            // "f 1/1/1 2/2/1 3/3/1 4/4/1 5/5/1"
            Regex faceRegex = new Regex(@"^f(?<face_data>\s+(?<vertex>\d+)/?(?<texture_coordinate>\d+)?/?(?<vertex_normal>\d+)?)+", RegexOptions.IgnoreCase);

            foreach (string s in strings)
            {
                if (vertexRegex.IsMatch(s))
                {
                    Match m = vertexRegex.Match(s);
                    float x = float.Parse(m.Groups["x"].Value);
                    float y = float.Parse(m.Groups["y"].Value);
                    float z = float.Parse(m.Groups["z"].Value);
                    // Rotate 90 degrees about the X axis - for some reason .obj files saved from sketchup have this issue...
                    Vector3 v = new Vector3(x, -z, y);
                    vertices.Add(v * scale);
                }
                else if (faceRegex.IsMatch(s))
                {
                    Match m = faceRegex.Match(s);

                    //Console.WriteLine(m.Groups["face_data"].Captures.Count);
                    //Console.WriteLine(m.Groups["vertex"].Captures.Count);
                    //Console.WriteLine(m.Groups["texture_coordinate"].Captures.Count);
                    //Console.WriteLine(m.Groups["vertex_normal"].Captures.Count);

                    //Face face = new Face();
                    Polygon polygon = new Polygon();

                    CaptureCollection vert_captures = m.Groups["vertex"].Captures;
                    CaptureCollection texcoord_captures = m.Groups["texture_coordinate"].Captures;
                    CaptureCollection norm_captures = m.Groups["vertex_normal"].Captures;

                    var vertexIndices = vert_captures.Cast<Capture>().Select(capture => int.Parse(capture.Value) - 1);

                    foreach (var vertexIndex in vertexIndices)
                    {
                        if (vertexIndex < 0 || vertexIndex > vertices.Count)
                        {
                            Console.WriteLine("Bad vertex index {0}, only {1} vertices loaded", vertexIndex, vertices.Count);
                        }
                        else
                        {
                            polygon.Add(vertices[vertexIndex]);
                        }
                    }
                    //for (int i = 0; i < vert_captures.Count; i++)
                    //{
                    //    int vert_index = int.Parse(vert_captures[i].Value) - 1;
                    //
                    //}
                    if (texcoord_captures.Count == vert_captures.Count)
                    {
                        // TODO: Add texture coordinates to the face
                    }
                    if (norm_captures.Count == vert_captures.Count)
                    {
                        // TODO: Add vertex normals to the face
                    }

                    if (polygon.Vertices.Count() < 3)
                    {
                        Console.WriteLine("Bad face defined, less than 3 vertices");
                    }
                    else
                    {
                        foreach (var triangle in polygon.ToTriangles())
                        {
                            triMesh.AddTriangle(triangle);
                        }
                    }
                }
            }
        }
Exemple #8
0
        //public List<Triangles> GetTriangles(Predicate<Triangle> trianglePredicate)
        //{
        //
        //}
        //
        //

        public List <TriangleMesh> Analyze()
        {
            List <TriangleMesh> meshes = new List <TriangleMesh>();
            // While there is a triangle on the top:

            // 1. Find a triangle on the top, remove it
            // 2. Find all connected triangles, remove them
            // 3. Add all removed triangles to a new mesh

            // Find

            var t = triangles;

            List <TriangleIndices> ignore = new List <TriangleIndices>();

            Func <Triangle, bool> TopTriangleCriteria    = triangle => Vector3.Dot(triangle.Plane.Normal, Vector3.UnitZ) == 1 && triangle.A.Z == MaxPoint.Z;
            Func <Triangle, bool> BottomTriangleCriteria = triangle => Vector3.Dot(triangle.Plane.Normal, Vector3.UnitZ) == -1 && triangle.A.Z == MinPoint.Z;
            Func <Triangle, bool> PocketCriteria1        = triangle => !TopTriangleCriteria(triangle) && Vector3.Dot(triangle.Plane.Normal, Vector3.UnitZ) > 0;
            Func <Triangle, bool> PocketCriteria2        = triangle => !TopTriangleCriteria(triangle) && Vector3.Dot(triangle.Plane.Normal, Vector3.UnitZ) >= 0;


            while (t.Count > 0)
            {
                var triangleIndices              = t[0];
                var triangle                     = new Triangle(vertices[triangleIndices.a], vertices[triangleIndices.b], vertices[triangleIndices.c]);
                var dot                          = Vector3.Dot(triangle.Plane.Normal, Vector3.UnitZ);
                Func <float, bool> dotTestTop    = dot_value => dot_value == 1;
                Func <float, bool> dotTestBottom = dot_value => dot_value == -1;
                if (TopTriangleCriteria(triangle))
                {
                    var connected = GetConnectedTriangles(triangleIndices, ignore, TopTriangleCriteria);
                    ignore.AddRange(connected);
                    TriangleMesh mesh = new TriangleMesh();
                    foreach (var indices in connected)
                    {
                        t.Remove(indices);
                        var newTriangle = new Triangle(vertices[indices.a], vertices[indices.b], vertices[indices.c]);
                        mesh.AddTriangle(newTriangle);
                    }
                    //meshes.Add(mesh);
                }
                else if (BottomTriangleCriteria(triangle))
                {
                    var connected = GetConnectedTriangles(triangleIndices, ignore, BottomTriangleCriteria);
                    ignore.AddRange(connected);
                    TriangleMesh mesh = new TriangleMesh();
                    foreach (var indices in connected)
                    {
                        t.Remove(indices);
                        var newTriangle = new Triangle(vertices[indices.a], vertices[indices.b], vertices[indices.c]);
                        mesh.AddTriangle(newTriangle);
                    }
                    //meshes.Add(mesh);
                }
                else if (PocketCriteria1(triangle))
                {
                    var connected = GetConnectedTriangles(triangleIndices, ignore, PocketCriteria2);
                    ignore.AddRange(connected);
                    TriangleMesh mesh = new TriangleMesh();
                    foreach (var indices in connected)
                    {
                        t.Remove(indices);
                        var newTriangle = new Triangle(vertices[indices.a], vertices[indices.b], vertices[indices.c]);
                        mesh.AddTriangle(newTriangle);
                    }
                    meshes.Add(mesh);
                }
                else
                {
                    //ignore.Add(t[0]);
                    t.RemoveAt(0);
                }
            }

            return(meshes);
        }
Exemple #9
0
 public Edge(TriangleMesh parent)
 {
     this.parentMesh = parent;
 }
        //public List<Triangles> GetTriangles(Predicate<Triangle> trianglePredicate)
        //{
        //
        //}
        //
        //
        public List<TriangleMesh> Analyze()
        {
            List<TriangleMesh> meshes = new List<TriangleMesh>();
            // While there is a triangle on the top:

            // 1. Find a triangle on the top, remove it
            // 2. Find all connected triangles, remove them
            // 3. Add all removed triangles to a new mesh

            // Find

            var t = triangles;

            List<TriangleIndices> ignore = new List<TriangleIndices>();

            Func<Triangle, bool> TopTriangleCriteria = triangle => Vector3.Dot(triangle.Plane.Normal, Vector3.UnitZ) == 1 && triangle.A.Z == MaxPoint.Z;
            Func<Triangle, bool> BottomTriangleCriteria = triangle => Vector3.Dot(triangle.Plane.Normal, Vector3.UnitZ) == -1 && triangle.A.Z == MinPoint.Z;
            Func<Triangle, bool> PocketCriteria1 = triangle => !TopTriangleCriteria(triangle) && Vector3.Dot(triangle.Plane.Normal, Vector3.UnitZ) > 0;
            Func<Triangle, bool> PocketCriteria2 = triangle => !TopTriangleCriteria(triangle) && Vector3.Dot(triangle.Plane.Normal, Vector3.UnitZ) >= 0;

            while (t.Count > 0)
            {
                var triangleIndices = t[0];
                var triangle = new Triangle(vertices[triangleIndices.a], vertices[triangleIndices.b], vertices[triangleIndices.c]);
                var dot = Vector3.Dot(triangle.Plane.Normal, Vector3.UnitZ);
                Func<float, bool> dotTestTop = dot_value => dot_value == 1;
                Func<float, bool> dotTestBottom = dot_value => dot_value == -1;
                if (TopTriangleCriteria(triangle))
                {
                    var connected = GetConnectedTriangles(triangleIndices, ignore, TopTriangleCriteria);
                    ignore.AddRange(connected);
                    TriangleMesh mesh = new TriangleMesh();
                    foreach (var indices in connected)
                    {
                        t.Remove(indices);
                        var newTriangle = new Triangle(vertices[indices.a], vertices[indices.b], vertices[indices.c]);
                        mesh.AddTriangle(newTriangle);
                    }
                    //meshes.Add(mesh);
                }
                else if (BottomTriangleCriteria(triangle))
                {
                    var connected = GetConnectedTriangles(triangleIndices, ignore, BottomTriangleCriteria);
                    ignore.AddRange(connected);
                    TriangleMesh mesh = new TriangleMesh();
                    foreach (var indices in connected)
                    {
                        t.Remove(indices);
                        var newTriangle = new Triangle(vertices[indices.a], vertices[indices.b], vertices[indices.c]);
                        mesh.AddTriangle(newTriangle);
                    }
                    //meshes.Add(mesh);
                }
                else if (PocketCriteria1(triangle))
                {
                    var connected = GetConnectedTriangles(triangleIndices, ignore, PocketCriteria2);
                    ignore.AddRange(connected);
                    TriangleMesh mesh = new TriangleMesh();
                    foreach (var indices in connected)
                    {
                        t.Remove(indices);
                        var newTriangle = new Triangle(vertices[indices.a], vertices[indices.b], vertices[indices.c]);
                        mesh.AddTriangle(newTriangle);
                    }
                    meshes.Add(mesh);
                }
                else
                {
                    //ignore.Add(t[0]);
                    t.RemoveAt(0);
                }
            }

            return meshes;
        }
        /// <summary>
        /// Split a mesh into meshes of connected triangles
        /// </summary>
        /// <returns></returns>
        public List<TriangleMesh> SplitDisconnected()
        {
            List<TriangleMesh> meshes = new List<TriangleMesh>();

            List<TriangleIndices> tempTriangles = new List<TriangleIndices>();

            tempTriangles = triangles.ToList();

            while(tempTriangles.Count > 0)
            {
                var mesh = new TriangleMesh();
                var first = tempTriangles[0];
                var connected = GetConnected(ref tempTriangles, first);
                foreach (var indices in connected)
                {
                    mesh.AddTriangle(new Triangle(vertices[indices.a], vertices[indices.b], vertices[indices.c]));
                }
                meshes.Add(mesh);
            }

            return meshes;
        }
Exemple #12
0
        public static void Load(string filepath, TriangleMesh triMesh, float scale)
        {
            List <Vector3> vertices = new List <Vector3>();

            string[] strings = System.IO.File.ReadAllLines(filepath);

            // Lines starting with v are a vertex:
            // "v 10.2426 4.5e-013 -31.7638"
            Regex vertexRegex = new Regex(@"^v\s+(?<x>\S+)\s+(?<y>\S+)\s+(?<z>\S+)", RegexOptions.IgnoreCase);

            // Lines starting with f are a face.  The indices are <vertex>/<texture>/<normal>, where texture and normal are optional.
            // "f 1/1/1 2/2/1 3/3/1 4/4/1 5/5/1"
            Regex faceRegex = new Regex(@"^f(?<face_data>\s+(?<vertex>\d+)/?(?<texture_coordinate>\d+)?/?(?<vertex_normal>\d+)?)+", RegexOptions.IgnoreCase);

            foreach (string s in strings)
            {
                if (vertexRegex.IsMatch(s))
                {
                    Match m = vertexRegex.Match(s);
                    float x = float.Parse(m.Groups["x"].Value);
                    float y = float.Parse(m.Groups["y"].Value);
                    float z = float.Parse(m.Groups["z"].Value);
                    // Rotate 90 degrees about the X axis - for some reason .obj files saved from sketchup have this issue...
                    Vector3 v = new Vector3(x, -z, y);
                    vertices.Add(v * scale);
                }
                else if (faceRegex.IsMatch(s))
                {
                    Match m = faceRegex.Match(s);

                    //Console.WriteLine(m.Groups["face_data"].Captures.Count);
                    //Console.WriteLine(m.Groups["vertex"].Captures.Count);
                    //Console.WriteLine(m.Groups["texture_coordinate"].Captures.Count);
                    //Console.WriteLine(m.Groups["vertex_normal"].Captures.Count);

                    //Face face = new Face();
                    Polygon polygon = new Polygon();

                    CaptureCollection vert_captures     = m.Groups["vertex"].Captures;
                    CaptureCollection texcoord_captures = m.Groups["texture_coordinate"].Captures;
                    CaptureCollection norm_captures     = m.Groups["vertex_normal"].Captures;

                    var vertexIndices = vert_captures.Cast <Capture>().Select(capture => int.Parse(capture.Value) - 1);

                    foreach (var vertexIndex in vertexIndices)
                    {
                        if (vertexIndex < 0 || vertexIndex > vertices.Count)
                        {
                            Console.WriteLine("Bad vertex index {0}, only {1} vertices loaded", vertexIndex, vertices.Count);
                        }
                        else
                        {
                            polygon.Add(vertices[vertexIndex]);
                        }
                    }
                    //for (int i = 0; i < vert_captures.Count; i++)
                    //{
                    //    int vert_index = int.Parse(vert_captures[i].Value) - 1;
                    //
                    //}
                    if (texcoord_captures.Count == vert_captures.Count)
                    {
                        // TODO: Add texture coordinates to the face
                    }
                    if (norm_captures.Count == vert_captures.Count)
                    {
                        // TODO: Add vertex normals to the face
                    }

                    if (polygon.Vertices.Count() < 3)
                    {
                        Console.WriteLine("Bad face defined, less than 3 vertices");
                    }
                    else
                    {
                        foreach (var triangle in polygon.ToTriangles())
                        {
                            triMesh.AddTriangle(triangle);
                        }
                    }
                }
            }
        }