Exemplo n.º 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, 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);
                }
            }
        }
Exemplo n.º 2
0
 static void Traverse(int x, int y, int z, VoxelModel m, bool[,,] ext, Queue<IntVector3> queue, uint adjcolor)
 {
     if (m.IsVoxelSolid(x, y, z) || ext[x, y, z])
     {
         return;
     }
     m[x, y, z] = adjcolor;
     queue.Enqueue(new IntVector3(x, y, z));
 }
Exemplo n.º 3
0
        public MeshSlices GenerateSlices(VoxelModel model, IProgressListener progress)
        {
            var slices = new MeshSlices();
            var dims = model.Dimensions;

            int totalsteps = 2 * (model.Width + model.Height + model.Depth);
            int step = 0;

            progress?.Report("Generating slices");

            for (int iaxis = 0; iaxis < 3; ++iaxis)
            {
                for (int iface = 0; iface < 2; ++iface)
                {

                    var axis = (Axis3) iaxis;
                    var paxis1 = (Axis3) ((iaxis + 1) % 3);
                    var paxis2 = (Axis3) ((iaxis + 2) % 3);
                    bool face = iface != 0;

                    int dim0 = dims[axis];
                    int dim1 = dims[paxis1];
                    int dim2 = dims[paxis2];

                    var slicelist = new MeshSlice[dim0];
                    slices[axis, face] = slicelist;

                    for (int layer = 0; layer < dim0; ++layer)
                    {
                        ++step;
                        progress?.Report((double)step / totalsteps);

                        var faces = new List<int>();
                        var ret = new List<IntVector3>();

                        var pt1 = new IntVector3();
                        pt1[axis] = layer;
                        for (int x = 0; x < dim1; ++x)
                        {
                            pt1[paxis1] = x;
                            for (int y = 0; y < dim2; ++y)
                            {
                                pt1[paxis2] = y;

                                bool solid1 = model.IsVoxelSolid(pt1);

                                var pt2 = pt1;
                                bool solid2 = false;
                                if (face)
                                {
                                    pt2[axis] += 1;
                                    if (pt2[axis] < dim0)
                                    {
                                        solid2 = model.IsVoxelSolid(pt2);
                                    }
                                }
                                else
                                {
                                    pt2[axis] -= 1;
                                    if (pt2[axis] >= 0)
                                    {
                                        solid2 = model.IsVoxelSolid(pt2);
                                    }
                                }

                                if (!solid1 || solid2)
                                {
                                    continue;
                                }

                                // Create quad
                                var qpt1 = pt1;
                                if (face)
                                {
                                    qpt1[axis] += 1;
                                    qpt1[paxis2] += 1;
                                }
                                var qpt2 = qpt1;
                                qpt2[paxis1] += 1;
                                var qpt3 = qpt1;
                                var qpt4 = qpt2;
                                if (face)
                                {
                                    qpt3[paxis2] -= 1;
                                    qpt4[paxis2] -= 1;
                                }
                                else
                                {
                                    qpt3[paxis2] += 1;
                                    qpt4[paxis2] += 1;
                                }

                                // Emit polygons
                                faces.Add(ret.Count);
                                ret.Add(qpt3);
                                ret.Add(qpt4);
                                ret.Add(qpt2);
                                ret.Add(qpt1);
                            } // for y
                        } // for x

                        slicelist[layer] = new MeshSlice()
                        {
                            Positions = ret.ToArray(),
                            Faces = faces.ToArray(),

                            Face = face,
                            Axis = axis,
                            Layer = layer
                        };

                    } // for slice
                } // iface
            } // iaxis
            return slices;
        }