Пример #1
0
        /// <summary>
        /// For each on-face vtx, we poke the face, and re-sort
        /// the remaining vertices on that face onto new faces/edges
        /// </summary>
        void insert_face_vertices()
        {
            while (FaceVertices.Count > 0)
            {
                var pair = FaceVertices.First();
                int tid  = pair.Key;
                List <SegmentVtx> triVerts = pair.Value;
                SegmentVtx        v        = triVerts[triVerts.Count - 1];
                triVerts.RemoveAt(triVerts.Count - 1);

                DMesh3.PokeTriangleInfo pokeInfo;
                MeshResult result = Target.PokeTriangle(tid, out pokeInfo);
                if (result != MeshResult.Ok)
                {
                    throw new Exception("shit");
                }

                int new_v = pokeInfo.new_vid;

                Target.SetVertex(new_v, v.v);
                v.vtx_id = new_v;
                VIDToSegVtxMap[v.vtx_id] = v;
                PointHash.InsertPoint(v.vtx_id, v.v);

                // remove this triangles vtx list because it is no longer valid
                FaceVertices.Remove(tid);

                // update remaining verts
                Index3i pokeEdges = pokeInfo.new_edges;
                var     pokeTris  = new Index3i(tid, pokeInfo.new_t1, pokeInfo.new_t2);
                foreach (SegmentVtx sv in triVerts)
                {
                    update_from_poke(sv, pokeEdges, pokeTris);
                    if (sv.type == 1)
                    {
                        add_edge_vtx(sv.elem_id, sv);
                    }
                    else if (sv.type == 2)
                    {
                        add_face_vtx(sv.elem_id, sv);
                    }
                }

                // track poke subfaces
                add_poke_subfaces(tid, ref pokeInfo);
            }
        }
Пример #2
0
        protected bool check_for_cracks(DMesh3 mesh, out int boundary_edge_count, double crack_tol = MathUtil.ZeroTolerancef)
        {
            boundary_edge_count = 0;
            var boundary_verts = new MeshVertexSelection(mesh);

            foreach (int eid in mesh.BoundaryEdgeIndices())
            {
                Index2i ev = mesh.GetEdgeV(eid);
                boundary_verts.Select(ev.a); boundary_verts.Select(ev.b);
                boundary_edge_count++;
            }
            if (boundary_verts.Count == 0)
            {
                return(false);
            }

            AxisAlignedBox3d bounds = mesh.CachedBounds;
            var borderV             = new PointHashGrid3d <int>(bounds.MaxDim / 128, -1);

            foreach (int vid in boundary_verts)
            {
                Vector3d v      = mesh.GetVertex(vid);
                var      result = borderV.FindNearestInRadius(v, crack_tol, (existing_vid) =>
                {
                    return(v.Distance(mesh.GetVertex(existing_vid)));
                });
                if (result.Key != -1)
                {
                    return(true);                               // we found a crack vertex!
                }

                borderV.InsertPoint(vid, v);
            }

            // found no cracks
            return(false);
        }
Пример #3
0
        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]);
        }