Beispiel #1
0
        public VoxelizationOutput Voxelize(VoxelizationInput input, Action <VoxelizationProgress> progress)
        {
            // Setup VBO state
            GL.EnableClientState(ArrayCap.VertexArray);
            GL.EnableClientState(ArrayCap.IndexArray);

            m_input = input;

            VoxelizationOutput output = new VoxelizationOutput();

            output.Octree = input.Octree;

            VoxelizationProgress vp = new VoxelizationProgress();

            vp.Status = "Voxelizing mesh with " + input.Octree.MaxLevels + " subdivision levels";
            progress(vp);

            GL.PushAttrib(AttribMask.AllAttribBits);
            for (int i = 0; i <= input.Octree.MaxLevels; i++)
            {
                vp.Progress = (i / (input.Octree.MaxLevels + 1.0f));
                vp.Status   = "Voxelizing octree level " + i;
                progress(vp);
                RecursiveSolveStatus(input.Octree.Root, i);
            }
            GL.PopAttrib();

            vp.Progress = 1;
            vp.Status   = "Done voxelizing mesh";
            progress(vp);

            return(output);
        }
        public VoxelizationOutput Voxelize(VoxelizationInput input, Action<VoxelizationProgress> progress)
        {
            // Setup VBO state
            GL.EnableClientState(ArrayCap.VertexArray);
            GL.EnableClientState(ArrayCap.IndexArray);

            m_input = input;

            VoxelizationOutput output = new VoxelizationOutput();
            output.Octree = input.Octree;

            VoxelizationProgress vp = new VoxelizationProgress();
            vp.Status = "Voxelizing mesh with " + input.Octree.MaxLevels + " subdivision levels";
            progress(vp);

            GL.PushAttrib(AttribMask.AllAttribBits);
            for (int i = 0; i <= input.Octree.MaxLevels; i++)
            {
                vp.Progress = (i / (input.Octree.MaxLevels + 1.0f));
                vp.Status = "Voxelizing octree level " + i;
                progress(vp);
                RecursiveSolveStatus(input.Octree.Root, i);
            }
            GL.PopAttrib();

            vp.Progress = 1;
            vp.Status = "Done voxelizing mesh";
            progress(vp);

            return output;
        }
        public void UpdateProgress(VoxelizationProgress vp)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<VoxelizationProgress>(UpdateProgress), vp);
            }
            else
            {
                m_progressBar.Value = (int)(vp.Progress * 100);
                if (m_progressBar.Value > 0)
                {
                    m_progressBar.Value -= 1;
                    m_progressBar.Value += 1;
                }
                m_coverageProgress.Text =
                    String.Format("Volume Coverage     : {0,5:0.##}%", (100 * vp.VolumeCoverage)) + "    " +
                    String.Format("Silhouette Coverage : {0,5:0.##}%", (100 * vp.SilhouetteCoverage));

                if (!String.IsNullOrEmpty(vp.Status))
                    m_progressText.AppendText(vp.Status + "\r\n");
            }
        }
