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"); }
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); }
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)); }