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); }
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); }
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])); }
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)); }
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)); }
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)); }
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)); }
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); } }
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); } }
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, "")); }
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, "")); } }