Example #1
0
        public DMesh3 remesh_constraints_fixedverts(int iterations, DMesh3 mesh, double min, double max, double angle)
        {
            AxisAlignedBox3d bounds = mesh.CachedBounds;

            // construct mesh projection target
            DMesh3 meshCopy = new DMesh3(mesh);

            meshCopy.CheckValidity();
            DMeshAABBTree3 tree = new DMeshAABBTree3(meshCopy);

            tree.Build();
            MeshProjectionTarget target = new MeshProjectionTarget()
            {
                Mesh = meshCopy, Spatial = tree
            };

            // construct constraint set
            MeshConstraints cons = new MeshConstraints();

            //EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip | EdgeRefineFlags.NoCollapse;
            EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip;

            foreach (int eid in mesh.EdgeIndices())
            {
                double fAngle = MeshUtil.OpeningAngleD(mesh, eid);
                if (fAngle > angle)
                {
                    cons.SetOrUpdateEdgeConstraint(eid, new EdgeConstraint(useFlags));
                    Index2i ev      = mesh.GetEdgeV(eid);
                    int     nSetID0 = (mesh.GetVertex(ev[0]).y > bounds.Center.y) ? 1 : 2;
                    int     nSetID1 = (mesh.GetVertex(ev[1]).y > bounds.Center.y) ? 1 : 2;
                    cons.SetOrUpdateVertexConstraint(ev[0], new VertexConstraint(true, nSetID0));
                    cons.SetOrUpdateVertexConstraint(ev[1], new VertexConstraint(true, nSetID1));
                }
            }

            Remesher r = new Remesher(mesh);

            r.Precompute();
            r.SetExternalConstraints(cons);
            r.SetProjectionTarget(target);
            r.EnableFlips     = r.EnableSplits = r.EnableCollapses = true;
            r.MinEdgeLength   = min;
            r.MaxEdgeLength   = max;
            r.EnableSmoothing = true;
            r.SmoothSpeedT    = 1;


            for (int k = 0; k < iterations; ++k)
            {
                r.BasicRemeshPass();
                mesh.CheckValidity();
            }


            return(mesh);
        }
Example #2
0
        void optimize_mesh(DMesh3 mesh)
        {
            Reducer         reducer     = new Reducer(mesh);
            MeshConstraints constraints = new MeshConstraints();

            MeshConstraintUtil.FixAllBoundaryEdges(constraints, mesh);
            reducer.SetExternalConstraints(constraints);
            reducer.ReduceToTriangleCount(1);

            Vector3d a, b, c, d;

            a = b = c = d = Vector3d.Zero;

            bool done = false;

            while (!done)
            {
                done = true;

                for (int eid = 0; eid < mesh.MaxEdgeID; ++eid)
                {
                    if (mesh.IsEdge(eid) == false)
                    {
                        continue;
                    }

                    Index4i evt = mesh.GetEdge(eid);
                    if (evt.d == DMesh3.InvalidID)
                    {
                        continue;
                    }
                    a = mesh.GetVertex(evt.a); b = mesh.GetVertex(evt.b);
                    Index2i ov = mesh.GetEdgeOpposingV(eid);
                    c = mesh.GetVertex(ov.a); d = mesh.GetVertex(ov.b);

                    if (c.DistanceSquared(d) > a.DistanceSquared(b))
                    {
                        continue;
                    }
                    if (MeshUtil.CheckIfEdgeFlipCreatesFlip(mesh, eid))
                    {
                        continue;
                    }

                    DMesh3.EdgeFlipInfo flipInfo;
                    if (mesh.FlipEdge(eid, out flipInfo) == MeshResult.Ok)
                    {
                        done = false;
                    }
                }
            }
        }
