Merge branch 'develop' into feature/cubiquity-version

This commit is contained in:
Daviw Williams
2013-05-16 16:06:53 +02:00
41 changed files with 881 additions and 290 deletions

View File

@ -32,7 +32,6 @@ SET(CORE_SRC_FILES
source/ArraySizes.cpp
source/AStarPathfinder.cpp
source/MinizCompressor.cpp
source/Log.cpp
source/Region.cpp
source/VertexTypes.cpp
)
@ -66,7 +65,6 @@ SET(CORE_INC_FILES
include/PolyVoxCore/LargeVolume.h
include/PolyVoxCore/LargeVolume.inl
include/PolyVoxCore/LargeVolumeSampler.inl
include/PolyVoxCore/Log.h
include/PolyVoxCore/LowPassFilter.h
include/PolyVoxCore/LowPassFilter.inl
include/PolyVoxCore/MarchingCubesSurfaceExtractor.h
@ -75,6 +73,8 @@ SET(CORE_INC_FILES
include/PolyVoxCore/MaterialDensityPair.h
include/PolyVoxCore/MinizCompressor.h
include/PolyVoxCore/PolyVoxForwardDeclarations.h
include/PolyVoxCore/Picking.h
include/PolyVoxCore/Picking.inl
include/PolyVoxCore/RawVolume.h
include/PolyVoxCore/RawVolume.inl
include/PolyVoxCore/RawVolumeSampler.inl

View File

@ -298,7 +298,7 @@ namespace PolyVox
hVal = SixConnectedCost(a, b);
break;
default:
POLYVOX_ASSERT(false, "Invalid case");
POLYVOX_THROW(std::invalid_argument, "Connectivity parameter has an unrecognised value.");
}
//Sanity checks in debug mode. These can come out eventually, but I

View File

@ -34,15 +34,24 @@ namespace PolyVox
template<typename VolumeType, typename IsVoxelTransparentCallback>
void calculateAmbientOcclusion(VolumeType* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, IsVoxelTransparentCallback isVoxelTransparentCallback)
{
//Make sure that the size of the volume is an exact multiple of the size of the array.
if(volInput->getWidth() % arrayResult->getDimension(0) != 0)
{
POLYVOX_THROW(std::invalid_argument, "Volume width must be an exact multiple of array width.");
}
if(volInput->getHeight() % arrayResult->getDimension(1) != 0)
{
POLYVOX_THROW(std::invalid_argument, "Volume width must be an exact multiple of array height.");
}
if(volInput->getDepth() % arrayResult->getDimension(2) != 0)
{
POLYVOX_THROW(std::invalid_argument, "Volume width must be an exact multiple of array depth.");
}
uint16_t uRandomUnitVectorIndex = 0;
uint16_t uRandomVectorIndex = 0;
uint16_t uIndexIncreament;
//Make sure that the size of the volume is an exact multiple of the size of the array.
POLYVOX_ASSERT(volInput->getWidth() % arrayResult->getDimension(0) == 0, "Volume width must be an exact multiple of array width.");
POLYVOX_ASSERT(volInput->getHeight() % arrayResult->getDimension(1) == 0, "Volume height must be an exact multiple of array height.");
POLYVOX_ASSERT(volInput->getDepth() % arrayResult->getDimension(2) == 0, "Volume depth must be an exact multiple of array depth.");
//Our initial indices. It doesn't matter exactly what we set here, but the code below makes
//sure they are different for different regions which helps reduce tiling patterns in the results.
uRandomUnitVectorIndex += region.getLowerX() + region.getLowerY() + region.getLowerZ();

View File

@ -73,7 +73,11 @@ namespace PolyVox
template <uint32_t noOfDims, typename ElementType>
SubArray<noOfDims-1, ElementType> Array<noOfDims, ElementType>::operator[](uint32_t uIndex)
{
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
if(uIndex >= m_pDimensions[0])
{
POLYVOX_THROW(std::out_of_range, "Array index out of range");
}
return
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
m_pDimensions+1, m_pOffsets+1);
@ -91,7 +95,11 @@ namespace PolyVox
template <uint32_t noOfDims, typename ElementType>
const SubArray<noOfDims-1, ElementType> Array<noOfDims, ElementType>::operator[](uint32_t uIndex) const
{
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
if(uIndex >= m_pDimensions[0])
{
POLYVOX_THROW(std::out_of_range, "Array index out of range");
}
return
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
m_pDimensions+1, m_pOffsets+1);
@ -139,7 +147,10 @@ namespace PolyVox
m_uNoOfElements = 1;
for (uint32_t i = 0; i<noOfDims; i++)
{
POLYVOX_ASSERT(pDimensions[i] != 0, "Invalid dimension");
if(pDimensions[i] == 0)
{
POLYVOX_THROW(std::out_of_range, "Invalid array dimension");
}
m_uNoOfElements *= pDimensions[i];
m_pDimensions[i] = pDimensions[i];
@ -186,7 +197,11 @@ namespace PolyVox
template <uint32_t noOfDims, typename ElementType>
uint32_t Array<noOfDims, ElementType>::getDimension(uint32_t uDimension)
{
POLYVOX_ASSERT(uDimension < noOfDims, "Dimension out of range");
if(uDimension >= noOfDims)
{
POLYVOX_THROW(std::out_of_range, "Array dimension out of range");
}
return m_pDimensions[uDimension];
}
@ -198,14 +213,14 @@ namespace PolyVox
,m_uNoOfElements(0)
{
//Not implemented
POLYVOX_ASSERT(false, "Not implemented.");
POLYVOX_THROW(not_implemented, "This function is not implemented and should never be called!");
}
template <uint32_t noOfDims, typename ElementType>
Array<noOfDims, ElementType>& Array<noOfDims, ElementType>::operator=(const Array<noOfDims, ElementType>& rhs)
{
//Not implemented
POLYVOX_ASSERT(false, "Not implemented.");
POLYVOX_THROW(not_implemented, "This function is not implemented and should never be called!");
return *this;
}
@ -251,14 +266,22 @@ namespace PolyVox
template <typename ElementType>
ElementType& Array<1, ElementType>::operator[] (uint32_t uIndex)
{
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
if(uIndex >= m_pDimensions[0])
{
POLYVOX_THROW(std::out_of_range, "Array index out of range");
}
return m_pElements[uIndex];
}
template <typename ElementType>
const ElementType& Array<1, ElementType>::operator[] (uint32_t uIndex) const
{
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
if(uIndex >= m_pDimensions[0])
{
POLYVOX_THROW(std::out_of_range, "Array index out of range");
}
return m_pElements[uIndex];
}
@ -307,14 +330,14 @@ namespace PolyVox
,m_pDimensions(0)
{
//Not implemented
POLYVOX_ASSERT(false, "Not implemented.");
POLYVOX_THROW(not_implemented, "This function is not implemented and should never be called!");
}
template <typename ElementType>
Array<1, ElementType>& Array<1, ElementType>::operator=(const Array<1, ElementType>& rhs)
{
//Not implemented
POLYVOX_ASSERT(false, "Not implemented.");
POLYVOX_THROW(not_implemented, "This function is not implemented and should never be called!");
return *this;
}

View File

@ -24,7 +24,6 @@ freely, subject to the following restrictions:
#ifndef __PolyVox_BaseVolume_H__
#define __PolyVox_BaseVolume_H__
#include "PolyVoxCore/Log.h"
#include "PolyVoxCore/Region.h"
#include "PolyVoxCore/Vector.h"

View File

@ -45,7 +45,7 @@ namespace PolyVox
template <typename VoxelType>
BaseVolume<VoxelType>::BaseVolume(const BaseVolume<VoxelType>& /*rhs*/)
{
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented for performance reasons.");
}
////////////////////////////////////////////////////////////////////////////////
@ -59,14 +59,14 @@ namespace PolyVox
////////////////////////////////////////////////////////////////////////////////
/// This function should never be called. Copying volumes by value would be expensive, and we want to prevent users from doing
/// it by accident (such as when passing them as paramenters to functions). That said, there are times when you really do want to
/// make a copy of a volume and in this case you should look at the Volumeresampler.
/// make a copy of a volume and in this case you should look at the VolumeResampler.
///
/// \sa VolumeResampler
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
BaseVolume<VoxelType>& BaseVolume<VoxelType>::operator=(const BaseVolume<VoxelType>& /*rhs*/)
{
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
}
////////////////////////////////////////////////////////////////////////////////
@ -162,7 +162,7 @@ namespace PolyVox
template <typename VoxelType>
VoxelType BaseVolume<VoxelType>::getVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/) const
{
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
return VoxelType();
}
@ -173,7 +173,7 @@ namespace PolyVox
template <typename VoxelType>
VoxelType BaseVolume<VoxelType>::getVoxel(const Vector3DInt32& /*v3dPos*/) const
{
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
return VoxelType();
}
@ -186,7 +186,7 @@ namespace PolyVox
template <typename VoxelType>
VoxelType BaseVolume<VoxelType>::getVoxelAt(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/) const
{
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
return VoxelType();
}
@ -197,7 +197,7 @@ namespace PolyVox
template <typename VoxelType>
VoxelType BaseVolume<VoxelType>::getVoxelAt(const Vector3DInt32& /*v3dPos*/) const
{
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
return VoxelType();
}
@ -210,7 +210,7 @@ namespace PolyVox
template <typename VoxelType>
VoxelType BaseVolume<VoxelType>::getVoxelWithWrapping(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, WrapMode /*eWrapMode*/, VoxelType /*tBorder*/) const
{
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
return VoxelType();
}
@ -221,7 +221,7 @@ namespace PolyVox
template <typename VoxelType>
VoxelType BaseVolume<VoxelType>::getVoxelWithWrapping(const Vector3DInt32& /*v3dPos*/, WrapMode /*eWrapMode*/, VoxelType /*tBorder*/) const
{
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
return VoxelType();
}
@ -244,7 +244,7 @@ namespace PolyVox
template <typename VoxelType>
bool BaseVolume<VoxelType>::setVoxelAt(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, VoxelType /*tValue*/)
{
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
return false;
}
@ -256,7 +256,7 @@ namespace PolyVox
template <typename VoxelType>
bool BaseVolume<VoxelType>::setVoxelAt(const Vector3DInt32& /*v3dPos*/, VoxelType /*tValue*/)
{
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
return false;
}

View File

@ -375,7 +375,7 @@ namespace PolyVox
default:
{
//Should never happen
POLYVOX_ASSERT(false, "Invalid case.");
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
return VoxelType();
}
}

View File

@ -37,24 +37,28 @@ namespace PolyVox
public:
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
{
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
POLYVOX_ASSERT(m_regValid.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
return m_pVolume.getVoxelAt(uXPos, uYPos, uZPos);
}
VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const
{
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
POLYVOX_ASSERT(m_regValid.containsPoint(v3dPos), "Position is outside valid region");
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
}
void setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) const
{
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
POLYVOX_ASSERT(m_regValid.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
m_pVolume.setVoxelAtConst(uXPos, uYPos, uZPos, tValue);
}
void setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue) const
{
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
POLYVOX_ASSERT(m_regValid.containsPoint(v3dPos), "Position is outside valid region");
setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
}

View File

@ -220,9 +220,9 @@ namespace PolyVox
}
}
// If we exit the loop here then apparently all the slots were full but none of them matched. I don't think
// this can happen so let's put an assert to make sure. If you hit this assert then please report it to us!
POLYVOX_ASSERT(false, "All slots full but no matches.");
// If we exit the loop here then apparently all the slots were full but none of them matched.
// This shouldn't ever happen, so if it does it is probably a bug in PolyVox. Please report it to us!
POLYVOX_THROW(std::runtime_error, "All slots full but no matches during cubic surface extraction. This is probably a bug in PolyVox");
return -1; //Should never happen.
}

