Пример #1
0
        public static void PreserveBoundaryLoops(MeshConstraints cons, NGonsCore.geometry3Sharp.mesh.DMesh3 mesh)
        {
            MeshBoundaryLoops loops = new MeshBoundaryLoops(mesh);

            foreach (EdgeLoop loop in loops)
            {
                DCurve3 loopC = MeshUtil.ExtractLoopV(mesh, loop.Vertices);
                DCurveProjectionTarget target = new DCurveProjectionTarget(loopC);
                ConstrainVtxLoopTo(cons, mesh, loop.Vertices, target);
            }
        }
Пример #2
0
        /// <summary>
        /// add topological edges/vertices as constraints for remeshing
        /// </summary>
        public void AddRemeshConstraints(MeshConstraints constraints)
        {
            validate_topology();

            int set_index = 10;

            foreach (EdgeSpan span in Spans)
            {
                var target = new DCurveProjectionTarget(span.ToCurve());
                MeshConstraintUtil.ConstrainVtxSpanTo(constraints, Mesh, span.Vertices, target, set_index++);
            }

            foreach (EdgeLoop loop in Loops)
            {
                var target = new DCurveProjectionTarget(loop.ToCurve());
                MeshConstraintUtil.ConstrainVtxLoopTo(constraints, Mesh, loop.Vertices, target, set_index++);
            }

            VertexConstraint corners = VertexConstraint.Pinned;

            corners.FixedSetID = -1;
            foreach (int vid in JunctionVertices)
            {
                if (constraints.HasVertexConstraint(vid))
                {
                    VertexConstraint v = constraints.GetVertexConstraint(vid);
                    v.Target     = null;
                    v.Fixed      = true;
                    v.FixedSetID = -1;
                    constraints.SetOrUpdateVertexConstraint(vid, v);
                }
                else
                {
                    constraints.SetOrUpdateVertexConstraint(vid, corners);
                }
            }
        }
Пример #3
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            DMesh3_goo     dMsh_goo = null;
            List <Point3d> points   = new List <Point3d>();
            double         targetL  = 0;
            int            numI     = 0;
            int            fixB     = 0;
            bool           projBack = false;
            double         smooth   = 0;

            DA.GetData(0, ref dMsh_goo);
            DA.GetDataList(2, points);
            DA.GetData(1, ref targetL);
            DA.GetData(6, ref numI);
            DA.GetData(3, ref fixB);
            DA.GetData(5, ref projBack);
            DA.GetData(7, ref smooth);

            List <EdgeConstraint_goo> edgeC = new List <EdgeConstraint_goo>();

            DA.GetDataList(4, edgeC);

            DMesh3 dMsh_copy = new DMesh3(dMsh_goo.Value);

            Remesher r = new Remesher(dMsh_copy);

            r.PreventNormalFlips = true;
            r.SetTargetEdgeLength(targetL);
            r.SmoothSpeedT = smooth;


            if (fixB == 2)
            {
                MeshConstraintUtil.FixAllBoundaryEdges(r);
            }
            else if (fixB == 1)
            {
                MeshConstraintUtil.PreserveBoundaryLoops(r);
            }
            else
            {
                r.SetExternalConstraints(new MeshConstraints());
            }

            if (edgeC.Count > 0)
            {
                for (int i = 0; i < edgeC.Count; i++)
                {
                    var tempEC = edgeC[i];

                    IProjectionTarget target = new DCurveProjectionTarget(tempEC.crv);

                    for (int j = 0; j < tempEC.edges.Length; j++)
                    {
                        tempEC.constraint.Target = target;
                        r.Constraints.SetOrUpdateEdgeConstraint(tempEC.edges[j], tempEC.constraint);
                    }

                    for (int j = 0; j < tempEC.vertices.Length; j++)
                    {
                        if (tempEC.PinVerts)
                        {
                            r.Constraints.SetOrUpdateVertexConstraint(tempEC.vertices[j], VertexConstraint.Pinned);
                        }
                        else
                        {
                            r.Constraints.SetOrUpdateVertexConstraint(tempEC.vertices[j], new VertexConstraint(target));
                        }
                    }
                }
            }

            if (points.Count > 0)
            {
                DMeshAABBTree3 mshAABB = new DMeshAABBTree3(dMsh_copy, true);

                var v3pts = points.Select(pt => pt.ToVec3d());

                foreach (var p in v3pts)
                {
                    int id = mshAABB.FindNearestVertex(p, 0.1);

                    if (id != -1)
                    {
                        r.Constraints.SetOrUpdateVertexConstraint(id, VertexConstraint.Pinned);
                    }
                }
            }

            if (projBack)
            {
                r.SetProjectionTarget(MeshProjectionTarget.Auto(dMsh_goo.Value));
            }


            for (int k = 0; k < numI; ++k)
            {
                r.BasicRemeshPass();
            }

            bool isValid = dMsh_copy.CheckValidity();

            if (!isValid)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Mesh seems to have been corrupted during remeshing. Please check...");
            }

            DA.SetData(0, dMsh_copy);
        }
