예제 #1
0
        protected virtual DMesh3 compute_wrap()
        {
            DMesh3 meshIn = MeshSource.GetDMeshUnsafe();

            double unsigned_offset = Math.Abs(distance);

            if (cached_sdf == null ||
                unsigned_offset > cached_sdf_max_offset ||
                grid_cell_size != cached_sdf.CellSize)
            {
                DMeshAABBTree3 use_spatial = input_spatial;
                CachingMeshSDF sdf         = new CachingMeshSDF(meshIn, grid_cell_size, use_spatial);
                sdf.MaxOffsetDistance = 2 * (float)unsigned_offset;

                sdf.CancelF = is_invalidated;
                sdf.Initialize();
                if (is_invalidated())
                {
                    return(null);
                }

                cached_sdf            = sdf;
                cached_sdf_max_offset = unsigned_offset;
                cached_sdf_bounds     = meshIn.CachedBounds;
            }

            var grid_iso = new CachingMeshSDFImplicit(cached_sdf);
            // currently MCPro-Continuation does not work w/ non-zero
            //   isovalues, so we have to shift our target offset externally
            var iso = new ImplicitOffset3d()
            {
                A = grid_iso, Offset = distance
            };

            MarchingCubesPro c = new MarchingCubesPro();

            c.Implicit = iso;
            c.Bounds   = cached_sdf_bounds;
            c.CubeSize = mesh_cell_size;
            c.Bounds.Expand(distance + 3 * c.CubeSize);

            c.CancelF = is_invalidated;
            c.GenerateContinuation(offset_seeds(meshIn, distance));
            if (is_invalidated())
            {
                return(null);
            }

            Reducer r = new Reducer(c.Mesh);

            r.FastCollapsePass(c.CubeSize * 0.5, 3, true);
            if (is_invalidated())
            {
                return(null);
            }

            if (min_component_volume > 0)
            {
                MeshEditor.RemoveSmallComponents(c.Mesh, min_component_volume, min_component_volume);
            }
            if (is_invalidated())
            {
                return(null);
            }

            DMesh3 offsetMesh = c.Mesh;

            MeshConnectedComponents comp = new MeshConnectedComponents(offsetMesh);

            comp.FindConnectedT();
            if (is_invalidated())
            {
                return(null);
            }
            DSubmesh3Set subMeshes = new DSubmesh3Set(offsetMesh, comp);

            if (is_invalidated())
            {
                return(null);
            }

            MeshSpatialSort sort = new MeshSpatialSort();

            foreach (var subMesh in subMeshes)
            {
                sort.AddMesh(subMesh.SubMesh, subMesh);
            }
            sort.Sort();
            if (is_invalidated())
            {
                return(null);
            }

            DMesh3 outerMesh = new DMesh3();

            foreach (var solid in sort.Solids)
            {
                DMesh3 outer = solid.Outer.Mesh;
                //if (is_outward_oriented(outer) == false)
                //    outer.ReverseOrientation();
                MeshEditor.Append(outerMesh, outer);
            }
            if (is_invalidated())
            {
                return(null);
            }

            return(compute_inset(outerMesh));
        }