Skip to content

Commit

Permalink
prototyped half support
Browse files Browse the repository at this point in the history
prototyped half support
  • Loading branch information
ghurstunither committed Feb 20, 2024
1 parent b2f758b commit c0cecf7
Show file tree
Hide file tree
Showing 16 changed files with 174 additions and 89 deletions.
2 changes: 1 addition & 1 deletion openvdb/openvdb/Grid.h
Original file line number Diff line number Diff line change
Expand Up @@ -1750,7 +1750,7 @@ createLevelSet(Real voxelSize, Real halfWidth)
using ValueType = typename GridType::ValueType;

// GridType::ValueType is required to be a floating-point scalar.
static_assert(std::is_floating_point<ValueType>::value,
static_assert(openvdb::is_floating_point<ValueType>::value,
"level-set grids must be floating-point-valued");

typename GridType::Ptr grid = GridType::create(
Expand Down
30 changes: 9 additions & 21 deletions openvdb/openvdb/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,7 @@
#include "Platform.h"
#include "TypeList.h" // backwards compat

#ifdef OPENVDB_USE_IMATH_HALF
#ifdef OPENVDB_IMATH_VERSION
#include <Imath/half.h>
#else
#include <OpenEXR/half.h>
#endif
namespace openvdb {
OPENVDB_USE_VERSION_NAMESPACE
namespace OPENVDB_VERSION_NAME {
namespace math {
using half = half;
}}}
#else
#include <openvdb/math/Half.h>
namespace openvdb {
OPENVDB_USE_VERSION_NAMESPACE
namespace OPENVDB_VERSION_NAME {
namespace math {
using half = internal::half;
}}}
#endif
#include <openvdb/math/HalfDecl.h>

#include <openvdb/math/Math.h>
#include <openvdb/math/BBox.h>
Expand Down Expand Up @@ -454,6 +434,14 @@ struct is_floating_point : std::is_floating_point<T> { };
template<>
struct is_floating_point<Half> : std::is_floating_point<float> { };


template<class T>
struct is_signed : std::is_signed<T> { };

template<>
struct is_signed<Half> : std::is_signed<float> { };


/// @brief Maps one type (e.g. the value types) to other types
template<typename T>
struct ValueToComputeMap
Expand Down
30 changes: 30 additions & 0 deletions openvdb/openvdb/math/HalfDecl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: MPL-2.0

#ifndef OPENVDB_HALFDECL_HAS_BEEN_INCLUDED
#define OPENVDB_HALFDECL_HAS_BEEN_INCLUDED

#ifdef OPENVDB_USE_IMATH_HALF
#ifdef OPENVDB_IMATH_VERSION
#include <Imath/half.h>
#else
#include <OpenEXR/half.h>
#endif
namespace openvdb {
OPENVDB_USE_VERSION_NAMESPACE
namespace OPENVDB_VERSION_NAME {
namespace math {
using half = half;
}}}
#else
#include <openvdb/math/Half.h>
namespace openvdb {
OPENVDB_USE_VERSION_NAMESPACE
namespace OPENVDB_VERSION_NAME {
namespace math {
using half = internal::half;
}}}
#endif


#endif // OPENVDB_HALFDECL_HAS_BEEN_INCLUDED
98 changes: 81 additions & 17 deletions openvdb/openvdb/math/Math.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <openvdb/Platform.h>
#include <openvdb/version.h>
#include <openvdb/math/HalfDecl.h>
#include <openvdb/util/Assert.h>
#include <boost/numeric/conversion/conversion_traits.hpp>
#include <algorithm> // for std::max()
Expand Down Expand Up @@ -146,9 +147,10 @@ template<> inline std::string negative(const std::string& val) { return val; }

//@{
/// Tolerance for floating-point comparison
template<typename T> struct Tolerance { static T value() { return zeroVal<T>(); } };
template<> struct Tolerance<float> { static float value() { return 1e-8f; } };
template<> struct Tolerance<double> { static double value() { return 1e-15; } };
template<typename T> struct Tolerance { static T value() { return zeroVal<T>(); } };
template<> struct Tolerance<math::half> { static math::half value() { return 0.00097656; } };
template<> struct Tolerance<float> { static float value() { return 1e-8f; } };
template<> struct Tolerance<double> { static double value() { return 1e-15; } };
//@}

//@{
Expand Down Expand Up @@ -362,6 +364,10 @@ isApproxZero(const Type& x, const Type& tolerance)
}


/// Return @c true if @a x is less than zero.
inline bool
isNegative(math::half& x) { return x.isNegative(); }

/// Return @c true if @a x is less than zero.
template<typename Type>
inline bool
Expand All @@ -375,6 +381,10 @@ template<> inline bool isNegative<bool>(const bool&) { return false; }
inline bool
isFinite(const float x) { return std::isfinite(x); }

/// Return @c true if @a x is finite.
inline bool
isFinite(const math::half x) { return x.isFinite(); }

/// Return @c true if @a x is finite.
template<typename Type, typename std::enable_if<std::is_arithmetic<Type>::value, int>::type = 0>
inline bool
Expand All @@ -385,6 +395,10 @@ isFinite(const Type& x) { return std::isfinite(static_cast<double>(x)); }
inline bool
isInfinite(const float x) { return std::isinf(x); }

/// Return @c true if @a x is an infinity value (either positive infinity or negative infinity).
inline bool
isInfinite(const math::half x) { return x.isInfinity(); }

/// Return @c true if @a x is an infinity value (either positive infinity or negative infinity).
template<typename Type, typename std::enable_if<std::is_arithmetic<Type>::value, int>::type = 0>
inline bool
Expand All @@ -395,6 +409,10 @@ isInfinite(const Type& x) { return std::isinf(static_cast<double>(x)); }
inline bool
isNan(const float x) { return std::isnan(x); }

/// Return @c true if @a x is a NaN (Not-A-Number) value.
inline bool
isNan(const math::half x) { return x.isNan(); }

/// Return @c true if @a x is a NaN (Not-A-Number) value.
template<typename Type, typename std::enable_if<std::is_arithmetic<Type>::value, int>::type = 0>
inline bool
Expand Down Expand Up @@ -570,6 +588,15 @@ Pow(Type x, int n)
return ans;
}

