Replaced constants with functions for type traits.
This commit is contained in:
		| @@ -37,18 +37,18 @@ namespace PolyVox | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		if(VoxelTypeTraits<VoxelType>::HasDensity) | ||||
| 		if(VoxelTypeTraits<VoxelType>::hasDensity()) | ||||
| 		{ | ||||
| 			//and if their density is above the threshold. | ||||
| 			VoxelType voxel = volData->getVoxelAt(v3dPos); | ||||
| 			VoxelType::DensityType tThreshold = (VoxelTypeTraits<VoxelType>::MinDensity + VoxelTypeTraits<VoxelType>::MaxDensity) / 2; | ||||
| 			VoxelType::DensityType tThreshold = (VoxelTypeTraits<VoxelType>::minDensity() + VoxelTypeTraits<VoxelType>::maxDensity()) / 2; | ||||
| 			if(voxel.getDensity() >= tThreshold) | ||||
| 			{ | ||||
| 				return false; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if(VoxelTypeTraits<VoxelType>::HasMaterial) | ||||
| 		if(VoxelTypeTraits<VoxelType>::hasMaterial()) | ||||
| 		{ | ||||
| 			//and if their material is not zero. | ||||
| 			VoxelType voxel = volData->getVoxelAt(v3dPos); | ||||
|   | ||||
| @@ -31,6 +31,9 @@ freely, subject to the following restrictions: | ||||
| #include <cassert> | ||||
| #include <limits> | ||||
|  | ||||
| #undef min | ||||
| #undef max | ||||
|  | ||||
| namespace PolyVox | ||||
| { | ||||
| 	///This class represents a voxel storing only a density. | ||||
| @@ -45,8 +48,11 @@ namespace PolyVox | ||||
| 	/// | ||||
| 	/// \sa Material, MaterialDensityPair | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| 	// int32_t template parameter is a dummy, required as the compiler expects to be able to declare an | ||||
| 	// instance of VoxelType::MaterialType without knowing that VoxelType doesn't actually have a material. | ||||
| 	template <typename Type> | ||||
| 	class Density : public Voxel<Type, uint8_t> | ||||
| 	class Density : public Voxel<Type, int32_t> | ||||
| 	{ | ||||
| 	public: | ||||
| 		//We expose DensityType and MaterialType in this way so that, when code is | ||||
| @@ -54,7 +60,7 @@ namespace PolyVox | ||||
| 		//using code such as 'VoxelType::DensityType value = voxel.getDensity()' | ||||
| 		//or 'VoxelType::MaterialType value = voxel.getMaterial()'. | ||||
| 		typedef Type DensityType; | ||||
| 		typedef uint8_t MaterialType; //Shouldn't define this one... | ||||
| 		typedef int32_t MaterialType; //Shouldn't define this one... | ||||
|  | ||||
| 		Density() : m_uDensity(0) {} | ||||
| 		Density(DensityType uDensity) : m_uDensity(uDensity) {} | ||||
| @@ -75,8 +81,8 @@ namespace PolyVox | ||||
| 		void setDensity(DensityType uDensity) { m_uDensity = uDensity; } | ||||
| 		//void setMaterial(MaterialType /*uMaterial*/) { assert(false); } //Cannot set material on voxel of type Density | ||||
|  | ||||
| 		//static DensityType getMaxDensity() throw() { return (std::numeric_limits<DensityType>::max)(); }  | ||||
| 		//static DensityType getMinDensity() throw() { return (std::numeric_limits<DensityType>::min)(); } | ||||
| 		//static DensityType getmaxDensity()() throw() { return (std::numeric_limits<DensityType>::max)(); }  | ||||
| 		//static DensityType getminDensity()() throw() { return (std::numeric_limits<DensityType>::min)(); } | ||||
| 		static DensityType getThreshold() throw() { return (std::numeric_limits<DensityType>::max)() / 2; } | ||||
|  | ||||
| 	private: | ||||
| @@ -103,60 +109,60 @@ namespace PolyVox | ||||
| 	class VoxelTypeTraits< DensityI8 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static bool HasDensity; | ||||
| 		const static bool HasMaterial; | ||||
| 		const static DensityI8::DensityType MinDensity; | ||||
| 		const static DensityI8::DensityType MaxDensity; | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
| 		static DensityI8::DensityType minDensity() { return -std::numeric_limits<DensityI8::DensityType>::max(); } | ||||
| 		static DensityI8::DensityType maxDensity() { return std::numeric_limits<DensityI8::DensityType>::max(); } | ||||
| 	}; | ||||
| 	 | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< DensityU8 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static bool HasDensity; | ||||
| 		const static bool HasMaterial; | ||||
| 		const static DensityU8::DensityType MinDensity; | ||||
| 		const static DensityU8::DensityType MaxDensity; | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
| 		static DensityU8::DensityType minDensity() { return std::numeric_limits<DensityU8::DensityType>::min(); } | ||||
| 		static DensityU8::DensityType maxDensity() { return std::numeric_limits<DensityU8::DensityType>::max(); } | ||||
| 	}; | ||||
| 	 | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< DensityI16 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static bool HasDensity; | ||||
| 		const static bool HasMaterial; | ||||
| 		const static DensityI16::DensityType MinDensity; | ||||
| 		const static DensityI16::DensityType MaxDensity; | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
| 		static DensityI16::DensityType minDensity() { return -std::numeric_limits<DensityI16::DensityType>::max(); } | ||||
| 		static DensityI16::DensityType maxDensity() { return std::numeric_limits<DensityI16::DensityType>::max(); } | ||||
| 	}; | ||||
| 	 | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< DensityU16 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static bool HasDensity; | ||||
| 		const static bool HasMaterial; | ||||
| 		const static DensityU16::DensityType MinDensity; | ||||
| 		const static DensityU16::DensityType MaxDensity; | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
| 		static DensityU16::DensityType minDensity() { return std::numeric_limits<DensityU16::DensityType>::min(); } | ||||
| 		static DensityU16::DensityType maxDensity() { return std::numeric_limits<DensityU16::DensityType>::max(); } | ||||
| 	}; | ||||
| 	 | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< DensityFloat > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static bool HasDensity; | ||||
| 		const static bool HasMaterial; | ||||
| 		const static DensityFloat::DensityType MinDensity; | ||||
| 		const static DensityFloat::DensityType MaxDensity; | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
| 		static DensityFloat::DensityType minDensity() { return -std::numeric_limits<DensityFloat::DensityType>::max(); } | ||||
| 		static DensityFloat::DensityType maxDensity() { return std::numeric_limits<DensityFloat::DensityType>::max(); } | ||||
| 	}; | ||||
| 	 | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< DensityDouble > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static bool HasDensity; | ||||
| 		const static bool HasMaterial; | ||||
| 		const static DensityDouble::DensityType MinDensity; | ||||
| 		const static DensityDouble::DensityType MaxDensity; | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
| 		static DensityDouble::DensityType minDensity() { return -std::numeric_limits<DensityDouble::DensityType>::max(); } | ||||
| 		static DensityDouble::DensityType maxDensity() { return std::numeric_limits<DensityDouble::DensityType>::max(); } | ||||
| 	}; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -45,15 +45,18 @@ namespace PolyVox | ||||
| 	/// | ||||
| 	/// \sa Density, MaterialDensityPair | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| 	// int32_t template parameter is a dummy, required as the compiler expects to be able to declare an | ||||
| 	// instance of VoxelType::DensityType without knowing that VoxelType doesn't actually have a density. | ||||
| 	template <typename Type> | ||||
| 	class Material : public Voxel<uint8_t, Type> | ||||
| 	class Material : public Voxel<int32_t, Type>  | ||||
| 	{ | ||||
| 	public: | ||||
| 		//We expose DensityType and MaterialType in this way so that, when code is | ||||
| 		//templatised on voxel type, it can determine the underlying storage type | ||||
| 		//using code such as 'VoxelType::DensityType value = voxel.getDensity()' | ||||
| 		//or 'VoxelType::MaterialType value = voxel.getMaterial()'. | ||||
| 		typedef uint8_t DensityType; //Shouldn't define this one... | ||||
| 		typedef int32_t DensityType; | ||||
| 		typedef Type MaterialType; | ||||
|  | ||||
| 		Material() : m_uMaterial(0) {} | ||||
| @@ -74,12 +77,12 @@ namespace PolyVox | ||||
| 			//We don't actually have a density, so make one up based on the material. | ||||
| 			if(m_uMaterial == 0) | ||||
| 			{ | ||||
| 				//return getMinDensity(); | ||||
| 				//return getminDensity()(); | ||||
| 				return 0; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				//return getMaxDensity(); | ||||
| 				//return getmaxDensity()(); | ||||
| 				return 2; | ||||
| 			} | ||||
| 		} | ||||
| @@ -89,8 +92,8 @@ namespace PolyVox | ||||
| 		void setDensity(DensityType /*uDensity*/) { assert(false); } //Cannot set density on voxel of type Material | ||||
| 		void setMaterial(MaterialType uMaterial) { m_uMaterial = uMaterial; } | ||||
|  | ||||
| 		//static DensityType getMaxDensity() throw() { return 2; } | ||||
| 		//static DensityType getMinDensity() throw() { return 0; } | ||||
| 		//static DensityType getmaxDensity()() throw() { return 2; } | ||||
| 		//static DensityType getminDensity()() throw() { return 0; } | ||||
| 		static DensityType getThreshold() throw() { return 1; } | ||||
|  | ||||
| 	private: | ||||
| @@ -111,30 +114,30 @@ namespace PolyVox | ||||
| 	class VoxelTypeTraits< MaterialU8 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static bool HasDensity; | ||||
| 		const static bool HasMaterial; | ||||
| 		const static MaterialU8::DensityType MinDensity; | ||||
| 		const static MaterialU8::DensityType MaxDensity; | ||||
| 		static bool hasDensity() { return false; } | ||||
| 		static bool hasMaterial() { return true; } | ||||
| 		static int minDensity() { assert(false); return 0; } | ||||
| 		static int maxDensity() { assert(false); return 0; } | ||||
| 	}; | ||||
|  | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< MaterialU16 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static bool HasDensity; | ||||
| 		const static bool HasMaterial; | ||||
| 		const static MaterialU16::DensityType MinDensity; | ||||
| 		const static MaterialU16::DensityType MaxDensity; | ||||
| 		static bool hasDensity() { return false; } | ||||
| 		static bool hasMaterial() { return true; } | ||||
| 		static int minDensity() { assert(false); return 0; } | ||||
| 		static int maxDensity() { assert(false); return 0; } | ||||
| 	}; | ||||
|  | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< MaterialU32 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static bool HasDensity; | ||||
| 		const static bool HasMaterial; | ||||
| 		const static MaterialU32::DensityType MinDensity; | ||||
| 		const static MaterialU32::DensityType MaxDensity; | ||||
| 		static bool hasDensity() { return false; } | ||||
| 		static bool hasMaterial() { return true; } | ||||
| 		static int minDensity() { assert(false); return 0; } | ||||
| 		static int maxDensity() { assert(false); return 0; } | ||||
| 	}; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -74,8 +74,8 @@ namespace PolyVox | ||||
| 		void setDensity(DensityType uDensity) { m_uDensity = uDensity; } | ||||
| 		void setMaterial(MaterialType uMaterial) { m_uMaterial = uMaterial; } | ||||
|  | ||||
| 		//static DensityType getMaxDensity() throw() { return (0x01 << NoOfDensityBits) - 1; } | ||||
| 		//static DensityType getMinDensity() throw() { return 0; } | ||||
| 		//static DensityType getmaxDensity()() throw() { return (0x01 << NoOfDensityBits) - 1; } | ||||
| 		//static DensityType getminDensity()() throw() { return 0; } | ||||
| 		static DensityType getThreshold() throw() {return  0x01 << (NoOfDensityBits - 1);} | ||||
|  | ||||
| 	private: | ||||
| @@ -90,20 +90,20 @@ namespace PolyVox | ||||
| 	class VoxelTypeTraits< MaterialDensityPair44 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static bool HasDensity; | ||||
| 		const static bool HasMaterial; | ||||
| 		const static MaterialDensityPair44::DensityType MinDensity; | ||||
| 		const static MaterialDensityPair44::DensityType MaxDensity; | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return true; } | ||||
| 		static MaterialDensityPair44::DensityType minDensity() { return 0; } | ||||
| 		static MaterialDensityPair44::DensityType maxDensity() { return 15; } | ||||
| 	}; | ||||
| 	 | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< MaterialDensityPair88 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static bool HasDensity; | ||||
| 		const static bool HasMaterial; | ||||
| 		const static MaterialDensityPair88::DensityType MinDensity; | ||||
| 		const static MaterialDensityPair88::DensityType MaxDensity; | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return true; } | ||||
| 		static MaterialDensityPair88::DensityType minDensity() { return 0; } | ||||
| 		static MaterialDensityPair88::DensityType maxDensity() { return 255; } | ||||
| 	}; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -36,7 +36,7 @@ namespace PolyVox | ||||
| 	class SurfaceExtractor | ||||
| 	{ | ||||
| 	public: | ||||
| 		SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result, typename VoxelType::DensityType tThreshold = (VoxelTypeTraits<VoxelType>::MinDensity + VoxelTypeTraits<VoxelType>::MaxDensity) / 2); | ||||
| 		SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result, typename VoxelType::DensityType tThreshold = (VoxelTypeTraits<VoxelType>::minDensity() + VoxelTypeTraits<VoxelType>::maxDensity()) / 2); | ||||
|  | ||||
| 		void execute(); | ||||
|  | ||||
|   | ||||
| @@ -433,7 +433,7 @@ namespace PolyVox | ||||
| 					const VoxelType v100 = m_sampVolume.getVoxel(); | ||||
| 					const Vector3DFloat n100 = computeCentralDifferenceGradient(m_sampVolume); | ||||
|  | ||||
| 					//float fInterp = static_cast<float>(v100.getDensity() - VoxelType::getMinDensity()) / static_cast<float>(VoxelType::getMaxDensity() - VoxelType::getMinDensity()); | ||||
| 					//float fInterp = static_cast<float>(v100.getDensity() - VoxelType::getminDensity()()) / static_cast<float>(VoxelType::getmaxDensity()() - VoxelType::getminDensity()()); | ||||
| 					float fInterp = static_cast<float>(m_tThreshold - v000.getDensity()) / static_cast<float>(v100.getDensity() - v000.getDensity()); | ||||
| 					//fInterp = 0.5f; | ||||
|  | ||||
| @@ -447,7 +447,7 @@ namespace PolyVox | ||||
| 					//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. | ||||
| 					uint32_t uMaterial = 0; | ||||
| 					if(VoxelTypeTraits<VoxelType>::HasMaterial) | ||||
| 					if(VoxelTypeTraits<VoxelType>::hasMaterial()) | ||||
| 					{ | ||||
| 						uMaterial = (std::max)(v000.getMaterial(), v100.getMaterial()); | ||||
| 					} | ||||
| @@ -477,7 +477,7 @@ namespace PolyVox | ||||
| 					//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. | ||||
| 					uint32_t uMaterial = 0; | ||||
| 					if(VoxelTypeTraits<VoxelType>::HasMaterial) | ||||
| 					if(VoxelTypeTraits<VoxelType>::hasMaterial()) | ||||
| 					{ | ||||
| 						uMaterial = (std::max)(v000.getMaterial(), v010.getMaterial()); | ||||
| 					} | ||||
| @@ -507,7 +507,7 @@ namespace PolyVox | ||||
| 					//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. | ||||
| 					uint32_t uMaterial = 0; | ||||
| 					if(VoxelTypeTraits<VoxelType>::HasMaterial) | ||||
| 					if(VoxelTypeTraits<VoxelType>::hasMaterial()) | ||||
| 					{ | ||||
| 						uMaterial = (std::max)(v000.getMaterial(), v001.getMaterial()); | ||||
| 					} | ||||
|   | ||||
| @@ -56,7 +56,7 @@ namespace PolyVox | ||||
| 	// Various properties of the voxel types can be expressed via types traits, similar to the way std::numeric_limits is implemented. | ||||
| 	// This has some advantages compared to storing the properties directly in the voxel class. For example, by using traits it is possible | ||||
| 	// to also apply these properties to primative types which might be desirable (the Volume classes do accept primative types as template | ||||
| 	// parameters). Also, properties such as MinDensity and MaxDensity would be difficult to represent though class members because they | ||||
| 	// parameters). Also, properties such as minDensity() and maxDensity() would be difficult to represent though class members because they | ||||
| 	// depend ont the type (float has a very different range from int8_t for example). | ||||
| 	// | ||||
| 	// The properties are currently exposed as constants because we need access to them at compile time. Ideally we would like to make them | ||||
| @@ -68,10 +68,15 @@ namespace PolyVox | ||||
| 	class VoxelTypeTraits | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static bool HasDensity; | ||||
| 		const static bool HasMaterial; | ||||
| 		const static typename Type::DensityType MinDensity; | ||||
| 		const static typename Type::DensityType MaxDensity; | ||||
| 		static bool hasDensity() { return false; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
|  | ||||
| 		// These default implementations return an int32_t rather than void so that the result can be | ||||
| 		// assigned to a variable for all voxel types (even those without density coponents). Calls | ||||
| 		// to these functions should be protected by calls to hasDensity(), but the compiler still | ||||
| 		// needs to ensure the assignment is compilable even if hasDensity() returns false. | ||||
| 		static int32_t minDensity() { assert(false); return 0; }  | ||||
| 		static int32_t maxDensity() { assert(false); return 0; } | ||||
| 	}; | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user