View File

@ -60,10 +60,10 @@ namespace PolyVox
template <typename VoxelType>
VoxelType Block<VoxelType>::getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const
{
// This is internal code not directly called by the user. For efficiency we assert rather than throwing.
POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block");
POLYVOX_ASSERT(uYPos < m_uSideLength, "Supplied position is outside of the block");
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the block");
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data - block must be decompressed before accessing voxels.");
return m_tUncompressedData
@ -83,10 +83,10 @@ namespace PolyVox
template <typename VoxelType>
void Block<VoxelType>::setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue)
{
// This is internal code not directly called by the user. For efficiency we assert rather than throwing.
POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block");
POLYVOX_ASSERT(uYPos < m_uSideLength, "Supplied position is outside of the block");
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the block");
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data - block must be decompressed before accessing voxels.");
m_tUncompressedData
@ -108,9 +108,6 @@ namespace PolyVox
template <typename VoxelType>
void Block<VoxelType>::initialise(uint16_t uSideLength)
{
//Debug mode validation
POLYVOX_ASSERT(isPowerOf2(uSideLength), "Block side length must be a power of two.");
//Release mode validation
if(!isPowerOf2(uSideLength))
{
@ -141,8 +138,16 @@ namespace PolyVox
template <typename VoxelType>
void Block<VoxelType>::compress(Compressor* pCompressor)
{
POLYVOX_ASSERT(pCompressor, "Compressor is not valid");
POLYVOX_ASSERT(m_bIsCompressed == false, "Attempted to compress block which is already flagged as compressed.");
if(m_bIsCompressed)
{
POLYVOX_THROW(invalid_operation, "Attempted to compress block which is already flagged as compressed.");
}
if(!pCompressor)
{
POLYVOX_THROW(std::invalid_argument, "A valid compressor must be provided");
}
POLYVOX_ASSERT(m_tUncompressedData != 0, "No uncompressed data is present.");
//If the uncompressed data hasn't actually been
@ -212,8 +217,16 @@ namespace PolyVox
template <typename VoxelType>
void Block<VoxelType>::uncompress(Compressor* pCompressor)
{
POLYVOX_ASSERT(pCompressor, "Compressor is not valid");
POLYVOX_ASSERT(m_bIsCompressed == true, "Attempted to uncompress block which is not flagged as compressed.");
if(!m_bIsCompressed)
{
POLYVOX_THROW(invalid_operation, "Attempted to uncompress block which is not flagged as compressed.");
}
if(!pCompressor)
{
POLYVOX_THROW(std::invalid_argument, "A valid compressor must be provided");
}
POLYVOX_ASSERT(m_tUncompressedData == 0, "Uncompressed data already exists.");
m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];

View File

@ -26,14 +26,19 @@ freely, subject to the following restrictions:
#include "PolyVoxCore/Impl/Config.h"
#include <cstdlib> //For std::exit
#include <iostream> //For std::cerr
#include <cstdlib> // For std::exit
#include <iostream> // For std::cerr
#include <stdexcept>
#include <sstream>
#include <string.h> // Exception constuctors take strings.
#if defined(_MSC_VER)
// In Visual Studio we can use this function to go into the debugger.
#define POLYVOX_HALT() __debugbreak()
#else
#define POLYVOX_HALT() std::exit(EXIT_FAILURE)
// On other platforms we just halt by forcing a crash.
// Hopefully this puts us in the debugger if one is running
#define POLYVOX_HALT() *((unsigned int*)0) = 0xDEAD
#endif
// Macros cannot contain #ifdefs, but some of our macros need to disable warnings and such warning supression is
@ -51,6 +56,44 @@ freely, subject to the following restrictions:
#define POLYVOX_UNUSED(x) do { (void)sizeof(x); } while(0)
/*
* Logging
* --------
* PolyVox provides basic logging facilities which can be redirected by your application.
*/
namespace PolyVox
{
class LogLevels
{
public:
enum LogLevel
{
Debug,
Info,
Warning,
Error,
Fatal
};
};
typedef LogLevels::LogLevel LogLevel;
typedef void (*LogHandler)(const std::string& message, LogLevel logLevel);
LogHandler getLogHandler();
void setLogHandler(LogHandler newHandler);
// The actual logging function
void log(const std::string& message, LogLevel logLevel);
// Some handy wrappers
void logDebug (const std::string& message);
void logInfo (const std::string& message);
void logWarning(const std::string& message);
void logError (const std::string& message);
void logFatal (const std::string& message);
}
/*
* Assertions
* ----------
@ -71,12 +114,14 @@ freely, subject to the following restrictions:
{ \
if (!(condition)) \
{ \
std::cerr << std::endl << std::endl; \
std::cerr << " PolyVox Assertion Failed!" << std::endl; \
std::cerr << " =========================" << std::endl; \
std::cerr << " Condition: " << #condition << std::endl; \
std::cerr << " Message: " << (message) << std::endl; \
std::cerr << " Location: " << "Line " << __LINE__ << " of " << __FILE__ << std::endl << std::endl; \
std::stringstream ss; \
ss << std::endl << std::endl; \
ss << " PolyVox Assertion Failed!" << std::endl; \
ss << " =========================" << std::endl; \
ss << " Condition: " << #condition << std::endl; \
ss << " Message: " << (message) << std::endl; \
ss << " Location: " << "Line " << __LINE__ << " of " << __FILE__ << std::endl << std::endl; \
logFatal(ss.str()); \
POLYVOX_HALT(); \
} \
} while(0) \
@ -130,7 +175,9 @@ freely, subject to the following restrictions:
* ...
*/
#ifdef POLYVOX_THROW_ENABLED
#define POLYVOX_THROW(type, message) throw type((message))
#define POLYVOX_THROW(type, message) \
log(message, LogLevels::Error); \
throw type((message))
#else
namespace PolyVox
{
@ -141,8 +188,37 @@ freely, subject to the following restrictions:
}
#define POLYVOX_THROW(type, message) \
log(message, LogLevels::Error); \
type except = (type)((message)); \
getThrowHandler()((except), __FILE__, __LINE__)
#endif
namespace PolyVox
{
/// A general purpose exception to indicate that an operation cannot be peformed.
class invalid_operation : public std::logic_error
{
public:
explicit invalid_operation(const std::string& message)
: logic_error(message.c_str()) {}
explicit invalid_operation(const char *message)
: logic_error(message) {}
};
/// Thrown to indicate that a function is deliberatly not implmented. For example, perhaps you called a function
/// in a base class whereas you are supposed to use a derived class which implements the function, or perhaps the
/// function is not defined for a particular template parameter. It may be that the function is required to
/// compile sucessfully but it should not be called.
class not_implemented : public std::logic_error
{
public:
explicit not_implemented(const std::string& message)
: logic_error(message.c_str()) {}
explicit not_implemented(const char *message)
: logic_error(message) {}
};
}
#endif //__PolyVox_ErrorHandling_H__

View File

@ -28,7 +28,11 @@ namespace PolyVox
template <uint32_t noOfDims, typename ElementType>
SubArray<noOfDims-1, ElementType> SubArray<noOfDims, ElementType>::operator[](uint32_t uIndex)
{
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
if(uIndex >= m_pDimensions[0])
{
POLYVOX_THROW(std::out_of_range, "Array index out of range");
}
return
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
m_pDimensions+1, m_pOffsets+1);
@ -37,7 +41,11 @@ namespace PolyVox
template <uint32_t noOfDims, typename ElementType>
const SubArray<noOfDims-1, ElementType> SubArray<noOfDims, ElementType>::operator[](uint32_t uIndex) const
{
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
if(uIndex >= m_pDimensions[0])
{
POLYVOX_THROW(std::out_of_range, "Array index out of range");
}
return
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
m_pDimensions+1, m_pOffsets+1);
@ -56,14 +64,22 @@ namespace PolyVox
template <typename ElementType>
ElementType& SubArray<1, ElementType>::operator[] (uint32_t uIndex)
{
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
if(uIndex >= m_pDimensions[0])
{
POLYVOX_THROW(std::out_of_range, "Array index out of range");
}
return m_pElements[uIndex];
}
template <typename ElementType>
const ElementType& SubArray<1, ElementType>::operator[] (uint32_t uIndex) const
{
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
if(uIndex >= m_pDimensions[0])
{
POLYVOX_THROW(std::out_of_range, "Array index out of range");
}
return m_pElements[uIndex];
}

View File

@ -31,6 +31,7 @@ namespace PolyVox
const Type& v0,const Type& v1,
const float x)
{
//This function is called frequently and is very short, so assert rather than exceptions.
POLYVOX_ASSERT((x >= 0.0f) && (x <= 1.0f), "Interpolation input out of 0.0 to 1.0 range.");
//Interpolate along X
@ -44,6 +45,7 @@ namespace PolyVox
const Type& v00,const Type& v10,const Type& v01,const Type& v11,
const float x, const float y)
{
//This function is called frequently and is very short, so assert rather than exceptions.
POLYVOX_ASSERT((x >= 0.0f) && (y >= 0.0f) &&
(x <= 1.0f) && (y <= 1.0f), "Interpolation input out of 0.0 to 1.0 range.");
@ -63,6 +65,7 @@ namespace PolyVox
const Type& v001,const Type& v101,const Type& v011,const Type& v111,
const float x, const float y, const float z)
{
//This function is called frequently and is very short, so assert rather than exceptions.
POLYVOX_ASSERT((x >= 0.0f) && (y >= 0.0f) && (z >= 0.0f) &&
(x <= 1.0f) && (y <= 1.0f) && (z <= 1.0f), "Interpolation input out of 0.0 to 1.0 range.");

View File

@ -27,7 +27,6 @@ freely, subject to the following restrictions:
#include "PolyVoxCore/BaseVolume.h"
#include "Impl/Block.h"
#include "PolyVoxCore/Compressor.h"
#include "PolyVoxCore/Log.h"
#include "PolyVoxCore/Region.h"
#include "PolyVoxCore/Vector.h"

View File

@ -90,7 +90,7 @@ namespace PolyVox
template <typename VoxelType>
LargeVolume<VoxelType>::LargeVolume(const LargeVolume<VoxelType>& /*rhs*/)
{
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented for performance reasons.");
}
////////////////////////////////////////////////////////////////////////////////
@ -112,7 +112,7 @@ namespace PolyVox
template <typename VoxelType>
LargeVolume<VoxelType>& LargeVolume<VoxelType>::operator=(const LargeVolume<VoxelType>& /*rhs*/)
{
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
}
////////////////////////////////////////////////////////////////////////////////
@ -124,6 +124,7 @@ namespace PolyVox
template <typename VoxelType>
VoxelType LargeVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
{
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
@ -228,7 +229,7 @@ namespace PolyVox
default:
{
//Should never happen
POLYVOX_ASSERT(false, "Invlaid case.");
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
return VoxelType();
}
}
@ -282,6 +283,7 @@ namespace PolyVox
template <typename VoxelType>
bool LargeVolume<VoxelType>::setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
{
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
@ -445,13 +447,8 @@ namespace PolyVox
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
void LargeVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength)
{
//Debug mode validation
POLYVOX_ASSERT(uBlockSideLength > 0, "Block side length cannot be zero.");
POLYVOX_ASSERT(isPowerOf2(uBlockSideLength), "Block side length must be a power of two.");
POLYVOX_ASSERT(m_pCompressor, "You must provide a compressor for the LargeVolume to use.");
//Release mode validation
{
//Validate parameters
if(uBlockSideLength == 0)
{
POLYVOX_THROW(std::invalid_argument, "Block side length cannot be zero.");

View File

@ -143,7 +143,7 @@ namespace PolyVox
}*/
//Need to think what effect this has on any existing iterators.
POLYVOX_ASSERT(false, "This function cnnot be used on LargeVolume samplers.");
POLYVOX_THROW(not_implemented, "This function cannot be used on LargeVolume samplers.");
return false;
}

View File

@ -1,63 +0,0 @@
/*******************************************************************************
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_Log_H__
#define __PolyVox_Log_H__
#include "Impl/TypeDef.h"
#include <string>
//Note: The functions in this file are not for the user to call - they are
//intended for internal use only. The only exception is that you may set the
//logHandler pointer to point at your own handling funtion for printing, etc.
namespace PolyVox
{
////////////////////////////////////////////////////////////////////////////////
/// Log levels for filtering logging events
////////////////////////////////////////////////////////////////////////////////
enum LogSeverity
{
LS_DEBUG, ///< Only displayed if it is a debug build
LS_INFO,
LS_WARN,
LS_ERROR
};
POLYVOX_API extern void (*logHandler)(std::string, int severity);
}
//Debug severity messages are only used if we are a debug build
#ifdef _DEBUG
#define POLYVOX_LOG_DEBUG(message) if(logHandler){logHandler(message, LS_DEBUG);}
#else
#define POLYVOX_LOG_DEBUG(message)
#endif
//Other severity levels work in both debug and release
#define POLYVOX_LOG_INFO(message) if(logHandler){logHandler(message, LS_INFO);}
#define POLYVOX_LOG_WARN(message) if(logHandler){logHandler(message, LS_WARN);}
#define POLYVOX_LOG_ERROR(message) if(logHandler){logHandler(message, LS_ERROR);}
#endif

View File

@ -39,14 +39,15 @@ namespace PolyVox
,m_uKernelSize(uKernelSize)
{
//Kernel size must be at least three
POLYVOX_ASSERT(m_uKernelSize >= 3, "Kernel size must be at least three");
m_uKernelSize = std::max(m_uKernelSize, static_cast<uint32_t>(3)); //For release builds
if(m_uKernelSize < 3)
{
POLYVOX_THROW(std::invalid_argument, "Kernel size must be at least three");
}
//Kernel size must be odd
POLYVOX_ASSERT(m_uKernelSize % 2 == 1, "Kernel size must be odd");
if(m_uKernelSize % 2 == 0) //For release builds
if(m_uKernelSize % 2 == 0)
{
m_uKernelSize++;
POLYVOX_THROW(std::invalid_argument, "Kernel size must be odd");
}
}

View File

@ -1,29 +1,49 @@
/*******************************************************************************
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.
*******************************************************************************/
#include "PolyVoxCore/Log.h"
namespace PolyVox
{
void (*logHandler)(std::string, int severity) = 0;
}
/*******************************************************************************
Copyright (c) 2013 Matt 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_Picking_H__
#define __PolyVox_Picking_H__
#include "PolyVoxCore/Vector.h"
namespace PolyVox
{
/**
* A structure containing the information about a picking operation
*/
struct PickResult
{
PickResult() : didHit(false) {}
bool didHit; ///< Did the picking operation hit anything
Vector3DInt32 hitVoxel; ///< The location of the solid voxel it hit
Vector3DInt32 previousVoxel; ///< The location of the voxel before the one it hit
};
/// Pick the first solid voxel along a vector
template<typename VolumeType>
PickResult pickVoxel(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, const typename VolumeType::VoxelType& emptyVoxelExample);
}
#include "PolyVoxCore/Picking.inl"
#endif //__PolyVox_Picking_H__

View File

@ -0,0 +1,84 @@
/*******************************************************************************
Copyright (c) 2013 Matt 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.
*******************************************************************************/
#include "PolyVoxCore/Raycast.h"
namespace PolyVox
{
namespace
{
/**
* This is just an implementation class for the pickVoxel function
*
* It makes note of the sort of empty voxel you're looking for in the constructor.
*
* Each time the operator() is called:
* * if it's hit a voxel it sets up the result and returns false
* * otherwise it preps the result for the next iteration and returns true
*/
template <typename VolumeType>
class RaycastPickingFunctor
{
public:
RaycastPickingFunctor(const typename VolumeType::VoxelType& emptyVoxelExample)
:m_emptyVoxelExample(emptyVoxelExample)
,m_result()
{
}
bool operator()(const typename VolumeType::Sampler& sampler)
{
if(sampler.getVoxel() != m_emptyVoxelExample) //If we've hit something
{
m_result.didHit = true;
m_result.hitVoxel = sampler.getPosition();
return false;
}
m_result.previousVoxel = sampler.getPosition();
return true;
}
const typename VolumeType::VoxelType& m_emptyVoxelExample;
PickResult m_result;
};
}
/**
* \param volData The volume to pass the ray though
* \param v3dStart The start position in the volume
* \param v3dDirectionAndLength The direction and length of the ray
* \param emptyVoxelExample The value used to represent empty voxels in your volume
*
* \return A PickResult containing the hit information
*/
template<typename VolumeType>
PickResult pickVoxel(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, const typename VolumeType::VoxelType& emptyVoxelExample)
{
RaycastPickingFunctor<VolumeType> functor(emptyVoxelExample);
raycastWithDirection(volData, v3dStart, v3dDirectionAndLength, functor);
return functor.m_result;
}
}

View File

@ -25,7 +25,6 @@ freely, subject to the following restrictions:
#define __PolyVox_RawVolume_H__
#include "PolyVoxCore/BaseVolume.h"
#include "PolyVoxCore/Log.h"
#include "PolyVoxCore/Region.h"
#include "PolyVoxCore/Vector.h"

View File

@ -47,7 +47,7 @@ namespace PolyVox
template <typename VoxelType>
RawVolume<VoxelType>::RawVolume(const RawVolume<VoxelType>& /*rhs*/)
{
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented for performance reasons.");
}
////////////////////////////////////////////////////////////////////////////////
@ -70,7 +70,7 @@ namespace PolyVox
template <typename VoxelType>
RawVolume<VoxelType>& RawVolume<VoxelType>::operator=(const RawVolume<VoxelType>& /*rhs*/)
{
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
}
////////////////////////////////////////////////////////////////////////////////
@ -82,6 +82,7 @@ namespace PolyVox
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
{
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner();
@ -186,7 +187,7 @@ namespace PolyVox
default:
{
//Should never happen
POLYVOX_ASSERT(false, "Invalid case.");
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
return VoxelType();
}
}
@ -254,10 +255,18 @@ namespace PolyVox
{
this->m_regValidRegion = regValidRegion;
//Ensure dimensions of the specified Region are valid
POLYVOX_ASSERT(this->getWidth() > 0, "Volume width must be greater than zero.");
POLYVOX_ASSERT(this->getHeight() > 0, "Volume width must be greater than zero.");
POLYVOX_ASSERT(this->getDepth() > 0, "Volume width must be greater than zero.");
if(this->getWidth() <= 0)
{
POLYVOX_THROW(std::invalid_argument, "Volume width must be greater than zero.");
}
if(this->getHeight() <= 0)
{
POLYVOX_THROW(std::invalid_argument, "Volume height must be greater than zero.");
}
if(this->getDepth() <= 0)
{
POLYVOX_THROW(std::invalid_argument, "Volume depth must be greater than zero.");
}
//Create the data
m_pData = new VoxelType[this->getWidth() * this->getHeight()* this->getDepth()];

View File

@ -27,7 +27,6 @@ freely, subject to the following restrictions:
#include "Impl/Utility.h"
#include "PolyVoxCore/BaseVolume.h"
#include "PolyVoxCore/Log.h"
#include "PolyVoxCore/Region.h"
#include "PolyVoxCore/Vector.h"

View File

@ -48,7 +48,7 @@ namespace PolyVox
template <typename VoxelType>
SimpleVolume<VoxelType>::SimpleVolume(const SimpleVolume<VoxelType>& /*rhs*/)
{
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented for performance reasons.");
}
////////////////////////////////////////////////////////////////////////////////
@ -70,7 +70,7 @@ namespace PolyVox
template <typename VoxelType>
SimpleVolume<VoxelType>& SimpleVolume<VoxelType>::operator=(const SimpleVolume<VoxelType>& /*rhs*/)
{
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
}
////////////////////////////////////////////////////////////////////////////////
@ -82,6 +82,7 @@ namespace PolyVox
template <typename VoxelType>
VoxelType SimpleVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
{
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
@ -186,7 +187,7 @@ namespace PolyVox
default:
{
//Should never happen
POLYVOX_ASSERT(false, "Invalid case.");
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
return VoxelType();
}
}
@ -212,6 +213,7 @@ namespace PolyVox
template <typename VoxelType>
bool SimpleVolume<VoxelType>::setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
{
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
@ -246,12 +248,7 @@ namespace PolyVox
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
void SimpleVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength)
{
//Debug mode validation
POLYVOX_ASSERT(uBlockSideLength >= 8, "Block side length should be at least 8");
POLYVOX_ASSERT(uBlockSideLength <= 256, "Block side length should not be more than 256");
POLYVOX_ASSERT(isPowerOf2(uBlockSideLength), "Block side length must be a power of two.");
{
//Release mode validation
if(uBlockSideLength < 8)
{

View File

@ -52,10 +52,10 @@ namespace PolyVox
template <typename VoxelType>
VoxelType SimpleVolume<VoxelType>::Block::getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const
{
// This is internal code not directly called by the user. For efficiency we assert rather than throwing.
POLYVOX_ASSERT(uXPos < m_uSideLength, "Position is outside of the block.");
POLYVOX_ASSERT(uYPos < m_uSideLength, "Position is outside of the block.");
POLYVOX_ASSERT(uZPos < m_uSideLength, "Position is outside of the block.");
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data available");
return m_tUncompressedData
@ -75,10 +75,10 @@ namespace PolyVox
template <typename VoxelType>
void SimpleVolume<VoxelType>::Block::setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue)
{
// This is internal code not directly called by the user. For efficiency we assert rather than throwing.
POLYVOX_ASSERT(uXPos < m_uSideLength, "Position is outside of the block.");
POLYVOX_ASSERT(uYPos < m_uSideLength, "Position is outside of the block.");
POLYVOX_ASSERT(uZPos < m_uSideLength, "Position is outside of the block.");
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data available");
m_tUncompressedData
@ -105,9 +105,6 @@ namespace PolyVox
template <typename VoxelType>
void SimpleVolume<VoxelType>::Block::initialise(uint16_t uSideLength)
{
//Debug mode validation
POLYVOX_ASSERT(isPowerOf2(uSideLength), "Block side length must be a power of two.");
//Release mode validation
if(!isPowerOf2(uSideLength))
{

View File

@ -414,7 +414,11 @@ namespace PolyVox
template <uint32_t Size, typename StorageType, typename OperationType>
inline StorageType Vector<Size, StorageType, OperationType>::getElement(uint32_t index) const
{
POLYVOX_ASSERT(index < Size, "Attempted to access invalid vector element.");
if(index >= Size)
{
POLYVOX_THROW(std::out_of_range, "Attempted to access invalid vector element.");
}
return m_tElements[index];
}
@ -465,7 +469,11 @@ namespace PolyVox
template <uint32_t Size, typename StorageType, typename OperationType>
inline void Vector<Size, StorageType, OperationType>::setElement(uint32_t index, StorageType tValue)
{
POLYVOX_ASSERT(index < Size, "Attempted to access invalid vector element.");
if(index >= Size)
{
POLYVOX_THROW(std::out_of_range, "Attempted to access invalid vector element.");
}
m_tElements[index] = tValue;
}
@ -645,10 +653,17 @@ namespace PolyVox
inline void Vector<Size, StorageType, OperationType>::normalise(void)
{
float fLength = this->length();
if(fLength <= 0.0)
{
POLYVOX_THROW(invalid_operation, "Cannot normalise a vector with a length of zero");
}
for(uint32_t ct = 0; ct < Size; ++ct)
{
// Standard float rules apply for divide-by-zero
m_tElements[ct] /= fLength;
//This shouldn't happen as we had the length check earlier. So it's probably a bug if it does happen.
POLYVOX_ASSERT(m_tElements[ct] == m_tElements[ct], "Obtained NAN during vector normalisation. Perhaps the input vector was too short?");
}
}

View File

@ -23,49 +23,135 @@ freely, subject to the following restrictions:
#include "PolyVoxCore/Impl/ErrorHandling.h"
#ifndef POLYVOX_THROW_ENABLED
namespace PolyVox
namespace PolyVox
{
void defaultLogHandler(const std::string& message, LogLevel logLevel)
{
void defaultThrowHandler(std::exception& e, const char* file, int line)
switch(logLevel)
{
std::cerr << std::endl << std::endl; \
std::cerr << " PolyVox exception thrown!" << std::endl; \
std::cerr << " =========================" << std::endl; \
std::cerr << " PolyVox has tried to throw an exception but it was built without support" << std::endl; \
std::cerr << " for exceptions. In this scenario PolyVox will call a 'throw handler'" << std::endl; \
std::cerr << " and this message is being printed by the default throw handler." << std::endl << std::endl; \
std::cerr << " If you don't want to enable exceptions then you should try to determine why" << std::endl; \
std::cerr << " this exception was thrown and make sure it doesn't happen again. If it was" << std::endl; \
std::cerr << " due to something like an invalid argument to a function then you should be" << std::endl; \
std::cerr << " able to fix it quite easily by validating parameters as appropriate. More" << std::endl; \
std::cerr << " complex exception scenarios (out of memory, etc) might be harder to fix and" << std::endl; \
std::cerr << " you should replace this default handler with something which is more" << std::endl; \
std::cerr << " meaningful to your users." << std::endl << std::endl; \
std::cerr << " Exception details" << std::endl; \
std::cerr << " -----------------" << std::endl; \
std::cerr << " Line: " << line << std::endl; \
std::cerr << " File: " << file << std::endl; \
std::cerr << " Message: " << e.what() << std::endl << std::endl; \
POLYVOX_HALT(); \
}
ThrowHandler& getThrowHandlerInstance()
{
static ThrowHandler s_fThrowHandler = &defaultThrowHandler;
return s_fThrowHandler;
}
ThrowHandler getThrowHandler()
{
return getThrowHandlerInstance();
}
void setThrowHandler(ThrowHandler fNewHandler)
{
getThrowHandlerInstance() = fNewHandler;
case LogLevels::Debug:
{
// Debug messages are not output by this default log handler.
// Provide a custom handler if you want to process them.
break;
}
case LogLevels::Info:
{
std::cout << "Info: " << message.c_str() << std::endl;
break;
}
case LogLevels::Warning:
{
std::cerr << "Warning: " << message.c_str() << std::endl;
break;
}
case LogLevels::Error:
{
std::cerr << "Error: " << message.c_str() << std::endl;
break;
}
case LogLevels::Fatal:
{
std::cerr << "Fatal: " << message.c_str() << std::endl;
break;
}
}
}
LogHandler& getLogHandlerInstance()
{
static LogHandler s_fLogHandler = &defaultLogHandler;
return s_fLogHandler;
}
LogHandler getLogHandler()
{
return getLogHandlerInstance();
}
void setLogHandler(LogHandler fNewHandler)
{
getLogHandlerInstance() = fNewHandler;
}
void log(const std::string& message, LogLevel logLevel)
{
LogHandler logHandler = getLogHandler();
if(logHandler)
{
logHandler(message, logLevel);
}
}
// Some handy wrappers
void logDebug(const std::string& message)
{
log(message, LogLevels::Debug );
}
void logInfo(const std::string& message)
{
log(message, LogLevels::Info);
}
void logWarning(const std::string& message)
{
log(message, LogLevels::Warning);
}
void logError(const std::string& message)
{
log(message, LogLevels::Error);
}
void logFatal(const std::string& message)
{
log(message, LogLevels::Fatal);
}
#ifndef POLYVOX_THROW_ENABLED
void defaultThrowHandler(std::exception& e, const char* file, int line)
{
std::stringstream ss; \
ss << std::endl << std::endl; \
ss << " PolyVox exception thrown!" << std::endl; \
ss << " =========================" << std::endl; \
ss << " PolyVox has tried to throw an exception but it was built without support" << std::endl; \
ss << " for exceptions. In this scenario PolyVox will call a 'throw handler'" << std::endl; \
ss << " and this message is being printed by the default throw handler." << std::endl << std::endl; \
ss << " If you don't want to enable exceptions then you should try to determine why" << std::endl; \
ss << " this exception was thrown and make sure it doesn't happen again. If it was" << std::endl; \
ss << " due to something like an invalid argument to a function then you should be" << std::endl; \
ss << " able to fix it quite easily by validating parameters as appropriate. More" << std::endl; \
ss << " complex exception scenarios (out of memory, etc) might be harder to fix and" << std::endl; \
ss << " you should replace this default handler with something which is more" << std::endl; \
ss << " meaningful to your users." << std::endl << std::endl; \
ss << " Exception details" << std::endl; \
ss << " -----------------" << std::endl; \
ss << " Line: " << line << std::endl; \
ss << " File: " << file << std::endl; \
ss << " Message: " << e.what() << std::endl << std::endl; \
logFatal(ss.str()); \
POLYVOX_HALT(); \
}
ThrowHandler& getThrowHandlerInstance()
{
static ThrowHandler s_fThrowHandler = &defaultThrowHandler;
return s_fThrowHandler;
}
ThrowHandler getThrowHandler()
{
return getThrowHandlerInstance();
}
void setThrowHandler(ThrowHandler fNewHandler)
{
getThrowHandlerInstance() = fNewHandler;
}
#endif
}

View File

@ -30,10 +30,6 @@ namespace PolyVox
//If this is not the case then the output is undefined.
uint8_t logBase2(uint32_t uInput)
{
//Debug mode validation
POLYVOX_ASSERT(uInput != 0, "Cannot compute the log of zero.");
POLYVOX_ASSERT(isPowerOf2(uInput), "Input must be a power of two in order to compute the log.");
//Release mode validation
if(uInput == 0)
{

View File

@ -78,7 +78,10 @@ namespace PolyVox
*/
void Region::accumulate(const Region& reg)
{
POLYVOX_ASSERT(reg.isValid(), "You cannot accumulate an invalid region."); //The result of accumulating an invalid region is not defined.
if(!reg.isValid())
{
POLYVOX_THROW(invalid_operation, "You cannot accumulate an invalid region."); //The result of accumulating an invalid region is not defined.
}
m_iLowerX = ((std::min)(m_iLowerX, reg.getLowerX()));
m_iLowerY = ((std::min)(m_iLowerY, reg.getLowerY()));

View File

@ -23,7 +23,7 @@ option(ENABLE_BINDINGS "Build Python bindings" ON)
if(ENABLE_BINDINGS)
find_package(SWIG)
mark_as_advanced(SWIG_DIR SWIG_VERSION)
find_package(PythonLibs)
find_package(PythonLibs 3)
if(CMAKE_VERSION VERSION_LESS "2.8.6")
set_package_info(SWIG "Bindings generator" http://www.swig.org)
set_package_info(PythonLibs "Programming language" http://www.python.org)
@ -43,6 +43,7 @@ if(ENABLE_BINDINGS)
set_source_files_properties(PolyVoxCore.i PROPERTIES CPLUSPLUS ON)
#set_source_files_properties(PolyVoxCore.i PROPERTIES SWIG_FLAGS "-builtin")
set(SWIG_MODULE_PolyVoxCorePython_EXTRA_FLAGS "-py3")
swig_add_module(PolyVoxCorePython python PolyVoxCore.i)
swig_link_libraries(PolyVoxCorePython ${PYTHON_LIBRARIES} PolyVoxCore)
set_target_properties(${SWIG_MODULE_PolyVoxCorePython_REAL_NAME} PROPERTIES OUTPUT_NAME _PolyVoxCore)

View File

@ -0,0 +1,8 @@
%module Picking
%{
#include "Picking.h"
%}
%include "Picking.h"
EXTRACTORS(pickVoxel)

View File

@ -90,3 +90,4 @@ EXTRACTOR(shortname, LargeVolume)
%include "CubicSurfaceExtractor.i"
%include "CubicSurfaceExtractorWithNormals.i"
%include "Raycast.i"
%include "Picking.i"