Exemple #1
0
 public SampledGridImplicit(MeshScalarSamplingGrid scalarGrid)
 {
     Initialize(scalarGrid);
 }
Exemple #2
0
 public void Initialize(MeshScalarSamplingGrid scalarGrid)
 {
     WindingGrid = new DenseGridTrilinearImplicit(scalarGrid.Grid, scalarGrid.GridOrigin, scalarGrid.CellSize);
     IsoValue    = scalarGrid.IsoValue;
 }
Exemple #3
0
        /// <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;
        }