//@{
/// Return @a b<sup>e</sup>.
inline math::half
Pow(math::half b, math::half e)
{
OPENVDB_ASSERT( b >= 0.0f && "Pow(half,half): base is negative" );
return math::half(powf(float(b),float(e)));
}

//@{
/// Return @a b<sup>e</sup>.
inline float
Expand All @@ -590,44 +617,61 @@ Pow(double b, double e)

// ==========> Max <==================

namespace internal {

inline const math::half&
max_impl(const math::half& a, const math::half& b)
{
return a > b ? a : b;
}

template<typename Type>
inline const Type&
max_impl(const Type& a, const Type& b)
{
return std::max(a,b);
}

} // namespace internal

/// Return the maximum of two values
template<typename Type>
inline const Type&
Max(const Type& a, const Type& b)
{
return std::max(a,b);
return internal::max_impl(a,b);
}

/// Return the maximum of three values
template<typename Type>
inline const Type&
Max(const Type& a, const Type& b, const Type& c)
{
return std::max(std::max(a,b), c);
return internal::max_impl(internal::max_impl(a,b), c);
}

/// Return the maximum of four values
template<typename Type>
inline const Type&
Max(const Type& a, const Type& b, const Type& c, const Type& d)
{
return std::max(std::max(a,b), std::max(c,d));
return internal::max_impl(internal::max_impl(a,b), internal::max_impl(c,d));
}

/// Return the maximum of five values
template<typename Type>
inline const Type&
Max(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e)
{
return std::max(std::max(a,b), Max(c,d,e));
return internal::max_impl(internal::max_impl(a,b), Max(c,d,e));
}

/// Return the maximum of six values
template<typename Type>
inline const Type&
Max(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e, const Type& f)
{
return std::max(Max(a,b,c), Max(d,e,f));
return internal::max_impl(Max(a,b,c), Max(d,e,f));
}

/// Return the maximum of seven values
Expand All @@ -636,7 +680,7 @@ inline const Type&
Max(const Type& a, const Type& b, const Type& c, const Type& d,
const Type& e, const Type& f, const Type& g)
{
return std::max(Max(a,b,c,d), Max(e,f,g));
return internal::max_impl(Max(a,b,c,d), Max(e,f,g));
}

/// Return the maximum of eight values
Expand All @@ -645,44 +689,64 @@ inline const Type&
Max(const Type& a, const Type& b, const Type& c, const Type& d,
const Type& e, const Type& f, const Type& g, const Type& h)
{
return std::max(Max(a,b,c,d), Max(e,f,g,h));
return internal::max_impl(Max(a,b,c,d), Max(e,f,g,h));
}


// ==========> Min <==================

namespace internal {

inline const math::half&
min_impl(const math::half& a, const math::half& b)
{
return a < b ? a : b;
}

template<typename Type>
inline const Type&
min_impl(const Type& a, const Type& b)
{
return std::min(a,b);
}

} // namespace internal

/// Return the minimum of two values
template<typename Type>
inline const Type&
Min(const Type& a, const Type& b) { return std::min(a, b); }
Min(const Type& a, const Type& b) { return internal::min_impl(a, b); }

/// Return the minimum of three values
template<typename Type>
inline const Type&
Min(const Type& a, const Type& b, const Type& c) { return std::min(std::min(a, b), c); }
Min(const Type& a, const Type& b, const Type& c)
{
return internal::min_impl(internal::min_impl(a, b), c);
}

