void smooth_and_remesh(MeshFaceSelection tris) { if (EnableLaplacianSmooth) { LaplacianMeshSmoother.RegionSmooth(Mesh, tris, 2, 2, false); } if (RemeshAfterSmooth) { tris.ExpandToOneRingNeighbours(2); tris.LocalOptimize(true, true); MeshProjectionTarget target = MeshProjectionTarget.Auto(Mesh, tris, 5); RegionRemesher remesh2 = new RegionRemesher(Mesh, tris); remesh2.SetTargetEdgeLength(TargetEdgeLength); remesh2.SmoothSpeedT = 1.0; remesh2.SetProjectionTarget(target); if (ConfigureRemesherF != null) { ConfigureRemesherF(remesh2, false); } for (int k = 0; k < 10; ++k) { remesh2.BasicRemeshPass(); } remesh2.BackPropropagate(); FillTriangles = remesh2.CurrentBaseTriangles; } else { FillTriangles = tris.ToArray(); } }
void smooth_and_remesh_preserve(MeshFaceSelection tris, bool bFinal) { if (EnableLaplacianSmooth) { LaplacianMeshSmoother.RegionSmooth(Mesh, tris, 2, 2, true); } if (RemeshAfterSmooth) { MeshProjectionTarget target = (bFinal) ? MeshProjectionTarget.Auto(Mesh, tris, 5) : null; RegionRemesher remesh2 = new RegionRemesher(Mesh, tris); remesh2.SetTargetEdgeLength(TargetEdgeLength); remesh2.SmoothSpeedT = 1.0; remesh2.SetProjectionTarget(target); if (ConfigureRemesherF != null) { ConfigureRemesherF(remesh2, false); } for (int k = 0; k < 10; ++k) { remesh2.BasicRemeshPass(); } remesh2.BackPropropagate(); FillTriangles = remesh2.CurrentBaseTriangles; } else { FillTriangles = tris.ToArray(); } }
public void Close_Flat() { double minlen, maxlen, avglen; MeshQueries.EdgeLengthStats(Mesh, out minlen, out maxlen, out avglen, 1000); double target_edge_len = (TargetEdgeLen <= 0) ? avglen : TargetEdgeLen; // massage around boundary loop cleanup_boundary(Mesh, InitialBorderLoop, avglen, 3); // find new border loop // [TODO] this just assumes there is only one!! MeshBoundaryLoops loops = new MeshBoundaryLoops(Mesh); EdgeLoop fill_loop = loops.Loops[0]; int extrude_group = (ExtrudeGroup == -1) ? Mesh.AllocateTriangleGroup() : ExtrudeGroup; int fill_group = (FillGroup == -1) ? Mesh.AllocateTriangleGroup() : FillGroup; // decide on projection plane //AxisAlignedBox3d loopbox = fill_loop.GetBounds(); //Vector3d topPt = loopbox.Center; //if ( bIsUpper ) { // topPt.y = loopbox.Max.y + 0.25 * dims.y; //} else { // topPt.y = loopbox.Min.y - 0.25 * dims.y; //} //Frame3f plane = new Frame3f((Vector3f)topPt); // extrude loop to this plane MeshExtrusion extrude = new MeshExtrusion(Mesh, fill_loop); extrude.PositionF = (v, n, i) => { return(FlatClosePlane.ProjectToPlane((Vector3F)v, 1)); }; extrude.Extrude(extrude_group); MeshValidation.IsBoundaryLoop(Mesh, extrude.NewLoop); Debug.Assert(Mesh.CheckValidity()); // smooth the extrude loop MeshLoopSmooth loop_smooth = new MeshLoopSmooth(Mesh, extrude.NewLoop); loop_smooth.ProjectF = (v, i) => { return(FlatClosePlane.ProjectToPlane((Vector3F)v, 1)); }; loop_smooth.Alpha = 0.5f; loop_smooth.Rounds = 100; loop_smooth.Smooth(); Debug.Assert(Mesh.CheckValidity()); // fill result SimpleHoleFiller filler = new SimpleHoleFiller(Mesh, extrude.NewLoop); filler.Fill(fill_group); Debug.Assert(Mesh.CheckValidity()); // make selection for remesh region MeshFaceSelection remesh_roi = new MeshFaceSelection(Mesh); remesh_roi.Select(extrude.NewTriangles); remesh_roi.Select(filler.NewTriangles); remesh_roi.ExpandToOneRingNeighbours(); remesh_roi.ExpandToOneRingNeighbours(); remesh_roi.LocalOptimize(true, true); int[] new_roi = remesh_roi.ToArray(); // get rid of extrude group FaceGroupUtil.SetGroupToGroup(Mesh, extrude_group, 0); /* clean up via remesh * - constrain loop we filled to itself */ RegionRemesher r = new RegionRemesher(Mesh, new_roi); DCurve3 top_curve = mesh.MeshUtil.ExtractLoopV(Mesh, extrude.NewLoop.Vertices); DCurveProjectionTarget curve_target = new DCurveProjectionTarget(top_curve); int[] top_loop = (int[])extrude.NewLoop.Vertices.Clone(); r.Region.MapVerticesToSubmesh(top_loop); MeshConstraintUtil.ConstrainVtxLoopTo(r.Constraints, r.Mesh, top_loop, curve_target); DMeshAABBTree3 spatial = new DMeshAABBTree3(Mesh); spatial.Build(); MeshProjectionTarget target = new MeshProjectionTarget(Mesh, spatial); r.SetProjectionTarget(target); bool bRemesh = true; if (bRemesh) { 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 = 1.0f; for (int k = 0; k < 40; ++k) { r.BasicRemeshPass(); } r.SetProjectionTarget(null); r.SmoothSpeedT = 0.25f; for (int k = 0; k < 10; ++k) { r.BasicRemeshPass(); } Debug.Assert(Mesh.CheckValidity()); r.BackPropropagate(); } // smooth around the join region to clean up ugliness smooth_region(Mesh, r.Region.BaseBorderV, 3); }
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(); }