Example #3
0
        public static DMesh3 MakeRemeshedCappedCylinder(double fResFactor = 1.0)
        {
            DMesh3 mesh = MakeCappedCylinder(false, 128);

            MeshUtil.ScaleMesh(mesh, Frame3f.Identity, new g3.Vector3f(1, 2, 1));

            // construct mesh projection target
            DMesh3         meshCopy = new DMesh3(mesh);
            DMeshAABBTree3 tree     = new DMeshAABBTree3(meshCopy);

            tree.Build();
            MeshProjectionTarget target = new MeshProjectionTarget()
            {
                Mesh    = meshCopy,
                Spatial = tree
            };
            MeshConstraints cons     = new MeshConstraints();
            EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip;

            foreach (int eid in mesh.EdgeIndices())
            {
                double fAngle = MeshUtil.OpeningAngleD(mesh, eid);
                if (fAngle > 30.0f)
                {
                    cons.SetOrUpdateEdgeConstraint(eid, new EdgeConstraint(useFlags));
                    Index2i ev      = mesh.GetEdgeV(eid);
                    int     nSetID0 = (mesh.GetVertex(ev[0]).y > 1) ? 1 : 2;
                    int     nSetID1 = (mesh.GetVertex(ev[1]).y > 1) ? 1 : 2;
                    cons.SetOrUpdateVertexConstraint(ev[0], new VertexConstraint(true, nSetID0));
                    cons.SetOrUpdateVertexConstraint(ev[1], new VertexConstraint(true, nSetID1));
                }
            }
            Remesher r = new Remesher(mesh);

            r.SetExternalConstraints(cons);
            r.SetProjectionTarget(target);
            r.Precompute();
            r.EnableFlips     = r.EnableSplits = r.EnableCollapses = true;
            r.MinEdgeLength   = 0.1f * fResFactor;
            r.MaxEdgeLength   = 0.2f * fResFactor;
            r.EnableSmoothing = true;
            r.SmoothSpeedT    = 0.5f;
            for (int k = 0; k < 20; ++k)
            {
                r.BasicRemeshPass();
            }
            return(mesh);
        }
Example #4
0
    void remove_old_vertices(int[] MapV, DMesh3 mesh)
    {
        HashSet <int> keepV = new HashSet <int>();

        for (int k = 0; k < MapV.Length; ++k)
        {
            if (MapV[k] != DMesh3.InvalidID)
            {
                keepV.Add(MapV[k]);
            }
        }

        Remesher r = new Remesher(mesh);

        //r.EnableCollapses = false;
        //r.EnableSplits = false;
        //r.EnableFlips = false;
        r.SmoothSpeedT = 1.0;
        //r.EnableSmoothing = false;
        r.PreventNormalFlips = true;
        r.SetTargetEdgeLength(1.0);
        //r.EnableSmoothing = false;
        MeshConstraints c = new MeshConstraints();

        foreach (int vid in keepV)
        {
            c.SetOrUpdateVertexConstraint(vid, VertexConstraint.Pinned);
        }
        r.SetExternalConstraints(c);

        double minE, maxE, avgE;

        MeshQueries.EdgeLengthStats(mesh, out minE, out maxE, out avgE);
        r.SetTargetEdgeLength(avgE * .3);

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

        //int iter = 0;
        //while (iter++ < 10) {
        //    r.SetTargetEdgeLength(iter * 1.0);
        //    for (int k = 0; k < 10; ++k)
        //        r.BasicRemeshPass();
        //}
    }
Example #5
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);
                }
            }
        }
        public static void test_reduce_constraints_fixedverts()
        {
            int    Slices = 128;
            DMesh3 mesh   = TestUtil.MakeCappedCylinder(false, Slices);

            MeshUtil.ScaleMesh(mesh, Frame3f.Identity, new Vector3f(1, 2, 1));
            mesh.CheckValidity();
            AxisAlignedBox3d bounds = mesh.CachedBounds;

            // construct mesh projection target
            DMesh3 meshCopy = new DMesh3(mesh);

            meshCopy.CheckValidity();
            DMeshAABBTree3 tree = new DMeshAABBTree3(meshCopy);

            tree.Build();
            MeshProjectionTarget target = new MeshProjectionTarget()
            {
                Mesh = meshCopy, Spatial = tree
            };

            if (WriteDebugMeshes)
            {
                TestUtil.WriteTestOutputMesh(mesh, "reduce_fixed_constraints_test_before.obj");
            }

            // construct constraint set
            MeshConstraints cons = new MeshConstraints();

            //EdgeRefineFlags useFlags = EdgeRefineFlags.NoCollapse;
            EdgeRefineFlags useFlags = EdgeRefineFlags.PreserveTopology;

            foreach (int eid in mesh.EdgeIndices())
            {
                double fAngle = MeshUtil.OpeningAngleD(mesh, eid);
                if (fAngle > 30.0f)
                {
                    cons.SetOrUpdateEdgeConstraint(eid, new EdgeConstraint(useFlags)
                    {
                        TrackingSetID = 1
                    });
                    Index2i ev      = mesh.GetEdgeV(eid);
                    int     nSetID0 = (mesh.GetVertex(ev[0]).y > bounds.Center.y) ? 1 : 2;
                    int     nSetID1 = (mesh.GetVertex(ev[1]).y > bounds.Center.y) ? 1 : 2;
                    cons.SetOrUpdateVertexConstraint(ev[0], new VertexConstraint(true, nSetID0));
                    cons.SetOrUpdateVertexConstraint(ev[1], new VertexConstraint(true, nSetID1));
                }
            }

            Reducer r = new Reducer(mesh);

            r.SetExternalConstraints(cons);
            r.SetProjectionTarget(target);

            r.ReduceToTriangleCount(50);
            mesh.CheckValidity();

            if (WriteDebugMeshes)
            {
                TestUtil.WriteTestOutputMesh(mesh, "reduce_fixed_constraints_test_after.obj");
            }
        }
