protected virtual DMesh3 BuildMesh_IdenticalWeld(STLSolid solid) { var builder = new DMesh3Builder(); builder.AppendNewMesh(false, false, false, false); DVectorArray3f vertices = solid.Vertices; int N = vertices.Count; int[] mapV = new int[N]; var 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; } } append_mapped_triangles(solid, builder, mapV); return(builder.Meshes[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); } }
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); } }
protected virtual DMesh3 BuildMesh_TolerantWeld(STLSolid solid, double weld_tolerance) { var builder = new DMesh3Builder(); builder.AppendNewMesh(false, false, false, false); DVectorArray3f vertices = solid.Vertices; int N = vertices.Count; int[] mapV = new int[N]; AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty; for (int i = 0; i < N; ++i) { bounds.Contain(vertices[i]); } // [RMS] because we are only searching within tiny radius, there is really no downside to // using lots of bins here, except memory usage. If we don't, and the mesh has a ton of triangles // very close together (happens all the time on big meshes!), then this step can start // to take an *extremely* long time! int num_bins = 256; if (N > 100000) { num_bins = 512; } if (N > 1000000) { num_bins = 1024; } if (N > 2000000) { num_bins = 2048; } if (N > 5000000) { num_bins = 4096; } var uniqueV = new PointHashGrid3d <int>(bounds.MaxDim / (float)num_bins, -1); var pos = new Vector3f[N]; for (int vi = 0; vi < N; ++vi) { Vector3f v = vertices[vi]; var pair = uniqueV.FindNearestInRadius(v, weld_tolerance, (vid) => { return(v.Distance(pos[vid])); }); if (pair.Key == -1) { int vid = builder.AppendVertex(v.x, v.y, v.z); uniqueV.InsertPoint(vid, v); mapV[vi] = vid; pos[vid] = v; } else { mapV[vi] = pair.Key; } } append_mapped_triangles(solid, builder, mapV); return(builder.Meshes[0]); }