示例#1
0
        public DMesh3 BooleanUnion(DMesh3 mesh1, DMesh3 mesh2)
        {
            BoundedImplicitFunction3d meshA = meshToImplicitF(mesh1, 128, 0.2f);
            BoundedImplicitFunction3d meshB = meshToImplicitF(mesh2, 128, 0.2f);

            //take the difference of the bolus mesh minus the tools
            var mesh = new ImplicitUnion3d()
            {
                A = meshA, B = meshB
            };

            //calculate the boolean mesh
            MarchingCubes c = new MarchingCubes();

            c.Implicit      = mesh;
            c.RootMode      = MarchingCubes.RootfindingModes.LerpSteps;
            c.RootModeSteps = 5;
            c.Bounds        = mesh.Bounds();
            c.CubeSize      = c.Bounds.MaxDim / 96;
            c.Bounds.Expand(3 * c.CubeSize);
            c.Generate();
            MeshNormals.QuickCompute(c.Mesh);

            //int triangleCount = c.Mesh.TriangleCount / 2;
            //Reducer r = new Reducer(c.Mesh);
            //r.ReduceToTriangleCount(triangleCount);
            return(c.Mesh);
        }
示例#2
0
        private static DMesh3 BooleanIntersection(DMesh3 mesh1, DMesh3 mesh2)
        {
            BoundedImplicitFunction3d meshA = meshToImplicitF(mesh1, 64, 0.2f);
            BoundedImplicitFunction3d meshB = meshToImplicitF(mesh2, 64, 0.2f);

            //take the intersection of the meshes minus the tools
            ImplicitIntersection3d mesh = new ImplicitIntersection3d()
            {
                A = meshA, B = meshB
            };

            //calculate the boolean mesh
            MarchingCubes c = new MarchingCubes();

            c.Implicit      = mesh;
            c.RootMode      = MarchingCubes.RootfindingModes.LerpSteps;
            c.RootModeSteps = 5;
            c.Bounds        = mesh.Bounds();
            c.CubeSize      = c.Bounds.MaxDim / 128;
            c.Bounds.Expand(3 * c.CubeSize);
            c.Generate();
            MeshNormals.QuickCompute(c.Mesh);

            int     triangleCount = c.Mesh.TriangleCount / 2;
            Reducer r             = new Reducer(c.Mesh);

            r.ReduceToTriangleCount(triangleCount);
            return(c.Mesh);
        }
示例#3
0
        //experimental
        public List <DMesh3> SliceMold(DMesh3 mesh_to_slice, int number_of_slices)
        {
            var meshes = new List <MeshGeometry3D>();

            //convert mesh to DMesh
            DMesh3 mesh = mesh_to_slice;

            //create cube for slicing
            double z_height       = mesh.GetBounds().Max.z - mesh.GetBounds().Min.z;
            double slice_interval = (double)(z_height / number_of_slices);
            double x_size         = mesh.GetBounds().Depth;
            double y_size         = mesh.GetBounds().Width;
            double low_z          = mesh.GetBounds().Min.z;


            //boolean intersection each mesh
            var sliced_meshes = new List <DMesh3>();

            for (int i = 0; i < number_of_slices; i++)
            {
                //create box
                Vector3d centre = new Vector3d(0, 0, low_z + slice_interval / 2 + i * (slice_interval));
                Vector3d extend = new Vector3d(
                    x_size,
                    y_size,
                    slice_interval / 2);

                ImplicitBox3d box = new ImplicitBox3d()
                {
                    Box = new Box3d(centre, extend)
                };

                //boolean overlap
                BoundedImplicitFunction3d meshA = meshToImplicitF(mesh, 64, 0.2f);

                //take the difference of the bolus mesh minus the tools
                ImplicitIntersection3d mesh_result = new ImplicitIntersection3d {
                    A = meshA, B = box
                };

                //calculate the boolean mesh
                MarchingCubes c = new MarchingCubes();
                c.Implicit      = mesh_result;
                c.RootMode      = MarchingCubes.RootfindingModes.LerpSteps;
                c.RootModeSteps = 5;
                c.Bounds        = mesh_result.Bounds();
                c.CubeSize      = c.Bounds.MaxDim / 256;
                c.Bounds.Expand(3 * c.CubeSize);
                c.Generate();
                MeshNormals.QuickCompute(c.Mesh);

                int     triangleCount = c.Mesh.TriangleCount / 3;
                Reducer r             = new Reducer(c.Mesh);
                r.ReduceToTriangleCount(triangleCount);

                sliced_meshes.Add(c.Mesh);
            }

            return(sliced_meshes);
        }
 void sample_min(BoundedImplicitFunction3d f, IEnumerable <Vector3i> indices)
 {
     gParallel.ForEach(indices, (idx) => {
         Vector3d v = Indexer.FromGrid(idx);
         double d   = f.Value(ref v);
         Grid.set_min(ref idx, (float)d);
     });
 }
