From af5a351b45f7ee1c11949e0584790fa69f0a917e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 26 Jun 2012 15:02:07 +0200 Subject: [PATCH] Added SurfaceExtractionController and modified SurfaceExtractor to use it. --- library/PolyVoxCore/CMakeLists.txt | 1 + .../PolyVoxCore/include/PolyVoxCore/Density.h | 28 +++++-- .../include/PolyVoxCore/Material.h | 19 +++++ .../include/PolyVoxCore/MaterialDensityPair.h | 37 +++++---- .../PolyVoxCore/SurfaceExtractionController.h | 48 +++++++++++ .../include/PolyVoxCore/SurfaceExtractor.h | 15 +--- .../include/PolyVoxCore/SurfaceExtractor.inl | 82 +++++++++---------- library/PolyVoxCore/source/Density.cpp | 6 -- .../source/MaterialDensityPair.cpp | 12 --- 9 files changed, 149 insertions(+), 99 deletions(-) create mode 100644 library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractionController.h diff --git a/library/PolyVoxCore/CMakeLists.txt b/library/PolyVoxCore/CMakeLists.txt index 7439a78c..98433464 100644 --- a/library/PolyVoxCore/CMakeLists.txt +++ b/library/PolyVoxCore/CMakeLists.txt @@ -65,6 +65,7 @@ SET(CORE_INC_FILES include/PolyVoxCore/SimpleVolume.inl include/PolyVoxCore/SimpleVolumeBlock.inl include/PolyVoxCore/SimpleVolumeSampler.inl + include/PolyVoxCore/SurfaceExtractionController.h include/PolyVoxCore/SurfaceExtractor.h include/PolyVoxCore/SurfaceExtractor.inl include/PolyVoxCore/SurfaceMesh.h diff --git a/library/PolyVoxCore/include/PolyVoxCore/Density.h b/library/PolyVoxCore/include/PolyVoxCore/Density.h index a4d784b4..36f8d085 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Density.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Density.h @@ -24,6 +24,7 @@ freely, subject to the following restrictions: #ifndef __PolyVox_Density_H__ #define __PolyVox_Density_H__ +#include "PolyVoxCore/SurfaceExtractionController.h" //We'll specialise the controller contained in here #include "PolyVoxCore/Voxel.h" #include "PolyVoxImpl/TypeDef.h" @@ -102,6 +103,24 @@ namespace PolyVox static Density8::DensityType minDensity() { return std::numeric_limits::min(); } static Density8::DensityType maxDensity() { return std::numeric_limits::max(); } }; + + template + class SurfaceExtractionController< Density > + { + public: + typedef Type DensityType; + typedef float MaterialType; + + DensityType convertToDensity(Density voxel) + { + return voxel.getDensity(); + } + + MaterialType convertToMaterial(Density voxel) + { + return 1; + } + }; } #include "PolyVoxCore/SurfaceExtractor.h" //VERY UGLY THAT WE NEED THIS!!! TO BE CONSIDERED... @@ -110,15 +129,6 @@ namespace PolyVox { template<> VoxelTypeTraits::DensityType convertToDensity(Density8 voxel); - - template<> - class ConvertToDensity - { - public: - typedef uint8_t DensityType; - - DensityType operator()(Density8 voxel); - }; } #endif //__PolyVox_Density_H__ diff --git a/library/PolyVoxCore/include/PolyVoxCore/Material.h b/library/PolyVoxCore/include/PolyVoxCore/Material.h index 407cb540..58226b16 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Material.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Material.h @@ -24,6 +24,7 @@ freely, subject to the following restrictions: #ifndef __PolyVox_Material_H__ #define __PolyVox_Material_H__ +#include "PolyVoxCore/SurfaceExtractionController.h" //We'll specialise the controller contained in here #include "PolyVoxCore/Voxel.h" #include "PolyVoxImpl/TypeDef.h" @@ -116,6 +117,24 @@ namespace PolyVox typedef Material Material8; typedef Material Material16; + template + class SurfaceExtractionController< Material > + { + public: + typedef int32_t DensityType; + typedef float MaterialType; + + DensityType convertToDensity(Material voxel) + { + return voxel.getDensity(); + } + + MaterialType convertToMaterial(Material voxel) + { + return voxel.getMaterial(); + } + }; + template<> class VoxelTypeTraits< Material8 > { diff --git a/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h b/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h index 00a25374..7333e62d 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h +++ b/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h @@ -24,6 +24,7 @@ freely, subject to the following restrictions: #ifndef __PolyVox_MaterialDensityPair_H__ #define __PolyVox_MaterialDensityPair_H__ +#include "PolyVoxCore/SurfaceExtractionController.h" //We'll specialise the controller contained in here #include "PolyVoxCore/Voxel.h" #include "PolyVoxImpl/TypeDef.h" @@ -96,6 +97,24 @@ namespace PolyVox DensityType m_uDensity : NoOfDensityBits; }; + template + class SurfaceExtractionController< MaterialDensityPair > + { + public: + typedef Type DensityType; + typedef Type MaterialType; + + DensityType convertToDensity(MaterialDensityPair voxel) + { + return voxel.getDensity(); + } + + MaterialType convertToMaterial(MaterialDensityPair voxel) + { + return voxel.getMaterial(); + } + }; + typedef MaterialDensityPair MaterialDensityPair44; typedef MaterialDensityPair MaterialDensityPair88; @@ -130,24 +149,6 @@ namespace PolyVox template<> VoxelTypeTraits::DensityType convertToDensity(MaterialDensityPair88 voxel); - template<> - class ConvertToDensity - { - public: - typedef uint32_t DensityType; - - DensityType operator()(MaterialDensityPair44 voxel); - }; - - template<> - class ConvertToDensity - { - public: - typedef uint32_t DensityType; - - DensityType operator()(MaterialDensityPair88 voxel); - }; - template<> class ConvertToMaterial { diff --git a/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractionController.h b/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractionController.h new file mode 100644 index 00000000..de594546 --- /dev/null +++ b/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractionController.h @@ -0,0 +1,48 @@ +/******************************************************************************* +Copyright (c) 2005-2009 David Williams + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*******************************************************************************/ + +#ifndef __PolyVox_SurfaceExtractionController_H__ +#define __PolyVox_SurfaceExtractionController_H__ + +namespace PolyVox +{ + template + class SurfaceExtractionController + { + public: + typedef VoxelType DensityType; + typedef float MaterialType; + + DensityType convertToDensity(VoxelType voxel) + { + return voxel; + } + + MaterialType convertToMaterial(VoxelType voxel) + { + return 1; + } + }; +} + +#endif diff --git a/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.h index d4d84092..3858943b 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.h +++ b/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.h @@ -29,6 +29,7 @@ freely, subject to the following restrictions: #include "PolyVoxCore/Array.h" #include "PolyVoxCore/SurfaceMesh.h" +#include "PolyVoxCore/SurfaceExtractionController.h" namespace PolyVox { @@ -42,17 +43,6 @@ namespace PolyVox static uint8_t maxDensity() { return 255; } }; - template - class ConvertToDensity - { - public: - typedef VoxelType DensityType; - DensityType operator()(VoxelType voxel) - { - return voxel; - } - }; - template class ConvertToMaterial { @@ -240,6 +230,9 @@ namespace PolyVox //Our threshold value typename VoxelTypeTraits::DensityType m_tThreshold; + + //Used to convert arbitrary voxel types in densities and materials. + SurfaceExtractionController m_controller; }; } diff --git a/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.inl b/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.inl index 51ccec58..fabc50c8 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.inl @@ -206,8 +206,6 @@ namespace PolyVox typename VolumeType::VoxelType v011; typename VolumeType::VoxelType v111; - ConvertToDensity DensityConverter; - if(isPrevZAvail) { if(isPrevYAvail) @@ -232,7 +230,7 @@ namespace PolyVox iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY | iPreviousCubeIndexZ; - if (DensityConverter(v111) < m_tThreshold) iCubeIndex |= 128; + if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } else //previous X not available { @@ -250,8 +248,8 @@ namespace PolyVox iCubeIndex = iPreviousCubeIndexY | iPreviousCubeIndexZ; - if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; - if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; + if (m_controller.convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; + if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } } else //previous Y not available @@ -272,8 +270,8 @@ namespace PolyVox iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexZ; - if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; - if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; + if (m_controller.convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; + if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } else //previous X not available { @@ -286,10 +284,10 @@ namespace PolyVox uint8_t iPreviousCubeIndexZ = pPreviousBitmask[uXRegSpace][uYRegSpace]; iCubeIndex = iPreviousCubeIndexZ >> 4; - if (convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16; - if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; - if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; - if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; + if (m_controller.convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16; + if (m_controller.convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; + if (m_controller.convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; + if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } } } @@ -314,8 +312,8 @@ namespace PolyVox iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY; - if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; - if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; + if (m_controller.convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; + if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } else //previous X not available { @@ -332,10 +330,10 @@ namespace PolyVox iCubeIndex = iPreviousCubeIndexY; - if (convertToDensity(v010) < m_tThreshold) iCubeIndex |= 4; - if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; - if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; - if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; + if (m_controller.convertToDensity(v010) < m_tThreshold) iCubeIndex |= 4; + if (m_controller.convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; + if (m_controller.convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; + if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } } else //previous Y not available @@ -355,10 +353,10 @@ namespace PolyVox iCubeIndex = iPreviousCubeIndexX; - if (convertToDensity(v100) < m_tThreshold) iCubeIndex |= 2; - if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; - if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; - if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; + if (m_controller.convertToDensity(v100) < m_tThreshold) iCubeIndex |= 2; + if (m_controller.convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; + if (m_controller.convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; + if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } else //previous X not available { @@ -372,14 +370,14 @@ namespace PolyVox v011 = m_sampVolume.peekVoxel0px1py1pz(); v111 = m_sampVolume.peekVoxel1px1py1pz(); - if (convertToDensity(v000) < m_tThreshold) iCubeIndex |= 1; - if (convertToDensity(v100) < m_tThreshold) iCubeIndex |= 2; - if (convertToDensity(v010) < m_tThreshold) iCubeIndex |= 4; - if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; - if (convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16; - if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; - if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; - if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; + if (m_controller.convertToDensity(v000) < m_tThreshold) iCubeIndex |= 1; + if (m_controller.convertToDensity(v100) < m_tThreshold) iCubeIndex |= 2; + if (m_controller.convertToDensity(v010) < m_tThreshold) iCubeIndex |= 4; + if (m_controller.convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; + if (m_controller.convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16; + if (m_controller.convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; + if (m_controller.convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; + if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } } } @@ -399,8 +397,6 @@ namespace PolyVox Array2DInt32& m_pCurrentVertexIndicesY, Array2DInt32& m_pCurrentVertexIndicesZ) { - ConvertToMaterial converter; - int32_t iZVolSpace = m_regSliceCurrent.getLowerCorner().getZ(); const uint32_t uZRegSpace = iZVolSpace - m_regSizeInVoxels.getLowerCorner().getZ(); @@ -437,7 +433,7 @@ namespace PolyVox const typename VolumeType::VoxelType v100 = m_sampVolume.getVoxel(); const Vector3DFloat n100 = computeCentralDifferenceGradient(m_sampVolume); - float fInterp = static_cast(m_tThreshold - convertToDensity(v000)) / static_cast(convertToDensity(v100) - convertToDensity(v000)); + float fInterp = static_cast(m_tThreshold - m_controller.convertToDensity(v000)) / static_cast(m_controller.convertToDensity(v100) - m_controller.convertToDensity(v000)); const Vector3DFloat v3dPosition(static_cast(iXVolSpace - m_regSizeInVoxels.getLowerCorner().getX()) + fInterp, static_cast(iYVolSpace - m_regSizeInVoxels.getLowerCorner().getY()), static_cast(iZVolSpace - m_regSizeInCells.getLowerCorner().getZ())); @@ -447,9 +443,9 @@ namespace PolyVox //Choose one of the two materials to use for the vertex (we don't interpolate as interpolation of //material IDs does not make sense). We take the largest, so that if we are working on a material-only //volume we get the one which is non-zero. Both materials can be non-zero if our volume has a density component. - typename ConvertToMaterial::MaterialType uMaterial000 = converter(v000); - typename ConvertToMaterial::MaterialType uMaterial100 = converter(v100); - typename ConvertToMaterial::MaterialType uMaterial = (std::max)(uMaterial000, uMaterial100); + typename SurfaceExtractionController::MaterialType uMaterial000 = m_controller.convertToMaterial(v000); + typename SurfaceExtractionController::MaterialType uMaterial100 = m_controller.convertToMaterial(v100); + typename SurfaceExtractionController::MaterialType uMaterial = (std::max)(uMaterial000, uMaterial100); PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast(uMaterial)); uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); @@ -463,7 +459,7 @@ namespace PolyVox const typename VolumeType::VoxelType v010 = m_sampVolume.getVoxel(); const Vector3DFloat n010 = computeCentralDifferenceGradient(m_sampVolume); - float fInterp = static_cast(m_tThreshold - convertToDensity(v000)) / static_cast(convertToDensity(v010) - convertToDensity(v000)); + float fInterp = static_cast(m_tThreshold - m_controller.convertToDensity(v000)) / static_cast(m_controller.convertToDensity(v010) - m_controller.convertToDensity(v000)); const Vector3DFloat v3dPosition(static_cast(iXVolSpace - m_regSizeInVoxels.getLowerCorner().getX()), static_cast(iYVolSpace - m_regSizeInVoxels.getLowerCorner().getY()) + fInterp, static_cast(iZVolSpace - m_regSizeInVoxels.getLowerCorner().getZ())); @@ -473,9 +469,9 @@ namespace PolyVox //Choose one of the two materials to use for the vertex (we don't interpolate as interpolation of //material IDs does not make sense). We take the largest, so that if we are working on a material-only //volume we get the one which is non-zero. Both materials can be non-zero if our volume has a density component. - typename ConvertToMaterial::MaterialType uMaterial000 = converter(v000); - typename ConvertToMaterial::MaterialType uMaterial010 = converter(v010); - uint32_t uMaterial = (std::max)(uMaterial000, uMaterial010); + typename SurfaceExtractionController::MaterialType uMaterial000 = m_controller.convertToMaterial(v000); + typename SurfaceExtractionController::MaterialType uMaterial010 = m_controller.convertToMaterial(v010); + typename SurfaceExtractionController::MaterialType uMaterial = (std::max)(uMaterial000, uMaterial010); PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast(uMaterial)); uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); @@ -489,7 +485,7 @@ namespace PolyVox const typename VolumeType::VoxelType v001 = m_sampVolume.getVoxel(); const Vector3DFloat n001 = computeCentralDifferenceGradient(m_sampVolume); - float fInterp = static_cast(m_tThreshold - convertToDensity(v000)) / static_cast(convertToDensity(v001) - convertToDensity(v000)); + float fInterp = static_cast(m_tThreshold - m_controller.convertToDensity(v000)) / static_cast(m_controller.convertToDensity(v001) - m_controller.convertToDensity(v000)); const Vector3DFloat v3dPosition(static_cast(iXVolSpace - m_regSizeInVoxels.getLowerCorner().getX()), static_cast(iYVolSpace - m_regSizeInVoxels.getLowerCorner().getY()), static_cast(iZVolSpace - m_regSizeInVoxels.getLowerCorner().getZ()) + fInterp); @@ -499,9 +495,9 @@ namespace PolyVox //Choose one of the two materials to use for the vertex (we don't interpolate as interpolation of //material IDs does not make sense). We take the largest, so that if we are working on a material-only //volume we get the one which is non-zero. Both materials can be non-zero if our volume has a density component. - typename ConvertToMaterial::MaterialType uMaterial000 = converter(v000); - typename ConvertToMaterial::MaterialType uMaterial001 = converter(v001); - uint32_t uMaterial = (std::max)(uMaterial000, uMaterial001); + typename SurfaceExtractionController::MaterialType uMaterial000 = m_controller.convertToMaterial(v000); + typename SurfaceExtractionController::MaterialType uMaterial001 = m_controller.convertToMaterial(v001); + typename SurfaceExtractionController::MaterialType uMaterial = (std::max)(uMaterial000, uMaterial001); PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast(uMaterial)); uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); diff --git a/library/PolyVoxCore/source/Density.cpp b/library/PolyVoxCore/source/Density.cpp index 81a124bb..0a3748c2 100644 --- a/library/PolyVoxCore/source/Density.cpp +++ b/library/PolyVoxCore/source/Density.cpp @@ -30,10 +30,4 @@ namespace PolyVox { return voxel.getDensity(); } - - //template<> - ConvertToDensity::DensityType ConvertToDensity::operator()(Density8 voxel) - { - return voxel.getDensity(); - } } diff --git a/library/PolyVoxCore/source/MaterialDensityPair.cpp b/library/PolyVoxCore/source/MaterialDensityPair.cpp index 50d5d271..f6d2c916 100644 --- a/library/PolyVoxCore/source/MaterialDensityPair.cpp +++ b/library/PolyVoxCore/source/MaterialDensityPair.cpp @@ -37,18 +37,6 @@ namespace PolyVox return voxel.getDensity(); } - //template<> - ConvertToDensity::DensityType ConvertToDensity::operator()(MaterialDensityPair44 voxel) - { - return voxel.getDensity(); - } - - //template<> - ConvertToDensity::DensityType ConvertToDensity::operator()(MaterialDensityPair88 voxel) - { - return voxel.getDensity(); - } - //template<> ConvertToMaterial::MaterialType ConvertToMaterial::operator()(MaterialDensityPair44 voxel) {