Example #1
0
        public void Apply(ref VoxelModel model, IProgressListener progress)
        {
            var m = model;

            progress?.Report("Analyzing structure");
            var ext = new ExteriorAnalyzer()
            {
                Model = m
            }.Analyze(new ProgressMapper(progress, 0.0, 1.0 / 3.0, null));

            progress?.Report("Creating shell");
            var extexpanded = new DilationFilter()
            {
                Distance = Distance,
                DistanceType = DistanceType
            }.Apply(ext, new ProgressMapper(progress, 1.0 / 3.0, 1.0 / 3.0, null));

            progress?.Report("Removing invisible voxels");

            int d1 = m.Width;
            int d2 = m.Height;
            int d3 = m.Depth;
            int d = IsExteriorSolid ? 0 : Distance;
            for (int x = d; x < d1 - d; ++x)
            {
                for (int y = d; y < d2 - d; ++y)
                {
                    for (int z = d; z < d3 - d; ++z)
                    {
                        if (!extexpanded[x, y, z])
                        {
                            m[x, y, z] = VoxelModel.EmptyVoxel;
                        }
                    }
                }
                progress?.Report((double)(x - d) / (d1 - d * 2) * (1.0 / 3.0) + 2.0 / 3.0);
            }
        }
Example #2
0
        public void Apply(ref VoxelModel model, IProgressListener progress)
        {
            var m = model;

            progress?.Report("Analyzing structure");
            var ext = new ExteriorAnalyzer()
            {
                Model = m
            }.Analyze(new ProgressMapper(progress, 0, 1.0 / 3.0, null));

            // Find the initial points (solid voxels adjacent to interior empty voxels)
            progress?.Report("Planting seeds");
            var queue = new Queue<IntVector3>();
            int width = m.Width, height = m.Height, depth = m.Depth;
            int numVoxelsToProcess = 0;
            for (int x = 0; x < width; ++x)
            {
                for (int y = 0; y < height; ++y)
                {
                    for (int z = 0; z < depth; ++z)
                    {
                        if (!ext[x, y, z] && !model.IsVoxelSolid(x, y, z))
                        {
                            ++numVoxelsToProcess;
                        }
                        if (!model.IsVoxelSolid(x, y, z))
                        {
                            continue;
                        }
                        queue.Enqueue(new IntVector3(x, y, z));
                    }
                }
                progress?.Report((double)(x + 1) / width * (1.0 / 3.0) + (1.0 / 3.0));
            }
            numVoxelsToProcess += queue.Count;

            progress?.Report("Filling inside");
            int numProcessed = 0;
            while (queue.Count > 0)
            {
                ++numProcessed;
                if ((numProcessed & 2047) == 0)
                {
                    progress?.Report((double)numProcessed / numVoxelsToProcess * (1.0 / 3.0) + (2.0 / 3.0));
                }

                var p = queue.Dequeue();
                uint color = m[p];
                if (p.X > 0)
                {
                    Traverse(p.X - 1, p.Y, p.Z, m, ext, queue, color);
                }
                if (p.Y > 0)
                {
                    Traverse(p.X, p.Y - 1, p.Z, m, ext, queue, color);
                }
                if (p.Z > 0)
                {
                    Traverse(p.X, p.Y, p.Z - 1, m, ext, queue, color);
                }
                if (p.X < width - 1)
                {
                    Traverse(p.X + 1, p.Y, p.Z, m, ext, queue, color);
                }
                if (p.Y < height - 1)
                {
                    Traverse(p.X, p.Y + 1, p.Z, m, ext, queue, color);
                }
                if (p.Z < depth - 1)
                {
                    Traverse(p.X, p.Y, p.Z + 1, m, ext, queue, color);
                }
            }
        }