示例#5
0
        public static ImplicitUnion3d ImplicitUnion(BoundedImplicitFunction3d meshA, BoundedImplicitFunction3d meshB)
        {
            var union = new ImplicitUnion3d()
            {
                A = meshA, B = meshB
            };

            return(union);
        }
示例#6
0
        public static ImplicitIntersection3d ImplicitIntersection(BoundedImplicitFunction3d meshA, BoundedImplicitFunction3d meshB)
        {
            var intersection = new ImplicitIntersection3d()
            {
                A = meshA, B = meshB
            };

            return(intersection);
        }
示例#7
0
        public static ImplicitBlend3d ImplicitBlend(BoundedImplicitFunction3d meshA, BoundedImplicitFunction3d meshB, double blend)
        {
            var blendMesh = new ImplicitBlend3d()
            {
                A = meshA, B = meshB, Blend = blend
            };

            return(blendMesh);
        }
示例#8
0
        public static ImplicitOffset3d ImplicitOffset(BoundedImplicitFunction3d mesh, double offset)
        {
            var offsetMesh = new ImplicitOffset3d()
            {
                A = mesh, Offset = offset
            };

            return(offsetMesh);
        }
示例#9
0
        public static ImplicitSmoothDifference3d ImplicitSmoothDifference(BoundedImplicitFunction3d meshA, BoundedImplicitFunction3d meshB)
        {
            var smoothMesh = new ImplicitSmoothDifference3d()
            {
                A = meshA, B = meshB
            };

            return(smoothMesh);
        }
示例#10
0
        public static ImplicitDifference3d ImplicitDifference(BoundedImplicitFunction3d meshA, BoundedImplicitFunction3d meshB)
        {
            var diff = new ImplicitDifference3d()
            {
                A = meshA, B = meshB
            };

            return(diff);
        }
示例#11
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            // INPUT
            // declaration
            Rhino.Geometry.Mesh meshA = null;
            Rhino.Geometry.Mesh meshB = null;
            int    num      = 0;
            double offset   = 0.00;
            double blend    = 1.00;
            bool   runIt    = false;
            bool   showIt   = false;
            bool   writeObj = false;
            string path     = null;

            DA.GetData(0, ref meshA);
            DA.GetData(1, ref meshB);
            DA.GetData(2, ref num);
            DA.GetData(3, ref blend);
            DA.GetData(4, ref offset);
            DA.GetData(5, ref runIt);
            DA.GetData(6, ref showIt);
            DA.GetData(7, ref writeObj);
            DA.GetData(8, ref path);

            // run

            if (runIt)
            {
                DMesh3 g3MeshA = ConvertDMesh(meshA);
                DMesh3 g3MeshB = ConvertDMesh(meshB);

                BoundedImplicitFunction3d implicitA = MeshMorphoLib.MeshClassFnc.MeshToImplicitF(g3MeshA, num, offset);
                BoundedImplicitFunction3d implicitB = MeshMorphoLib.MeshClassFnc.MeshToImplicitF(g3MeshB, num, offset);


                var    implicitBlendDone = MeshMorphoLib.MeshClassFnc.ImplicitBlend(implicitA, implicitB, blend);
                DMesh3 newMesh           = MeshMorphoLib.MeshClassFnc.GenerateMeshF(implicitBlendDone, num);
                if (showIt)
                {
                    Rhino.Geometry.Mesh resultMesh = MeshMorphoLib.MeshIntegration.ConvertToRhinoMesh(newMesh);
                    DA.SetData(0, resultMesh);
                }
                if (writeObj)
                {
                    try
                    {
                        string fullFolder = System.IO.Path.Combine(path, "MorphoModel.obj");
                        MeshClassIO.WriteMesh(newMesh, fullFolder);
                        DA.SetData(1, fullFolder);
                    }
                    catch
                    {
                        this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Please provide a valid path.");
                    }
                }
            }
        }
