Exemple #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(NGonsCore.geometry3Sharp.mesh.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();
        }
Exemple #2
0
        // smooths embedded loop in mesh, by first smoothing edge loop and then
        // smoothing vertex neighbourhood
        // [TODO] geodesic nbrhoold instead of # of rings
        // [TODO] reprojection?
        public static void smooth_loop(NGonsCore.geometry3Sharp.mesh.DMesh3 mesh, EdgeLoop loop, int nRings)
        {
            MeshFaceSelection roi_t = new MeshFaceSelection(mesh);

            roi_t.SelectVertexOneRings(loop.Vertices);
            for (int i = 0; i < nRings; ++i)
            {
                roi_t.ExpandToOneRingNeighbours();
            }
            roi_t.LocalOptimize(true, true);

            MeshVertexSelection roi_v = new MeshVertexSelection(mesh);

            roi_v.SelectTriangleVertices(roi_t.ToArray());
            roi_v.Deselect(loop.Vertices);

            MeshLoopSmooth loop_smooth = new MeshLoopSmooth(mesh, loop);

            loop_smooth.Rounds = 1;

            MeshIterativeSmooth mesh_smooth = new MeshIterativeSmooth(mesh, roi_v.ToArray(), true);

            mesh_smooth.Rounds = 1;

            for (int i = 0; i < 10; ++i)
            {
                loop_smooth.Smooth();
                mesh_smooth.Smooth();
            }
        }
Exemple #3
0
        // local mesh smooth applied to all vertices in N-rings around input list
        public static void smooth_region(NGonsCore.geometry3Sharp.mesh.DMesh3 mesh, IEnumerable <int> vertices, int nRings)
        {
            MeshFaceSelection roi_t = new MeshFaceSelection(mesh);

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

            MeshVertexSelection roi_v = new MeshVertexSelection(mesh);

            roi_v.SelectTriangleVertices(roi_t.ToArray());

            MeshIterativeSmooth mesh_smooth = new MeshIterativeSmooth(mesh, roi_v.ToArray(), true);

            mesh_smooth.Alpha  = 0.2f;
            mesh_smooth.Rounds = 10;
            mesh_smooth.Smooth();
        }
Exemple #4
0
        protected void do_flatten(DMesh3 mesh)
        {
            double   BAND_HEIGHT = flatten_band_height;
            Vector3d down_axis   = -Vector3d.AxisY;
            double   dot_thresh  = 0.2;

            AxisAlignedBox3d bounds  = mesh.CachedBounds;
            DMeshAABBTree3   spatial = new DMeshAABBTree3(mesh, true);

            Ray3d   ray     = new Ray3d(bounds.Center - 2 * bounds.Height * Vector3d.AxisY, Vector3d.AxisY);
            int     hit_tid = spatial.FindNearestHitTriangle(ray);
            Frame3f hitF;

            MeshQueries.RayHitPointFrame(mesh, spatial, ray, out hitF);
            Vector3d basePt = hitF.Origin;

            Frame3f basePlane = new Frame3f(basePt, Vector3f.AxisY);

            MeshConnectedComponents components = new MeshConnectedComponents(mesh)
            {
                FilterF = (tid) => {
                    if (mesh.GetTriangleGroup(tid) != LastExtrudeOuterGroupID)
                    {
                        return(false);
                    }
                    Vector3d n, c; double a;
                    mesh.GetTriInfo(tid, out n, out a, out c);
                    double h = Math.Abs(c.y - basePt.y);
                    if (h > BAND_HEIGHT)
                    {
                        return(false);
                    }
                    if (n.Dot(down_axis) < dot_thresh)
                    {
                        return(false);
                    }
                    return(true);
                },
                SeedFilterF = (tid) => {
                    return(tid == hit_tid);
                }
            };

            components.FindConnectedT();

            MeshFaceSelection all_faces = new MeshFaceSelection(mesh);

            foreach (var comp in components)
            {
                MeshVertexSelection vertices = new MeshVertexSelection(mesh);
                vertices.SelectTriangleVertices(comp.Indices);
                foreach (int vid in vertices)
                {
                    Vector3d v = mesh.GetVertex(vid);
                    v = basePlane.ProjectToPlane((Vector3f)v, 2);
                    mesh.SetVertex(vid, v);
                }
                all_faces.SelectVertexOneRings(vertices);
            }

            all_faces.ExpandToOneRingNeighbours(3, (tid) => {
                return(mesh.GetTriangleGroup(tid) == LastExtrudeOuterGroupID);
            });

            RegionRemesher r = new RegionRemesher(mesh, all_faces);

            r.SetProjectionTarget(MeshProjectionTarget.Auto(mesh));
            r.SetTargetEdgeLength(2.0f);
            r.SmoothSpeedT = 1.0f;
            for (int k = 0; k < 10; ++k)
            {
                r.BasicRemeshPass();
            }
            r.SetProjectionTarget(null);
            r.SmoothSpeedT = 1.0f;
            for (int k = 0; k < 10; ++k)
            {
                r.BasicRemeshPass();
            }
            r.BackPropropagate();
        }