Beispiel #4
0
        public void UpdateProgress(VoxelizationProgress vp)
        {
            if (InvokeRequired)
            {
                Invoke(new Action <VoxelizationProgress>(UpdateProgress), vp);
            }
            else
            {
                m_progressBar.Value = (int)(vp.Progress * 100);
                if (m_progressBar.Value > 0)
                {
                    m_progressBar.Value -= 1;
                    m_progressBar.Value += 1;
                }
                m_coverageProgress.Text =
                    String.Format("Volume Coverage     : {0,5:0.##}%", (100 * vp.VolumeCoverage)) + "    " +
                    String.Format("Silhouette Coverage : {0,5:0.##}%", (100 * vp.SilhouetteCoverage));

                if (!String.IsNullOrEmpty(vp.Status))
                {
                    m_progressText.AppendText(vp.Status + "\r\n");
                }
            }
        }
        public virtual VoxelizationOutput Generate(VoxelizationInput input, Action<VoxelizationProgress> progress)
        {
            VoxelizationProgress vp = new VoxelizationProgress();

            DateTime start = DateTime.Now;

            vp.Status = "Building voxel field from octree";
            progress(vp);

            VoxelField voxelField = new VoxelField(input.Octree);

            Byte fillByte = 2;
            float oldPercent = 1.0f;
            float newPercent = 1.0f;

            List<Occluder> occluders = new List<Occluder>();

            vp.Status = "Calculating original mesh silhouette coverage";
            progress(vp);

            SilhouetteOcclusionValidator sov = new SilhouetteOcclusionValidator(1024, 1024);

            long groundSideCoverage, groundTopCoverage;
            sov.ComputeCoverage(input.OriginalMesh, input.Octree.MeshBounds, out groundSideCoverage, out groundTopCoverage);
            long totalCoverage = groundSideCoverage + groundTopCoverage;
            if (totalCoverage == 0)
                totalCoverage = 1;

            vp.Status = "Fitting boxes into mesh...";
            progress(vp);

            long oldOcclusion = 0;

            do
            {
                Vector3i densestVoxel = FindHighestDensityVoxel(voxelField);

                AABBi occluderBounds;
                if (input.Type == OcclusionType.BoxExpansion)
                {
                    occluderBounds = ExpandAndFillBox(voxelField, ref densestVoxel, fillByte);
                }
                //else if (input.Type == OcclusionType.SimulatedAnnealing)
                //{
                //    occluderBounds = SimulatedAnnealingFill(input, sov, voxelField, ref densestVoxel, fillByte, occluders);
                //}
                else if (input.Type == OcclusionType.BruteForce)
                {
                    occluderBounds = BruteForceFill(input, sov, voxelField, densestVoxel, fillByte, occluders);
                }
                else
                {
                    throw new Exception("Unknown occluder generation type!");
                }

                List<AABBi> relevantOccluders = GetRelevantOccluders(input, occluders);
                relevantOccluders.Add(occluderBounds);

                long newOcclusion = MeasureOccluderOcclusion(sov, input, relevantOccluders);

                Occluder occluder = new Occluder();
                occluder.Bounds = occluderBounds;
                occluder.DeltaOcclusion = (newOcclusion - oldOcclusion) / (double)totalCoverage;

                occluders.Add(occluder);

                if (occluder.DeltaOcclusion > input.MinimumOcclusion)
                    oldOcclusion = newOcclusion;

                Debug.WriteLine("Coverage " + occluder.DeltaOcclusion);
                Debug.WriteLine("Bounds (" + occluder.Bounds.MinX + "x" + occluder.Bounds.MaxX + " " + occluder.Bounds.MinY + "x" + occluder.Bounds.MaxY + " " + occluder.Bounds.MinZ + "x" + occluder.Bounds.MaxZ + ")");

                oldPercent = newPercent;
                newPercent = MeasureUnboxedVoxels(voxelField);

                Debug.WriteLine("(" + densestVoxel.X + "," + densestVoxel.Y + "," + densestVoxel.Z + ")\tCoverage=" + ((1 - newPercent) * 100) + "%\tDelta=" + ((oldPercent - newPercent) * 100) + "%");

                vp.Progress = Math.Min(((1 - newPercent) / input.MinimumVolume), 1.0f);
                vp.SilhouetteCoverage = oldOcclusion / (double)totalCoverage;
                vp.VolumeCoverage = 1 - newPercent;
                vp.Status = String.Format("Occlusion Progress : {0:0.##}%", (100 * vp.Progress));

                progress(vp);

            } while (newPercent > (1 - input.MinimumVolume));

            Mesh mesh = BuildMeshFromBoxes(input, GetRelevantOccluders(input, occluders));

            VoxelizationOutput output = new VoxelizationOutput();

            if (input.Retriangulate)
            {
                vp.Status = "Retriangulating occluder mesh";
                progress(vp);

                Mesh triangulatedMesh = MeshOptimizer.Retriangulate(input, mesh, out output.DebugLines);
                if (triangulatedMesh != null)
                    mesh = triangulatedMesh;
            }

            vp.Status = "Filtering polygons";
            progress(vp);

            mesh = PolygonFilter.Filter(input, mesh);

            vp.Status = "Generating final occlusion mesh";
            progress(vp);

            // Prepare the output
            output.Octree = input.Octree;
            output.TimeTaken = DateTime.Now - start;
            output.VolumeCoverage = 1 - newPercent;
            output.SilhouetteCoverage = oldOcclusion / (double)totalCoverage;
            output.OccluderMesh = new RenderableMesh(mesh, true);

            vp.Status = "Cleanup...";
            progress(vp);

            sov.Dispose();

            return output;
        }
