Merge branch 'develop' of git@gitorious.org:polyvox/polyvox.git
This commit is contained in:
		| @@ -36,7 +36,8 @@ if(SPHINXBUILD_EXECUTABLE) | ||||
| 		COMMENT "Building PolyVox manual" | ||||
| 	) | ||||
| 	add_dependencies(manual doc) | ||||
| 	SET_PROPERTY(TARGET manual PROPERTY FOLDER "documentation") | ||||
| 	set_target_properties(manual PROPERTIES PROJECT_LABEL "Manual") #Set label seen in IDE | ||||
| 	SET_PROPERTY(TARGET manual PROPERTY FOLDER "Documentation") | ||||
| else() | ||||
| 	if(NOT SPHINXBUILD_EXECUTABLE) | ||||
| 		message(STATUS "`sphinx-build` was not found. Try setting SPHINXBUILD_EXECUTABLE to its location.") | ||||
|   | ||||
| @@ -59,7 +59,7 @@ IF(MSVC) | ||||
| 	SET_TARGET_PROPERTIES(BasicExample PROPERTIES COMPILE_FLAGS "/W4 /wd4127") | ||||
| ENDIF(MSVC) | ||||
| TARGET_LINK_LIBRARIES(BasicExample ${QT_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} PolyVoxCore) | ||||
| SET_PROPERTY(TARGET BasicExample PROPERTY FOLDER "examples/Basic") | ||||
| SET_PROPERTY(TARGET BasicExample PROPERTY FOLDER "Examples") | ||||
|  | ||||
| #Install - Only install the example in Windows | ||||
| IF(WIN32) | ||||
|   | ||||
| @@ -65,7 +65,7 @@ IF(MSVC) | ||||
| 	SET_TARGET_PROPERTIES(OpenGLExample PROPERTIES COMPILE_FLAGS "/W4 /wd4127") | ||||
| ENDIF(MSVC) | ||||
| TARGET_LINK_LIBRARIES(OpenGLExample ${QT_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} PolyVoxCore) | ||||
| SET_PROPERTY(TARGET OpenGLExample PROPERTY FOLDER "examples/OpenGL") | ||||
| SET_PROPERTY(TARGET OpenGLExample PROPERTY FOLDER "Examples") | ||||
|  | ||||
| #Install - Only install the example in Windows | ||||
| IF(WIN32) | ||||
|   | ||||
| @@ -101,12 +101,14 @@ int main(int argc, char *argv[]) | ||||
| 	createCubeInVolume(volData, Vector3DInt32(midPos-10, 1, midPos-10), Vector3DInt32(midPos+10, maxPos-1, midPos+10), MaterialDensityPair44::getMaxDensity()); | ||||
| 	createCubeInVolume(volData, Vector3DInt32(midPos-10, midPos-10 ,1), Vector3DInt32(midPos+10, midPos+10, maxPos-1), MaterialDensityPair44::getMaxDensity()); | ||||
|  | ||||
| 	//Smooth part of the volume | ||||
| 	RawVolume<MaterialDensityPair44> tempVolume(PolyVox::Region(0,0,0,128, 128, 128)); | ||||
| 	LowPassFilter< LargeVolume<MaterialDensityPair44>, RawVolume<MaterialDensityPair44> > pass1(&volData, PolyVox::Region(Vector3DInt32(62, 62, 62), Vector3DInt32(126, 126, 126)), &tempVolume, PolyVox::Region(Vector3DInt32(62, 62, 62), Vector3DInt32(126, 126, 126)), 3); | ||||
| 	pass1.executeSAT(); | ||||
| 	LowPassFilter< RawVolume<MaterialDensityPair44>, LargeVolume<MaterialDensityPair44> > pass2(&tempVolume, PolyVox::Region(Vector3DInt32(62, 62, 62), Vector3DInt32(126, 126, 126)), &volData, PolyVox::Region(Vector3DInt32(62, 62, 62), Vector3DInt32(126, 126, 126)), 3); | ||||
| 	pass2.executeSAT(); | ||||
| 	//I've removed this smoothing because it doesn't really make sense to apply a low pass filter to a volume with material values.  | ||||
| 	//I could implement the mathematical operators for MaterialDensityPair in such a way that they ignores the materials but this  | ||||
| 	//seems to be setting a bad example. Users can add this operators in their own classes if they want smoothing. | ||||
| 	//RawVolume<MaterialDensityPair44> tempVolume(PolyVox::Region(0,0,0,128, 128, 128)); | ||||
| 	//LowPassFilter< LargeVolume<MaterialDensityPair44>, RawVolume<MaterialDensityPair44> > pass1(&volData, PolyVox::Region(Vector3DInt32(62, 62, 62), Vector3DInt32(126, 126, 126)), &tempVolume, PolyVox::Region(Vector3DInt32(62, 62, 62), Vector3DInt32(126, 126, 126)), 3); | ||||
| 	//pass1.executeSAT(); | ||||
| 	//LowPassFilter< RawVolume<MaterialDensityPair44>, LargeVolume<MaterialDensityPair44> > pass2(&tempVolume, PolyVox::Region(Vector3DInt32(62, 62, 62), Vector3DInt32(126, 126, 126)), &volData, PolyVox::Region(Vector3DInt32(62, 62, 62), Vector3DInt32(126, 126, 126)), 3); | ||||
| 	//pass2.executeSAT(); | ||||
|  | ||||
| 	QApplication app(argc, argv); | ||||
|  | ||||
|   | ||||
| @@ -61,7 +61,7 @@ IF(MSVC) | ||||
| 	SET_TARGET_PROPERTIES(PagingExample PROPERTIES COMPILE_FLAGS "/W4 /wd4127") | ||||
| ENDIF(MSVC) | ||||
| TARGET_LINK_LIBRARIES(PagingExample ${QT_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} PolyVoxCore) | ||||
| SET_PROPERTY(TARGET PagingExample PROPERTY FOLDER "examples/Paging") | ||||
| SET_PROPERTY(TARGET PagingExample PROPERTY FOLDER "Examples") | ||||
|  | ||||
| #Install - Only install the example in Windows | ||||
| IF(WIN32) | ||||
|   | ||||
| @@ -59,7 +59,7 @@ IF(MSVC) | ||||
| 	SET_TARGET_PROPERTIES(SmoothLODExample PROPERTIES COMPILE_FLAGS "/W4 /wd4127") #All warnings | ||||
| ENDIF(MSVC) | ||||
| TARGET_LINK_LIBRARIES(SmoothLODExample ${QT_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} PolyVoxCore) | ||||
| SET_PROPERTY(TARGET SmoothLODExample PROPERTY FOLDER "examples/SmoothLOD") | ||||
| SET_PROPERTY(TARGET SmoothLODExample PROPERTY FOLDER "Examples") | ||||
|  | ||||
| #Install - Only install the example in Windows | ||||
| IF(WIN32) | ||||
|   | ||||
| @@ -59,8 +59,8 @@ if(DOXYGEN_FOUND) | ||||
| 		SOURCES Doxyfile.in polyvox.qhcp.in Mainpage.dox | ||||
| 		VERBATIM | ||||
| 	) | ||||
| 	set_target_properties(doc PROPERTIES PROJECT_LABEL "Documentation") #Set label seen in IDE | ||||
| 	set_property(TARGET doc PROPERTY FOLDER "library/doc") | ||||
| 	set_target_properties(doc PROPERTIES PROJECT_LABEL "API Reference") #Set label seen in IDE | ||||
| 	set_property(TARGET doc PROPERTY FOLDER "Documentation") | ||||
| 	 | ||||
| 	#If we found qcollectiongenerator then do more processing | ||||
| 	if(QT_QCOLLECTIONGENERATOR_EXECUTABLE) | ||||
|   | ||||
| @@ -144,7 +144,7 @@ IF(LIBRARY_TYPE STREQUAL "DYNAMIC") | ||||
| 	ADD_LIBRARY(PolyVoxCore SHARED ${CORE_SRC_FILES} ${CORE_INC_FILES} ${IMPL_SRC_FILES} ${IMPL_INC_FILES}) | ||||
| 	SET_TARGET_PROPERTIES(PolyVoxCore PROPERTIES COMPILE_FLAGS "-DPOLYVOX_SHARED_EXPORTS") | ||||
| ENDIF() | ||||
| SET_PROPERTY(TARGET PolyVoxCore PROPERTY FOLDER "library/PolyVoxCore") | ||||
| SET_PROPERTY(TARGET PolyVoxCore PROPERTY FOLDER "Library") | ||||
|  | ||||
| SET_TARGET_PROPERTIES(PolyVoxCore PROPERTIES VERSION ${POLYVOX_VERSION} SOVERSION ${POLYVOX_VERSION_MAJOR}) | ||||
| IF(MSVC) | ||||
|   | ||||
| @@ -36,17 +36,9 @@ freely, subject to the following restrictions: | ||||
|  | ||||
| namespace PolyVox | ||||
| { | ||||
| 	///This class represents a voxel storing only a density. | ||||
| 	/// This class represents a voxel storing only a density. | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	/// In order to perform a surface extraction on a LargeVolume, PolyVox needs the underlying | ||||
| 	/// voxel type to provide both getDensity() and getMaterial() functions. The getDensity() | ||||
| 	/// function is used to determine if a voxel is 'solid', and if it is then the getMaterial() | ||||
| 	/// funtion is used to determine what material should be assigned to the resulting mesh. | ||||
| 	/// | ||||
| 	/// This class meets these requirements, although it only actually stores a density value. | ||||
| 	/// For the getMaterial() function it just returns a constant value of '1'. | ||||
| 	/// | ||||
| 	/// \sa Material, MaterialDensityPair | ||||
| 	/// Detailed description... | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| 	// int32_t template parameter is a dummy, required as the compiler expects to be able to declare an | ||||
| @@ -55,15 +47,18 @@ namespace PolyVox | ||||
| 	class Density | ||||
| 	{ | ||||
| 	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 Type DensityType; | ||||
| 		typedef int32_t MaterialType; //Shouldn't define this one... | ||||
|  | ||||
| 		/// Constructor | ||||
| 		Density() : m_uDensity(0) {} | ||||
| 		Density(DensityType uDensity) : m_uDensity(uDensity) {} | ||||
|  | ||||
| 		/// Copy constructor | ||||
| 		Density(Type uDensity) : m_uDensity(uDensity) {} | ||||
|  | ||||
| 		// The LowPassFilter uses this to convert between normal and accumulated types. | ||||
| 		/// Copy constructor with cast | ||||
| 		template <typename CastType> explicit Density(const Density<CastType>& density) throw() | ||||
| 		{ | ||||
| 			m_uDensity = static_cast<Type>(density.getDensity()); | ||||
| 		} | ||||
|  | ||||
| 		bool operator==(const Density& rhs) const throw() | ||||
| 		{ | ||||
| @@ -75,31 +70,68 @@ namespace PolyVox | ||||
| 			return !(*this == rhs); | ||||
| 		} | ||||
|  | ||||
| 		// For densities we can supply mathematical operators which behave in an intuitive way. | ||||
| 		// In particular the ability to add and subtract densities is important in order to | ||||
| 		// apply an averaging filter. The ability to divide by an integer is also needed for | ||||
| 		// this same purpose. | ||||
| 		Density<Type>& operator+=(const Density<Type>& rhs) | ||||
| 		{ | ||||
| 			m_uDensity += rhs.m_uDensity; | ||||
| 			return *this; | ||||
| 		} | ||||
|  | ||||
| 		Density<Type>& operator-=(const Density<Type>& rhs) | ||||
| 		{ | ||||
| 			m_uDensity -= rhs.m_uDensity; | ||||
| 			return *this; | ||||
| 		} | ||||
|  | ||||
| 		Density<Type>& operator/=(uint32_t rhs) | ||||
| 		{ | ||||
| 			m_uDensity /= rhs; | ||||
| 			return *this; | ||||
| 		} | ||||
|  | ||||
| 		DensityType getDensity() const throw() { return m_uDensity; } | ||||
| 		void setDensity(DensityType uDensity) { m_uDensity = uDensity; } | ||||
| 		Type getDensity() const throw() { return m_uDensity; } | ||||
| 		void setDensity(Type uDensity) { m_uDensity = uDensity; } | ||||
|  | ||||
| 		static DensityType getMaxDensity() throw() { return (std::numeric_limits<DensityType>::max)(); }  | ||||
| 		static DensityType getMinDensity() throw() { return (std::numeric_limits<DensityType>::min)(); } | ||||
| 		static Type getMaxDensity() throw() { return (std::numeric_limits<Type>::max)(); }  | ||||
| 		static Type getMinDensity() throw() { return (std::numeric_limits<Type>::min)(); } | ||||
|  | ||||
| 	private: | ||||
| 		DensityType m_uDensity; | ||||
| 		Type m_uDensity; | ||||
| 	}; | ||||
|  | ||||
| 	template <typename Type> | ||||
| 	Density<Type> operator+(const Density<Type>& lhs, const Density<Type>& rhs) throw() | ||||
| 	{ | ||||
| 		Density<Type> result = lhs; | ||||
| 		result += rhs; | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	template <typename Type> | ||||
| 	Density<Type> operator-(const Density<Type>& lhs, const Density<Type>& rhs) throw() | ||||
| 	{ | ||||
| 		Density<Type> result = lhs; | ||||
| 		result -= rhs; | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	template <typename Type> | ||||
| 	Density<Type> operator/(const Density<Type>& lhs, uint32_t rhs) throw() | ||||
| 	{ | ||||
| 		Density<Type> result = lhs; | ||||
| 		result /= rhs; | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	// These are the predefined density types. The 8-bit types are sufficient for many purposes (including | ||||
| 	// most games) but 16-bit and float types do have uses particularly in medical/scientific visualisation. | ||||
| 	typedef Density<uint8_t> Density8; | ||||
| 	typedef Density<uint16_t> Density16; | ||||
| 	typedef Density<uint32_t> Density32; | ||||
| 	typedef Density<float> DensityFloat; | ||||
|  | ||||
| 	/** | ||||
| 	 * This is a specialisation of DefaultMarchingCubesController for the Density voxel type | ||||
|   | ||||
| @@ -30,7 +30,7 @@ freely, subject to the following restrictions: | ||||
|  | ||||
| namespace PolyVox | ||||
| { | ||||
| 	template< typename SrcVolumeType, typename DstVolumeType> | ||||
| 	template< typename SrcVolumeType, typename DstVolumeType, typename AccumulationType> | ||||
| 	class LowPassFilter | ||||
| 	{ | ||||
| 	public: | ||||
|   | ||||
| @@ -23,8 +23,8 @@ freely, subject to the following restrictions: | ||||
|  | ||||
| namespace PolyVox | ||||
| { | ||||
| 	template< typename SrcVolumeType, typename DstVolumeType> | ||||
| 	LowPassFilter<SrcVolumeType, DstVolumeType>::LowPassFilter(SrcVolumeType* pVolSrc, Region regSrc, DstVolumeType* pVolDst, Region regDst, uint32_t uKernelSize) | ||||
| 	template< typename SrcVolumeType, typename DstVolumeType, typename AccumulationType> | ||||
| 	LowPassFilter<SrcVolumeType, DstVolumeType, AccumulationType>::LowPassFilter(SrcVolumeType* pVolSrc, Region regSrc, DstVolumeType* pVolDst, Region regDst, uint32_t uKernelSize) | ||||
| 		:m_pVolSrc(pVolSrc) | ||||
| 		,m_regSrc(regSrc) | ||||
| 		,m_pVolDst(pVolDst) | ||||
| @@ -43,8 +43,8 @@ namespace PolyVox | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	template< typename SrcVolumeType, typename DstVolumeType> | ||||
| 	void LowPassFilter<SrcVolumeType, DstVolumeType>::execute() | ||||
| 	template< typename SrcVolumeType, typename DstVolumeType, typename AccumulationType> | ||||
| 	void LowPassFilter<SrcVolumeType, DstVolumeType, AccumulationType>::execute() | ||||
| 	{ | ||||
| 		int32_t iSrcMinX = m_regSrc.getLowerCorner().getX(); | ||||
| 		int32_t iSrcMinY = m_regSrc.getLowerCorner().getY(); | ||||
| @@ -70,52 +70,50 @@ namespace PolyVox | ||||
| 			{ | ||||
| 				for(int32_t iSrcX = iSrcMinX, iDstX = iDstMinX; iSrcX <= iSrcMaxX; iSrcX++, iDstX++) | ||||
| 				{ | ||||
| 					//VoxelType tSrcVoxel = m_pVolSrc->getVoxelAt(iSrcX, iSrcY, iSrcZ); | ||||
| 					AccumulationType tSrcVoxel(0); | ||||
| 					srcSampler.setPosition(iSrcX, iSrcY, iSrcZ); | ||||
|  | ||||
| 					typename SrcVolumeType::VoxelType tSrcVoxel = srcSampler.getVoxel(); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1nx1ny1nz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1nx1ny0pz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1nx1ny1pz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1nx0py1nz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1nx0py0pz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1nx0py1pz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1nx1py1nz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1nx1py0pz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1nx1py1pz()); | ||||
|  | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1nx1ny1nz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1nx1ny0pz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1nx1ny1pz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1nx0py1nz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1nx0py0pz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1nx0py1pz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1nx1py1nz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1nx1py0pz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1nx1py1pz(); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel0px1ny1nz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel0px1ny0pz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel0px1ny1pz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel0px0py1nz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel0px0py0pz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel0px0py1pz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel0px1py1nz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel0px1py0pz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel0px1py1pz()); | ||||
|  | ||||
| 					tSrcVoxel += srcSampler.peekVoxel0px1ny1nz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel0px1ny0pz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel0px1ny1pz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel0px0py1nz(); | ||||
| 					//tSrcVoxel += srcSampler.peekVoxel0px0py0pz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel0px0py1pz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel0px1py1nz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel0px1py0pz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel0px1py1pz(); | ||||
|  | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1px1ny1nz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1px1ny0pz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1px1ny1pz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1px0py1nz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1px0py0pz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1px0py1pz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1px1py1nz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1px1py0pz(); | ||||
| 					tSrcVoxel += srcSampler.peekVoxel1px1py1pz(); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1px1ny1nz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1px1ny0pz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1px1ny1pz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1px0py1nz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1px0py0pz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1px0py1pz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1px1py1nz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1px1py0pz()); | ||||
| 					tSrcVoxel += static_cast<AccumulationType>(srcSampler.peekVoxel1px1py1pz()); | ||||
|  | ||||
| 					tSrcVoxel /= 27; | ||||
|  | ||||
| 					//tSrcVoxel.setDensity(uDensity); | ||||
| 					m_pVolDst->setVoxelAt(iSrcX, iSrcY, iSrcZ, tSrcVoxel); | ||||
| 					m_pVolDst->setVoxelAt(iSrcX, iSrcY, iSrcZ, static_cast<DstVolumeType::VoxelType>(tSrcVoxel)); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	template< typename SrcVolumeType, typename DstVolumeType> | ||||
| 	void LowPassFilter<SrcVolumeType, DstVolumeType>::executeSAT() | ||||
| 	template< typename SrcVolumeType, typename DstVolumeType, typename AccumulationType> | ||||
| 	void LowPassFilter<SrcVolumeType, DstVolumeType, AccumulationType>::executeSAT() | ||||
| 	{ | ||||
| 		const uint32_t border = (m_uKernelSize - 1) / 2; | ||||
|  | ||||
| @@ -124,7 +122,7 @@ namespace PolyVox | ||||
|  | ||||
| 		//Use floats for the SAT volume to ensure it works with negative | ||||
| 		//densities and with both integral and floating point input volumes. | ||||
| 		RawVolume<float> satVolume(Region(satLowerCorner, satUpperCorner)); | ||||
| 		RawVolume<AccumulationType> satVolume(Region(satLowerCorner, satUpperCorner)); | ||||
|  | ||||
| 		//Clear to zeros (necessary?) | ||||
| 		//FIXME - use Volume::fill() method. Implemented in base class as below | ||||
| @@ -140,9 +138,9 @@ namespace PolyVox | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		RawVolume<float>::Sampler satVolumeIter(&satVolume); | ||||
| 		RawVolume<AccumulationType>::Sampler satVolumeIter(&satVolume); | ||||
|  | ||||
| 		IteratorController<RawVolume<float>::Sampler> satIterCont; | ||||
| 		IteratorController<RawVolume<AccumulationType>::Sampler> satIterCont; | ||||
| 		satIterCont.m_regValid = Region(satLowerCorner, satUpperCorner); | ||||
| 		satIterCont.m_Iter = &satVolumeIter; | ||||
| 		satIterCont.reset(); | ||||
| @@ -156,9 +154,8 @@ namespace PolyVox | ||||
|  | ||||
| 		do | ||||
| 		{ | ||||
| 			float previousSum = satVolumeIter.peekVoxel1nx0py0pz(); | ||||
|  | ||||
| 			float currentVal = static_cast<float>(srcVolumeIter.getVoxel().getDensity()); | ||||
| 			AccumulationType previousSum = static_cast<AccumulationType>(satVolumeIter.peekVoxel1nx0py0pz()); | ||||
| 			AccumulationType currentVal = static_cast<AccumulationType>(srcVolumeIter.getVoxel()); | ||||
|  | ||||
| 			satVolumeIter.setVoxel(previousSum + currentVal); | ||||
|  | ||||
| @@ -173,8 +170,8 @@ namespace PolyVox | ||||
| 			{ | ||||
| 				for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) | ||||
| 				{ | ||||
| 					uint32_t previousSum = satVolume.getVoxelAt(x-1,y,z); | ||||
| 					uint32_t currentVal = m_pVolSrc->getVoxelAt(x,y,z).getDensity(); | ||||
| 					AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxelAt(x-1,y,z)); | ||||
| 					AccumulationType currentVal = static_cast<AccumulationType>(m_pVolSrc->getVoxelAt(x,y,z)); | ||||
|  | ||||
| 					satVolume.setVoxelAt(x,y,z,previousSum + currentVal); | ||||
| 				} | ||||
| @@ -187,8 +184,8 @@ namespace PolyVox | ||||
| 			{ | ||||
| 				for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) | ||||
| 				{ | ||||
| 					float previousSum = satVolume.getVoxelAt(x,y-1,z); | ||||
| 					float currentSum = satVolume.getVoxelAt(x,y,z); | ||||
| 					AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxelAt(x,y-1,z)); | ||||
| 					AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxelAt(x,y,z)); | ||||
|  | ||||
| 					satVolume.setVoxelAt(x,y,z,previousSum + currentSum); | ||||
| 				} | ||||
| @@ -201,8 +198,8 @@ namespace PolyVox | ||||
| 			{ | ||||
| 				for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) | ||||
| 				{ | ||||
| 					float previousSum = satVolume.getVoxelAt(x,y,z-1); | ||||
| 					float currentSum = satVolume.getVoxelAt(x,y,z); | ||||
| 					AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxelAt(x,y,z-1)); | ||||
| 					AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxelAt(x,y,z)); | ||||
|  | ||||
| 					satVolume.setVoxelAt(x,y,z,previousSum + currentSum); | ||||
| 				} | ||||
| @@ -229,38 +226,20 @@ namespace PolyVox | ||||
| 					int32_t satUpperY = iSrcY + border; | ||||
| 					int32_t satUpperZ = iSrcZ + border; | ||||
|  | ||||
| 					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); | ||||
|  | ||||
| 					float sum = h+c-d-g-f-a+b+e; | ||||
| 					AccumulationType a = satVolume.getVoxelAt(satLowerX,satLowerY,satLowerZ); | ||||
| 					AccumulationType b = satVolume.getVoxelAt(satUpperX,satLowerY,satLowerZ); | ||||
| 					AccumulationType c = satVolume.getVoxelAt(satLowerX,satUpperY,satLowerZ); | ||||
| 					AccumulationType d = satVolume.getVoxelAt(satUpperX,satUpperY,satLowerZ); | ||||
| 					AccumulationType e = satVolume.getVoxelAt(satLowerX,satLowerY,satUpperZ); | ||||
| 					AccumulationType f = satVolume.getVoxelAt(satUpperX,satLowerY,satUpperZ); | ||||
| 					AccumulationType g = satVolume.getVoxelAt(satLowerX,satUpperY,satUpperZ); | ||||
| 					AccumulationType h = satVolume.getVoxelAt(satUpperX,satUpperY,satUpperZ); | ||||
|  | ||||
| 					AccumulationType sum = h+c-d-g-f-a+b+e; | ||||
| 					uint32_t sideLength = border * 2 + 1; | ||||
| 					AccumulationType average = sum / (sideLength*sideLength*sideLength); | ||||
|  | ||||
| 					float average = sum / (static_cast<float>(sideLength*sideLength*sideLength)); | ||||
|  | ||||
| 					//Note: These lines need consideration if src and dest have different voxel types. | ||||
| 					typename SrcVolumeType::VoxelType voxel = m_pVolSrc->getVoxelAt(iDstX, iDstY, iDstZ); | ||||
|  | ||||
| 					voxel.setDensity(static_cast<typename SrcVolumeType::VoxelType::DensityType>(average)); | ||||
|  | ||||
| 					m_pVolDst->setVoxelAt(iDstX, iDstY, iDstZ, voxel); | ||||
|  | ||||
|  | ||||
| 					//float maxSolid = border * 2/* + 1*/; | ||||
| 					/*maxSolid = maxSolid * maxSolid * maxSolid; | ||||
|  | ||||
| 					float percentSolid = noSolid / maxSolid; | ||||
| 					float percentEmpty = 1.0f - percentSolid; | ||||
|  | ||||
| 					(*mAmbientOcclusionVolume)[ambVolZ][ambVolY][ambVolX] = 255 * percentEmpty;*/ | ||||
|  | ||||
| 					//(*mAmbientOcclusionVolume)[ambVolZ][ambVolY][ambVolX] = 255 - ((h+c-d-g-f-a+b+e) * 19); //FIXME - should not be 9 | ||||
| 					m_pVolDst->setVoxelAt(iDstX, iDstY, iDstZ, static_cast<DstVolumeType::VoxelType>(average)); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
| @@ -34,14 +34,7 @@ namespace PolyVox | ||||
| { | ||||
| 	///This class represents a voxel storing only a material. | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	/// In order to perform a surface extraction on a LargeVolume, PolyVox needs the underlying | ||||
| 	/// voxel type to provide both getDensity() and getMaterial() functions. The getDensity() | ||||
| 	/// function is used to determine if a voxel is 'solid', and if it is then the getMaterial() | ||||
| 	/// funtion is used to determine what material should be assigned to the resulting mesh. | ||||
| 	/// | ||||
| 	/// This class meets these requirements, although it only actually stores a material value. | ||||
| 	/// For the getDensity() function it simply returns the smallest possible density if the | ||||
| 	/// material is zero and the largest possible density if the material is not zero. | ||||
| 	/// Detailed description... | ||||
| 	/// | ||||
| 	/// \sa Density, MaterialDensityPair | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -52,15 +45,8 @@ namespace PolyVox | ||||
| 	class Material | ||||
| 	{ | ||||
| 	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 int32_t DensityType; | ||||
| 		typedef Type MaterialType; | ||||
|  | ||||
| 		Material() : m_uMaterial(0) {} | ||||
| 		Material(MaterialType uMaterial) : m_uMaterial(uMaterial) {} | ||||
| 		Material(Type uMaterial) : m_uMaterial(uMaterial) {} | ||||
|  | ||||
| 		bool operator==(const Material& rhs) const throw() | ||||
| 		{ | ||||
| @@ -72,11 +58,11 @@ namespace PolyVox | ||||
| 			return !(*this == rhs); | ||||
| 		} | ||||
|  | ||||
| 		MaterialType getMaterial() const throw() { return m_uMaterial; } | ||||
| 		void setMaterial(MaterialType uMaterial) { m_uMaterial = uMaterial; } | ||||
| 		Type getMaterial() const throw() { return m_uMaterial; } | ||||
| 		void setMaterial(Type uMaterial) { m_uMaterial = uMaterial; } | ||||
|  | ||||
| 	private: | ||||
| 		MaterialType m_uMaterial; | ||||
| 		Type m_uMaterial; | ||||
| 	}; | ||||
|  | ||||
| 	typedef Material<uint8_t> Material8; | ||||
|   | ||||
| @@ -33,15 +33,7 @@ namespace PolyVox | ||||
| { | ||||
| 	/// This class represents a voxel storing only a density. | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	/// In order to perform a surface extraction on a LargeVolume, PolyVox needs the underlying | ||||
| 	/// voxel type to provide both getDensity() and getMaterial() functions. The getDensity() | ||||
| 	/// function is used to determine if a voxel is 'solid', and if it is then the getMaterial() | ||||
| 	/// funtion is used to determine what material should be assigned to the resulting mesh. | ||||
| 	/// | ||||
| 	/// This class meets these requirements, and does so by storing and returning both a material | ||||
| 	/// and a density value. Via the template parameters it is possible to control how much | ||||
| 	/// precision is given to each. For example, if you create a class with 8 bits of storage, | ||||
| 	/// you might choose to allocate 6 bits for the density and 2 bits for the material. | ||||
| 	/// Detailed description... | ||||
| 	/// | ||||
| 	/// \sa Density, Material | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -49,13 +41,6 @@ namespace PolyVox | ||||
| 	class MaterialDensityPair | ||||
| 	{ | ||||
| 	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 Type DensityType; | ||||
| 		typedef Type MaterialType; | ||||
|  | ||||
| 		MaterialDensityPair() : m_uMaterial(0), m_uDensity(0) {} | ||||
| 		MaterialDensityPair(Type uMaterial, Type uDensity) : m_uMaterial(uMaterial), m_uDensity(uDensity) {} | ||||
|  | ||||
| @@ -87,18 +72,18 @@ namespace PolyVox | ||||
| 			return *this; | ||||
| 		} | ||||
|  | ||||
| 		DensityType getDensity() const throw() { return m_uDensity; } | ||||
| 		MaterialType getMaterial() const throw() { return m_uMaterial; } | ||||
| 		Type getDensity() const throw() { return m_uDensity; } | ||||
| 		Type getMaterial() const throw() { return m_uMaterial; } | ||||
|  | ||||
| 		void setDensity(DensityType uDensity) { m_uDensity = uDensity; } | ||||
| 		void setMaterial(MaterialType uMaterial) { m_uMaterial = uMaterial; } | ||||
| 		void setDensity(Type uDensity) { m_uDensity = uDensity; } | ||||
| 		void setMaterial(Type uMaterial) { m_uMaterial = uMaterial; } | ||||
|  | ||||
| 		static DensityType getMaxDensity() throw() { return (0x01 << NoOfDensityBits) - 1; } | ||||
| 		static DensityType getMinDensity() throw() { return 0; } | ||||
| 		static Type getMaxDensity() throw() { return (0x01 << NoOfDensityBits) - 1; } | ||||
| 		static Type getMinDensity() throw() { return 0; } | ||||
|  | ||||
| 	private: | ||||
| 		MaterialType m_uMaterial : NoOfMaterialBits; | ||||
| 		DensityType m_uDensity : NoOfDensityBits; | ||||
| 		Type m_uMaterial : NoOfMaterialBits; | ||||
| 		Type m_uDensity : NoOfDensityBits; | ||||
| 	}; | ||||
|  | ||||
| 	template<typename Type, uint8_t NoOfMaterialBits, uint8_t NoOfDensityBits> | ||||
|   | ||||
| @@ -61,7 +61,7 @@ IF(LIBRARY_TYPE STREQUAL "DYNAMIC") | ||||
| 	ADD_LIBRARY(PolyVoxUtil SHARED ${UTIL_SRC_FILES} ${UTIL_INC_FILES}) | ||||
| 	SET_TARGET_PROPERTIES(PolyVoxUtil PROPERTIES COMPILE_FLAGS "-DPOLYVOX_SHARED_EXPORTS") | ||||
| ENDIF() | ||||
| SET_PROPERTY(TARGET PolyVoxUtil PROPERTY FOLDER "library/PolyVoxUtil") | ||||
| SET_PROPERTY(TARGET PolyVoxUtil PROPERTY FOLDER "Library") | ||||
|  | ||||
| TARGET_LINK_LIBRARIES(PolyVoxUtil PolyVoxCore) | ||||
| SET_TARGET_PROPERTIES(PolyVoxUtil PROPERTIES VERSION ${POLYVOX_VERSION} SOVERSION ${POLYVOX_VERSION_MAJOR}) | ||||
|   | ||||
| @@ -46,7 +46,7 @@ if(ENABLE_BINDINGS) | ||||
| 		swig_add_module(PolyVoxCore python PolyVoxCore.i) | ||||
| 		swig_link_libraries(PolyVoxCore ${PYTHON_LIBRARIES} PolyVoxCore) | ||||
| 		#set_target_properties(${SWIG_MODULE_PolyVoxCore_REAL_NAME} PROPERTIES SUFFIX ".pyd") | ||||
| 		SET_PROPERTY(TARGET ${SWIG_MODULE_PolyVoxCore_REAL_NAME} PROPERTY FOLDER "library/bindings") | ||||
| 		SET_PROPERTY(TARGET ${SWIG_MODULE_PolyVoxCore_REAL_NAME} PROPERTY FOLDER "Bindings") | ||||
| 	else() | ||||
| 		set(BUILD_BINDINGS OFF CACHE BOOL "Will the bindings be built" FORCE) | ||||
| 	endif() | ||||
|   | ||||
| @@ -36,7 +36,7 @@ MACRO(CREATE_TEST headerfile sourcefile executablename) | ||||
| 	ELSE(WIN32) | ||||
| 		SET(LATEST_TEST ${CMAKE_CURRENT_BINARY_DIR}/${executablename}) | ||||
| 	ENDIF(WIN32) | ||||
| 	SET_PROPERTY(TARGET ${executablename} PROPERTY FOLDER "tests") | ||||
| 	SET_PROPERTY(TARGET ${executablename} PROPERTY FOLDER "Tests") | ||||
| ENDMACRO(CREATE_TEST) | ||||
|  | ||||
| IF(NOT QT_QTTEST_FOUND) | ||||
|   | ||||
| @@ -58,29 +58,30 @@ void TestLowPassFilter::testExecute() | ||||
|  | ||||
| 	RawVolume<Density8> resultVolume(reg); | ||||
|  | ||||
| 	LowPassFilter< RawVolume<Density8>, RawVolume<Density8> > pass1(&volData, reg, &resultVolume, reg, 5); | ||||
| 	LowPassFilter< RawVolume<Density8>, RawVolume<Density8>, Density16 > lowPassfilter(&volData, reg, &resultVolume, reg, 5); | ||||
|  | ||||
| 	pass1.execute(); | ||||
| 	//Test the normal implementation | ||||
| 	lowPassfilter.execute(); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(0,0,0), Density8(4)); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(1,1,1), Density8(21)); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(2,2,2), Density8(10)); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(3,3,3), Density8(21)); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(4,4,4), Density8(10)); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(5,5,5), Density8(21)); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(6,6,6), Density8(10)); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(7,7,7), Density8(4)); | ||||
|  | ||||
| 	std::cout << "Input volume:" << std::endl; | ||||
| 	std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(0,0,0).getDensity()) << std::endl; // 32 | ||||
| 	std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(1,1,1).getDensity()) << std::endl; // 0 | ||||
| 	std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(2,2,2).getDensity()) << std::endl; // 3 | ||||
| 	std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(3,3,3).getDensity()) << std::endl; // 0 | ||||
| 	std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(4,4,4).getDensity()) << std::endl; // 32 | ||||
| 	std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(5,5,5).getDensity()) << std::endl; // 0 | ||||
| 	std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(6,6,6).getDensity()) << std::endl; // 32 | ||||
| 	std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(7,7,7).getDensity()) << std::endl; // 0 | ||||
|  | ||||
| 	std::cout << std::endl << "Output volume:" << std::endl; | ||||
| 	std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(0,0,0).getDensity()) << std::endl; // 4 | ||||
| 	std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(1,1,1).getDensity()) << std::endl; // 21 | ||||
| 	std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(2,2,2).getDensity()) << std::endl; // 10 | ||||
| 	std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(3,3,3).getDensity()) << std::endl; // 21 | ||||
| 	std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(4,4,4).getDensity()) << std::endl; // 10 | ||||
| 	std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(5,5,5).getDensity()) << std::endl; // 21 | ||||
| 	std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(6,6,6).getDensity()) << std::endl; // 10 | ||||
| 	std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(7,7,7).getDensity()) << std::endl; // 4 | ||||
| 	//Test the SAT implmentation | ||||
| 	//FIXME - Shouldn't the results be the same as the normal case? | ||||
| 	lowPassfilter.executeSAT(); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(0,0,0), Density8(4)); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(1,1,1), Density8(8)); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(2,2,2), Density8(19)); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(3,3,3), Density8(12)); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(4,4,4), Density8(19)); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(5,5,5), Density8(12)); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(6,6,6), Density8(8)); | ||||
| 	QCOMPARE(resultVolume.getVoxelAt(7,7,7), Density8(2)); | ||||
| } | ||||
|  | ||||
| QTEST_MAIN(TestLowPassFilter) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user