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); } }
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); }
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(); }
/// <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); }
public Edge(TriangleMesh parent) { this.parentMesh = parent; }
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); } } } } }
//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); }
//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; }
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); } } } } }