示例#12
0
        private DMesh3 GenerateMeshBase(BoundedImplicitFunction3d root, AxisAlignedBox3d filterBox)
        {
            MarchingCubes c = new MarchingCubes();

            c.Implicit      = root;
            c.RootMode      = MarchingCubes.RootfindingModes.LerpSteps; // cube-edge convergence method
            c.RootModeSteps = 5;                                        // number of iterations
            c.Bounds        = filterBox;                                //_sideFilterBox;
            c.CubeSize      = _cubeSize / 4.0;
            c.Generate();
            MeshNormals.QuickCompute(c.Mesh);                           // generate normals

            return(c.Mesh);
        }
示例#13
0
        // generateMeshF() meshes the input implicit function at
        // the given cell resolution, and writes out the resulting mesh
        DMesh3 generatMeshF(BoundedImplicitFunction3d root, int numcells)
        {
            MarchingCubes c = new MarchingCubes();

            c.Implicit      = root;
            c.RootMode      = MarchingCubes.RootfindingModes.LerpSteps; // cube-edge convergence method
            c.RootModeSteps = 5;                                        // number of iterations
            c.Bounds        = root.Bounds();
            c.CubeSize      = c.Bounds.MaxDim / numcells;
            c.Bounds.Expand(3 * c.CubeSize);  // leave a buffer of cells
            c.Generate();
            MeshNormals.QuickCompute(c.Mesh); // generate normals
            return(c.Mesh);                   // write mesh
        }
        public void SetSources(List <DMeshSourceOp> sources)
        {
            if (mesh_sources != null)
            {
                throw new Exception("todo: handle changing sources!");
            }
            mesh_sources = new List <DMeshSourceOp>(sources);
            foreach (var source in mesh_sources)
            {
                source.OperatorModified += on_input_modified;
            }

            cached_sdfs = new MeshSignedDistanceGrid[sources.Count];
            cached_isos = new BoundedImplicitFunction3d[sources.Count];

            invalidate();
        }