Example #7
0
        public static Mesh RemeshTest(Mesh inMesh, double fResScale = 1.0, int iterations = 50)
        {
            inMesh.Faces.ConvertQuadsToTriangles();
            DMesh3 mesh = inMesh.ToDMesh3();

            mesh.CheckValidity();
            AxisAlignedBox3d bounds = mesh.CachedBounds;

            // construct mesh projection target
            DMesh3 meshCopy = new DMesh3(mesh);

            meshCopy.CheckValidity();
            DMeshAABBTree3 tree = new DMeshAABBTree3(meshCopy);

            tree.Build();
            MeshProjectionTarget target = new MeshProjectionTarget()
            {
                Mesh    = meshCopy,
                Spatial = tree
            };

            // construct constraint set
            MeshConstraints cons = new MeshConstraints();

            //EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip | EdgeRefineFlags.NoCollapse;
            EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip;

            foreach (int eid in mesh.EdgeIndices())
            {
                double fAngle = MeshUtil.OpeningAngleD(mesh, eid);
                if (fAngle > 30.0)
                {
                    cons.SetOrUpdateEdgeConstraint(eid, new EdgeConstraint(useFlags));
                    Index2i ev      = mesh.GetEdgeV(eid);
                    int     nSetID0 = (mesh.GetVertex(ev[0]).y > bounds.Center.y) ? 1 : 2;
                    int     nSetID1 = (mesh.GetVertex(ev[1]).y > bounds.Center.y) ? 1 : 2;
                    cons.SetOrUpdateVertexConstraint(ev[0], new VertexConstraint(true, nSetID0));
                    cons.SetOrUpdateVertexConstraint(ev[1], new VertexConstraint(true, nSetID1));
                }
            }

            Remesher r = new Remesher(mesh);

            r.Precompute();
            r.SetExternalConstraints(cons);
            r.SetProjectionTarget(target);

            r.EnableFlips     = r.EnableSplits = r.EnableCollapses = true;
            r.MinEdgeLength   = 0.5 * fResScale;
            r.MaxEdgeLength   = 1.0 * fResScale;
            r.EnableSmoothing = true;
            r.SmoothSpeedT    = 0.5;

            try
            {
                for (int k = 0; k < iterations; ++k)
                {
                    r.BasicRemeshPass();
                    // mesh.CheckValidity();
                }
            }
            catch
            {
                // ignore
            }

            return(mesh.ToRhinoMesh());
        }
