/////////////////////////////////////////////////////////////////////////// // // 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace boost::python; using namespace PyImath; namespace { template IMATH_NAMESPACE::Box > computeBoundingBox(const PyImath::FixedArray >& position) { IMATH_NAMESPACE::Box > bounds; int len = position.len(); for (int i = 0; i < len; ++i) bounds.extendBy(position[i]); return bounds; } IMATH_NAMESPACE::M44d procrustes1 (PyObject* from_input, PyObject* to_input, PyObject* weights_input = 0, bool doScale = false) { // Verify the sequences: if (!PySequence_Check (from_input)) { PyErr_SetString (PyExc_TypeError, "Expected a sequence type for 'from'"); boost::python::throw_error_already_set(); } if (!PySequence_Check (to_input)) { PyErr_SetString (PyExc_TypeError, "Expected a sequence type for 'to'"); boost::python::throw_error_already_set(); } bool useWeights = PySequence_Check (weights_input); // Now verify the lengths: const size_t n = PySequence_Length (from_input); if (n != PySequence_Length (to_input) || (useWeights && n != PySequence_Length (weights_input))) { PyErr_SetString (PyExc_TypeError, "'from, 'to', and 'weights' should all have the same lengths."); boost::python::throw_error_already_set(); } std::vector from; from.reserve (n); std::vector to; to.reserve (n); std::vector weights; weights.reserve (n); for (size_t i = 0; i < n; ++i) { PyObject* f = PySequence_GetItem (from_input, i); PyObject* t = PySequence_GetItem (to_input, i); PyObject* w = 0; if (useWeights) w = PySequence_GetItem (weights_input, i); if (f == 0 || t == 0 || (useWeights && w == 0)) { PyErr_SetString (PyExc_TypeError, "Missing element in array"); boost::python::throw_error_already_set(); } from.push_back (boost::python::extract (f)); to.push_back (boost::python::extract (t)); if (useWeights) weights.push_back (boost::python::extract (w)); } if (useWeights) return IMATH_NAMESPACE::procrustesRotationAndTranslation (&from[0], &to[0], &weights[0], n, doScale); else return IMATH_NAMESPACE::procrustesRotationAndTranslation (&from[0], &to[0], n, doScale); } FixedArray2D rangeX(int sizeX, int sizeY) { FixedArray2D f(sizeX, sizeY); for (int j=0; j rangeY(int sizeX, int sizeY) { FixedArray2D f(sizeX, sizeY); for (int j=0; j iex(PyImport_ImportModule("iex")); if (PyErr_Occurred()) boost::python::throw_error_already_set(); scope().attr("iex") = iex; scope().attr("__doc__") = "Imath module"; register_basicTypes(); class_ iclass2D = IntArray2D::register_("IntArray2D","Fixed length array of ints"); add_arithmetic_math_functions(iclass2D); add_mod_math_functions(iclass2D); add_comparison_functions(iclass2D); add_ordered_comparison_functions(iclass2D); add_explicit_construction_from_type(iclass2D); add_explicit_construction_from_type(iclass2D); class_ imclass = IntMatrix::register_("IntMatrix","Fixed size matrix of ints"); add_arithmetic_math_functions(imclass); class_ fclass2D = FloatArray2D::register_("FloatArray2D","Fixed length 2D array of floats"); add_arithmetic_math_functions(fclass2D); add_pow_math_functions(fclass2D); add_comparison_functions(fclass2D); add_ordered_comparison_functions(fclass2D); add_explicit_construction_from_type(fclass2D); add_explicit_construction_from_type(fclass2D); class_ fmclass = FloatMatrix::register_("FloatMatrix","Fixed size matrix of floats"); add_arithmetic_math_functions(fmclass); add_pow_math_functions(fmclass); class_ dclass2D = DoubleArray2D::register_("DoubleArray2D","Fixed length array of doubles"); add_arithmetic_math_functions(dclass2D); add_pow_math_functions(dclass2D); add_comparison_functions(dclass2D); add_ordered_comparison_functions(dclass2D); add_explicit_construction_from_type(dclass2D); add_explicit_construction_from_type(dclass2D); class_ dmclass = DoubleMatrix::register_("DoubleMatrix","Fixed size matrix of doubles"); add_arithmetic_math_functions(dmclass); add_pow_math_functions(dmclass); def("rangeX", &rangeX); def("rangeY", &rangeY); // // Vec2 // register_Vec2(); register_Vec2(); register_Vec2(); register_Vec2(); class_ > v2s_class = register_Vec2Array(); class_ > v2i_class = register_Vec2Array(); class_ > v2f_class = register_Vec2Array(); class_ > v2d_class = register_Vec2Array(); add_explicit_construction_from_type(v2i_class); add_explicit_construction_from_type(v2i_class); add_explicit_construction_from_type(v2f_class); add_explicit_construction_from_type(v2f_class); add_explicit_construction_from_type(v2d_class); add_explicit_construction_from_type(v2d_class); // // Vec3 // register_Vec3(); register_Vec3(); register_Vec3(); register_Vec3(); register_Vec3(); class_ > v3s_class = register_Vec3Array(); class_ > v3i_class = register_Vec3Array(); class_ > v3f_class = register_Vec3Array(); class_ > v3d_class = register_Vec3Array(); add_explicit_construction_from_type(v3i_class); add_explicit_construction_from_type(v3i_class); add_explicit_construction_from_type(v3f_class); add_explicit_construction_from_type(v3f_class); add_explicit_construction_from_type(v3d_class); add_explicit_construction_from_type(v3d_class); // // Vec4 // register_Vec4(); register_Vec4(); register_Vec4(); register_Vec4(); register_Vec4(); class_ > v4s_class = register_Vec4Array(); class_ > v4i_class = register_Vec4Array(); class_ > v4f_class = register_Vec4Array(); class_ > v4d_class = register_Vec4Array(); add_explicit_construction_from_type(v4i_class); add_explicit_construction_from_type(v4i_class); add_explicit_construction_from_type(v4f_class); add_explicit_construction_from_type(v4f_class); add_explicit_construction_from_type(v4d_class); // // Quat // register_Quat(); register_Quat(); class_ > quatf_class = register_QuatArray(); class_ > quatd_class = register_QuatArray(); add_explicit_construction_from_type(quatf_class); add_explicit_construction_from_type(quatd_class); // // Euler // register_Euler(); register_Euler(); class_ > eulerf_class = register_EulerArray(); class_ > eulerd_class = register_EulerArray(); add_explicit_construction_from_type(eulerf_class); add_explicit_construction_from_type(eulerd_class); // // Box2 // register_Box2(); register_Box2(); register_Box2(); register_Box2(); class_ > b2s_class = register_BoxArray(); class_ > b2i_class = register_BoxArray(); class_ > b2f_class = register_BoxArray(); class_ > b2d_class = register_BoxArray(); // // Box3 // register_Box3(); register_Box3(); register_Box3(); register_Box3(); class_ > b3s_class = register_BoxArray(); class_ > b3i_class = register_BoxArray(); class_ > b3f_class = register_BoxArray(); class_ > b3d_class = register_BoxArray(); // // Matrix33/44 // register_Matrix33(); register_Matrix33(); register_Matrix44(); register_Matrix44(); // // M33/44Array // class_ > m44d_class = register_M44Array(); class_ > m44f_class = register_M44Array(); add_explicit_construction_from_type< IMATH_NAMESPACE::Matrix44 >(m44d_class); add_explicit_construction_from_type< IMATH_NAMESPACE::Matrix44 > (m44f_class); class_ > m33d_class = register_M33Array(); class_ > m33f_class = register_M33Array(); add_explicit_construction_from_type< IMATH_NAMESPACE::Matrix33 >(m33d_class); add_explicit_construction_from_type< IMATH_NAMESPACE::Matrix33 > (m33f_class); // // String Array // register_StringArrays(); // // Color3/4 // register_Color3(); register_Color3(); register_Color4(); register_Color4(); // // C3/4Array // class_ > c3f_class = register_Color3Array(); class_ > c3c_class = register_Color3Array(); add_explicit_construction_from_type(c3f_class); add_explicit_construction_from_type(c3f_class); class_ > c4f_class = register_Color4Array(); class_ > c4c_class = register_Color4Array(); // // Color4Array // register_Color4Array2D(); register_Color4Array2D(); // // Frustum // register_Frustum(); register_Frustum(); register_FrustumTest(); register_FrustumTest(); // // Plane // register_Plane(); register_Plane(); // // Line // register_Line(); register_Line(); // // Shear // register_Shear(); register_Shear(); // // Utility Functions // register_functions(); def("procrustesRotationAndTranslation", procrustes1, args("fromPts", "toPts", "weights", "doScale"), // Can't use 'from' and 'to' because 'from' is a reserved keywork in Python "Computes the orthogonal transform (consisting only of rotation and translation) mapping the " "'fromPts' points as close as possible to the 'toPts' points in the least squares norm. The 'fromPts' and " "'toPts' lists must be the same length or the function will error out. If weights " "are provided, then the points are weighted (that is, some points are considered more important " "than others while computing the transform). If the 'doScale' parameter is True, then " "the resulting matrix is also allowed to have a uniform scale."); // // Rand // register_Rand32(); register_Rand48(); // // Initialize constants // scope().attr("EULER_XYZ") = IMATH_NAMESPACE::Eulerf::XYZ; scope().attr("EULER_XZY") = IMATH_NAMESPACE::Eulerf::XZY; scope().attr("EULER_YZX") = IMATH_NAMESPACE::Eulerf::YZX; scope().attr("EULER_YXZ") = IMATH_NAMESPACE::Eulerf::YXZ; scope().attr("EULER_ZXY") = IMATH_NAMESPACE::Eulerf::ZXY; scope().attr("EULER_ZYX") = IMATH_NAMESPACE::Eulerf::ZYX; scope().attr("EULER_XZX") = IMATH_NAMESPACE::Eulerf::XZX; scope().attr("EULER_XYX") = IMATH_NAMESPACE::Eulerf::XYX; scope().attr("EULER_YXY") = IMATH_NAMESPACE::Eulerf::YXY; scope().attr("EULER_YZY") = IMATH_NAMESPACE::Eulerf::YZY; scope().attr("EULER_ZYZ") = IMATH_NAMESPACE::Eulerf::ZYZ; scope().attr("EULER_ZXZ") = IMATH_NAMESPACE::Eulerf::ZXZ; scope().attr("EULER_XYZr") = IMATH_NAMESPACE::Eulerf::XYZr; scope().attr("EULER_XZYr") = IMATH_NAMESPACE::Eulerf::XZYr; scope().attr("EULER_YZXr") = IMATH_NAMESPACE::Eulerf::YZXr; scope().attr("EULER_YXZr") = IMATH_NAMESPACE::Eulerf::YXZr; scope().attr("EULER_ZXYr") = IMATH_NAMESPACE::Eulerf::ZXYr; scope().attr("EULER_ZYXr") = IMATH_NAMESPACE::Eulerf::ZYXr; scope().attr("EULER_XZXr") = IMATH_NAMESPACE::Eulerf::XZXr; scope().attr("EULER_XYXr") = IMATH_NAMESPACE::Eulerf::XYXr; scope().attr("EULER_YXYr") = IMATH_NAMESPACE::Eulerf::YXYr; scope().attr("EULER_YZYr") = IMATH_NAMESPACE::Eulerf::YZYr; scope().attr("EULER_ZYZr") = IMATH_NAMESPACE::Eulerf::ZYZr; scope().attr("EULER_ZXZr") = IMATH_NAMESPACE::Eulerf::ZXZr; scope().attr("EULER_X_AXIS") = IMATH_NAMESPACE::Eulerf::X; scope().attr("EULER_Y_AXIS") = IMATH_NAMESPACE::Eulerf::Y; scope().attr("EULER_Z_AXIS") = IMATH_NAMESPACE::Eulerf::Z; scope().attr("INT_MIN") = IMATH_NAMESPACE::limits::min(); scope().attr("INT_MAX") = IMATH_NAMESPACE::limits::max(); scope().attr("INT_SMALLEST") = IMATH_NAMESPACE::limits::smallest(); scope().attr("INT_EPS") = IMATH_NAMESPACE::limits::epsilon(); scope().attr("FLT_MIN") = IMATH_NAMESPACE::limits::min(); scope().attr("FLT_MAX") = IMATH_NAMESPACE::limits::max(); scope().attr("FLT_SMALLEST") = IMATH_NAMESPACE::limits::smallest(); scope().attr("FLT_EPS") = IMATH_NAMESPACE::limits::epsilon(); scope().attr("DBL_MIN") = IMATH_NAMESPACE::limits::min(); scope().attr("DBL_MAX") = IMATH_NAMESPACE::limits::max(); scope().attr("DBL_SMALLEST") = IMATH_NAMESPACE::limits::smallest(); scope().attr("DBL_EPS") = IMATH_NAMESPACE::limits::epsilon(); // // Register Exceptions // PyIex::registerExc("NullVecExc","imath"); PyIex::registerExc("NullQuatExc","imath"); PyIex::registerExc("SingMatrixExc","imath"); PyIex::registerExc("ZeroScaleExc","imath"); PyIex::registerExc("IntVecNormalizeExc","imath"); def("computeBoundingBox", &computeBoundingBox, "computeBoundingBox(position) -- computes the bounding box from the position array."); def("computeBoundingBox", &computeBoundingBox, "computeBoundingBox(position) -- computes the bounding box from the position array."); }