From 46801f1e3ddc4f2b45bc69e86b541cc5b8d8bc38 Mon Sep 17 00:00:00 2001 From: David Williams Date: Thu, 14 May 2009 22:52:55 +0000 Subject: [PATCH] Work on refactoring surface extractor. --- examples/OpenGL/OpenGLWidget.cpp | 2 +- .../PolyVoxImpl/DecimatedSurfaceExtractor.h | 3 +- .../PolyVoxImpl/FastSurfaceExtractor.h | 3 +- .../PolyVoxImpl/DecimatedSurfaceExtractor.cpp | 403 +++++++++--------- .../PolyVoxImpl/FastSurfaceExtractor.cpp | 360 ++++++++-------- 5 files changed, 368 insertions(+), 403 deletions(-) diff --git a/examples/OpenGL/OpenGLWidget.cpp b/examples/OpenGL/OpenGLWidget.cpp index d2f33202..851c8124 100644 --- a/examples/OpenGL/OpenGLWidget.cpp +++ b/examples/OpenGL/OpenGLWidget.cpp @@ -64,7 +64,7 @@ void OpenGLWidget::setVolume(PolyVox::Volume* volData) Vector3DInt32 regUpperCorner(regionEndX, regionEndY, regionEndZ); //Extract the surface for this region - extractSurface(m_volData, 0, PolyVox::Region(regLowerCorner, regUpperCorner), ispCurrent); + extractSurface(m_volData, 1, PolyVox::Region(regLowerCorner, regUpperCorner), ispCurrent); //computeNormalsForVertices(m_volData, *ispCurrent, SOBEL_SMOOTHED); //*ispCurrent = getSmoothedSurface(*ispCurrent); diff --git a/library/PolyVoxCore/include/PolyVoxImpl/DecimatedSurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxImpl/DecimatedSurfaceExtractor.h index edd2e06c..0fcbaac0 100644 --- a/library/PolyVoxCore/include/PolyVoxImpl/DecimatedSurfaceExtractor.h +++ b/library/PolyVoxCore/include/PolyVoxImpl/DecimatedSurfaceExtractor.h @@ -34,8 +34,7 @@ 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 computeInitialDecimatedBitmaskForSlice(VolumeIterator& volIter, uint8_t uLevel, const Region& regSlice, const Vector3DFloat& offset, uint8_t *bitmask); - uint32_t computeDecimatedBitmaskForSliceFromPrevious(VolumeIterator& volIter, uint8_t uLevel, const Region& regSlice, const Vector3DFloat& offset, uint8_t *bitmask, uint8_t *previousBitmask); + uint32_t computeDecimatedBitmaskForSlice(VolumeIterator& volIter, uint8_t uLevel, const Region& regSlice, const Vector3DFloat& offset, uint8_t *bitmask, uint8_t *previousBitmask); void generateDecimatedIndicesForSlice(VolumeIterator& 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(VolumeIterator& volIter, uint8_t uLevel, Region& regSlice, const Vector3DFloat& offset, uint8_t* bitmask, IndexedSurfacePatch* singleMaterialPatch,int32_t vertexIndicesX[],int32_t vertexIndicesY[],int32_t vertexIndicesZ[]); } diff --git a/library/PolyVoxCore/include/PolyVoxImpl/FastSurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxImpl/FastSurfaceExtractor.h index b71f8e9e..5ae0d479 100644 --- a/library/PolyVoxCore/include/PolyVoxImpl/FastSurfaceExtractor.h +++ b/library/PolyVoxCore/include/PolyVoxImpl/FastSurfaceExtractor.h @@ -33,8 +33,7 @@ namespace PolyVox { void extractFastSurfaceImpl(Volume* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch); uint32_t getIndex(uint32_t x, uint32_t y, uint32_t regionWidth); - uint32_t computeInitialRoughBitmaskForSlice(VolumeIterator& volIter, const Region& regSlice, const Vector3DFloat& offset, uint8_t *bitmask); - uint32_t computeRoughBitmaskForSliceFromPrevious(VolumeIterator& volIter, const Region& regSlice, const Vector3DFloat& offset, uint8_t *bitmask, uint8_t *previousBitmask); + uint32_t computeRoughBitmaskForSlice(VolumeIterator& volIter, const Region& regSlice, const Vector3DFloat& offset, uint8_t *bitmask, uint8_t *previousBitmask); void generateRoughIndicesForSlice(VolumeIterator& 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(VolumeIterator& volIter, Region& regSlice, const Vector3DFloat& offset, uint8_t* bitmask, IndexedSurfacePatch* singleMaterialPatch,int32_t vertexIndicesX[],int32_t vertexIndicesY[],int32_t vertexIndicesZ[]); } diff --git a/library/PolyVoxCore/source/PolyVoxImpl/DecimatedSurfaceExtractor.cpp b/library/PolyVoxCore/source/PolyVoxImpl/DecimatedSurfaceExtractor.cpp index 608ff4fd..9b963a4b 100644 --- a/library/PolyVoxCore/source/PolyVoxImpl/DecimatedSurfaceExtractor.cpp +++ b/library/PolyVoxCore/source/PolyVoxImpl/DecimatedSurfaceExtractor.cpp @@ -80,7 +80,7 @@ namespace PolyVox VolumeIterator volIter(*volumeData); //Compute bitmask for initial slice - uint32_t uNoOfNonEmptyCellsForSlice0 = computeInitialDecimatedBitmaskForSlice(volIter, uLevel, regSlice0, offset, bitmask0); + 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 @@ -92,7 +92,7 @@ namespace PolyVox Region regSlice1(regSlice0); regSlice1.shift(Vector3DInt32(0,0,uStepSize)); - uint32_t uNoOfNonEmptyCellsForSlice1 = computeDecimatedBitmaskForSliceFromPrevious(volIter, uLevel, regSlice1, offset, bitmask1, bitmask0); + uint32_t uNoOfNonEmptyCellsForSlice1 = computeDecimatedBitmaskForSlice(volIter, uLevel, regSlice1, offset, bitmask1, bitmask0); if(uNoOfNonEmptyCellsForSlice1 != 0) { @@ -132,241 +132,236 @@ namespace PolyVox }*/ } - uint32_t computeInitialDecimatedBitmaskForSlice(VolumeIterator& volIter, uint8_t uLevel, const Region& regSlice, const Vector3DFloat& offset, uint8_t* bitmask) + uint32_t computeDecimatedBitmaskForSlice(VolumeIterator& 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 y = regSlice.getLowerCorner().getY(); y <= regSlice.getUpperCorner().getY(); y += uStepSize) + for(uint16_t uYVolSpace = regSlice.getLowerCorner().getY(); uYVolSpace <= regSlice.getUpperCorner().getY(); uYVolSpace += uStepSize) { - for(uint16_t x = regSlice.getLowerCorner().getX(); x <= regSlice.getUpperCorner().getX(); x += uStepSize) - { - //Current position - volIter.setPosition(x,y,regSlice.getLowerCorner().getZ()); - - //Determine the index into the edge table which tells us which vertices are inside of the surface - uint8_t iCubeIndex = 0; - - if((x==regSlice.getLowerCorner().getX()) && (y==regSlice.getLowerCorner().getY())) - { - volIter.setPosition(x,y,regSlice.getLowerCorner().getZ()); - const uint8_t v000 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(x+uStepSize,y,regSlice.getLowerCorner().getZ()); - const uint8_t v100 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(x,y+uStepSize,regSlice.getLowerCorner().getZ()); - const uint8_t v010 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()); - const uint8_t v110 = volIter.getSubSampledVoxel(uLevel); - - volIter.setPosition(x,y,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v001 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(x+uStepSize,y,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v101 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(x,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v011 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+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; - } - else if((x>regSlice.getLowerCorner().getX()) && y==regSlice.getLowerCorner().getY()) - { - volIter.setPosition(x+uStepSize,y,regSlice.getLowerCorner().getZ()); - const uint8_t v100 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()); - const uint8_t v110 = volIter.getSubSampledVoxel(uLevel); - - volIter.setPosition(x+uStepSize,y,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v101 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); - - //x - uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(x- offset.getX()-uStepSize,y- offset.getY(), 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 if((x==regSlice.getLowerCorner().getX()) && (y>regSlice.getLowerCorner().getY())) - { - volIter.setPosition(x,y+uStepSize,regSlice.getLowerCorner().getZ()); - const uint8_t v010 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()); - const uint8_t v110 = volIter.getSubSampledVoxel(uLevel); - - volIter.setPosition(x,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v011 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); - - //y - uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY()-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 - { - volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()); - const uint8_t v110 = volIter.getSubSampledVoxel(uLevel); - - volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); - - //y - uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY()-uStepSize, regSlice.width()+1)]; - iPreviousCubeIndexY &= 204; //204 = 128+64+8+4 - iPreviousCubeIndexY >>= 2; - - //x - uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(x- offset.getX()-uStepSize,y- offset.getY(), 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; - } - - //Save the bitmask - bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY(), regSlice.width()+1)] = iCubeIndex; - - if(edgeTable[iCubeIndex] != 0) - { - ++uNoOfNonEmptyCells; - } - - } - } - - return uNoOfNonEmptyCells; - } - - uint32_t computeDecimatedBitmaskForSliceFromPrevious(VolumeIterator& 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 y = regSlice.getLowerCorner().getY(); y <= regSlice.getUpperCorner().getY(); y += uStepSize) - { - for(uint16_t x = regSlice.getLowerCorner().getX(); x <= regSlice.getUpperCorner().getX(); x += uStepSize) + for(uint16_t uXVolSpace = regSlice.getLowerCorner().getX(); uXVolSpace <= regSlice.getUpperCorner().getX(); uXVolSpace += uStepSize) { + uint16_t uZVolSpace = regSlice.getLowerCorner().getZ(); //Current position - volIter.setPosition(x,y,regSlice.getLowerCorner().getZ()); + 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; - if((x==regSlice.getLowerCorner().getX()) && (y==regSlice.getLowerCorner().getY())) + bool isPrevXAvail = uXRegSpace > 0; + bool isPrevYAvail = uYRegSpace > 0; + bool isPrevZAvail = previousBitmask != 0; + + if(isPrevZAvail) { - volIter.setPosition(x,y,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v001 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(x+uStepSize,y,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v101 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(x,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v011 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); + 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(x- offset.getX(),y- offset.getY(), regSlice.width()+1)]; - iCubeIndex = iPreviousCubeIndexZ >> 4; + //z + uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(uXRegSpace,uYRegSpace, regSlice.width()+1)]; + iPreviousCubeIndexZ >>= 4; - if (v001 == 0) iCubeIndex |= 16; - if (v101 == 0) iCubeIndex |= 32; - if (v011 == 0) iCubeIndex |= 64; - if (v111 == 0) iCubeIndex |= 128; + //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 if((x>regSlice.getLowerCorner().getX()) && y==regSlice.getLowerCorner().getY()) + else //previous Z not available { - volIter.setPosition(x+uStepSize,y,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v101 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); + if(isPrevYAvail) + { + if(isPrevXAvail) + { + volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace+uStepSize,uZVolSpace); + const uint8_t v110 = volIter.getSubSampledVoxel(uLevel); - //z - uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY(), regSlice.width()+1)]; - iPreviousCubeIndexZ >>= 4; + volIter.setPosition(uXVolSpace+uStepSize,uYVolSpace+uStepSize,uZVolSpace+uStepSize); + const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); - //x - uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(x- offset.getX()-uStepSize,y- offset.getY(), regSlice.width()+1)]; - iPreviousCubeIndexX &= 160; //160 = 128+32 - iPreviousCubeIndexX >>= 1; + //y + uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(uXRegSpace,uYRegSpace-uStepSize, regSlice.width()+1)]; + iPreviousCubeIndexY &= 204; //204 = 128+64+8+4 + iPreviousCubeIndexY >>= 2; - iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexZ; + //x + uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(uXRegSpace-uStepSize,uYRegSpace, regSlice.width()+1)]; + iPreviousCubeIndexX &= 170; //170 = 128+32+8+2 + iPreviousCubeIndexX >>= 1; - if (v101 == 0) iCubeIndex |= 32; - if (v111 == 0) iCubeIndex |= 128; - } - else if((x==regSlice.getLowerCorner().getX()) && (y>regSlice.getLowerCorner().getY())) - { - volIter.setPosition(x,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v011 = volIter.getSubSampledVoxel(uLevel); - volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); + iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY; - //z - uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY(), regSlice.width()+1)]; - iPreviousCubeIndexZ >>= 4; + 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); - //y - uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY()-uStepSize, regSlice.width()+1)]; - iPreviousCubeIndexY &= 192; //192 = 128 + 64 - iPreviousCubeIndexY >>= 2; + 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); - iCubeIndex = iPreviousCubeIndexY | iPreviousCubeIndexZ; + //y + uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(uXRegSpace,uYRegSpace-uStepSize, regSlice.width()+1)]; + iPreviousCubeIndexY &= 204; //204 = 128+64+8+4 + iPreviousCubeIndexY >>= 2; - if (v011 == 0) iCubeIndex |= 64; - if (v111 == 0) iCubeIndex |= 128; - } - else - { - volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize); - const uint8_t v111 = volIter.getSubSampledVoxel(uLevel); + iCubeIndex = iPreviousCubeIndexY; - //z - uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY(), regSlice.width()+1)]; - iPreviousCubeIndexZ >>= 4; + 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); - //y - uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY()-uStepSize, regSlice.width()+1)]; - iPreviousCubeIndexY &= 192; //192 = 128 + 64 - iPreviousCubeIndexY >>= 2; + 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(x- offset.getX()-uStepSize,y- offset.getY(), regSlice.width()+1)]; - iPreviousCubeIndexX &= 128; - iPreviousCubeIndexX >>= 1; + //x + uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(uXRegSpace-uStepSize,uYRegSpace, regSlice.width()+1)]; + iPreviousCubeIndexX &= 170; //170 = 128+32+8+2 + iPreviousCubeIndexX >>= 1; - iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY | iPreviousCubeIndexZ; + iCubeIndex = iPreviousCubeIndexX; - if (v111 == 0) iCubeIndex |= 128; + 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(x- offset.getX(),y- offset.getY(), regSlice.width()+1)] = iCubeIndex; + bitmask[getDecimatedIndex(uXRegSpace,uYVolSpace- offset.getY(), regSlice.width()+1)] = iCubeIndex; if(edgeTable[iCubeIndex] != 0) { diff --git a/library/PolyVoxCore/source/PolyVoxImpl/FastSurfaceExtractor.cpp b/library/PolyVoxCore/source/PolyVoxImpl/FastSurfaceExtractor.cpp index 870430a9..81df910f 100644 --- a/library/PolyVoxCore/source/PolyVoxImpl/FastSurfaceExtractor.cpp +++ b/library/PolyVoxCore/source/PolyVoxImpl/FastSurfaceExtractor.cpp @@ -62,7 +62,7 @@ namespace PolyVox VolumeIterator volIter(*volumeData); //Compute bitmask for initial slice - uint32_t uNoOfNonEmptyCellsForSlice0 = computeInitialRoughBitmaskForSlice(volIter, regSlice0, offset, bitmask0); + 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 @@ -74,7 +74,7 @@ namespace PolyVox Region regSlice1(regSlice0); regSlice1.shift(Vector3DInt32(0,0,1)); - uint32_t uNoOfNonEmptyCellsForSlice1 = computeRoughBitmaskForSliceFromPrevious(volIter, regSlice1, offset, bitmask1, bitmask0); + uint32_t uNoOfNonEmptyCellsForSlice1 = computeRoughBitmaskForSlice(volIter, regSlice1, offset, bitmask1, bitmask0); if(uNoOfNonEmptyCellsForSlice1 != 0) { @@ -110,7 +110,7 @@ namespace PolyVox return x + (y * (regionWidth+1)); } - uint32_t computeInitialRoughBitmaskForSlice(VolumeIterator& volIter, const Region& regSlice, const Vector3DFloat& offset, uint8_t* bitmask) + uint32_t computeRoughBitmaskForSlice(VolumeIterator& volIter, const Region& regSlice, const Vector3DFloat& offset, uint8_t* bitmask, uint8_t* previousBitmask) { uint32_t uNoOfNonEmptyCells = 0; @@ -132,90 +132,188 @@ namespace PolyVox (uYVolSpace < volIter.getVolume().getHeight()-1) && (uZVolSpace < volIter.getVolume().getDepth()-1)) { - if((uXRegSpace==0) && (uYRegSpace==0)) + bool isPrevXAvail = uXRegSpace > 0; + bool isPrevYAvail = uYRegSpace > 0; + bool isPrevZAvail = previousBitmask != 0; + + if(isPrevZAvail) { - const uint8_t v000 = volIter.getVoxel(); - const uint8_t v100 = volIter.peekVoxel1px0py0pz(); - const uint8_t v010 = volIter.peekVoxel0px1py0pz(); - const uint8_t v110 = volIter.peekVoxel1px1py0pz(); + if(isPrevYAvail) + { + if(isPrevXAvail) + { + const uint8_t v111 = volIter.peekVoxel1px1py1pz(); - 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)]; + iPreviousCubeIndexZ >>= 4; - 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; + //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 if((uXRegSpace>0) && uYRegSpace==0) + else //previous Z not available { - const uint8_t v100 = volIter.peekVoxel1px0py0pz(); - const uint8_t v110 = volIter.peekVoxel1px1py0pz(); + if(isPrevYAvail) + { + if(isPrevXAvail) + { + const uint8_t v110 = volIter.peekVoxel1px1py0pz(); + const uint8_t v111 = volIter.peekVoxel1px1py1pz(); - const uint8_t v101 = volIter.peekVoxel1px0py1pz(); - 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; + //x + uint8_t iPreviousCubeIndexX = bitmask[getIndex(uXRegSpace-1,uYRegSpace, regSlice.width()+1)]; + iPreviousCubeIndexX &= 170; //170 = 128+32+8+2 + iPreviousCubeIndexX >>= 1; - iCubeIndex = iPreviousCubeIndexX; + iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY; - if (v100 == 0) iCubeIndex |= 2; - if (v110 == 0) iCubeIndex |= 8; - if (v101 == 0) iCubeIndex |= 32; - if (v111 == 0) iCubeIndex |= 128; - } - else if((uXRegSpace==0) && (uYRegSpace>0)) - { - const uint8_t v010 = volIter.peekVoxel0px1py0pz(); - const uint8_t v110 = volIter.peekVoxel1px1py0pz(); + 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(); + 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; + //y + uint8_t iPreviousCubeIndexY = bitmask[getIndex(uXRegSpace,uYRegSpace-1, regSlice.width()+1)]; + iPreviousCubeIndexY &= 204; //204 = 128+64+8+4 + iPreviousCubeIndexY >>= 2; - iCubeIndex = iPreviousCubeIndexY; + iCubeIndex = iPreviousCubeIndexY; - if (v010 == 0) iCubeIndex |= 4; - if (v110 == 0) iCubeIndex |= 8; - if (v011 == 0) iCubeIndex |= 64; - if (v111 == 0) iCubeIndex |= 128; - } - else - { - const uint8_t v110 = volIter.peekVoxel1px1py0pz(); - const uint8_t v111 = volIter.peekVoxel1px1py1pz(); + 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(); - //y - uint8_t iPreviousCubeIndexY = bitmask[getIndex(uXRegSpace,uYRegSpace-1, regSlice.width()+1)]; - iPreviousCubeIndexY &= 204; //204 = 128+64+8+4 - iPreviousCubeIndexY >>= 2; + 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; + //x + uint8_t iPreviousCubeIndexX = bitmask[getIndex(uXRegSpace-1,uYRegSpace, regSlice.width()+1)]; + iPreviousCubeIndexX &= 170; //170 = 128+32+8+2 + iPreviousCubeIndexX >>= 1; - iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY; + iCubeIndex = iPreviousCubeIndexX; - if (v110 == 0) iCubeIndex |= 8; - if (v111 == 0) iCubeIndex |= 128; + 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 - { + 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 ); @@ -244,132 +342,6 @@ namespace PolyVox ++uNoOfNonEmptyCells; } - }//while(volIter.moveForwardInRegionXYZ());//For each cell - } - - return uNoOfNonEmptyCells; - } - - uint32_t computeRoughBitmaskForSliceFromPrevious(VolumeIterator& 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)) - { - if((uXRegSpace==0) && (uYRegSpace==0)) - { - 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 if((uXRegSpace>0) && uYRegSpace==0) - { - 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 if((uXRegSpace==0) && (uYRegSpace>0)) - { - 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 - { - 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; - - //x - uint8_t iPreviousCubeIndexX = bitmask[getIndex(uXRegSpace-1,uYRegSpace, regSlice.width()+1)]; - iPreviousCubeIndexX &= 128; - iPreviousCubeIndexX >>= 1; - - iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY | iPreviousCubeIndexZ; - - if (v111 == 0) iCubeIndex |= 128; - } - } - else - { - 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 (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; - } - } }