Example #8
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");
        }
        public static DMesh3 RemeshMesh(g3.DMesh3 mesh, float minEdgeLength, float maxEdgeLength, float contraintAngle, float smoothSpeed, int smoothPasses, List <Line3d> constrainedLines)
        {
            // construct mesh projection target
            DMesh3         meshCopy = new DMesh3(mesh);
            DMeshAABBTree3 tree     = new DMeshAABBTree3(meshCopy);

            tree.Build();
            MeshProjectionTarget target = new MeshProjectionTarget()
            {
                Mesh    = meshCopy,
                Spatial = tree
            };

            MeshConstraints cons     = new MeshConstraints();
            EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip;

            foreach (int eid in mesh.EdgeIndices())
            {
                double fAngle = MeshUtil.OpeningAngleD(mesh, eid);

                Index2i ev = mesh.GetEdgeV(eid);

                if (fAngle > contraintAngle)
                {
                    cons.SetOrUpdateEdgeConstraint(eid, new EdgeConstraint(useFlags));


                    // TODO Ids based off of ?? What?
                    int nSetID0 = (mesh.GetVertex(ev[0]).y > 1) ? 1 : 2;
                    int nSetID1 = (mesh.GetVertex(ev[1]).y > 1) ? 1 : 2;
                    cons.SetOrUpdateVertexConstraint(ev[0], new VertexConstraint(true, nSetID0));
                    cons.SetOrUpdateVertexConstraint(ev[1], new VertexConstraint(true, nSetID1));
                }

                Vector3d p1 = mesh.GetVertex(ev.a);
                Vector3d p2 = mesh.GetVertex(ev.b);


                foreach (var v in constrainedLines)
                {
                    if (p1.CompareTo(v.Origin) == 0)
                    {
                        Vector3d p = v.PointAt(1.0);

                        if (p2.CompareTo(p) == 0)
                        {
                            cons.SetOrUpdateEdgeConstraint(eid, EdgeConstraint.FullyConstrained);
                            break;
                        }
                    }
                }

                foreach (var v in constrainedLines)
                {
                    if (p2.CompareTo(v.Origin) == 0)
                    {
                        Vector3d p = v.PointAt(1.0);

                        if (p1.CompareTo(p) == 0)
                        {
                            cons.SetOrUpdateEdgeConstraint(eid, EdgeConstraint.FullyConstrained);
                            break;
                        }
                    }
                }
            }

            Remesher r = new Remesher(mesh);

            r.SetExternalConstraints(cons);
            r.SetProjectionTarget(target);
            r.Precompute();
            r.EnableFlips     = r.EnableSplits = r.EnableCollapses = true;
            r.MinEdgeLength   = minEdgeLength;     //0.1f;
            r.MaxEdgeLength   = maxEdgeLength;     // 0.2f;
            r.EnableSmoothing = true;
            r.SmoothSpeedT    = smoothSpeed;       // .5;
            for (int k = 0; k < smoothPasses; ++k) // smoothPasses = 20
            {
                r.BasicRemeshPass();
            }
            return(mesh);
        }
Example #10
0
        //

        public static DMesh3 RemeshMeshNew(g3.DMesh3 mesh, float minEdgeLength, float maxEdgeLength, float contraintAngle, float smoothSpeed, int smoothPasses, g3.DMesh3 projectMeshInput = null, float projectAmount = 1.0f, float projectedDistance = float.MaxValue)
        {
            g3.DMesh3 projectMesh = projectMeshInput;

            if (projectMesh == null)
            {
                projectMesh = mesh;
            }

            DMesh3         projectMeshCopy = new DMesh3(projectMesh);
            DMeshAABBTree3 treeProject     = new DMeshAABBTree3(projectMeshCopy);

            treeProject.Build();
            GopherMeshProjectionTarget targetProject = new GopherMeshProjectionTarget()
            {
                Mesh        = projectMeshCopy,
                Spatial     = treeProject,
                amount      = projectAmount,
                maxDistance = projectedDistance
            };

            MeshConstraints cons     = new MeshConstraints();
            EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip;

            foreach (int eid in mesh.EdgeIndices())
            {
                double fAngle = MeshUtil.OpeningAngleD(mesh, eid);
                if (fAngle > contraintAngle)
                {
                    cons.SetOrUpdateEdgeConstraint(eid, new EdgeConstraint(useFlags));
                    Index2i ev = mesh.GetEdgeV(eid);
                    //int nSetID0 = (mesh.GetVertex(ev[0]).y > 1) ? 1 : 2;
                    //int nSetID1 = (mesh.GetVertex(ev[1]).y > 1) ? 1 : 2;
                    cons.SetOrUpdateVertexConstraint(ev[0], new VertexConstraint(true));
                    cons.SetOrUpdateVertexConstraint(ev[1], new VertexConstraint(true));
                }
            }

            // TODO Constrain Vertices too far away
            foreach (int vid in mesh.VertexIndices())
            {
                var v = mesh.GetVertex(vid);

                //v.Distance()
                //targetProject.Project()
            }

            Remesher rProjected = new Remesher(mesh);

            rProjected.SetExternalConstraints(cons);
            rProjected.SetProjectionTarget(targetProject);
            rProjected.Precompute();
            rProjected.EnableFlips     = rProjected.EnableSplits = rProjected.EnableCollapses = true;
            rProjected.MinEdgeLength   = minEdgeLength; //0.1f;
            rProjected.MaxEdgeLength   = maxEdgeLength; // 0.2f;
            rProjected.EnableSmoothing = true;
            rProjected.SmoothSpeedT    = smoothSpeed;   // .5;

            if (projectMeshInput != null)
            {
                float bestSmoothPassProjectAmount     = projectAmount / smoothPasses;
                float testbestSmoothPassProjectAmount = float.MaxValue;
                for (float smoothPassProjectAmount = -.1f; smoothPassProjectAmount < 1.1f; smoothPassProjectAmount += 0.005f)
                {
                    double test = 0;

                    for (int i = 0; i < smoothPasses; i++)
                    {
                        test = 1.0 * smoothPassProjectAmount + test * (1 - smoothPassProjectAmount);
                    }

                    if (Math.Abs(test - projectAmount) < Math.Abs(testbestSmoothPassProjectAmount - projectAmount))
                    {
                        bestSmoothPassProjectAmount     = (float)smoothPassProjectAmount;
                        testbestSmoothPassProjectAmount = (float)test;
                    }
                }

                targetProject.amount      = bestSmoothPassProjectAmount;
                targetProject.maxDistance = projectedDistance;

                for (int k = 0; k < smoothPasses; ++k) // smoothPasses = 20
                {
                    rProjected.BasicRemeshPass();
                }
            }
            else
            {
                for (int k = 0; k < smoothPasses; ++k) // smoothPasses = 20
                {
                    rProjected.BasicRemeshPass();
                }
            }


            return(mesh);
        }
