예제 #1
0
        public static RegionRemesher QuickRemesh(DMesh3 mesh, int[] tris,
                                                 double targetEdgeLen, double smoothSpeed,
                                                 int rounds,
                                                 IProjectionTarget target,
                                                 QuickRemeshFlags flags = QuickRemeshFlags.PreventNormalFlips)
        {
            var remesh = new RegionRemesher(mesh, tris);

            if (target != null)
            {
                remesh.SetProjectionTarget(target);
            }

            remesh.SetTargetEdgeLength(targetEdgeLen);
            remesh.SmoothSpeedT = smoothSpeed;
            if ((flags & QuickRemeshFlags.PreventNormalFlips) != 0)
            {
                remesh.PreventNormalFlips = true;
            }

            for (int k = 0; k < rounds; ++k)
            {
                remesh.BasicRemeshPass();
            }
            remesh.BackPropropagate();
            return(remesh);
        }
예제 #2
0
        public static RegionRemesher QuickRemesh(DMesh3 mesh, int[] tris,
                                                 double targetEdgeLen, double smoothSpeed,
                                                 int rounds,
                                                 IProjectionTarget target)
        {
            RegionRemesher remesh = new RegionRemesher(mesh, tris);

            if (target != null)
            {
                remesh.SetProjectionTarget(target);
            }
            remesh.SetTargetEdgeLength(targetEdgeLen);
            remesh.SmoothSpeedT = smoothSpeed;
            for (int k = 0; k < rounds; ++k)
            {
                remesh.BasicRemeshPass();
            }
            remesh.BackPropropagate();
            return(remesh);
        }
예제 #3
0
        public virtual bool Trim()
        {
            if (Spatial == null)
            {
                Spatial = new DMeshAABBTree3(new DMesh3(Mesh, false, MeshComponents.None));
                Spatial.Build();
            }

            if (seed_tri == -1)
            {
                seed_tri = Spatial.FindNearestTriangle(seed_pt);
            }

            var loop = new MeshFacesFromLoop(Mesh, TrimLine, Spatial, seed_tri);

            MeshFaceSelection selection = loop.ToSelection();

            selection.LocalOptimize(true, true);
            var editor = new MeshEditor(Mesh);

            editor.RemoveTriangles(selection, true);

            var components = new MeshConnectedComponents(Mesh);

            components.FindConnectedT();
            if (components.Count > 1)
            {
                int keep = components.LargestByCount;
                for (int i = 0; i < components.Count; ++i)
                {
                    if (i != keep)
                    {
                        editor.RemoveTriangles(components[i].Indices, true);
                    }
                }
            }
            editor.RemoveAllBowtieVertices(true);

            var  loops   = new MeshBoundaryLoops(Mesh);
            bool loopsOK = false;

            try
            {
                loopsOK = loops.Compute();
            }
            catch (Exception)
            {
                return(false);
            }
            if (!loopsOK)
            {
                return(false);
            }


            // [TODO] to support trimming mesh w/ existing holes, we need to figure out which
            // loop we created in RemoveTriangles above!
            if (loops.Count > 1)
            {
                return(false);
            }

            int[] loopVerts = loops[0].Vertices;

            var borderTris = new MeshFaceSelection(Mesh);

            borderTris.SelectVertexOneRings(loopVerts);
            borderTris.ExpandToOneRingNeighbours(RemeshBorderRings);

            var remesh = new RegionRemesher(Mesh, borderTris.ToArray());

            remesh.Region.MapVerticesToSubmesh(loopVerts);

            double target_len = TargetEdgeLength;

            if (target_len <= 0)
            {
                double mine, maxe, avge;
                MeshQueries.EdgeLengthStatsFromEdges(Mesh, loops[0].Edges, out mine, out maxe, out avge);
                target_len = avge;
            }

            var meshTarget = new MeshProjectionTarget(Spatial.Mesh, Spatial);

            remesh.SetProjectionTarget(meshTarget);
            remesh.SetTargetEdgeLength(target_len);
            remesh.SmoothSpeedT = SmoothingAlpha;

            var curveTarget = new DCurveProjectionTarget(TrimLine);
            var multiTarget = new SequentialProjectionTarget(curveTarget, meshTarget);

            int set_id = 3;

            MeshConstraintUtil.ConstrainVtxLoopTo(remesh, loopVerts, multiTarget, set_id);

            for (int i = 0; i < RemeshRounds; ++i)
            {
                remesh.BasicRemeshPass();
            }

            remesh.BackPropropagate();

            // [TODO] output loop somehow...use MeshConstraints.FindConstrainedEdgesBySetID(set_id)...

            return(true);
        }         // Trim()