コード例 #1
0
        void compute_cache_lazy_sdfs()
        {
            if (cached_lazy_sdfs == null)
            {
                cached_lazy_sdfs         = new CachingMeshSDF[mesh_sources.Count];
                cached_lazy_sdf_maxdists = new double[mesh_sources.Count];
            }
            cache_bvtrees(false);

            double need_distance = blend_falloff;

            gParallel.ForEach(Interval1i.Range(mesh_sources.Count), (k) => {
                if (need_distance > cached_lazy_sdf_maxdists[k])
                {
                    cached_lazy_sdfs[k] = null;
                }

                // [TODO] we could expand via flood-fill here instead of throwing away all previously computed!

                if (cached_lazy_sdfs[k] != null)
                {
                    return;
                }
                if (is_invalidated())
                {
                    return;
                }

                float use_max_offset = (float)blend_falloff; // (float)(3 * blend_falloff);

                DMesh3 source_mesh = mesh_sources[k].GetDMeshUnsafe();
                CachingMeshSDF sdf = new CachingMeshSDF(source_mesh, grid_cell_size, cached_bvtrees[k])
                {
                    MaxOffsetDistance = use_max_offset
                };
                sdf.CancelF = is_invalidated;
                sdf.Initialize();
                if (is_invalidated())
                {
                    return;
                }

                cached_lazy_sdfs[k]         = sdf;
                cached_lazy_sdf_maxdists[k] = use_max_offset;
            });
        }
コード例 #2
0
        public static void test_2()
        {
            DMesh3         mesh      = TestUtil.LoadTestInputMesh("bunny_solid.obj");
            DMeshAABBTree3 spatial   = new DMeshAABBTree3(mesh, true);
            int            num_cells = 64;
            double         cell_size = mesh.CachedBounds.MaxDim / num_cells;

            CachingMeshSDF sdf = new CachingMeshSDF(mesh, cell_size, spatial);

            sdf.MaxOffsetDistance = (float)(4 * cell_size);
            sdf.Initialize();

            gParallel.ForEach(sdf.Grid.Indices(), (idx) => {
                sdf.GetValue(idx);
            });

            CachingMeshSDFImplicit sdf_iso = new CachingMeshSDFImplicit(sdf);
            var skel_field = new DistanceFieldToSkeletalField()
            {
                DistanceField = sdf_iso, FalloffDistance = 5 * cell_size
            };

            MarchingCubesPro c = new MarchingCubesPro();

            //c.Implicit = sdf_iso;
            c.Implicit = skel_field;
            //c.IsoValue = DistanceFieldToSkeletalField.ZeroIsocontour;
            c.Bounds   = mesh.CachedBounds;
            c.CubeSize = c.Bounds.MaxDim / 128;
            c.Bounds.Expand(3 * c.CubeSize);
            c.RootMode        = MarchingCubesPro.RootfindingModes.Bisection;
            c.ParallelCompute = false;

            c.Generate();
            //c.GenerateContinuation(mesh.Vertices());

            c.Mesh.ReverseOrientation();

            TestUtil.WriteTestOutputMesh(c.Mesh, "mcpro_output.obj");
        }
コード例 #3
0
ファイル: MeshWrapOp.cs プロジェクト: tomleetv/gsShapeModels
        protected virtual DMesh3 compute_inset(DMesh3 meshIn)
        {
            double unsigned_offset = Math.Abs(distance);

            DMeshAABBTree3 use_spatial = new DMeshAABBTree3(meshIn, true);

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

            CachingMeshSDF sdf = new CachingMeshSDF(meshIn, grid_cell_size, use_spatial);

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

            var sdf_iso = new CachingMeshSDFImplicit(sdf);
            // currently MCPro-Continuation does not work w/ non-zero
            //   isovalues, so we have to shift our target offset externally
            ImplicitOffset3d iso = new ImplicitOffset3d()
            {
                A = sdf_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);
            }

            return(c.Mesh);
        }
コード例 #4
0
ファイル: MeshWrapOp.cs プロジェクト: tomleetv/gsShapeModels
        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));
        }