Example #11
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Mesh           m          = DA.Fetch <Mesh>("Mesh");
            bool           fixEdges   = DA.Fetch <bool>("FixEdges");
            double         l          = DA.Fetch <double>("EdgeLength");
            int            iterations = DA.Fetch <int>("Iterations");
            List <Point3d> fixPt      = DA.FetchList <Point3d>("FixPt");
            bool           project    = DA.Fetch <bool>("Project");
            bool           loops      = DA.Fetch <bool>("Loops");

            Mesh mesh = m.DuplicateMesh();

            mesh.Faces.ConvertQuadsToTriangles();

            double len = (l == 0) ? mesh.GetBoundingBox(false).Diagonal.Length * 0.1 : l;



            //r.PreventNormalFlips = true;

            List <int> ids = new List <int>();

            Point3d[] pts = mesh.Vertices.ToPoint3dArray();
            foreach (Point3d p in fixPt)
            {
                ids.Add(NGonsCore.PointUtil.ClosestPoint(p, pts));
            }



            DMesh3   dmesh = mesh.ToDMesh3();
            Remesher r     = new Remesher(dmesh);

            r.Precompute();
            r.SetTargetEdgeLength(len);
            r.SmoothSpeedT = 0.5;
            if (project)
            {
                r.SetProjectionTarget(MeshProjectionTarget.Auto(dmesh));
            }

            r.EnableFlips     = r.EnableSplits = r.EnableCollapses = true;
            r.EnableSmoothing = true;


            MeshConstraints cons = new MeshConstraints();


            if (ids.Count > 0)
            {
                foreach (int id in ids)
                {
                    //cons.SetOrUpdateVertexConstraint(id, new VertexConstraint(true, 1));
                    cons.SetOrUpdateVertexConstraint(id, VertexConstraint.Pinned);
                }
            }
            r.SetExternalConstraints(cons);

            r.Precompute();

            if (fixEdges)
            {
                //r.SetExternalConstraints(new MeshConstraints());
                MeshConstraintUtil.FixAllBoundaryEdges(r);
                MeshConstraintUtil.FixAllBoundaryEdges_AllowSplit(cons, dmesh, 0);
                //MeshConstraintUtil.FixAllBoundaryEdges_AllowCollapse(cons, dmesh, 0);
            }

            if (loops)
            {
                MeshConstraintUtil.PreserveBoundaryLoops(r); //project to edge
                                                             //MeshConstraintUtil.PreserveBoundaryLoops(cons,dmesh);//project to edge
            }
            r.SetExternalConstraints(cons);


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



            //output
            if (ids.Count > 0 && !fixEdges)
            {
                this.Message = "Vertices";
            }
            else if (ids.Count == 0 && fixEdges)
            {
                this.Message = "Edges";
            }
            else if (ids.Count > 0 && fixEdges)
            {
                this.Message = "Vertices + Edges";
            }
            else
            {
                this.Message = "";
            }



            dmesh = new DMesh3(dmesh, true);
            Mesh rmesh = dmesh.ToRhinoMesh();

            if (loops)
            {
                Mesh mesh_ = rmesh.DuplicateMesh();
                Rhino.IndexPair[] closestEdges = new Rhino.IndexPair[fixPt.Count];

                int counter = 0;
                foreach (Point3d p in fixPt)
                {
                    double[] d   = new double[rmesh.TopologyEdges.Count];
                    int[]    eid = new int[rmesh.TopologyEdges.Count];

                    for (int i = 0; i < rmesh.TopologyEdges.Count; i++)
                    {
                        if (rmesh.TopologyEdges.GetConnectedFaces(i).Length == 1)
                        {
                            Line line = rmesh.TopologyEdges.EdgeLine(i);
                            line.ClosestPoint(p, true);
                            d[i] = line.ClosestPoint(p, true).DistanceToSquared(p); //line.From.DistanceToSquared(p) + line.To.DistanceToSquared(p);
                        }
                        else
                        {
                            d[i] = 99999;
                        }
                        eid[i] = i;
                    }



                    Array.Sort(d, eid);

                    closestEdges[counter++] = rmesh.TopologyEdges.GetTopologyVertices(eid[0]);
                }

                for (int i = 0; i < fixPt.Count; i++)
                {
                    mesh_.Vertices.Add(fixPt[i]);
                    mesh_.Faces.AddFace(rmesh.Vertices.Count + i, closestEdges[i].I, closestEdges[i].J);
                }
                rmesh = mesh_;
            }
            rmesh.UnifyNormals();
            rmesh.RebuildNormals();
            // rmesh.UnifyNormals();



            DA.SetData(0, rmesh);
        }
        public static void test_remesh_constraints_vertcurves()
        {
            int    Slices = 16;
            DMesh3 mesh   = TestUtil.MakeCappedCylinder(false, Slices);

            MeshUtil.ScaleMesh(mesh, Frame3f.Identity, new Vector3f(1, 2, 1));
            //DMesh3 mesh = TestUtil.MakeRemeshedCappedCylinder(0.25);
            //DMesh3 mesh = TestUtil.MakeRemeshedCappedCylinder(1.0);
            mesh.CheckValidity();
            AxisAlignedBox3d bounds = mesh.CachedBounds;

            // construct mesh projection target
            DMesh3 meshCopy = new DMesh3(mesh);

            meshCopy.CheckValidity();
            DMeshAABBTree3 tree = new DMeshAABBTree3(meshCopy);

            tree.Build();
            MeshProjectionTarget mesh_target = new MeshProjectionTarget()
            {
                Mesh = meshCopy, Spatial = tree
            };

            // cylinder projection target
            CylinderProjectionTarget cyl_target = new CylinderProjectionTarget()
            {
                Cylinder = new Cylinder3d(new Vector3d(0, 1, 0), Vector3d.AxisY, 1, 2)
            };

            //IProjectionTarget target = mesh_target;
            IProjectionTarget target = cyl_target;

            // construct projection target circles
            CircleProjectionTarget bottomCons = new CircleProjectionTarget()
            {
                Circle = new Circle3d(bounds.Center, 1.0)
            };

            bottomCons.Circle.Center.y = bounds.Min.y;
            CircleProjectionTarget topCons = new CircleProjectionTarget()
            {
                Circle = new Circle3d(bounds.Center, 1.0)
            };

            topCons.Circle.Center.y = bounds.Max.y;


            if (WriteDebugMeshes)
            {
                TestUtil.WriteDebugMesh(mesh, "remesh_analytic_constraints_test_before.obj");
            }

            // construct constraint set
            MeshConstraints cons = new MeshConstraints();

            //EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip | EdgeRefineFlags.NoCollapse;
            EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip;

            bool bConstrainVertices = true;

            foreach (int eid in mesh.EdgeIndices())
            {
                double fAngle = MeshUtil.OpeningAngleD(mesh, eid);
                if (fAngle > 30.0f)
                {
                    Index2i  ev  = mesh.GetEdgeV(eid);
                    Vector3d ev0 = mesh.GetVertex(ev[0]);
                    Vector3d ev1 = mesh.GetVertex(ev[1]);
                    CircleProjectionTarget loopTarget = null;
                    if (ev0.y > bounds.Center.y && ev1.y > bounds.Center.y)
                    {
                        loopTarget = topCons;
                    }
                    else if (ev0.y < bounds.Center.y && ev1.y < bounds.Center.y)
                    {
                        loopTarget = bottomCons;
                    }

                    cons.SetOrUpdateEdgeConstraint(eid, new EdgeConstraint(useFlags, loopTarget));
                    if (bConstrainVertices && loopTarget != null)
                    {
                        cons.SetOrUpdateVertexConstraint(ev[0], new VertexConstraint(loopTarget));
                        cons.SetOrUpdateVertexConstraint(ev[1], new VertexConstraint(loopTarget));
                    }
                }
            }


            Remesher r = new Remesher(mesh);

            //r.SetExternalConstraints(cons);
            r.SetProjectionTarget(target);
            r.Precompute();
            r.ENABLE_PROFILING = true;

            var stopwatch = Stopwatch.StartNew();

            //double fResScale = 1.0f;
            double fResScale = 0.5f;

            r.EnableFlips     = r.EnableSplits = r.EnableCollapses = true;
            r.MinEdgeLength   = 0.1f * fResScale;
            r.MaxEdgeLength   = 0.2f * fResScale;
            r.EnableSmoothing = true;
            r.SmoothSpeedT    = 1.0f;

            try {
                for (int k = 0; k < 20; ++k)
                {
                    r.BasicRemeshPass();
                    mesh.CheckValidity();
                }
            } catch {
                // continue;
            }
            stopwatch.Stop();
            System.Console.WriteLine("Second Pass Timing: " + stopwatch.Elapsed);

            if (WriteDebugMeshes)
            {
                TestUtil.WriteDebugMesh(mesh, "remesh_analytic_constraints_test_after.obj");
            }
        }
        public static void test_remesh_constraints_fixedverts()
        {
            int    Slices = 128;
            DMesh3 mesh   = TestUtil.MakeCappedCylinder(false, Slices);

            MeshUtil.ScaleMesh(mesh, Frame3f.Identity, new Vector3f(1, 2, 1));
            mesh.CheckValidity();
            AxisAlignedBox3d bounds = mesh.CachedBounds;

            // construct mesh projection target
            DMesh3 meshCopy = new DMesh3(mesh);

            meshCopy.CheckValidity();
            DMeshAABBTree3 tree = new DMeshAABBTree3(meshCopy);

            tree.Build();
            MeshProjectionTarget target = new MeshProjectionTarget()
            {
                Mesh = meshCopy, Spatial = tree
            };

            if (WriteDebugMeshes)
            {
                TestUtil.WriteDebugMesh(mesh, "remesh_fixed_constraints_test_before.obj");
            }

            // construct constraint set
            MeshConstraints cons = new MeshConstraints();

            //EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip | EdgeRefineFlags.NoCollapse;
            EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip;

            foreach (int eid in mesh.EdgeIndices())
            {
                double fAngle = MeshUtil.OpeningAngleD(mesh, eid);
                if (fAngle > 30.0f)
                {
                    cons.SetOrUpdateEdgeConstraint(eid, new EdgeConstraint(useFlags));
                    Index2i ev      = mesh.GetEdgeV(eid);
                    int     nSetID0 = (mesh.GetVertex(ev[0]).y > bounds.Center.y) ? 1 : 2;
                    int     nSetID1 = (mesh.GetVertex(ev[1]).y > bounds.Center.y) ? 1 : 2;
                    cons.SetOrUpdateVertexConstraint(ev[0], new VertexConstraint(true, nSetID0));
                    cons.SetOrUpdateVertexConstraint(ev[1], new VertexConstraint(true, nSetID1));
                }
            }

            Remesher r = new Remesher(mesh);

            r.Precompute();
            r.SetExternalConstraints(cons);
            r.SetProjectionTarget(target);

            var stopwatch = Stopwatch.StartNew();

            //double fResScale = 1.0f;
            double fResScale = 0.5f;

            r.EnableFlips     = r.EnableSplits = r.EnableCollapses = true;
            r.MinEdgeLength   = 0.1f * fResScale;
            r.MaxEdgeLength   = 0.2f * fResScale;
            r.EnableSmoothing = true;
            r.SmoothSpeedT    = 0.5f;

            try {
                for (int k = 0; k < 20; ++k)
                {
                    r.BasicRemeshPass();
                    mesh.CheckValidity();
                }
            } catch {
                // ignore
            }

            stopwatch.Stop();
            System.Console.WriteLine("Second Pass Timing: " + stopwatch.Elapsed);

            if (WriteDebugMeshes)
            {
                TestUtil.WriteDebugMesh(mesh, "remesh_fixed_constraints_test_after.obj");
            }
        }
