Exemple #1
0
        public static void printVoxelizedRepresentation(Bitmap3 bmp, String outputPath)
        {
            VoxelSurfaceGenerator voxGen = new VoxelSurfaceGenerator();

            voxGen.Voxels = bmp;
            voxGen.Generate();
            DMesh3 voxMesh = voxGen.Meshes[0];

            Util.WriteDebugMesh(voxMesh, outputPath);
        }
        public static void test_voxel_surface()
        {
            //DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj");
            DMesh3         mesh    = TestUtil.LoadTestInputMesh("holey_bunny_2.obj");
            DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh, autoBuild: true);

            AxisAlignedBox3d bounds         = mesh.CachedBounds;
            int    numcells                 = 64;
            double cellsize                 = bounds.MaxDim / numcells;
            MeshSignedDistanceGrid levelSet = new MeshSignedDistanceGrid(mesh, cellsize);

            levelSet.UseParallel = true;
            levelSet.Compute();

            Bitmap3 bmp = new Bitmap3(levelSet.Dimensions);

            foreach (Vector3i idx in bmp.Indices())
            {
                float f = levelSet[idx.x, idx.y, idx.z];
                bmp.Set(idx, (f < 0) ? true : false);
            }


            //AxisAlignedBox3d bounds = mesh.CachedBounds;
            //int numcells = 32;
            //double cellsize = bounds.MaxDim / numcells;
            //ShiftGridIndexer3 indexer = new ShiftGridIndexer3(bounds.Min-2*cellsize, cellsize);

            //Bitmap3 bmp = new Bitmap3(new Vector3i(numcells, numcells, numcells));
            //foreach (Vector3i idx in bmp.Indices()) {
            //    Vector3d v = indexer.FromGrid(idx);
            //    bmp.Set(idx, spatial.IsInside(v));
            //}

            //spatial.WindingNumber(Vector3d.Zero);
            //Bitmap3 bmp = new Bitmap3(new Vector3i(numcells+3, numcells+3, numcells+3));
            //gParallel.ForEach(bmp.Indices(), (idx) => {
            //    Vector3d v = indexer.FromGrid(idx);
            //    bmp.SafeSet(idx, spatial.WindingNumber(v) > 0.8);
            //});


            VoxelSurfaceGenerator voxGen = new VoxelSurfaceGenerator();

            voxGen.Voxels       = bmp;
            voxGen.ColorSourceF = (idx) => {
                return(new Colorf((float)idx.x, (float)idx.y, (float)idx.z) * (1.0f / numcells));
            };
            voxGen.Generate();
            DMesh3 voxMesh = voxGen.Meshes[0];

            Util.WriteDebugMesh(voxMesh, "c:\\scratch\\temp.obj");

            TestUtil.WriteTestOutputMesh(voxMesh, "voxel_surf.obj", true, true);
        }
Exemple #3
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            int        num_cells = 128;
            DMesh3_goo dMsh_goo  = null;

            DA.GetData(0, ref dMsh_goo);
            DA.GetData(1, ref num_cells);

            DMesh3 dMsh_copy = new DMesh3(dMsh_goo.Value);
            double cell_size = dMsh_copy.CachedBounds.MaxDim / num_cells;

            DMeshAABBTree3 spatial = new DMeshAABBTree3(dMsh_copy, autoBuild: true);

            AxisAlignedBox3d  bounds   = dMsh_copy.CachedBounds;
            double            cellsize = bounds.MaxDim / num_cells;
            ShiftGridIndexer3 indexer  = new ShiftGridIndexer3(bounds.Min, cellsize);

            Bitmap3 bmp = new Bitmap3(new Vector3i(num_cells, num_cells, num_cells));

            foreach (Vector3i idx in bmp.Indices())
            {
                g3.Vector3d v = indexer.FromGrid(idx);
                bmp.Set(idx, spatial.IsInside(v));
            }

            VoxelSurfaceGenerator voxGen = new VoxelSurfaceGenerator();

            voxGen.Voxels = bmp;
            voxGen.Generate();
            DMesh3 voxMesh = voxGen.Meshes[0];

            var vecSize = dMsh_copy.CachedBounds.Extents;
            var box     = dMsh_copy.GetBounds();

            // Scale voxel mesh
            //MeshTransforms.Scale(voxMesh,)

            DA.SetData(0, voxMesh);
        }
