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 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 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 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); } } } } }