Example #14
0
        public DMesh3 remesh_constraints_vertcurves(int iterations, DMesh3 mesh, double min, double max, double angle)
        {
            mesh.CheckValidity();
            AxisAlignedBox3d bounds = mesh.CachedBounds;

            // construct mesh projection target
            DMesh3 meshCopy = new DMesh3(mesh);

            meshCopy.CheckValidity();
            DMeshAABBTree3 tree = new DMeshAABBTree3(meshCopy);

            tree.Build();
            MeshProjectionTarget mesh_target = new MeshProjectionTarget()
            {
                Mesh    = meshCopy,
                Spatial = tree
            };

            // cylinder projection target
            CylinderProjectionTarget cyl_target = new CylinderProjectionTarget()
            {
                Cylinder = new Cylinder3d(new Vector3D(0, 1, 0), Vector3D.AxisY, 1, 2)
            };

            //IProjectionTarget target = mesh_target;
            IProjectionTarget target = cyl_target;

            // construct projection target circles
            CircleProjectionTarget bottomCons = new CircleProjectionTarget()
            {
                Circle = new Circle3d(bounds.Center, 1.0)
            };

            bottomCons.Circle.Center.y = bounds.Min.y;
            CircleProjectionTarget topCons = new CircleProjectionTarget()
            {
                Circle = new Circle3d(bounds.Center, 1.0)
            };

            topCons.Circle.Center.y = bounds.Max.y;


            // construct constraint set
            MeshConstraints cons = new MeshConstraints();

            //EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip | EdgeRefineFlags.NoCollapse;
            EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip;

            bool bConstrainVertices = true;

            foreach (int eid in mesh.EdgeIndices())
            {
                double fAngle = MeshUtil.OpeningAngleD(mesh, eid);
                if (fAngle > 30.0f)
                {
                    Index2i  ev  = mesh.GetEdgeV(eid);
                    Vector3D ev0 = mesh.GetVertex(ev[0]);
                    Vector3D ev1 = mesh.GetVertex(ev[1]);
                    CircleProjectionTarget loopTarget = null;
                    if (ev0.y > bounds.Center.y && ev1.y > bounds.Center.y)
                    {
                        loopTarget = topCons;
                    }
                    else if (ev0.y < bounds.Center.y && ev1.y < bounds.Center.y)
                    {
                        loopTarget = bottomCons;
                    }

                    cons.SetOrUpdateEdgeConstraint(eid, new EdgeConstraint(useFlags, loopTarget));
                    if (bConstrainVertices && loopTarget != null)
                    {
                        cons.SetOrUpdateVertexConstraint(ev[0], new VertexConstraint(loopTarget));
                        cons.SetOrUpdateVertexConstraint(ev[1], new VertexConstraint(loopTarget));
                    }
                }
            }


            Remesher r = new Remesher(mesh);

            //r.SetExternalConstraints(cons);
            r.SetProjectionTarget(target);
            r.Precompute();
            r.ENABLE_PROFILING = true;
            r.EnableFlips      = r.EnableSplits = r.EnableCollapses = true;
            r.MinEdgeLength    = min;
            r.MaxEdgeLength    = max;
            r.EnableSmoothing  = true;
            r.SmoothSpeedT     = 1.0f;

            for (int k = 0; k < iterations; ++k)
            {
                r.BasicRemeshPass();
                mesh.CheckValidity();
            }

            return(mesh);
        }