Exemplo n.º 1
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()