/// Return the minimum of four values
template<typename Type>
inline const Type&
Min(const Type& a, const Type& b, const Type& c, const Type& d)
{
return std::min(std::min(a, b), std::min(c, d));
return internal::min_impl(internal::min_impl(a, b), internal::min_impl(c, d));
}

/// Return the minimum of five values
template<typename Type>
inline const Type&
Min(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e)
{
return std::min(std::min(a,b), Min(c,d,e));
return internal::min_impl(internal::min_impl(a,b), Min(c,d,e));
}

/// Return the minimum of six values
template<typename Type>
inline const Type&
Min(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e, const Type& f)
{
return std::min(Min(a,b,c), Min(d,e,f));
return internal::min_impl(Min(a,b,c), Min(d,e,f));
}

/// Return the minimum of seven values
Expand All @@ -691,7 +755,7 @@ inline const Type&
Min(const Type& a, const Type& b, const Type& c, const Type& d,
const Type& e, const Type& f, const Type& g)
{
return std::min(Min(a,b,c,d), Min(e,f,g));
return internal::min_impl(Min(a,b,c,d), Min(e,f,g));
}

/// Return the minimum of eight values
Expand All @@ -700,7 +764,7 @@ inline const Type&
Min(const Type& a, const Type& b, const Type& c, const Type& d,
const Type& e, const Type& f, const Type& g, const Type& h)
{
return std::min(Min(a,b,c,d), Min(e,f,g,h));
return internal::min_impl(Min(a,b,c,d), Min(e,f,g,h));
}


Expand Down
12 changes: 6 additions & 6 deletions openvdb/openvdb/math/Stencils.h
Original file line number Diff line number Diff line change
Expand Up @@ -1545,7 +1545,7 @@ class CurvatureStencil: public BaseStencil<CurvatureStencil<GridT, IsSafe>, Grid
{
Real alpha, normGrad;
return this->meanCurvature(alpha, normGrad) ?
ValueType(alpha*mInv2Dx/math::Pow3(normGrad)) : 0;
ValueType(alpha*mInv2Dx/math::Pow3(normGrad)) : ValueType(0);
}

/// @brief Return the Gaussian curvature at the previously buffered location.
Expand All @@ -1556,7 +1556,7 @@ class CurvatureStencil: public BaseStencil<CurvatureStencil<GridT, IsSafe>, Grid
{
Real alpha, normGrad;
return this->gaussianCurvature(alpha, normGrad) ?
ValueType(alpha*mInvDx2/math::Pow4(normGrad)) : 0;
ValueType(alpha*mInvDx2/math::Pow4(normGrad)) : ValueType(0);
}

/// @brief Return both the mean and the Gaussian curvature at the
Expand All @@ -1571,7 +1571,7 @@ class CurvatureStencil: public BaseStencil<CurvatureStencil<GridT, IsSafe>, Grid
mean = ValueType(alphaM*mInv2Dx/math::Pow3(normGrad));
gauss = ValueType(alphaG*mInvDx2/math::Pow4(normGrad));
} else {
mean = gauss = 0;
mean = gauss = ValueType(0);
}
}

Expand All @@ -1585,7 +1585,7 @@ class CurvatureStencil: public BaseStencil<CurvatureStencil<GridT, IsSafe>, Grid
{
Real alpha, normGrad;
return this->meanCurvature(alpha, normGrad) ?
ValueType(alpha*mInvDx2/(2*math::Pow2(normGrad))) : 0;
ValueType(alpha*mInvDx2/(2*math::Pow2(normGrad))) : ValueType(0);
}

/// Return the mean Gaussian multiplied by the norm of the
Expand All @@ -1597,7 +1597,7 @@ class CurvatureStencil: public BaseStencil<CurvatureStencil<GridT, IsSafe>, Grid
{
Real alpha, normGrad;
return this->gaussianCurvature(alpha, normGrad) ?
ValueType(2*alpha*mInv2Dx*mInvDx2/math::Pow3(normGrad)) : 0;
ValueType(2*alpha*mInv2Dx*mInvDx2/math::Pow3(normGrad)) : ValueType(0);
}

/// @brief Return both the mean and the Gaussian curvature at the
Expand Down Expand Up @@ -1627,7 +1627,7 @@ class CurvatureStencil: public BaseStencil<CurvatureStencil<GridT, IsSafe>, Grid
Real alphaM, alphaG, normGrad;
if (this->curvatures(alphaM, alphaG, normGrad)) {
const Real mean = alphaM*mInv2Dx/math::Pow3(normGrad);
const Real tmp = std::sqrt(mean*mean - alphaG*mInvDx2/math::Pow4(normGrad));
const Real tmp = math::Sqrt(mean*mean - alphaG*mInvDx2/math::Pow4(normGrad));
pair.first = ValueType(mean - tmp);
pair.second = ValueType(mean + tmp);
}
Expand Down
Loading

0 comments on commit c0cecf7

Please sign in to comment.