From 69d6ad86a72afb53aa093d67fc4f6e165f85326b Mon Sep 17 00:00:00 2001 From: David Williams Date: Sun, 31 May 2009 09:59:43 +0000 Subject: [PATCH] Removed old, redundant surface extraction algorithms (FastSurfaceExtractor and DecimatedSurfaceExtractor). These are now replaced by the general SurfaceExtractor. --- examples/OpenGL/OpenGLWidget.h | 1 - examples/OpenGL/main.cpp | 1 - library/PolyVoxCore/CMakeLists.txt | 6 - .../PolyVoxImpl/DecimatedSurfaceExtractor.h | 42 -- .../PolyVoxImpl/FastSurfaceExtractor.h | 41 -- .../PolyVoxCore/include/SurfaceExtractors.h | 40 -- .../PolyVoxImpl/DecimatedSurfaceExtractor.cpp | 542 ------------------ .../PolyVoxImpl/FastSurfaceExtractor.cpp | 537 ----------------- .../PolyVoxCore/source/SurfaceExtractors.cpp | 32 -- .../source/VolumeChangeTracker.cpp | 1 - 10 files changed, 1243 deletions(-) delete mode 100644 library/PolyVoxCore/include/PolyVoxImpl/DecimatedSurfaceExtractor.h delete mode 100644 library/PolyVoxCore/include/PolyVoxImpl/FastSurfaceExtractor.h delete mode 100644 library/PolyVoxCore/include/SurfaceExtractors.h delete mode 100644 library/PolyVoxCore/source/PolyVoxImpl/DecimatedSurfaceExtractor.cpp delete mode 100644 library/PolyVoxCore/source/PolyVoxImpl/FastSurfaceExtractor.cpp delete mode 100644 library/PolyVoxCore/source/SurfaceExtractors.cpp diff --git a/examples/OpenGL/OpenGLWidget.h b/examples/OpenGL/OpenGLWidget.h index 33248f51..4f1bbca9 100644 --- a/examples/OpenGL/OpenGLWidget.h +++ b/examples/OpenGL/OpenGLWidget.h @@ -8,7 +8,6 @@ #include "Volume.h" #include "IndexedSurfacePatch.h" -#include "SurfaceExtractors.h" #include "PolyVoxImpl/Utility.h" #include "OpenGLImmediateModeSupport.h" diff --git a/examples/OpenGL/main.cpp b/examples/OpenGL/main.cpp index 681fce7a..3cf0343d 100644 --- a/examples/OpenGL/main.cpp +++ b/examples/OpenGL/main.cpp @@ -1,7 +1,6 @@ #include "Log.h" #include "Volume.h" #include "IndexedSurfacePatch.h" -#include "SurfaceExtractors.h" #include "PolyVoxImpl/Utility.h" #include "OpenGLImmediateModeSupport.h" diff --git a/library/PolyVoxCore/CMakeLists.txt b/library/PolyVoxCore/CMakeLists.txt index 553051ec..bf945f9a 100644 --- a/library/PolyVoxCore/CMakeLists.txt +++ b/library/PolyVoxCore/CMakeLists.txt @@ -9,7 +9,6 @@ SET(CORE_SRC_FILES source/Log.cpp source/Region.cpp source/SurfaceExtractor.cpp - source/SurfaceExtractors.cpp source/SurfaceVertex.cpp source/VoxelFilters.cpp ) @@ -22,7 +21,6 @@ SET(CORE_INC_FILES include/PolyVoxForwardDeclarations.h include/Region.h include/SurfaceExtractor.h - include/SurfaceExtractors.h include/SurfaceVertex.h include/Vector.h include/Vector.inl @@ -34,8 +32,6 @@ SET(CORE_INC_FILES ) SET(IMPL_SRC_FILES - source/PolyVoxImpl/DecimatedSurfaceExtractor.cpp - source/PolyVoxImpl/FastSurfaceExtractor.cpp source/PolyVoxImpl/MarchingCubesTables.cpp source/PolyVoxImpl/Utility.cpp ) @@ -44,8 +40,6 @@ SET(IMPL_INC_FILES include/PolyVoxImpl/Block.h include/PolyVoxImpl/Block.inl include/PolyVoxImpl/CPlusPlusZeroXSupport.h - include/PolyVoxImpl/DecimatedSurfaceExtractor.h - include/PolyVoxImpl/FastSurfaceExtractor.h include/PolyVoxImpl/MarchingCubesTables.h include/PolyVoxImpl/TypeDef.h include/PolyVoxImpl/Utility.h diff --git a/library/PolyVoxCore/include/PolyVoxImpl/DecimatedSurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxImpl/DecimatedSurfaceExtractor.h deleted file mode 100644 index 524b4469..00000000 --- a/library/PolyVoxCore/include/PolyVoxImpl/DecimatedSurfaceExtractor.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma region License -/****************************************************************************** -This file is part of the PolyVox library -Copyright (C) 2006 David Williams - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -******************************************************************************/ -#pragma endregion - -#ifndef __PolyVoxImpl_DecimatedSurfaceExtractor_H__ -#define __PolyVoxImpl_DecimatedSurfaceExtractor_H__ - -#pragma region Headers -#include "../PolyVoxForwardDeclarations.h" -#include "TypeDef.h" - -#include "CPlusPlusZeroXSupport.h" -#pragma endregion - -namespace PolyVox -{ - uint32_t getDecimatedIndex(uint32_t x, uint32_t y, uint32_t regionWidth); - - void extractDecimatedSurfaceImpl(Volume* volumeData, uint8_t uLevel, Region region, IndexedSurfacePatch* singleMaterialPatch); - uint32_t computeDecimatedBitmaskForSlice(VolumeSampler& volIter, uint8_t uLevel, const Region& regSlice, const Vector3DFloat& offset, uint8_t *bitmask, uint8_t *previousBitmask); - void generateDecimatedIndicesForSlice(VolumeSampler& volIter, uint8_t uLevel, const Region& regSlice, IndexedSurfacePatch* singleMaterialPatch, const Vector3DFloat& offset, uint8_t* bitmask0, uint8_t* bitmask1, int32_t vertexIndicesX0[],int32_t vertexIndicesY0[],int32_t vertexIndicesZ0[], int32_t vertexIndicesX1[],int32_t vertexIndicesY1[],int32_t vertexIndicesZ1[]); - void generateDecimatedVerticesForSlice(VolumeSampler& volIter, uint8_t uLevel, Region& regSlice, const Vector3DFloat& offset, uint8_t* bitmask, IndexedSurfacePatch* singleMaterialPatch,int32_t vertexIndicesX[],int32_t vertexIndicesY[],int32_t vertexIndicesZ[]); -} - -#endif diff --git a/library/PolyVoxCore/include/PolyVoxImpl/FastSurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxImpl/FastSurfaceExtractor.h deleted file mode 100644 index b5593144..00000000 --- a/library/PolyVoxCore/include/PolyVoxImpl/FastSurfaceExtractor.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma region License -/****************************************************************************** -This file is part of the PolyVox library -Copyright (C) 2006 David Williams - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -******************************************************************************/ -#pragma endregion - -#ifndef __PolyVoxImpl_FastSurfaceExtractor_H__ -#define __PolyVoxImpl_FastSurfaceExtractor_H__ - -#pragma region Headers -#include "../PolyVoxForwardDeclarations.h" -#include "TypeDef.h" - -#include "CPlusPlusZeroXSupport.h" -#pragma endregion - -namespace PolyVox -{ - void extractFastSurfaceImpl(Volume* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch); - uint32_t getIndex(uint32_t x, uint32_t y, uint32_t regionWidth); - uint32_t computeRoughBitmaskForSlice(VolumeSampler& volIter, const Region& regSlice, const Vector3DFloat& offset, uint8_t *bitmask, uint8_t *previousBitmask); - void generateRoughIndicesForSlice(VolumeSampler& volIter, const Region& regSlice, IndexedSurfacePatch* singleMaterialPatch, const Vector3DFloat& offset, uint8_t* bitmask0, uint8_t* bitmask1, int32_t vertexIndicesX0[],int32_t vertexIndicesY0[],int32_t vertexIndicesZ0[], int32_t vertexIndicesX1[],int32_t vertexIndicesY1[],int32_t vertexIndicesZ1[]); - void generateRoughVerticesForSlice(VolumeSampler& volIter, Region& regSlice, const Vector3DFloat& offset, uint8_t* bitmask, IndexedSurfacePatch* singleMaterialPatch,int32_t vertexIndicesX[],int32_t vertexIndicesY[],int32_t vertexIndicesZ[]); -} - -#endif diff --git a/library/PolyVoxCore/include/SurfaceExtractors.h b/library/PolyVoxCore/include/SurfaceExtractors.h deleted file mode 100644 index 48f7a674..00000000 --- a/library/PolyVoxCore/include/SurfaceExtractors.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma region License -/****************************************************************************** -This file is part of the PolyVox library -Copyright (C) 2006 David Williams - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -******************************************************************************/ -#pragma endregion - -#ifndef __PolyVox_SurfaceExtractors_H__ -#define __PolyVox_SurfaceExtractors_H__ - -#pragma region Headers -#include "PolyVoxForwardDeclarations.h" -#include "PolyVoxImpl/TypeDef.h" - -#include "PolyVoxImpl/CPlusPlusZeroXSupport.h" - -#include -#pragma endregion - -namespace PolyVox -{ - POLYVOXCORE_API void extractSurface(Volume* volumeData, uint8_t uLevel, Region region, IndexedSurfacePatch* singleMaterialPatch); - POLYVOXCORE_API void extractReferenceSurface(Volume* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch); -} - -#endif diff --git a/library/PolyVoxCore/source/PolyVoxImpl/DecimatedSurfaceExtractor.cpp b/library/PolyVoxCore/source/PolyVoxImpl/DecimatedSurfaceExtractor.cpp deleted file mode 100644 index 9f195379..00000000 --- a/library/PolyVoxCore/source/PolyVoxImpl/DecimatedSurfaceExtractor.cpp +++ /dev/null @@ -1,542 +0,0 @@ -#pragma region License -/****************************************************************************** -This file is part of the PolyVox library -Copyright (C) 2006 David Williams - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -******************************************************************************/ -#pragma endregion - -#include "PolyVoxImpl/DecimatedSurfaceExtractor.h" - -#include "Volume.h" -#include "GradientEstimators.h" -#include "IndexedSurfacePatch.h" -#include "PolyVoxImpl/MarchingCubesTables.h" -#include "Region.h" -#include "VolumeSampler.h" - -#include - -using namespace std; - -namespace PolyVox -{ - uint32_t getDecimatedIndex(uint32_t x, uint32_t y , uint32_t regionWidth) - { - return x + (y * (regionWidth+1)); - } - - void extractDecimatedSurfaceImpl(Volume* volumeData, uint8_t uLevel, Region region, IndexedSurfacePatch* singleMaterialPatch) - { - singleMaterialPatch->clear(); - - //For edge indices - //FIXME - do the slices need to be this big? Surely for a decimated mesh they can be smaller? - //FIXME - Instead of region.width()+2 we used to use POLYVOX_REGION_SIDE_LENGTH+1 - //Normally POLYVOX_REGION_SIDE_LENGTH is the same as region.width() (often 32) but at the - //edges of the volume it is 1 smaller. Need to think what values really belong here. - int32_t* vertexIndicesX0 = new int32_t[(region.width()+2) * (region.height()+2)]; - int32_t* vertexIndicesY0 = new int32_t[(region.width()+2) * (region.height()+2)]; - int32_t* vertexIndicesZ0 = new int32_t[(region.width()+2) * (region.height()+2)]; - int32_t* vertexIndicesX1 = new int32_t[(region.width()+2) * (region.height()+2)]; - int32_t* vertexIndicesY1 = new int32_t[(region.width()+2) * (region.height()+2)]; - int32_t* vertexIndicesZ1 = new int32_t[(region.width()+2) * (region.height()+2)]; - - //Cell bitmasks - uint8_t* bitmask0 = new uint8_t[(region.width()+2) * (region.height()+2)]; - uint8_t* bitmask1 = new uint8_t[(region.width()+2) * (region.height()+2)]; - - const uint8_t uStepSize = uLevel == 0 ? 1 : 1 << uLevel; - - //When generating the mesh for a region we actually look outside it in the - // back, bottom, right direction. Protect against access violations by cropping region here - Region regVolume = volumeData->getEnclosingRegion(); - regVolume.setUpperCorner(regVolume.getUpperCorner() - Vector3DInt32(2*uStepSize-1,2*uStepSize-1,2*uStepSize-1)); - region.cropTo(regVolume); - - //Offset from volume corner - const Vector3DFloat offset = static_cast(region.getLowerCorner()); - - //Create a region corresponding to the first slice - Region regSlice0(region); - Vector3DInt32 v3dUpperCorner = regSlice0.getUpperCorner(); - v3dUpperCorner.setZ(regSlice0.getLowerCorner().getZ()); //Set the upper z to the lower z to make it one slice thick. - regSlice0.setUpperCorner(v3dUpperCorner); - - //Iterator to access the volume data - VolumeSampler volIter(*volumeData); - - //Compute bitmask for initial slice - uint32_t uNoOfNonEmptyCellsForSlice0 = computeDecimatedBitmaskForSlice(volIter, uLevel, regSlice0, offset, bitmask0, 0); - if(uNoOfNonEmptyCellsForSlice0 != 0) - { - //If there were some non-empty cells then generate initial slice vertices for them - generateDecimatedVerticesForSlice(volIter, uLevel, regSlice0, offset, bitmask0, singleMaterialPatch, vertexIndicesX0, vertexIndicesY0, vertexIndicesZ0); - } - - for(uint32_t uSlice = 1; ((uSlice <= region.depth()) && (uSlice + offset.getZ() <= regVolume.getUpperCorner().getZ())); uSlice += uStepSize) - { - Region regSlice1(regSlice0); - regSlice1.shift(Vector3DInt32(0,0,uStepSize)); - - uint32_t uNoOfNonEmptyCellsForSlice1 = computeDecimatedBitmaskForSlice(volIter, uLevel, regSlice1, offset, bitmask1, bitmask0); - - if(uNoOfNonEmptyCellsForSlice1 != 0) - { - generateDecimatedVerticesForSlice(volIter, uLevel, regSlice1, offset, bitmask1, singleMaterialPatch, vertexIndicesX1, vertexIndicesY1, vertexIndicesZ1); - } - - if((uNoOfNonEmptyCellsForSlice0 != 0) || (uNoOfNonEmptyCellsForSlice1 != 0)) - { - generateDecimatedIndicesForSlice(volIter, uLevel, regSlice0, singleMaterialPatch, offset, bitmask0, bitmask1, vertexIndicesX0, vertexIndicesY0, vertexIndicesZ0, vertexIndicesX1, vertexIndicesY1, vertexIndicesZ1); - } - - std::swap(uNoOfNonEmptyCellsForSlice0, uNoOfNonEmptyCellsForSlice1); - std::swap(bitmask0, bitmask1); - std::swap(vertexIndicesX0, vertexIndicesX1); - std::swap(vertexIndicesY0, vertexIndicesY1); - std::swap(vertexIndicesZ0, vertexIndicesZ1); - - regSlice0 = regSlice1; - } - - delete[] bitmask0; - delete[] bitmask1; - delete[] vertexIndicesX0; - delete[] vertexIndicesX1; - delete[] vertexIndicesY0; - delete[] vertexIndicesY1; - delete[] vertexIndicesZ0; - delete[] vertexIndicesZ1; - - - /*std::vector::iterator iterSurfaceVertex = singleMaterialPatch->getVertices().begin(); - while(iterSurfaceVertex != singleMaterialPatch->getVertices().end()) - { - Vector3DFloat tempNormal = computeDecimatedNormal(volumeData, static_cast(iterSurfaceVertex->getPosition() + offset), CENTRAL_DIFFERENCE); - const_cast(*iterSurfaceVertex).setNormal(tempNormal); - ++iterSurfaceVertex; - }*/ - } - - uint32_t computeDecimatedBitmaskForSlice(VolumeSampler& volIter, uint8_t uLevel, const Region& regSlice, const Vector3DFloat& offset, uint8_t* bitmask, uint8_t* previousBitmask) - { - const uint8_t uStepSize = uLevel == 0 ? 1 : 1 << uLevel; - uint32_t uNoOfNonEmptyCells = 0; - - //Iterate over each cell in the region - for(uint16_t uYVolSpace = regSlice.getLowerCorner().getY(); uYVolSpace <= regSlice.getUpperCorner().getY(); uYVolSpace += uStepSize) - { - for(uint16_t uXVolSpace = regSlice.getLowerCorner().getX(); uXVolSpace <= regSlice.getUpperCorner().getX(); uXVolSpace += uStepSize) - { - uint16_t uZVolSpace = regSlice.getLowerCorner().getZ(); - //Current position - volIter.setPosition(uXVolSpace,uYVolSpace,uZVolSpace); - - const uint16_t uXRegSpace = volIter.getPosX() - offset.getX(); - const uint16_t uYRegSpace = volIter.getPosY() - offset.getY(); - - //Determine the index into the edge table which tells us which vertices are inside of the surface - uint8_t iCubeIndex = 0; - - bool isPrevXAvail = uXRegSpace > 0; - bool isPrevYAvail = uYRegSpace > 0; - bool isPrevZAvail = previousBitmask != 0; - - if(isPrevZAvail) - { - if(isPrevYAvail) - { - if(isPrevXAvail) - { - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace+uStepSize,uZVolSpace+uStepSize); - const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); - - //z - uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; - iPreviousCubeIndexZ >>= 4; - - //y - uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(uXRegSpace,uYRegSpace-uStepSize, regSlice.width()+1)]; - iPreviousCubeIndexY &= 192; //192 = 128 + 64 - iPreviousCubeIndexY >>= 2; - - //x - uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(uXRegSpace-uStepSize,uYRegSpace, regSlice.width()+1)]; - iPreviousCubeIndexX &= 128; - iPreviousCubeIndexX >>= 1; - - iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY | iPreviousCubeIndexZ; - - if (v111 == 0) iCubeIndex |= 128; - } - else //previous X not available - { - volIter.setPosition(uXVolSpace,uYVolSpace+uStepSize,uZVolSpace+uStepSize); - const uint8_t v011 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace+uStepSize,uZVolSpace+uStepSize); - const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); - - //z - uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; - iPreviousCubeIndexZ >>= 4; - - //y - uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(uXRegSpace,uYRegSpace-uStepSize, regSlice.width()+1)]; - iPreviousCubeIndexY &= 192; //192 = 128 + 64 - iPreviousCubeIndexY >>= 2; - - iCubeIndex = iPreviousCubeIndexY | iPreviousCubeIndexZ; - - if (v011 == 0) iCubeIndex |= 64; - if (v111 == 0) iCubeIndex |= 128; - } - } - else //previous Y not available - { - if(isPrevXAvail) - { - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace,uZVolSpace+uStepSize); - const uint8_t v101 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace+uStepSize,uZVolSpace+uStepSize); - const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); - - //z - uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; - iPreviousCubeIndexZ >>= 4; - - //x - uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(uXRegSpace-uStepSize,uYRegSpace, regSlice.width()+1)]; - iPreviousCubeIndexX &= 160; //160 = 128+32 - iPreviousCubeIndexX >>= 1; - - iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexZ; - - if (v101 == 0) iCubeIndex |= 32; - if (v111 == 0) iCubeIndex |= 128; - } - else //previous X not available - { - volIter.setPosition(uXVolSpace,uYVolSpace,uZVolSpace+uStepSize); - const uint8_t v001 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace,uZVolSpace+uStepSize); - const uint8_t v101 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(uXVolSpace,uYVolSpace+uStepSize,uZVolSpace+uStepSize); - const uint8_t v011 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace+uStepSize,uZVolSpace+uStepSize); - const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); - - //z - uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; - iCubeIndex = iPreviousCubeIndexZ >> 4; - - if (v001 == 0) iCubeIndex |= 16; - if (v101 == 0) iCubeIndex |= 32; - if (v011 == 0) iCubeIndex |= 64; - if (v111 == 0) iCubeIndex |= 128; - } - } - } - else //previous Z not available - { - if(isPrevYAvail) - { - if(isPrevXAvail) - { - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace+uStepSize,uZVolSpace); - const uint8_t v110 = volIter.getSubSampledVoxel(uLevel); - - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace+uStepSize,uZVolSpace+uStepSize); - const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); - - //y - uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(uXRegSpace,uYRegSpace-uStepSize, regSlice.width()+1)]; - iPreviousCubeIndexY &= 204; //204 = 128+64+8+4 - iPreviousCubeIndexY >>= 2; - - //x - uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(uXRegSpace-uStepSize,uYRegSpace, regSlice.width()+1)]; - iPreviousCubeIndexX &= 170; //170 = 128+32+8+2 - iPreviousCubeIndexX >>= 1; - - iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY; - - if (v110 == 0) iCubeIndex |= 8; - if (v111 == 0) iCubeIndex |= 128; - } - else //previous X not available - { - volIter.setPosition(uXVolSpace,uYVolSpace+uStepSize,uZVolSpace); - const uint8_t v010 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace+uStepSize,uZVolSpace); - const uint8_t v110 = volIter.getSubSampledVoxel(uLevel); - - volIter.setPosition(uXVolSpace,uYVolSpace+uStepSize,uZVolSpace+uStepSize); - const uint8_t v011 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace+uStepSize,uZVolSpace+uStepSize); - const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); - - //y - uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(uXRegSpace,uYRegSpace-uStepSize, regSlice.width()+1)]; - iPreviousCubeIndexY &= 204; //204 = 128+64+8+4 - iPreviousCubeIndexY >>= 2; - - iCubeIndex = iPreviousCubeIndexY; - - if (v010 == 0) iCubeIndex |= 4; - if (v110 == 0) iCubeIndex |= 8; - if (v011 == 0) iCubeIndex |= 64; - if (v111 == 0) iCubeIndex |= 128; - } - } - else //previous Y not available - { - if(isPrevXAvail) - { - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace,uZVolSpace); - const uint8_t v100 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace+uStepSize,uZVolSpace); - const uint8_t v110 = volIter.getSubSampledVoxel(uLevel); - - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace,uZVolSpace+uStepSize); - const uint8_t v101 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace+uStepSize,uZVolSpace+uStepSize); - const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); - - //x - uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(uXRegSpace-uStepSize,uYRegSpace, regSlice.width()+1)]; - iPreviousCubeIndexX &= 170; //170 = 128+32+8+2 - iPreviousCubeIndexX >>= 1; - - iCubeIndex = iPreviousCubeIndexX; - - if (v100 == 0) iCubeIndex |= 2; - if (v110 == 0) iCubeIndex |= 8; - if (v101 == 0) iCubeIndex |= 32; - if (v111 == 0) iCubeIndex |= 128; - } - else //previous X not available - { - volIter.setPosition(uXVolSpace,uYVolSpace,uZVolSpace); - const uint8_t v000 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace,uZVolSpace); - const uint8_t v100 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(uXVolSpace,uYVolSpace+uStepSize,uZVolSpace); - const uint8_t v010 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace+uStepSize,uZVolSpace); - const uint8_t v110 = volIter.getSubSampledVoxel(uLevel); - - volIter.setPosition(uXVolSpace,uYVolSpace,uZVolSpace+uStepSize); - const uint8_t v001 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace,uZVolSpace+uStepSize); - const uint8_t v101 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(uXVolSpace,uYVolSpace+uStepSize,uZVolSpace+uStepSize); - const uint8_t v011 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace+uStepSize,uZVolSpace+uStepSize); - const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); - - if (v000 == 0) iCubeIndex |= 1; - if (v100 == 0) iCubeIndex |= 2; - if (v010 == 0) iCubeIndex |= 4; - if (v110 == 0) iCubeIndex |= 8; - if (v001 == 0) iCubeIndex |= 16; - if (v101 == 0) iCubeIndex |= 32; - if (v011 == 0) iCubeIndex |= 64; - if (v111 == 0) iCubeIndex |= 128; - } - } - } - - //Save the bitmask - bitmask[getDecimatedIndex(uXRegSpace,uYVolSpace- offset.getY(), regSlice.width()+1)] = iCubeIndex; - - if(edgeTable[iCubeIndex] != 0) - { - ++uNoOfNonEmptyCells; - } - - }//For each cell - } - - return uNoOfNonEmptyCells; - } - - void generateDecimatedVerticesForSlice(VolumeSampler& volIter, uint8_t uLevel, Region& regSlice, const Vector3DFloat& offset, uint8_t* bitmask, IndexedSurfacePatch* singleMaterialPatch,int32_t vertexIndicesX[],int32_t vertexIndicesY[],int32_t vertexIndicesZ[]) - { - const uint8_t uStepSize = uLevel == 0 ? 1 : 1 << uLevel; - - //Iterate over each cell in the region - for(uint16_t y = regSlice.getLowerCorner().getY(); y <= regSlice.getUpperCorner().getY(); y += uStepSize) - { - for(uint16_t x = regSlice.getLowerCorner().getX(); x <= regSlice.getUpperCorner().getX(); x += uStepSize) - { - //Current position - const uint16_t z = regSlice.getLowerCorner().getZ(); - - volIter.setPosition(x,y,z); - const uint8_t v000 = volIter.getSubSampledVoxel(uLevel); - - //Determine the index into the edge table which tells us which vertices are inside of the surface - uint8_t iCubeIndex = bitmask[getDecimatedIndex(x - offset.getX(),y - offset.getY(), regSlice.width()+1)]; - - /* Cube is entirely in/out of the surface */ - if (edgeTable[iCubeIndex] == 0) - { - continue; - } - - /* Find the vertices where the surface intersects the cube */ - if (edgeTable[iCubeIndex] & 1) - { - if(x != regSlice.getUpperCorner().getX()) - { - volIter.setPosition(x + uStepSize,y,z); - const uint8_t v100 = volIter.getSubSampledVoxel(uLevel); - const Vector3DFloat v3dPosition(x - offset.getX() + 0.5f * uStepSize, y - offset.getY(), z - offset.getZ()); - const Vector3DFloat v3dNormal(v000 > v100 ? 1.0f : -1.0f,0.0,0.0); - const uint8_t uMaterial = v000 | v100; //Because one of these is 0, the or operation takes the max. - SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial); - uint32_t uLastVertexIndex = singleMaterialPatch->addVertex(surfaceVertex); - vertexIndicesX[getDecimatedIndex(x - offset.getX(),y - offset.getY(), regSlice.width()+1)] = uLastVertexIndex; - } - } - if (edgeTable[iCubeIndex] & 8) - { - if(y != regSlice.getUpperCorner().getY()) - { - volIter.setPosition(x,y + uStepSize,z); - const uint8_t v010 = volIter.getSubSampledVoxel(uLevel); - const Vector3DFloat v3dPosition(x - offset.getX(), y - offset.getY() + 0.5f * uStepSize, z - offset.getZ()); - const Vector3DFloat v3dNormal(0.0,v000 > v010 ? 1.0f : -1.0f,0.0); - const uint8_t uMaterial = v000 | v010; //Because one of these is 0, the or operation takes the max. - SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial); - uint32_t uLastVertexIndex = singleMaterialPatch->addVertex(surfaceVertex); - vertexIndicesY[getDecimatedIndex(x - offset.getX(),y - offset.getY(), regSlice.width()+1)] = uLastVertexIndex; - } - } - if (edgeTable[iCubeIndex] & 256) - { - //if(z != regSlice.getUpperCorner.getZ()) - { - volIter.setPosition(x,y,z + uStepSize); - const uint8_t v001 = volIter.getSubSampledVoxel(uLevel); - const Vector3DFloat v3dPosition(x - offset.getX(), y - offset.getY(), z - offset.getZ() + 0.5f * uStepSize); - const Vector3DFloat v3dNormal(0.0,0.0,v000 > v001 ? 1.0f : -1.0f); - const uint8_t uMaterial = v000 | v001; //Because one of these is 0, the or operation takes the max. - const SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial); - uint32_t uLastVertexIndex = singleMaterialPatch->addVertex(surfaceVertex); - vertexIndicesZ[getDecimatedIndex(x - offset.getX(),y - offset.getY(), regSlice.width()+1)] = uLastVertexIndex; - } - } - }//For each cell - } - } - - void generateDecimatedIndicesForSlice(VolumeSampler& volIter, uint8_t uLevel, const Region& regSlice, IndexedSurfacePatch* singleMaterialPatch, const Vector3DFloat& offset, uint8_t* bitmask0, uint8_t* bitmask1, int32_t vertexIndicesX0[],int32_t vertexIndicesY0[],int32_t vertexIndicesZ0[], int32_t vertexIndicesX1[],int32_t vertexIndicesY1[],int32_t vertexIndicesZ1[]) - { - const uint8_t uStepSize = uLevel == 0 ? 1 : 1 << uLevel; - uint32_t indlist[12]; - - for(uint16_t y = regSlice.getLowerCorner().getY() - offset.getY(); y < regSlice.getUpperCorner().getY() - offset.getY(); y += uStepSize) - { - for(uint16_t x = regSlice.getLowerCorner().getX() - offset.getX(); x < regSlice.getUpperCorner().getX() - offset.getX(); x += uStepSize) - { - //Current position - const uint16_t z = regSlice.getLowerCorner().getZ() - offset.getZ(); - - //Determine the index into the edge table which tells us which vertices are inside of the surface - uint8_t iCubeIndex = bitmask0[getDecimatedIndex(x,y, regSlice.width()+1)]; - - /* Cube is entirely in/out of the surface */ - if (edgeTable[iCubeIndex] == 0) - { - continue; - } - - /* Find the vertices where the surface intersects the cube */ - if (edgeTable[iCubeIndex] & 1) - { - indlist[0] = vertexIndicesX0[getDecimatedIndex(x,y, regSlice.width()+1)]; - assert(indlist[0] != -1); - } - if (edgeTable[iCubeIndex] & 2) - { - indlist[1] = vertexIndicesY0[getDecimatedIndex(x+uStepSize,y, regSlice.width()+1)]; - assert(indlist[1] != -1); - } - if (edgeTable[iCubeIndex] & 4) - { - indlist[2] = vertexIndicesX0[getDecimatedIndex(x,y+uStepSize, regSlice.width()+1)]; - assert(indlist[2] != -1); - } - if (edgeTable[iCubeIndex] & 8) - { - indlist[3] = vertexIndicesY0[getDecimatedIndex(x,y, regSlice.width()+1)]; - assert(indlist[3] != -1); - } - if (edgeTable[iCubeIndex] & 16) - { - indlist[4] = vertexIndicesX1[getDecimatedIndex(x,y, regSlice.width()+1)]; - assert(indlist[4] != -1); - } - if (edgeTable[iCubeIndex] & 32) - { - indlist[5] = vertexIndicesY1[getDecimatedIndex(x+uStepSize,y, regSlice.width()+1)]; - assert(indlist[5] != -1); - } - if (edgeTable[iCubeIndex] & 64) - { - indlist[6] = vertexIndicesX1[getDecimatedIndex(x,y+uStepSize, regSlice.width()+1)]; - assert(indlist[6] != -1); - } - if (edgeTable[iCubeIndex] & 128) - { - indlist[7] = vertexIndicesY1[getDecimatedIndex(x,y, regSlice.width()+1)]; - assert(indlist[7] != -1); - } - if (edgeTable[iCubeIndex] & 256) - { - indlist[8] = vertexIndicesZ0[getDecimatedIndex(x,y, regSlice.width()+1)]; - assert(indlist[8] != -1); - } - if (edgeTable[iCubeIndex] & 512) - { - indlist[9] = vertexIndicesZ0[getDecimatedIndex(x+uStepSize,y, regSlice.width()+1)]; - assert(indlist[9] != -1); - } - if (edgeTable[iCubeIndex] & 1024) - { - indlist[10] = vertexIndicesZ0[getDecimatedIndex(x+uStepSize,y+uStepSize, regSlice.width()+1)]; - assert(indlist[10] != -1); - } - if (edgeTable[iCubeIndex] & 2048) - { - indlist[11] = vertexIndicesZ0[getDecimatedIndex(x,y+uStepSize, regSlice.width()+1)]; - assert(indlist[11] != -1); - } - - for (int i=0;triTable[iCubeIndex][i]!=-1;i+=3) - { - uint32_t ind0 = indlist[triTable[iCubeIndex][i ]]; - uint32_t ind1 = indlist[triTable[iCubeIndex][i+1]]; - uint32_t ind2 = indlist[triTable[iCubeIndex][i+2]]; - - singleMaterialPatch->addTriangle(ind0, ind1, ind2); - }//For each triangle - }//For each cell - } - } -} diff --git a/library/PolyVoxCore/source/PolyVoxImpl/FastSurfaceExtractor.cpp b/library/PolyVoxCore/source/PolyVoxImpl/FastSurfaceExtractor.cpp deleted file mode 100644 index 1fed6d71..00000000 --- a/library/PolyVoxCore/source/PolyVoxImpl/FastSurfaceExtractor.cpp +++ /dev/null @@ -1,537 +0,0 @@ -#pragma region License -/****************************************************************************** -This file is part of the PolyVox library -Copyright (C) 2006 David Williams - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -******************************************************************************/ -#pragma endregion - -#include "PolyVoxImpl/FastSurfaceExtractor.h" - -#include "VolumeSampler.h" -#include "IndexedSurfacePatch.h" -#include "PolyVoxImpl/MarchingCubesTables.h" -#include "SurfaceVertex.h" - -namespace PolyVox -{ - - void extractFastSurfaceImpl(Volume* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch) - { - singleMaterialPatch->clear(); - - //For edge indices - int32_t* vertexIndicesX0 = new int32_t[(region.width()+2) * (region.height()+2)]; - int32_t* vertexIndicesY0 = new int32_t[(region.width()+2) * (region.height()+2)]; - int32_t* vertexIndicesZ0 = new int32_t[(region.width()+2) * (region.height()+2)]; - int32_t* vertexIndicesX1 = new int32_t[(region.width()+2) * (region.height()+2)]; - int32_t* vertexIndicesY1 = new int32_t[(region.width()+2) * (region.height()+2)]; - int32_t* vertexIndicesZ1 = new int32_t[(region.width()+2) * (region.height()+2)]; - - //Cell bitmasks - uint8_t* bitmask0 = new uint8_t[(region.width()+2) * (region.height()+2)]; - uint8_t* bitmask1 = new uint8_t[(region.width()+2) * (region.height()+2)]; - - //When generating the mesh for a region we actually look one voxel outside it in the - // back, bottom, right direction. Protect against access violations by cropping region here - Region regVolume = volumeData->getEnclosingRegion(); - //regVolume.setUpperCorner(regVolume.getUpperCorner() - Vector3DInt32(1,1,1)); - region.cropTo(regVolume); - - //Offset from volume corner - const Vector3DFloat offset = static_cast(region.getLowerCorner()); - - //Create a region corresponding to the first slice - Region regSlice0(region); - regSlice0.setUpperCorner(Vector3DInt32(regSlice0.getUpperCorner().getX(),regSlice0.getUpperCorner().getY(),regSlice0.getLowerCorner().getZ())); - - //Iterator to access the volume data - VolumeSampler volIter(*volumeData); - - //Compute bitmask for initial slice - uint32_t uNoOfNonEmptyCellsForSlice0 = computeRoughBitmaskForSlice(volIter, regSlice0, offset, bitmask0, 0); - if(uNoOfNonEmptyCellsForSlice0 != 0) - { - //If there were some non-empty cells then generate initial slice vertices for them - generateRoughVerticesForSlice(volIter,regSlice0, offset, bitmask0, singleMaterialPatch, vertexIndicesX0, vertexIndicesY0, vertexIndicesZ0); - } - - for(uint32_t uSlice = 0; ((uSlice < region.depth()) && (uSlice + offset.getZ() < region.getUpperCorner().getZ())); ++uSlice) - { - Region regSlice1(regSlice0); - regSlice1.shift(Vector3DInt32(0,0,1)); - - uint32_t uNoOfNonEmptyCellsForSlice1 = computeRoughBitmaskForSlice(volIter, regSlice1, offset, bitmask1, bitmask0); - - if(uNoOfNonEmptyCellsForSlice1 != 0) - { - generateRoughVerticesForSlice(volIter,regSlice1, offset, bitmask1, singleMaterialPatch, vertexIndicesX1, vertexIndicesY1, vertexIndicesZ1); - } - - if((uNoOfNonEmptyCellsForSlice0 != 0) || (uNoOfNonEmptyCellsForSlice1 != 0)) - { - generateRoughIndicesForSlice(volIter, regSlice0, singleMaterialPatch, offset, bitmask0, bitmask1, vertexIndicesX0, vertexIndicesY0, vertexIndicesZ0, vertexIndicesX1, vertexIndicesY1, vertexIndicesZ1); - } - - std::swap(uNoOfNonEmptyCellsForSlice0, uNoOfNonEmptyCellsForSlice1); - std::swap(bitmask0, bitmask1); - std::swap(vertexIndicesX0, vertexIndicesX1); - std::swap(vertexIndicesY0, vertexIndicesY1); - std::swap(vertexIndicesZ0, vertexIndicesZ1); - - regSlice0 = regSlice1; - } - - delete[] bitmask0; - delete[] bitmask1; - delete[] vertexIndicesX0; - delete[] vertexIndicesX1; - delete[] vertexIndicesY0; - delete[] vertexIndicesY1; - delete[] vertexIndicesZ0; - delete[] vertexIndicesZ1; - } - - uint32_t getIndex(uint32_t x, uint32_t y, uint32_t regionWidth) - { - return x + (y * (regionWidth+1)); - } - - uint32_t computeRoughBitmaskForSlice(VolumeSampler& volIter, const Region& regSlice, const Vector3DFloat& offset, uint8_t* bitmask, uint8_t* previousBitmask) - { - uint32_t uNoOfNonEmptyCells = 0; - - //Iterate over each cell in the region - for(uint16_t uYVolSpace = regSlice.getLowerCorner().getY(); uYVolSpace <= regSlice.getUpperCorner().getY(); uYVolSpace++) - { - for(uint16_t uXVolSpace = regSlice.getLowerCorner().getX(); uXVolSpace <= regSlice.getUpperCorner().getX(); uXVolSpace++) - { - uint16_t uZVolSpace = regSlice.getLowerCorner().getZ(); - volIter.setPosition(uXVolSpace,uYVolSpace,uZVolSpace); - //Current position - const uint16_t uXRegSpace = volIter.getPosX() - offset.getX(); - const uint16_t uYRegSpace = volIter.getPosY() - offset.getY(); - - //Determine the index into the edge table which tells us which vertices are inside of the surface - uint8_t iCubeIndex = 0; - - if((uXVolSpace < volIter.getVolume().getWidth()-1) && - (uYVolSpace < volIter.getVolume().getHeight()-1) && - (uZVolSpace < volIter.getVolume().getDepth()-1)) - { - bool isPrevXAvail = uXRegSpace > 0; - bool isPrevYAvail = uYRegSpace > 0; - bool isPrevZAvail = previousBitmask != 0; - - if(isPrevZAvail) - { - if(isPrevYAvail) - { - if(isPrevXAvail) - { - const uint8_t v111 = volIter.peekVoxel1px1py1pz(); - - //z - uint8_t iPreviousCubeIndexZ = previousBitmask[getIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; - iPreviousCubeIndexZ >>= 4; - - //y - uint8_t iPreviousCubeIndexY = bitmask[getIndex(uXRegSpace,uYRegSpace-1, regSlice.width()+1)]; - iPreviousCubeIndexY &= 204; //204 = 128+64+8+4 - iPreviousCubeIndexY >>= 2; - - //x - uint8_t iPreviousCubeIndexX = bitmask[getIndex(uXRegSpace-1,uYRegSpace, regSlice.width()+1)]; - iPreviousCubeIndexX &= 170; //170 = 128+32+8+2 - iPreviousCubeIndexX >>= 1; - - iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY | iPreviousCubeIndexZ; - - if (v111 == 0) iCubeIndex |= 128; - } - else //previous X not available - { - const uint8_t v011 = volIter.peekVoxel0px1py1pz(); - const uint8_t v111 = volIter.peekVoxel1px1py1pz(); - - //z - uint8_t iPreviousCubeIndexZ = previousBitmask[getIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; - iPreviousCubeIndexZ >>= 4; - - //y - uint8_t iPreviousCubeIndexY = bitmask[getIndex(uXRegSpace,uYRegSpace-1, regSlice.width()+1)]; - iPreviousCubeIndexY &= 192; //192 = 128 + 64 - iPreviousCubeIndexY >>= 2; - - iCubeIndex = iPreviousCubeIndexY | iPreviousCubeIndexZ; - - if (v011 == 0) iCubeIndex |= 64; - if (v111 == 0) iCubeIndex |= 128; - } - } - else //previous Y not available - { - if(isPrevXAvail) - { - const uint8_t v101 = volIter.peekVoxel1px0py1pz(); - const uint8_t v111 = volIter.peekVoxel1px1py1pz(); - - //z - uint8_t iPreviousCubeIndexZ = previousBitmask[getIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; - iPreviousCubeIndexZ >>= 4; - - //x - uint8_t iPreviousCubeIndexX = bitmask[getIndex(uXRegSpace-1,uYRegSpace, regSlice.width()+1)]; - iPreviousCubeIndexX &= 160; //160 = 128+32 - iPreviousCubeIndexX >>= 1; - - iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexZ; - - if (v101 == 0) iCubeIndex |= 32; - if (v111 == 0) iCubeIndex |= 128; - } - else //previous X not available - { - const uint8_t v001 = volIter.peekVoxel0px0py1pz(); - const uint8_t v101 = volIter.peekVoxel1px0py1pz(); - const uint8_t v011 = volIter.peekVoxel0px1py1pz(); - const uint8_t v111 = volIter.peekVoxel1px1py1pz(); - - //z - uint8_t iPreviousCubeIndexZ = previousBitmask[getIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; - iCubeIndex = iPreviousCubeIndexZ >> 4; - - if (v001 == 0) iCubeIndex |= 16; - if (v101 == 0) iCubeIndex |= 32; - if (v011 == 0) iCubeIndex |= 64; - if (v111 == 0) iCubeIndex |= 128; - } - } - } - else //previous Z not available - { - if(isPrevYAvail) - { - if(isPrevXAvail) - { - const uint8_t v110 = volIter.peekVoxel1px1py0pz(); - const uint8_t v111 = volIter.peekVoxel1px1py1pz(); - - //y - uint8_t iPreviousCubeIndexY = bitmask[getIndex(uXRegSpace,uYRegSpace-1, regSlice.width()+1)]; - iPreviousCubeIndexY &= 204; //204 = 128+64+8+4 - iPreviousCubeIndexY >>= 2; - - //x - uint8_t iPreviousCubeIndexX = bitmask[getIndex(uXRegSpace-1,uYRegSpace, regSlice.width()+1)]; - iPreviousCubeIndexX &= 170; //170 = 128+32+8+2 - iPreviousCubeIndexX >>= 1; - - iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY; - - if (v110 == 0) iCubeIndex |= 8; - if (v111 == 0) iCubeIndex |= 128; - } - else //previous X not available - { - const uint8_t v010 = volIter.peekVoxel0px1py0pz(); - const uint8_t v110 = volIter.peekVoxel1px1py0pz(); - - const uint8_t v011 = volIter.peekVoxel0px1py1pz(); - const uint8_t v111 = volIter.peekVoxel1px1py1pz(); - - //y - uint8_t iPreviousCubeIndexY = bitmask[getIndex(uXRegSpace,uYRegSpace-1, regSlice.width()+1)]; - iPreviousCubeIndexY &= 204; //204 = 128+64+8+4 - iPreviousCubeIndexY >>= 2; - - iCubeIndex = iPreviousCubeIndexY; - - if (v010 == 0) iCubeIndex |= 4; - if (v110 == 0) iCubeIndex |= 8; - if (v011 == 0) iCubeIndex |= 64; - if (v111 == 0) iCubeIndex |= 128; - } - } - else //previous Y not available - { - if(isPrevXAvail) - { - const uint8_t v100 = volIter.peekVoxel1px0py0pz(); - const uint8_t v110 = volIter.peekVoxel1px1py0pz(); - - const uint8_t v101 = volIter.peekVoxel1px0py1pz(); - const uint8_t v111 = volIter.peekVoxel1px1py1pz(); - - //x - uint8_t iPreviousCubeIndexX = bitmask[getIndex(uXRegSpace-1,uYRegSpace, regSlice.width()+1)]; - iPreviousCubeIndexX &= 170; //170 = 128+32+8+2 - iPreviousCubeIndexX >>= 1; - - iCubeIndex = iPreviousCubeIndexX; - - if (v100 == 0) iCubeIndex |= 2; - if (v110 == 0) iCubeIndex |= 8; - if (v101 == 0) iCubeIndex |= 32; - if (v111 == 0) iCubeIndex |= 128; - } - else //previous X not available - { - const uint8_t v000 = volIter.getVoxel(); - const uint8_t v100 = volIter.peekVoxel1px0py0pz(); - const uint8_t v010 = volIter.peekVoxel0px1py0pz(); - const uint8_t v110 = volIter.peekVoxel1px1py0pz(); - - const uint8_t v001 = volIter.peekVoxel0px0py1pz(); - const uint8_t v101 = volIter.peekVoxel1px0py1pz(); - const uint8_t v011 = volIter.peekVoxel0px1py1pz(); - const uint8_t v111 = volIter.peekVoxel1px1py1pz(); - - if (v000 == 0) iCubeIndex |= 1; - if (v100 == 0) iCubeIndex |= 2; - if (v010 == 0) iCubeIndex |= 4; - if (v110 == 0) iCubeIndex |= 8; - if (v001 == 0) iCubeIndex |= 16; - if (v101 == 0) iCubeIndex |= 32; - if (v011 == 0) iCubeIndex |= 64; - if (v111 == 0) iCubeIndex |= 128; - } - } - } - } - else //We're at the edge of the volume - use bounds checking. - { - const uint8_t v000 = volIter.getVoxel(); - const uint8_t v100 = volIter.getVolume().getVoxelAtWithBoundCheck(uXVolSpace+1, uYVolSpace , uZVolSpace ); - const uint8_t v010 = volIter.getVolume().getVoxelAtWithBoundCheck(uXVolSpace , uYVolSpace+1, uZVolSpace ); - const uint8_t v110 = volIter.getVolume().getVoxelAtWithBoundCheck(uXVolSpace+1, uYVolSpace+1, uZVolSpace ); - - const uint8_t v001 = volIter.getVolume().getVoxelAtWithBoundCheck(uXVolSpace , uYVolSpace , uZVolSpace+1); - const uint8_t v101 = volIter.getVolume().getVoxelAtWithBoundCheck(uXVolSpace+1, uYVolSpace , uZVolSpace+1); - const uint8_t v011 = volIter.getVolume().getVoxelAtWithBoundCheck(uXVolSpace , uYVolSpace+1, uZVolSpace+1); - const uint8_t v111 = volIter.getVolume().getVoxelAtWithBoundCheck(uXVolSpace+1, uYVolSpace+1, uZVolSpace+1); - - if (v000 == 0) iCubeIndex |= 1; - if (v100 == 0) iCubeIndex |= 2; - if (v010 == 0) iCubeIndex |= 4; - if (v110 == 0) iCubeIndex |= 8; - if (v001 == 0) iCubeIndex |= 16; - if (v101 == 0) iCubeIndex |= 32; - if (v011 == 0) iCubeIndex |= 64; - if (v111 == 0) iCubeIndex |= 128; - } - - //Save the bitmask - bitmask[getIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)] = iCubeIndex; - - if(edgeTable[iCubeIndex] != 0) - { - ++uNoOfNonEmptyCells; - } - - } - } - - return uNoOfNonEmptyCells; - } - - void generateRoughVerticesForSlice(VolumeSampler& volIter, Region& regSlice, const Vector3DFloat& offset, uint8_t* bitmask, IndexedSurfacePatch* singleMaterialPatch,int32_t vertexIndicesX[],int32_t vertexIndicesY[],int32_t vertexIndicesZ[]) - { - //Iterate over each cell in the region - for(uint16_t uYVolSpace = regSlice.getLowerCorner().getY(); uYVolSpace <= regSlice.getUpperCorner().getY(); uYVolSpace++) - { - for(uint16_t uXVolSpace = regSlice.getLowerCorner().getX(); uXVolSpace <= regSlice.getUpperCorner().getX(); uXVolSpace++) - { - uint16_t uZVolSpace = regSlice.getLowerCorner().getZ(); - volIter.setPosition(uXVolSpace,uYVolSpace,uZVolSpace); - - //Current position - const uint16_t uXRegSpace = volIter.getPosX() - offset.getX(); - const uint16_t uYRegSpace = volIter.getPosY() - offset.getY(); - const uint16_t uZRegSpace = volIter.getPosZ() - offset.getZ(); - - const uint8_t v000 = volIter.getVoxel(); - - //Determine the index into the edge table which tells us which vertices are inside of the surface - uint8_t iCubeIndex = bitmask[getIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; - - /* Cube is entirely in/out of the surface */ - if (edgeTable[iCubeIndex] == 0) - { - continue; - } - - /* Find the vertices where the surface intersects the cube */ - if (edgeTable[iCubeIndex] & 1) - { - if((uXRegSpace + offset.getX()) != regSlice.getUpperCorner().getX()) - { - const uint8_t v100 = volIter.peekVoxel1px0py0pz(); - const Vector3DFloat v3dPosition(uXRegSpace + 0.5f, uYRegSpace, uZRegSpace); - const Vector3DFloat v3dNormal(v000 > v100 ? 1.0f : -1.0f, 0.0f, 0.0f); - const uint8_t uMaterial = v000 | v100; //Because one of these is 0, the or operation takes the max. - const SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial); - uint32_t uLastVertexIndex = singleMaterialPatch->addVertex(surfaceVertex); - vertexIndicesX[getIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)] = uLastVertexIndex; - } - } - if (edgeTable[iCubeIndex] & 8) - { - if((uYRegSpace + offset.getY()) != regSlice.getUpperCorner().getY()) - { - const uint8_t v010 = volIter.peekVoxel0px1py0pz(); - const Vector3DFloat v3dPosition(uXRegSpace, uYRegSpace + 0.5f, uZRegSpace); - const Vector3DFloat v3dNormal(0.0f, v000 > v010 ? 1.0f : -1.0f, 0.0f); - const uint8_t uMaterial = v000 | v010; - SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial); - uint32_t uLastVertexIndex = singleMaterialPatch->addVertex(surfaceVertex); - vertexIndicesY[getIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)] = uLastVertexIndex; - } - } - if (edgeTable[iCubeIndex] & 256) - { - uint8_t v001; - if((uZRegSpace + offset.getZ()) != regSlice.getUpperCorner().getZ()) - { - v001 = volIter.peekVoxel0px0py1pz(); - } - else - { - v001 = volIter.getVolume().getVoxelAtWithBoundCheck(uXVolSpace,uYVolSpace,uZVolSpace+1); - } - const Vector3DFloat v3dPosition(uXRegSpace, uYRegSpace, uZRegSpace + 0.5f); - const Vector3DFloat v3dNormal(0.0f, 0.0f, v000 > v001 ? 1.0f : -1.0f); - const uint8_t uMaterial = v000 | v001; - SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial); - uint32_t uLastVertexIndex = singleMaterialPatch->addVertex(surfaceVertex); - vertexIndicesZ[getIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)] = uLastVertexIndex; - } - } - } - } - - void generateRoughIndicesForSlice(VolumeSampler& volIter, const Region& regSlice, IndexedSurfacePatch* singleMaterialPatch, const Vector3DFloat& offset, uint8_t* bitmask0, uint8_t* bitmask1, int32_t vertexIndicesX0[],int32_t vertexIndicesY0[],int32_t vertexIndicesZ0[], int32_t vertexIndicesX1[],int32_t vertexIndicesY1[],int32_t vertexIndicesZ1[]) - { - uint32_t indlist[12]; - - //Iterate over each cell in the region - for(uint16_t uYVolSpace = regSlice.getLowerCorner().getY(); uYVolSpace < regSlice.getUpperCorner().getY(); uYVolSpace++) - { - for(uint16_t uXVolSpace = regSlice.getLowerCorner().getX(); uXVolSpace < regSlice.getUpperCorner().getX(); uXVolSpace++) - { - uint16_t uZVolSpace = regSlice.getLowerCorner().getZ(); - volIter.setPosition(uXVolSpace,uYVolSpace,uZVolSpace); - - //Current position - const uint16_t uXRegSpace = volIter.getPosX() - offset.getX(); - const uint16_t uYRegSpace = volIter.getPosY() - offset.getY(); - const uint16_t uZRegSpace = volIter.getPosZ() - offset.getZ(); - - //Determine the index into the edge table which tells us which vertices are inside of the surface - uint8_t iCubeIndex = bitmask0[getIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; - - /* Cube is entirely in/out of the surface */ - if (edgeTable[iCubeIndex] == 0) - { - continue; - } - - /* Find the vertices where the surface intersects the cube */ - if (edgeTable[iCubeIndex] & 1) - { - indlist[0] = vertexIndicesX0[getIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; - assert(indlist[0] != -1); - assert(indlist[0] < 10000); - } - if (edgeTable[iCubeIndex] & 2) - { - indlist[1] = vertexIndicesY0[getIndex(uXRegSpace+1,uYRegSpace, regSlice.width()+1)]; - assert(indlist[1] != -1); - assert(indlist[1] < 10000); - } - if (edgeTable[iCubeIndex] & 4) - { - indlist[2] = vertexIndicesX0[getIndex(uXRegSpace,uYRegSpace+1, regSlice.width()+1)]; - assert(indlist[2] != -1); - assert(indlist[2] < 10000); - } - if (edgeTable[iCubeIndex] & 8) - { - indlist[3] = vertexIndicesY0[getIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; - assert(indlist[3] != -1); - assert(indlist[3] < 10000); - } - if (edgeTable[iCubeIndex] & 16) - { - indlist[4] = vertexIndicesX1[getIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; - assert(indlist[4] != -1); - assert(indlist[4] < 10000); - } - if (edgeTable[iCubeIndex] & 32) - { - indlist[5] = vertexIndicesY1[getIndex(uXRegSpace+1,uYRegSpace, regSlice.width()+1)]; - assert(indlist[5] != -1); - assert(indlist[5] < 10000); - } - if (edgeTable[iCubeIndex] & 64) - { - indlist[6] = vertexIndicesX1[getIndex(uXRegSpace,uYRegSpace+1, regSlice.width()+1)]; - assert(indlist[6] != -1); - assert(indlist[6] < 10000); - } - if (edgeTable[iCubeIndex] & 128) - { - indlist[7] = vertexIndicesY1[getIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; - assert(indlist[7] != -1); - assert(indlist[7] < 10000); - } - if (edgeTable[iCubeIndex] & 256) - { - indlist[8] = vertexIndicesZ0[getIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; - assert(indlist[8] != -1); - assert(indlist[8] < 10000); - } - if (edgeTable[iCubeIndex] & 512) - { - indlist[9] = vertexIndicesZ0[getIndex(uXRegSpace+1,uYRegSpace, regSlice.width()+1)]; - assert(indlist[9] != -1); - assert(indlist[9] < 10000); - } - if (edgeTable[iCubeIndex] & 1024) - { - indlist[10] = vertexIndicesZ0[getIndex(uXRegSpace+1,uYRegSpace+1, regSlice.width()+1)]; - assert(indlist[10] != -1); - assert(indlist[10] < 10000); - } - if (edgeTable[iCubeIndex] & 2048) - { - indlist[11] = vertexIndicesZ0[getIndex(uXRegSpace,uYRegSpace+1, regSlice.width()+1)]; - assert(indlist[11] != -1); - assert(indlist[11] < 10000); - } - - for (int i=0;triTable[iCubeIndex][i]!=-1;i+=3) - { - uint32_t ind0 = indlist[triTable[iCubeIndex][i ]]; - uint32_t ind1 = indlist[triTable[iCubeIndex][i+1]]; - uint32_t ind2 = indlist[triTable[iCubeIndex][i+2]]; - - singleMaterialPatch->addTriangle(ind0, ind1, ind2); - }//For each triangle - } - } - } -} \ No newline at end of file diff --git a/library/PolyVoxCore/source/SurfaceExtractors.cpp b/library/PolyVoxCore/source/SurfaceExtractors.cpp deleted file mode 100644 index 646426f9..00000000 --- a/library/PolyVoxCore/source/SurfaceExtractors.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "SurfaceExtractors.h" - -#include "Volume.h" -#include "GradientEstimators.h" -#include "IndexedSurfacePatch.h" -#include "PolyVoxImpl/MarchingCubesTables.h" -#include "Region.h" -#include "VolumeSampler.h" - -#include "PolyVoxImpl/DecimatedSurfaceExtractor.h" -#include "PolyVoxImpl/FastSurfaceExtractor.h" - -#include - -using namespace std; - -namespace PolyVox -{ - void extractSurface(Volume* volumeData, uint8_t uLevel, Region region, IndexedSurfacePatch* singleMaterialPatch) - { - if(uLevel == 0) - { - extractFastSurfaceImpl(volumeData, region, singleMaterialPatch); - } - else - { - extractDecimatedSurfaceImpl(volumeData, uLevel, region, singleMaterialPatch); - } - - singleMaterialPatch->m_Region = region; - } -} diff --git a/library/PolyVoxUtil/source/VolumeChangeTracker.cpp b/library/PolyVoxUtil/source/VolumeChangeTracker.cpp index 57182ba6..b17ed5f9 100644 --- a/library/PolyVoxUtil/source/VolumeChangeTracker.cpp +++ b/library/PolyVoxUtil/source/VolumeChangeTracker.cpp @@ -24,7 +24,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "GradientEstimators.h" #include "IndexedSurfacePatch.h" #include "PolyVoxImpl/MarchingCubesTables.h" -#include "SurfaceExtractors.h" #include "SurfaceVertex.h" #include "PolyVoxImpl/Utility.h" #include "Vector.h"