From d5d6319087191a60bce090747d0c4b20e634f328 Mon Sep 17 00:00:00 2001 From: David Williams Date: Sat, 3 Dec 2011 09:43:27 +0000 Subject: [PATCH] Fixes to behavour of LowPassFilter. --- .../include/PolyVoxCore/LowPassFilter.inl | 50 ++++++++++--------- tests/TestLowPassFilter.cpp | 26 ++++++++-- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/LowPassFilter.inl b/library/PolyVoxCore/include/PolyVoxCore/LowPassFilter.inl index 9e6bc66d..c5ad68b6 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LowPassFilter.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/LowPassFilter.inl @@ -118,14 +118,18 @@ namespace PolyVox template< template class SrcVolumeType, template class DestVolumeType, typename VoxelType> void LowPassFilter::executeSAT() { - const int border = m_uKernelSize - 1; + const uint32_t border = (m_uKernelSize - 1) / 2; - Vector3DInt32 satLowerCorner = m_regSrc.getLowerCorner() - Vector3DInt32(border+1, border+1, border+1); + Vector3DInt32 satLowerCorner = m_regSrc.getLowerCorner() - Vector3DInt32(border, border, border); Vector3DInt32 satUpperCorner = m_regSrc.getUpperCorner() + Vector3DInt32(border, border, border); - RawVolume satVolume(Region(satLowerCorner, satUpperCorner)); + //Use floats for the SAT volume to ensure it works with negative + //densities and with both integral and floating point input volumes. + RawVolume satVolume(Region(satLowerCorner, satUpperCorner)); //Clear to zeros (necessary?) + //FIXME - use Volume::fill() method. Implemented in base class as below + //but with optimised implementations in subclasses? for(int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++) { for(int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++) @@ -137,9 +141,9 @@ namespace PolyVox } } - RawVolume::Sampler satVolumeIter(&satVolume); + RawVolume::Sampler satVolumeIter(&satVolume); - IteratorController::Sampler> satIterCont; + IteratorController::Sampler> satIterCont; satIterCont.m_regValid = Region(satLowerCorner, satUpperCorner); satIterCont.m_Iter = &satVolumeIter; satIterCont.reset(); @@ -153,9 +157,9 @@ namespace PolyVox do { - uint32_t previousSum = satVolumeIter.peekVoxel1nx0py0pz(); + float previousSum = satVolumeIter.peekVoxel1nx0py0pz(); - uint32_t currentVal = srcVolumeIter.getVoxel().getDensity(); + float currentVal = static_cast(srcVolumeIter.getVoxel().getDensity()); satVolumeIter.setVoxel(previousSum + currentVal); @@ -184,8 +188,8 @@ namespace PolyVox { for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) { - uint32_t previousSum = satVolume.getVoxelAt(x,y-1,z); - uint32_t currentSum = satVolume.getVoxelAt(x,y,z); + float previousSum = satVolume.getVoxelAt(x,y-1,z); + float currentSum = satVolume.getVoxelAt(x,y,z); satVolume.setVoxelAt(x,y,z,previousSum + currentSum); } @@ -198,8 +202,8 @@ namespace PolyVox { for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) { - uint32_t previousSum = satVolume.getVoxelAt(x,y,z-1); - uint32_t currentSum = satVolume.getVoxelAt(x,y,z); + float previousSum = satVolume.getVoxelAt(x,y,z-1); + float currentSum = satVolume.getVoxelAt(x,y,z); satVolume.setVoxelAt(x,y,z,previousSum + currentSum); } @@ -227,24 +231,24 @@ namespace PolyVox int32_t satUpperY = iSrcY + border; int32_t satUpperZ = iSrcZ + border; - int32_t a = satVolume.getVoxelAt(satLowerX,satLowerY,satLowerZ); - int32_t b = satVolume.getVoxelAt(satUpperX,satLowerY,satLowerZ); - int32_t c = satVolume.getVoxelAt(satLowerX,satUpperY,satLowerZ); - int32_t d = satVolume.getVoxelAt(satUpperX,satUpperY,satLowerZ); - int32_t e = satVolume.getVoxelAt(satLowerX,satLowerY,satUpperZ); - int32_t f = satVolume.getVoxelAt(satUpperX,satLowerY,satUpperZ); - int32_t g = satVolume.getVoxelAt(satLowerX,satUpperY,satUpperZ); - int32_t h = satVolume.getVoxelAt(satUpperX,satUpperY,satUpperZ); + float a = satVolume.getVoxelAt(satLowerX,satLowerY,satLowerZ); + float b = satVolume.getVoxelAt(satUpperX,satLowerY,satLowerZ); + float c = satVolume.getVoxelAt(satLowerX,satUpperY,satLowerZ); + float d = satVolume.getVoxelAt(satUpperX,satUpperY,satLowerZ); + float e = satVolume.getVoxelAt(satLowerX,satLowerY,satUpperZ); + float f = satVolume.getVoxelAt(satUpperX,satLowerY,satUpperZ); + float g = satVolume.getVoxelAt(satLowerX,satUpperY,satUpperZ); + float h = satVolume.getVoxelAt(satUpperX,satUpperY,satUpperZ); - int32_t sum = h+c-d-g-f-a+b+e; + float sum = h+c-d-g-f-a+b+e; - int32_t sideLength = border * 2 + 1; + uint32_t sideLength = border * 2 + 1; - int32_t average = sum / (sideLength*sideLength*sideLength); + float average = sum / (static_cast(sideLength*sideLength*sideLength)); VoxelType voxel = m_pVolSrc->getVoxelAt(iDstX, iDstY, iDstZ); - voxel.setDensity(average); + voxel.setDensity(static_cast(average)); m_pVolDst->setVoxelAt(iDstX, iDstY, iDstZ, voxel); diff --git a/tests/TestLowPassFilter.cpp b/tests/TestLowPassFilter.cpp index f4129253..474e5021 100644 --- a/tests/TestLowPassFilter.cpp +++ b/tests/TestLowPassFilter.cpp @@ -33,7 +33,7 @@ using namespace PolyVox; void TestLowPassFilter::testExecute() { - const int32_t g_uVolumeSideLength = 16; + const int32_t g_uVolumeSideLength = 8; Region reg(Vector3DInt32(0,0,0), Vector3DInt32(g_uVolumeSideLength-1, g_uVolumeSideLength-1, g_uVolumeSideLength-1)); @@ -60,11 +60,27 @@ void TestLowPassFilter::testExecute() LowPassFilter pass1(&volData, reg, &resultVolume, reg, 5); - pass1.executeSAT(); + pass1.execute(); - std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(1,2,3).getDensity()) << std::endl; // 7 - std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(10,6,7).getDensity()) << std::endl; // 17 - std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(15,2,12).getDensity()) << std::endl; // 4 + std::cout << "Input volume:" << std::endl; + std::cout << "Voxel = " << static_cast(volData.getVoxelAt(0,0,0).getDensity()) << std::endl; // 32 + std::cout << "Voxel = " << static_cast(volData.getVoxelAt(1,1,1).getDensity()) << std::endl; // 0 + std::cout << "Voxel = " << static_cast(volData.getVoxelAt(2,2,2).getDensity()) << std::endl; // 3 + std::cout << "Voxel = " << static_cast(volData.getVoxelAt(3,3,3).getDensity()) << std::endl; // 0 + std::cout << "Voxel = " << static_cast(volData.getVoxelAt(4,4,4).getDensity()) << std::endl; // 32 + std::cout << "Voxel = " << static_cast(volData.getVoxelAt(5,5,5).getDensity()) << std::endl; // 0 + std::cout << "Voxel = " << static_cast(volData.getVoxelAt(6,6,6).getDensity()) << std::endl; // 32 + std::cout << "Voxel = " << static_cast(volData.getVoxelAt(7,7,7).getDensity()) << std::endl; // 0 + + std::cout << std::endl << "Output volume:" << std::endl; + std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(0,0,0).getDensity()) << std::endl; // 4 + std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(1,1,1).getDensity()) << std::endl; // 21 + std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(2,2,2).getDensity()) << std::endl; // 10 + std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(3,3,3).getDensity()) << std::endl; // 21 + std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(4,4,4).getDensity()) << std::endl; // 10 + std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(5,5,5).getDensity()) << std::endl; // 21 + std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(6,6,6).getDensity()) << std::endl; // 10 + std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(7,7,7).getDensity()) << std::endl; // 4 } QTEST_MAIN(TestLowPassFilter)