Exemple #4
0
        public static DMesh3 MineCraft(DMesh3 mesh, int num_cells, out double scalefactor)
        {
            DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh, autoBuild: true);


            AxisAlignedBox3d bounds   = mesh.CachedBounds;
            double           cellsize = bounds.MaxDim / num_cells;

            scalefactor = cellsize;

            ShiftGridIndexer3 indexer = new ShiftGridIndexer3(bounds.Min, cellsize);

            Bitmap3 bmp = new Bitmap3(new Vector3i(num_cells, num_cells, num_cells));

            foreach (Vector3i idx in bmp.Indices())
            {
                g3.Vector3d v = indexer.FromGrid(idx);
                if (spatial.IsInside(v))
                {
                    bmp.Set(idx, true);
                }
                else
                {
                    bmp.Set(idx, false);
                }
            }

            VoxelSurfaceGenerator voxGen = new VoxelSurfaceGenerator();

            voxGen.Voxels = bmp;
            voxGen.Generate();

            DMesh3 voxMesh = voxGen.Meshes[0];

            return(voxMesh);
        }
        void process_version2(DenseGrid3f supportGrid, DenseGridTrilinearImplicit distanceField)
        {
            int      ni = supportGrid.ni, nj = supportGrid.nj, nk = supportGrid.nk;
            float    dx     = (float)CellSize;
            Vector3f origin = this.GridOrigin;

            // sweep values down layer by layer
            DenseGrid2f prev = supportGrid.get_slice(nj - 1, 1);
            DenseGrid2f tmp  = new DenseGrid2f(prev);

            Bitmap3 bmp = new Bitmap3(new Vector3i(ni, nj, nk));

            for (int j = nj - 2; j >= 0; j--)
            {
                // skeletonize prev layer
                DenseGrid2i prev_skel = binarize(prev, 0.0f);
                skeletonize(prev_skel, null, 2);
                //dilate_loners(prev_skel, null, 2);

                if (j == 0)
                {
                    dilate(prev_skel, null, true);
                    dilate(prev_skel, null, true);
                }

                for (int k = 1; k < nk - 1; ++k)
                {
                    for (int i = 1; i < ni - 1; ++i)
                    {
                        bmp[new Vector3i(i, j, k)] = (prev_skel[i, k] == 1) ? true : false;
                    }
                }

                smooth(prev, tmp, 0.5f, 5);

                DenseGrid2f cur = supportGrid.get_slice(j, 1);
                cur.set_min(prev);

                for (int k = 1; k < nk - 1; ++k)
                {
                    for (int i = 1; i < ni - 1; ++i)
                    {
                        float skelf = prev_skel[i, k] > 0 ? -1.0f : int.MaxValue;
                        cur[i, k] = Math.Min(cur[i, k], skelf);

                        if (cur[i, k] < 0)
                        {
                            Vector3d cell_center = new Vector3f(i * dx, j * dx, k * dx) + origin;
                            if (distanceField.Value(ref cell_center) < -CellSize)
                            {
                                cur[i, k] = 1;
                            }
                        }
                    }
                }

                for (int k = 1; k < nk - 1; ++k)
                {
                    for (int i = 1; i < ni - 1; ++i)
                    {
                        if (is_loner(prev_skel, i, k))
                        {
                            foreach (Vector2i d in gIndices.GridOffsets8)
                            {
                                float f = 1.0f / (float)Math.Sqrt(d.x * d.x + d.y * d.y);
                                cur[i + d.x, k + d.y] += -0.25f * f;
                            }
                        }
                    }
                }

                for (int k = 1; k < nk - 1; ++k)
                {
                    for (int i = 1; i < ni - 1; ++i)
                    {
                        supportGrid[i, j, k] = cur[i, k];
                    }
                }

                prev.swap(cur);
            }


            VoxelSurfaceGenerator gen = new VoxelSurfaceGenerator()
            {
                Voxels = bmp
            };

            gen.Generate();
            Util.WriteDebugMesh(gen.Meshes[0], "c:\\scratch\\binary.obj");
        }
    void update_mesh()
    {
        clear_mesh();

        AxisAlignedBox3i bounds    = grid.Extents;
        Vector3i         minCorner = bounds.Min;
        Vector3f         cornerXYZ = grid.ToXYZ(minCorner);

        Bitmap3d bmp;

        try {
            bmp = new Bitmap3d(bounds.Diagonal + Vector3i.One);
        } catch (Exception e) {
            Debug.Log("update_mesh: exception allocating grid of size " + bounds.Diagonal);
            throw e;
        }

        foreach (Vector3i idx in grid.GridIndices(MinSamples))
        {
            Vector3i bidx = idx - minCorner;
            try {
                bmp.Set(bidx, true);
            } catch (Exception e) {
                Debug.Log("bad index is " + bidx + "  grid dims " + bmp.Dimensions);
                throw e;
            }
        }

        // get rid of one-block tubes, floaters, etc.
        // todo: use a queue instead of passes? or just descend into
        //  nbrs when changing one block? one pass to compute counts and
        //  then another to remove? (yes that is a good idea...)
        bmp.Filter(2);
        bmp.Filter(2);
        bmp.Filter(2);
        bmp.Filter(2);
        bmp.Filter(2);
        bmp.Filter(2);


        VoxelSurfaceGenerator gen = new VoxelSurfaceGenerator()
        {
            Voxels = bmp, Clockwise = false,
            MaxMeshElementCount = 65000,
            ColorSourceF        = (idx) => {
                idx = idx + minCorner;
                return(grid.GetColor(idx));
            }
        };

        gen.Generate();
        List <DMesh3> meshes = gen.Meshes;

        List <fMeshGameObject> newMeshGOs = new List <fMeshGameObject>();

        foreach (DMesh3 mesh in meshes)
        {
            MeshTransforms.Scale(mesh, grid.GridStepSize);
            MeshTransforms.Translate(mesh, cornerXYZ);

            Mesh            m      = UnityUtil.DMeshToUnityMesh(mesh, false);
            fMeshGameObject meshGO = GameObjectFactory.CreateMeshGO("gridmesh", m, false, true);
            meshGO.SetMaterial(MaterialUtil.CreateStandardVertexColorMaterialF(Colorf.White));
            newMeshGOs.Add(meshGO);
        }

        CurrentMeshGOs = newMeshGOs;
    }