public MarchingCubes() { // initialize w/ a basic sphere example Implicit = new ImplicitSphere3d(); Bounds = new AxisAlignedBox3d(Vector3d.Zero, 8); CubeSize = 0.25; }
public WindingFieldImplicit(ImplicitFunction3d wf, double isoValue) { WindingF = wf; IsoValue = isoValue; }
protected virtual void compute_hollow() { double offset_distance = -wall_thickness; if (cached_sdf == null || wall_thickness > cached_sdf_max_offset || grid_cell_size != cached_sdf.CellSize) { DMesh3 meshIn = MeshSource.GetDMeshUnsafe(); int exact_cells = (int)((wall_thickness) / grid_cell_size) + 1; // only use spatial DS if we are computing enough cells DMeshAABBTree3 use_spatial = GenerateClosedMeshOp.MeshSDFShouldUseSpatial(input_spatial, exact_cells, grid_cell_size, input_mesh_edge_stats.z); MeshSignedDistanceGrid sdf = new MeshSignedDistanceGrid(meshIn, grid_cell_size, use_spatial) { ExactBandWidth = exact_cells }; if (use_spatial != null) { sdf.NarrowBandMaxDistance = wall_thickness + grid_cell_size; sdf.ComputeMode = MeshSignedDistanceGrid.ComputeModes.NarrowBand_SpatialFloodFill; } sdf.CancelF = is_invalidated; sdf.Compute(); if (is_invalidated()) { return; } cached_sdf = sdf; cached_sdf_max_offset = wall_thickness; cached_sdf_bounds = meshIn.CachedBounds; } var iso = new DenseGridTrilinearImplicit(cached_sdf.Grid, cached_sdf.GridOrigin, cached_sdf.CellSize); ImplicitOffset3d shell_field = new ImplicitOffset3d() { A = iso, Offset = offset_distance }; ImplicitFunction3d use_iso = shell_field; if (enable_infill) { GridDistanceField grid_df = new GridDistanceField() { CellSize = infill_spacing, Radius = infill_thickness * 0.5, Origin = cached_sdf.GridOrigin }; ImplicitDifference3d diff = new ImplicitDifference3d() { A = shell_field, B = grid_df }; use_iso = diff; } MarchingCubes c = new MarchingCubes(); c.Implicit = use_iso; c.IsoValue = 0; c.Bounds = cached_sdf_bounds; c.CubeSize = mesh_cell_size; c.Bounds.Expand(offset_distance + 3 * c.CubeSize); c.RootMode = MarchingCubes.RootfindingModes.LerpSteps; c.RootModeSteps = 5; c.CancelF = is_invalidated; c.Generate(); if (is_invalidated()) { return; } Reducer r = new Reducer(c.Mesh); r.FastCollapsePass(c.CubeSize * 0.5, 3, true); if (is_invalidated()) { return; } //r.ReduceToTriangleCount(c.Mesh.TriangleCount / 5); //if (is_invalidated()) // return; if (min_component_volume > 0) { MeshEditor.RemoveSmallComponents(c.Mesh, min_component_volume, min_component_volume); } if (is_invalidated()) { return; } c.Mesh.AttachMetadata("is_partial", new object()); ResultMesh = c.Mesh; }