public SampledGridImplicit(MeshScalarSamplingGrid scalarGrid) { Initialize(scalarGrid); }
public void Initialize(MeshScalarSamplingGrid scalarGrid) { WindingGrid = new DenseGridTrilinearImplicit(scalarGrid.Grid, scalarGrid.GridOrigin, scalarGrid.CellSize); IsoValue = scalarGrid.IsoValue; }
/// <summary> /// Sample analytic winding number into grid in narrow-band around target isovalue, /// and then extract using marching cubes. /// /// TODO: don't need to discard current grid when isovalue changes, just need to /// re-run the front propagation part of mwn.Compute()! /// If this is done, then use this instead of update_winding_fast() for open meshes /// </summary> protected virtual void update_winding() { DMesh3 meshIn = MeshSource.GetDMeshUnsafe(); if (spatialPro == null || spatial_timestamp != meshIn.ShapeTimestamp) { spatialPro = new DMeshAABBTreePro(meshIn, true); spatialPro.FastWindingNumber(Vector3d.Zero); spatial_timestamp = meshIn.ShapeTimestamp; } if (is_invalidated()) { return; } if (cached_mwn_grid == null || grid_cell_size != cached_mwn_grid.CellSize || (float)winding_iso != cached_mwn_grid.IsoValue) { Func <Vector3d, double> fastWN = (q) => { return(spatialPro.FastWindingNumber(q)); }; var mwn = new MeshScalarSamplingGrid(meshIn, grid_cell_size, fastWN) { IsoValue = (float)winding_iso }; mwn.CancelF = is_invalidated; mwn.Compute(); if (is_invalidated()) { return; } cached_mwn_grid = mwn; cached_mwn_bounds = meshIn.CachedBounds; } MarchingCubes c = new MarchingCubes(); c.Implicit = new SampledGridImplicit(cached_mwn_grid); c.IsoValue = 0.0; c.Bounds = cached_mwn_bounds; c.CubeSize = mesh_cell_size; c.Bounds.Expand(3 * c.CubeSize); c.RootMode = MarchingCubes.RootfindingModes.Bisection; c.RootModeSteps = 10; 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; } if (min_component_volume > 0) { MeshEditor.RemoveSmallComponents(c.Mesh, min_component_volume, min_component_volume); } if (is_invalidated()) { return; } // reproject - if we want to do this, we need to create spatial and meshIn above! gParallel.ForEach(c.Mesh.VertexIndices(), (vid) => { if (is_invalidated()) { return; } Vector3d v = c.Mesh.GetVertex(vid); int tid = spatialPro.FindNearestTriangle(v, grid_cell_size * MathUtil.SqrtTwo); if (tid != DMesh3.InvalidID) { var query = MeshQueries.TriangleDistance(meshIn, tid, v); if (v.Distance(query.TriangleClosest) < grid_cell_size) { c.Mesh.SetVertex(vid, query.TriangleClosest); } } }); if (is_invalidated()) { return; } ResultMesh = c.Mesh; }