示例#1
0
        // This function does local remeshing around a boundary loop within a fixed # of
        // rings, to try to 'massage' it into a cleaner shape/topology
        // [TODO] use geodesic distance instead of fixed # of rings?
        public static void cleanup_boundary(DMesh3 mesh, EdgeLoop loop, double target_edge_len, int nRings = 3)
        {
            Debug.Assert(loop.IsBoundaryLoop());

            MeshFaceSelection roi = new MeshFaceSelection(mesh);

            roi.SelectVertexOneRings(loop.Vertices);

            for (int i = 0; i < nRings; ++i)
            {
                roi.ExpandToOneRingNeighbours();
            }
            roi.LocalOptimize(true, true);

            RegionRemesher r = new RegionRemesher(mesh, roi.ToArray());

            r.Precompute();
            r.EnableFlips     = r.EnableSplits = r.EnableCollapses = true;
            r.MinEdgeLength   = target_edge_len;
            r.MaxEdgeLength   = 2 * target_edge_len;
            r.EnableSmoothing = true;
            r.SmoothSpeedT    = 0.1f;
            for (int k = 0; k < nRings * 3; ++k)
            {
                r.BasicRemeshPass();
            }
            Debug.Assert(mesh.CheckValidity());

            r.BackPropropagate();
        }
示例#2
0
        // This function does local remeshing around a boundary loop within a fixed # of
        // rings, to try to 'massage' it into a cleaner shape/topology.
        // The result_edges list is the mapped edges of loop on the resulting mesh, but it is *not* in-order
        // [TODO] use geodesic distance instead of fixed # of rings?
        public static void cleanup_boundary(DMesh3 mesh, EdgeLoop loop, double target_edge_len, out List <int> result_edges, int nRings = 3)
        {
            Debug.Assert(loop.IsBoundaryLoop());

            var roi = new MeshFaceSelection(mesh);

            roi.SelectVertexOneRings(loop.Vertices);

            for (int i = 0; i < nRings; ++i)
            {
                roi.ExpandToOneRingNeighbours();
            }

            roi.LocalOptimize(true, true);

            var r = new RegionRemesher(mesh, roi.ToArray());

            // tag the input loop edges in the remesher, so that we can find this loop afterwards
            int[] init_loop_edges = new int[loop.EdgeCount];
            Array.Copy(loop.Edges, init_loop_edges, loop.EdgeCount);
            r.Region.MapEdgesToSubmesh(init_loop_edges);
            MeshConstraintUtil.AddTrackedEdges(r.Constraints, init_loop_edges, 100);
            //foreach (int eid in init_loop_edges)
            //    Debug.Assert(r.Region.SubMesh.IsBoundaryEdge(eid));

            r.Precompute();
            r.EnableFlips     = r.EnableSplits = r.EnableCollapses = true;
            r.MinEdgeLength   = target_edge_len;
            r.MaxEdgeLength   = 2 * target_edge_len;
            r.EnableSmoothing = true;
            r.SmoothSpeedT    = 0.1f;
            for (int k = 0; k < nRings * 3; ++k)
            {
                r.BasicRemeshPass();
            }

            Debug.Assert(mesh.CheckValidity());

            // extract the edges we tagged (they are unordered)
            List <int> new_loop_edges = r.Constraints.FindConstrainedEdgesBySetID(100);

            //foreach (int eid in new_loop_edges)
            //    Debug.Assert(r.Region.SubMesh.IsBoundaryEdge(eid));

            r.BackPropropagate();

            // map the extracted edges back to the backpropped input mesh
            result_edges = MeshIndexUtil.MapEdgesViaVertexMap(r.ReinsertSubToBaseMapV, r.Region.SubMesh, r.BaseMesh, new_loop_edges);
            //foreach (int eid in result_edges)
            //    Debug.Assert(mesh.IsBoundaryEdge(eid));
        }