Пример #4
0
        public static void quick_test_2()
        {
            DMesh3         target        = TestUtil.LoadTestInputMesh("cylinder_orig.obj");
            DMeshAABBTree3 targetSpatial = new DMeshAABBTree3(target, true);

            DMesh3         mesh        = TestUtil.LoadTestInputMesh("cylinder_approx.obj");
            DMeshAABBTree3 meshSpatial = new DMeshAABBTree3(mesh, true);

            double search_dist = 10.0;

            MeshTopology topo = new MeshTopology(target);

            topo.Compute();

            RemesherPro r = new RemesherPro(mesh);

            r.SetTargetEdgeLength(2.0);
            r.SmoothSpeedT = 0.5;
            r.SetProjectionTarget(MeshProjectionTarget.Auto(target));
            MeshConstraints cons = new MeshConstraints();

            r.SetExternalConstraints(cons);


            int set_id = 1;

            foreach (var loop in topo.Loops)
            {
                DCurveProjectionTarget curveTarget = new DCurveProjectionTarget(loop.ToCurve(target));
                set_id++;

                // pick a set of points we will find paths between. We will chain
                // up those paths and constrain them to target loops.
                // (this part is the hack!)
                List <int> target_verts = new List <int>();
                List <int> mesh_verts   = new List <int>();
                for (int k = 0; k < loop.VertexCount; k += 5)
                {
                    target_verts.Add(loop.Vertices[k]);

                    Vector3d vCurve   = target.GetVertex(loop.Vertices[k]);
                    int      mesh_vid = meshSpatial.FindNearestVertex(vCurve, search_dist);
                    mesh_verts.Add(mesh_vid);
                }
                int NT = target_verts.Count;

                // find the paths to assemble the edge chain
                // [TODO] need to filter out junction vertices? or will they just handle themselves
                //   because they can be collapsed away?
                List <int> vert_seq = new List <int>();
                for (int k = 0; k < NT; k++)
                {
                    EdgeSpan e = find_edge_path(mesh, mesh_verts[k], mesh_verts[(k + 1) % NT]);
                    int      n = e.Vertices.Length;
                    for (int i = 0; i < n - 1; ++i)
                    {
                        vert_seq.Add(e.Vertices[i]);
                    }
                }

                // now it's easy, just add the loop constraint
                EdgeLoop full_loop = EdgeLoop.FromVertices(mesh, vert_seq);
                MeshConstraintUtil.ConstrainVtxLoopTo(cons, mesh, full_loop.Vertices, curveTarget, set_id);
            }


            r.FastestRemesh();

            TestUtil.WriteTestOutputMesh(mesh, "curves_test_out.obj");
        }
Пример #5
0
        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);
        }