/////////////////////////////////////////////////////////////////////////// // // Copyright (c) 1998-2011, Industrial Light & Magic, a division of Lucas // Digital Ltd. LLC // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Industrial Light & Magic nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // /////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include namespace PyImath { using namespace boost::python; using namespace PyImath; namespace { template struct rotationXYZWithUpDir_op { static IMATH_NAMESPACE::Vec3 apply(const IMATH_NAMESPACE::Vec3 &from, const IMATH_NAMESPACE::Vec3 &to, const IMATH_NAMESPACE::Vec3 &up) { IMATH_NAMESPACE::Vec3 retval; IMATH_NAMESPACE::extractEulerXYZ(IMATH_NAMESPACE::rotationMatrixWithUpDir(from,to,up),retval); return retval; } }; template struct abs_op { static T apply(T value) { return IMATH_NAMESPACE::abs(value); } }; template struct sign_op { static T apply(T value) { return IMATH_NAMESPACE::sign(value); } }; template struct log_op { static T apply(T value) { return ::log(value); } }; template struct log10_op { static T apply(T value) { return ::log10(value); } }; template struct lerp_op { static T apply(T a, T b, T t) { return IMATH_NAMESPACE::lerp(a,b,t); } }; template struct ulerp_op { static T apply(T a, T b, T t) { return IMATH_NAMESPACE::ulerp(a,b,t); } }; template struct lerpfactor_op { static T apply(T a, T b, T t) { return IMATH_NAMESPACE::lerpfactor(a,b,t); } }; template struct clamp_op { static T apply(T value, T low, T high) { return IMATH_NAMESPACE::clamp(value,low,high); } }; template struct cmp_op { static T apply(T value) { return IMATH_NAMESPACE::cmp(value); } }; template struct cmpt_op { static T apply(T value) { return IMATH_NAMESPACE::cmpt(value); } }; template struct iszero_op { static T apply(T value) { return IMATH_NAMESPACE::iszero(value); } }; template struct equal_op { static T apply(T value) { return IMATH_NAMESPACE::equal(value); } }; template struct floor_op { static int apply(T value) { return IMATH_NAMESPACE::floor(value); } }; template struct ceil_op { static int apply(T value) { return IMATH_NAMESPACE::ceil(value); } }; template struct trunc_op { static int apply(T value) { return IMATH_NAMESPACE::trunc(value); } }; struct divs_op { static int apply(int x, int y) { return IMATH_NAMESPACE::divs(x,y); } }; struct mods_op { static int apply(int x, int y) { return IMATH_NAMESPACE::mods(x,y); } }; struct divp_op { static int apply(int x, int y) { return IMATH_NAMESPACE::divp(x,y); } }; struct modp_op { static int apply(int x, int y) { return IMATH_NAMESPACE::modp(x,y); } }; struct bias_op { static inline float apply(float x, float b) { if (b != 0.5f) { static const float inverse_log_half = 1.0f / std::log(0.5f); const float biasPow = std::log(b)*inverse_log_half; return std::pow(x, biasPow); } return x; } }; struct gain_op { static inline float apply(float x, float g) { if (x < 0.5f) return 0.5f*bias_op::apply(2.0f*x, 1.0f - g); else return 1.0f - 0.5f*bias_op::apply(2.0f - 2.0f*x, 1.0f - g); } }; } // namespace void register_functions() { // // Utility Functions // // nb: MSVC gets confused about which arg we want (it thinks it // might be boost::arg), so telling it which one explicitly here. typedef boost::python::arg arg; PyImath::generate_bindings,boost::mpl::true_>( "abs", "return the absolute value of 'value'", (arg("value"))); PyImath::generate_bindings,boost::mpl::true_>( "abs", "return the absolute value of 'value'", (arg("value"))); PyImath::generate_bindings,boost::mpl::true_>( "abs", "return the absolute value of 'value'", (arg("value"))); PyImath::generate_bindings,boost::mpl::true_>( "sign", "return 1 or -1 based on the sign of 'value'", (arg("value"))); PyImath::generate_bindings,boost::mpl::true_>( "sign", "return 1 or -1 based on the sign of 'value'", (arg("value"))); PyImath::generate_bindings,boost::mpl::true_>( "sign", "return 1 or -1 based on the sign of 'value'", (arg("value"))); PyImath::generate_bindings,boost::mpl::true_>( "log", "return the natural log of 'value'", (arg("value"))); PyImath::generate_bindings,boost::mpl::true_>( "log", "return the natural log of 'value'", (arg("value"))); PyImath::generate_bindings,boost::mpl::true_>( "log10", "return the base 10 log of 'value'", (arg("value"))); PyImath::generate_bindings,boost::mpl::true_>( "log10", "return the base 10 log of 'value'", (arg("value"))); PyImath::generate_bindings,boost::mpl::true_,boost::mpl::true_,boost::mpl::true_>( "lerp", "return the linear interpolation of 'a' to 'b' using parameter 't'", (arg("a"),arg("b"),arg("t"))); PyImath::generate_bindings,boost::mpl::true_,boost::mpl::true_,boost::mpl::true_>( "lerp", "return the linear interpolation of 'a' to 'b' using parameter 't'", (arg("a"),arg("b"),arg("t"))); PyImath::generate_bindings,boost::mpl::true_,boost::mpl::true_,boost::mpl::true_>( "lerpfactor", "return how far m is between a and b, that is return t such that\n" "if:\n" " t = lerpfactor(m, a, b);\n" "then:\n" " m = lerp(a, b, t);\n" "\n" "If a==b, return 0.\n", (arg("m"),arg("a"),arg("b"))); PyImath::generate_bindings,boost::mpl::true_,boost::mpl::true_,boost::mpl::true_>( "lerpfactor", "return how far m is between a and b, that is return t such that\n" " if:\n" " t = lerpfactor(m, a, b);\n" " then:\n" " m = lerp(a, b, t);\n" " if a==b, return 0.\n", (arg("m"),arg("a"),arg("b"))); PyImath::generate_bindings,boost::mpl::true_,boost::mpl::true_,boost::mpl::true_>( "clamp", "return the value clamped to the range [low,high]", (arg("value"),arg("low"),arg("high"))); PyImath::generate_bindings,boost::mpl::true_,boost::mpl::true_,boost::mpl::true_>( "clamp", "return the value clamped to the range [low,high]", (arg("value"),arg("low"),arg("high"))); PyImath::generate_bindings,boost::mpl::true_,boost::mpl::true_,boost::mpl::true_>( "clamp", "return the value clamped to the range [low,high]", (arg("value"),arg("low"),arg("high"))); def("cmp", IMATH_NAMESPACE::cmp); def("cmp", IMATH_NAMESPACE::cmp); def("cmpt", IMATH_NAMESPACE::cmpt); def("cmpt", IMATH_NAMESPACE::cmpt); def("iszero", IMATH_NAMESPACE::iszero); def("iszero", IMATH_NAMESPACE::iszero); def("equal", IMATH_NAMESPACE::equal); def("equal", IMATH_NAMESPACE::equal); PyImath::generate_bindings,boost::mpl::true_>( "floor", "return the closest integer less than or equal to 'value'", (arg("value"))); PyImath::generate_bindings,boost::mpl::true_>( "floor", "return the closest integer less than or equal to 'value'", (arg("value"))); PyImath::generate_bindings,boost::mpl::true_>( "ceil", "return the closest integer greater than or equal to 'value'", (arg("value"))); PyImath::generate_bindings,boost::mpl::true_>( "ceil", "return the closest integer greater than or equal to 'value'", (arg("value"))); PyImath::generate_bindings,boost::mpl::true_>( "trunc", "return the closest integer with magnitude less than or equal to 'value'", (arg("value"))); PyImath::generate_bindings,boost::mpl::true_>( "trunc", "return the closest integer with magnitude less than or equal to 'value'", (arg("value"))); PyImath::generate_bindings( "divs", "return x/y where the remainder has the same sign as x:\n" " divs(x,y) == (abs(x) / abs(y)) * (sign(x) * sign(y))\n", (arg("x"),arg("y"))); PyImath::generate_bindings( "mods", "return x%y where the remainder has the same sign as x:\n" " mods(x,y) == x - y * divs(x,y)\n", (arg("x"),arg("y"))); PyImath::generate_bindings( "divp", "return x/y where the remainder is always positive:\n" " divp(x,y) == floor (double(x) / double (y))\n", (arg("x"),arg("y"))); PyImath::generate_bindings( "modp", "return x%y where the remainder is always positive:\n" " modp(x,y) == x - y * divp(x,y)\n", (arg("x"),arg("y"))); PyImath::generate_bindings( "bias", "bias(x,b) is a gamma correction that remaps the unit interval such that bias(0.5, b) = b.", (arg("x"),arg("b"))); PyImath::generate_bindings( "gain", "gain(x,g) is a gamma correction that remaps the unit interval with the property that gain(0.5, g) = 0.5.\n" "The gain function can be thought of as two scaled bias curves forming an 'S' shape in the unit interval.", (arg("x"),arg("g"))); // // Vectorized utility functions // PyImath::generate_bindings,boost::mpl::true_,boost::mpl::true_,boost::mpl::true_>( "rotationXYZWithUpDir", "return the XYZ rotation vector that rotates 'fromDir' to 'toDir'" "using the up vector 'upDir'", args("fromDir","toDir","upDir")); } } // namespace PyImath