示例#15
0
        public static DMesh3 GenerateMeshF(BoundedImplicitFunction3d mesh, int num_cells)
        {
            MarchingCubes c = new MarchingCubes();

            c.Implicit      = mesh;
            c.RootMode      = MarchingCubes.RootfindingModes.LerpSteps; // cube-edge convergence method
            c.RootModeSteps = 5;                                        // number of iterations
            c.Bounds        = mesh.Bounds();
            c.CubeSize      = c.Bounds.MaxDim / num_cells;
            c.Bounds.Expand(3 * c.CubeSize);                            // leave a buffer of cells
            c.Generate();
            MeshNormals.QuickCompute(c.Mesh);                           // generate normals

            DMesh3 outputMesh = c.Mesh;

            return(outputMesh);
        }
        void generate_mesh(DenseGrid3f supportGrid, DenseGridTrilinearImplicit distanceField)
        {
            DenseGridTrilinearImplicit volume = new DenseGridTrilinearImplicit(
                supportGrid, GridOrigin, CellSize);
            BoundedImplicitFunction3d inputF = volume;

            if (SubtractMesh)
            {
                BoundedImplicitFunction3d sub = distanceField;
                if (SubtractMeshOffset > 0)
                {
                    sub = new ImplicitOffset3d()
                    {
                        A = distanceField, Offset = SubtractMeshOffset
                    }
                }
                ;
                ImplicitDifference3d subtract = new ImplicitDifference3d()
                {
                    A = volume, B = sub
                };
                inputF = subtract;
            }

            ImplicitHalfSpace3d cutPlane = new ImplicitHalfSpace3d()
            {
                Origin = Vector3d.Zero, Normal = Vector3d.AxisY
            };
            ImplicitDifference3d cut = new ImplicitDifference3d()
            {
                A = inputF, B = cutPlane
            };

            MarchingCubes mc = new MarchingCubes()
            {
                Implicit = cut, Bounds = grid_bounds, CubeSize = CellSize
            };

            mc.Bounds.Min.y  = -2 * mc.CubeSize;
            mc.Bounds.Min.x -= 2 * mc.CubeSize; mc.Bounds.Min.z -= 2 * mc.CubeSize;
            mc.Bounds.Max.x += 2 * mc.CubeSize; mc.Bounds.Max.z += 2 * mc.CubeSize;
            mc.Generate();

            SupportMesh = mc.Mesh;
        }
    }
        public void AddToolApplication(BoundedImplicitFunction3d toolApplication)
        {
            bool notify = false;

            lock (_lockObj)
            {
                if (_toolApplications == null)
                {
                    _toolApplications = new List <BoundedImplicitFunction3d>();
                    notify            = true;
                }
            }

            _toolApplications.Add(toolApplication);
            if (notify)
            {
                RisePropertyChanged(nameof(IsCorrupted));
            }
        }
示例#18
0
        private static DMesh3 GenerateMeshF(BoundedImplicitFunction3d root, int numcells)
        {
            var bounds = root.Bounds();

            var c = new MarchingCubes()
            {
                Implicit      = root,
                RootMode      = MarchingCubes.RootfindingModes.LerpSteps,                 // cube-edge convergence method
                RootModeSteps = 5,                                                        // number of iterations
                Bounds        = bounds,
                CubeSize      = bounds.MaxDim / numcells,
            };

            c.Bounds.Expand(3 * c.CubeSize);                                        // leave a buffer of cells
            c.Generate();

            MeshNormals.QuickCompute(c.Mesh);                                       // generate normals
            return(c.Mesh);
        }
        internal Task <bool> ApplyActionAsync(BoundedImplicitFunction3d toolApplication)
        {
            return(Task.Run(async() =>
            {
                AddToolApplication(toolApplication);

                try
                {
                    InternalGeometry = await Task.Run(() => GenerateMesh());
                    OnActionApplied();

                    return true;
                }
                catch (System.Exception)
                {
                    return false;
                }
            }));
        }
        public void Sample(BoundedImplicitFunction3d f, double expandRadius = 0)
        {
            AxisAlignedBox3d bounds = f.Bounds();

            Vector3d expand  = expandRadius * Vector3d.One;
            Vector3i gridMin = Indexer.ToGrid(bounds.Min - expand),
                     gridMax = Indexer.ToGrid(bounds.Max + expand) + Vector3i.One;

            gridMin = GridBounds.ClampExclusive(gridMin);
            gridMax = GridBounds.ClampExclusive(gridMax);

            AxisAlignedBox3i gridbox = new AxisAlignedBox3i(gridMin, gridMax);

            switch (CombineMode)
            {
            case CombineModes.DistanceMinUnion:
                sample_min(f, gridbox.IndicesInclusive());
                break;
            }
        }
示例#21
0
        public void SetSources(List <DMeshSourceOp> sources)
        {
            if (mesh_sources != null)
            {
                throw new Exception("MeshVoxelBlendOp.SetSources: handle changing sources!");
            }
            //if (sources.Count != 2)
            //    throw new Exception("MeshVoxelBlendOp.SetSources: only two sources supported!");
            mesh_sources = new List <DMeshSourceOp>(sources);
            foreach (var source in mesh_sources)
            {
                source.OperatorModified += on_input_modified;
            }

            cached_sdfs    = new MeshSignedDistanceGrid[sources.Count];
            cached_isos    = new BoundedImplicitFunction3d[sources.Count];
            cached_bvtrees = new DMeshAABBTreePro[sources.Count];

            invalidate();
        }