Beispiel #6
0
        public virtual VoxelizationOutput Generate(VoxelizationInput input, Action <VoxelizationProgress> progress)
        {
            VoxelizationProgress vp = new VoxelizationProgress();

            DateTime start = DateTime.Now;

            vp.Status = "Building voxel field from octree";
            progress(vp);

            VoxelField voxelField = new VoxelField(input.Octree);

            Byte  fillByte   = 2;
            float oldPercent = 1.0f;
            float newPercent = 1.0f;

            List <Occluder> occluders = new List <Occluder>();

            vp.Status = "Calculating original mesh silhouette coverage";
            progress(vp);

            SilhouetteOcclusionValidator sov = new SilhouetteOcclusionValidator(1024, 1024);

            long groundSideCoverage, groundTopCoverage;

            sov.ComputeCoverage(input.OriginalMesh, input.Octree.MeshBounds, out groundSideCoverage, out groundTopCoverage);
            long totalCoverage = groundSideCoverage + groundTopCoverage;

            if (totalCoverage == 0)
            {
                totalCoverage = 1;
            }

            vp.Status = "Fitting boxes into mesh...";
            progress(vp);

            long oldOcclusion = 0;

            do
            {
                Vector3i densestVoxel = FindHighestDensityVoxel(voxelField);

                AABBi occluderBounds;
                if (input.Type == OcclusionType.BoxExpansion)
                {
                    occluderBounds = ExpandAndFillBox(voxelField, ref densestVoxel, fillByte);
                }
                //else if (input.Type == OcclusionType.SimulatedAnnealing)
                //{
                //    occluderBounds = SimulatedAnnealingFill(input, sov, voxelField, ref densestVoxel, fillByte, occluders);
                //}
                else if (input.Type == OcclusionType.BruteForce)
                {
                    occluderBounds = BruteForceFill(input, sov, voxelField, densestVoxel, fillByte, occluders);
                }
                else
                {
                    throw new Exception("Unknown occluder generation type!");
                }

                List <AABBi> relevantOccluders = GetRelevantOccluders(input, occluders);
                relevantOccluders.Add(occluderBounds);

                long newOcclusion = MeasureOccluderOcclusion(sov, input, relevantOccluders);

                Occluder occluder = new Occluder();
                occluder.Bounds         = occluderBounds;
                occluder.DeltaOcclusion = (newOcclusion - oldOcclusion) / (double)totalCoverage;

                occluders.Add(occluder);

                if (occluder.DeltaOcclusion > input.MinimumOcclusion)
                {
                    oldOcclusion = newOcclusion;
                }

                Debug.WriteLine("Coverage " + occluder.DeltaOcclusion);
                Debug.WriteLine("Bounds (" + occluder.Bounds.MinX + "x" + occluder.Bounds.MaxX + " " + occluder.Bounds.MinY + "x" + occluder.Bounds.MaxY + " " + occluder.Bounds.MinZ + "x" + occluder.Bounds.MaxZ + ")");

                oldPercent = newPercent;
                newPercent = MeasureUnboxedVoxels(voxelField);

                Debug.WriteLine("(" + densestVoxel.X + "," + densestVoxel.Y + "," + densestVoxel.Z + ")\tCoverage=" + ((1 - newPercent) * 100) + "%\tDelta=" + ((oldPercent - newPercent) * 100) + "%");

                vp.Progress           = Math.Min(((1 - newPercent) / input.MinimumVolume), 1.0f);
                vp.SilhouetteCoverage = oldOcclusion / (double)totalCoverage;
                vp.VolumeCoverage     = 1 - newPercent;
                vp.Status             = String.Format("Occlusion Progress : {0:0.##}%", (100 * vp.Progress));

                progress(vp);
            } while (newPercent > (1 - input.MinimumVolume));

            Mesh mesh = BuildMeshFromBoxes(input, GetRelevantOccluders(input, occluders));

            VoxelizationOutput output = new VoxelizationOutput();

            if (input.Retriangulate)
            {
                vp.Status = "Retriangulating occluder mesh";
                progress(vp);

                Mesh triangulatedMesh = MeshOptimizer.Retriangulate(input, mesh, out output.DebugLines);
                if (triangulatedMesh != null)
                {
                    mesh = triangulatedMesh;
                }
            }

            vp.Status = "Filtering polygons";
            progress(vp);

            mesh = PolygonFilter.Filter(input, mesh);

            vp.Status = "Generating final occlusion mesh";
            progress(vp);

            // Prepare the output
            output.Octree             = input.Octree;
            output.TimeTaken          = DateTime.Now - start;
            output.VolumeCoverage     = 1 - newPercent;
            output.SilhouetteCoverage = oldOcclusion / (double)totalCoverage;
            output.OccluderMesh       = new RenderableMesh(mesh, true);

            vp.Status = "Cleanup...";
            progress(vp);

            sov.Dispose();

            return(output);
        }