示例#22
0
        protected virtual void compute_shell_distancefield()
        {
            if (cached_is_closed == false)
            {
                compute_shell_distancefield_unsigned();
                return;
            }

            double     offset_distance = shell_thickness;
            Interval1d shell_range     = new Interval1d(0, offset_distance);

            if (shell_direction == ShellDirections.Symmetric)
            {
                shell_range = new Interval1d(-offset_distance / 2, offset_distance / 2);
            }
            else if (shell_direction == ShellDirections.Inner)
            {
                shell_range     = new Interval1d(-offset_distance, 0);
                offset_distance = -offset_distance;
            }


            if (cached_sdf == null ||
                shell_thickness > cached_sdf_max_offset ||
                grid_cell_size != cached_sdf.CellSize)
            {
                DMesh3 meshIn      = MeshSource.GetDMeshUnsafe();
                int    exact_cells = (int)((shell_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 = shell_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 = shell_thickness;
                cached_sdf_bounds     = meshIn.CachedBounds;
            }

            var iso = new DenseGridTrilinearImplicit(cached_sdf.Grid, cached_sdf.GridOrigin, cached_sdf.CellSize);
            BoundedImplicitFunction3d shell_field = (shell_direction == ShellDirections.Symmetric) ?
                                                    (BoundedImplicitFunction3d) new ImplicitShell3d()
            {
                A = iso, Inside = shell_range
            } :
            (BoundedImplicitFunction3d) new ImplicitOffset3d()
            {
                A = iso, Offset = offset_distance
            };
            //var shell_field = new ImplicitShell3d() { A = iso, Inside = shell_range };
            //BoundedImplicitFunction3d shell_field = (signed_field) ?
            //    (BoundedImplicitFunction3d)new ImplicitShell3d() { A = iso, Inside = shell_range } :
            //    (BoundedImplicitFunction3d)new ImplicitOffset3d() { A = iso, Offset = offset_distance };
            //ImplicitOffset3d offset = new ImplicitOffset3d() { A = iso, Offset = offset_distance };

            MarchingCubes c = new MarchingCubes();

            c.Implicit = shell_field;
            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;
            }

            if (min_component_volume > 0)
            {
                MeshEditor.RemoveSmallComponents(c.Mesh, min_component_volume, min_component_volume);
            }
            if (is_invalidated())
            {
                return;
            }

            if (shell_surface_only)
            {
                if (shell_direction == ShellDirections.Inner || shell_direction == ShellDirections.Outer)
                {
                    c.Mesh.AttachMetadata("is_partial", new object());
                }
            }

            ResultMesh = c.Mesh;
        }
示例#23
0
        public static void test_marching_cubes_implicits()
        {
            DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj");

            MeshTransforms.Translate(mesh, -mesh.CachedBounds.Center);
            double meshCellsize             = mesh.CachedBounds.MaxDim / 32;
            MeshSignedDistanceGrid levelSet = new MeshSignedDistanceGrid(mesh, meshCellsize);

            levelSet.ExactBandWidth = 3;
            levelSet.UseParallel    = true;
            levelSet.ComputeMode    = MeshSignedDistanceGrid.ComputeModes.NarrowBandOnly;
            levelSet.Compute();
            var meshIso = new DenseGridTrilinearImplicit(levelSet.Grid, levelSet.GridOrigin, levelSet.CellSize);


            ImplicitOffset3d offsetMeshIso = new ImplicitOffset3d()
            {
                A = meshIso, Offset = 2.0
            };

            double           r       = 15.0;
            ImplicitSphere3d sphere1 = new ImplicitSphere3d()
            {
                Origin = Vector3d.Zero,
                Radius = r
            };
            ImplicitSphere3d sphere2 = new ImplicitSphere3d()
            {
                Origin = r * Vector3d.AxisX,
                Radius = r
            };
            ImplicitAxisAlignedBox3d aabox1 = new ImplicitAxisAlignedBox3d()
            {
                AABox = new AxisAlignedBox3d(r * 0.5 * Vector3d.One, r, r * 0.75, r * 0.5)
            };
            ImplicitBox3d box1 = new ImplicitBox3d()
            {
                Box = new Box3d(new Frame3f(r * 0.5 * Vector3d.One, Vector3d.One.Normalized),
                                new Vector3d(r, r * 0.75, r * 0.5))
            };
            ImplicitLine3d line1 = new ImplicitLine3d()
            {
                Segment = new Segment3d(Vector3d.Zero, r * Vector3d.One),
                Radius  = 3.0
            };
            ImplicitHalfSpace3d half1 = new ImplicitHalfSpace3d()
            {
                Origin = Vector3d.Zero, Normal = Vector3d.One.Normalized
            };

            ImplicitUnion3d union = new ImplicitUnion3d()
            {
                A = sphere1, B = line1
            };
            ImplicitDifference3d difference = new ImplicitDifference3d()
            {
                A = meshIso, B = aabox1
            };
            ImplicitIntersection3d intersect = new ImplicitIntersection3d()
            {
                A = meshIso, B = half1
            };
            ImplicitNaryUnion3d nunion = new ImplicitNaryUnion3d()
            {
                Children = new List <BoundedImplicitFunction3d>()
                {
                    offsetMeshIso, sphere1, sphere2
                }
            };
            ImplicitNaryDifference3d ndifference = new ImplicitNaryDifference3d()
            {
                A    = offsetMeshIso,
                BSet = new List <BoundedImplicitFunction3d>()
                {
                    sphere1, sphere2
                }
            };
            ImplicitBlend3d blend = new ImplicitBlend3d()
            {
                A = sphere1, B = sphere2
            };

            BoundedImplicitFunction3d root = intersect;

            AxisAlignedBox3d bounds = root.Bounds();
            int           numcells  = 64;
            MarchingCubes c         = new MarchingCubes();

            c.RootMode      = MarchingCubes.RootfindingModes.LerpSteps;
            c.RootModeSteps = 5;
            c.Implicit      = root;
            c.Bounds        = bounds;
            c.CubeSize      = bounds.MaxDim / numcells;
            c.Bounds.Expand(3 * c.CubeSize);

            c.Generate();

            MeshNormals.QuickCompute(c.Mesh);
            TestUtil.WriteTestOutputMesh(c.Mesh, "marching_cubes_implicit.obj");
        }
 public void ApplyAction(BoundedImplicitFunction3d toolApplication)
 {
     AddToolApplication(toolApplication);
     InternalGeometry = GenerateMesh();
     OnActionApplied();
 }
        protected virtual DMesh3 compute_wrap()
        {
            cache_input_sdfs();
            if (is_invalidated())
            {
                return(null);
            }

            BoundedImplicitFunction3d iso = null;

            if (op_type == OpTypes.Union)
            {
                iso = new ImplicitNaryUnion3d()
                {
                    Children = new List <BoundedImplicitFunction3d>(cached_isos)
                };
            }
            else if (op_type == OpTypes.Intersection)
            {
                iso = new ImplicitNaryIntersection3d()
                {
                    Children = new List <BoundedImplicitFunction3d>(cached_isos)
                };
            }
            else if (op_type == OpTypes.Difference)
            {
                iso = new ImplicitNaryDifference3d()
                {
                    A    = cached_isos[0],
                    BSet = new List <BoundedImplicitFunction3d>(cached_isos.Skip(1))
                };
            }

            MarchingCubes c = new MarchingCubes();

            c.Implicit = iso;
            c.IsoValue = 0;
            c.Bounds   = iso.Bounds();
            c.CubeSize = mesh_cell_size;
            c.Bounds.Expand(3 * c.CubeSize);
            c.RootMode      = MarchingCubes.RootfindingModes.Bisection;
            c.RootModeSteps = 5;

            c.CancelF = is_invalidated;
            c.Generate();
            if (is_invalidated())
            {
                return(null);
            }

            Reducer r = new Reducer(c.Mesh);

            r.FastCollapsePass(c.CubeSize / 2, 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);
        }