Disabled external gits

This commit is contained in:
2022-04-07 18:46:57 +02:00
parent 88cb3426ad
commit 15e7120d6d
5316 changed files with 4563444 additions and 6 deletions

View File

@ -0,0 +1,70 @@
ADD_LIBRARY ( PyImath ${LIB_TYPE}
PyImath.cpp
PyImathAutovectorize.cpp
PyImathBox2Array.cpp
PyImathBox3Array.cpp
PyImathBox.cpp
PyImathColor3.cpp
PyImathColor4.cpp
PyImathEuler.cpp
PyImathFixedArray.cpp
PyImathFrustum.cpp
PyImathLine.cpp
PyImathMatrix33.cpp
PyImathMatrix44.cpp
PyImathPlane.cpp
PyImathQuat.cpp
PyImathRandom.cpp
PyImathShear.cpp
PyImathStringArray.cpp
PyImathStringTable.cpp
PyImathTask.cpp
PyImathUtil.cpp
PyImathFixedVArray.cpp
PyImathVec2fd.cpp
PyImathVec2si.cpp
PyImathVec3fd.cpp
PyImathVec3siArray.cpp
PyImathVec3si.cpp
PyImathVec4fd.cpp
PyImathVec4siArray.cpp
PyImathVec4si.cpp
)
TARGET_LINK_LIBRARIES ( PyImath
Iex${ILMBASE_LIBSUFFIX}
IexMath${ILMBASE_LIBSUFFIX}
Imath${ILMBASE_LIBSUFFIX}
${Boost_LIBRARIES}
${PYTHON_LIBRARIES}
)
INSTALL ( TARGETS PyImath
DESTINATION
lib
)
ADD_LIBRARY ( imathmodule ${LIB_TYPE}
imathmodule.cpp
PyImathFun.cpp
PyImathBasicTypes.cpp
)
SET_TARGET_PROPERTIES ( imathmodule
PROPERTIES PREFIX "" SUFFIX ".so" BUILD_WITH_INSTALL_RPATH ON
)
TARGET_LINK_LIBRARIES ( imathmodule
PyImath
PyIex
Imath${ILMBASE_LIBSUFFIX}
Iex${ILMBASE_LIBSUFFIX}
${Boost_LIBRARIES}
)
INSTALL ( TARGETS imathmodule
DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages
)

View File

@ -0,0 +1,93 @@
## Process this file with automake to produce Makefile.in
pyexec_LTLIBRARIES = imathmodule.la
lib_LTLIBRARIES = libPyImath.la
libPyImath_la_SOURCES = PyImath.cpp \
PyImathAutovectorize.cpp \
PyImathBox2Array.cpp \
PyImathBox3Array.cpp \
PyImathBox.cpp \
PyImathColor3.cpp \
PyImathColor4.cpp \
PyImathEuler.cpp \
PyImathFixedArray.cpp \
PyImathFrustum.cpp \
PyImathLine.cpp \
PyImathMatrix33.cpp \
PyImathMatrix44.cpp \
PyImathPlane.cpp \
PyImathQuat.cpp \
PyImathRandom.cpp \
PyImathShear.cpp \
PyImathStringArray.cpp \
PyImathStringTable.cpp \
PyImathTask.cpp \
PyImathUtil.cpp \
PyImathFixedVArray.cpp \
PyImathVec2fd.cpp \
PyImathVec2si.cpp \
PyImathVec3fd.cpp \
PyImathVec3siArray.cpp \
PyImathVec3si.cpp \
PyImathVec4fd.cpp \
PyImathVec4siArray.cpp \
PyImathVec4si.cpp
libPyImathinclude_HEADERS = PyImath.h \
PyImathAutovectorize.h \
PyImathBoxArrayImpl.h \
PyImathBox.h \
PyImathColor3ArrayImpl.h \
PyImathColor4Array2DImpl.h \
PyImathColor4ArrayImpl.h \
PyImathColor.h \
PyImathDecorators.h \
PyImathEuler.h \
PyImathExport.h \
PyImathFixedArray2D.h \
PyImathFixedArray.h \
PyImathFixedMatrix.h \
PyImathFrustum.h \
PyImathLine.h \
PyImathMathExc.h \
PyImathMatrix.h \
PyImathOperators.h \
PyImathPlane.h \
PyImathQuat.h \
PyImathRandom.h \
PyImathShear.h \
PyImathStringArray.h \
PyImathStringArrayRegister.h \
PyImathStringTable.h \
PyImathTask.h \
PyImathUtil.h \
PyImathFixedVArray.h \
PyImathVec2Impl.h \
PyImathVec3ArrayImpl.h \
PyImathVec3Impl.h \
PyImathVec4ArrayImpl.h \
PyImathVec4Impl.h \
PyImathVec.h \
PyImathVecOperators.h
libPyImath_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ \
-no-undefined
libPyImath_la_LIBADD = -lz $(top_builddir)/PyIex/libPyIex.la \
@ILMBASE_LIBS@ @BOOST_PYTHON_LIBS@
libPyImathincludedir = $(includedir)/OpenEXR
imathmodule_la_SOURCES = imathmodule.cpp \
PyImathFun.cpp \
PyImathBasicTypes.cpp
imathmodule_la_LDFLAGS = -avoid-version -module
imathmodule_la_LIBADD = -lPyImath @BOOST_PYTHON_LIBS@
noinst_HEADERS = PyImathFun.h \
PyImathBasicTypes.h
INCLUDES = @ILMBASE_CXXFLAGS@ \
-I$(top_builddir) \
-I$(top_srcdir)/PyIex \
-I$(top_srcdir)/config

View File

@ -0,0 +1,52 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2008-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 <PyImath.h>
#include <PyIex.h>
#include <PyImathExport.h>
namespace PyImath {
template <> PYIMATH_EXPORT const char * BoolArray::name() { return "BoolArray"; }
template <> PYIMATH_EXPORT const char * SignedCharArray::name() { return "SignedCharArray"; }
template <> PYIMATH_EXPORT const char * UnsignedCharArray::name() { return "UnsignedCharArray"; }
template <> PYIMATH_EXPORT const char * ShortArray::name() { return "ShortArray"; }
template <> PYIMATH_EXPORT const char * UnsignedShortArray::name(){ return "UnsignedShortArray"; }
template <> PYIMATH_EXPORT const char * IntArray::name() { return "IntArray"; }
template <> PYIMATH_EXPORT const char * UnsignedIntArray::name() { return "UnsignedIntArray"; }
template <> PYIMATH_EXPORT const char * FloatArray::name() { return "FloatArray"; }
template <> PYIMATH_EXPORT const char * DoubleArray::name() { return "DoubleArray"; }
template <> PYIMATH_EXPORT const char * VIntArray::name() { return "VIntArray"; }
}

View File

@ -0,0 +1,72 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006-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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImath_h_
#define _PyImath_h_
#include <ImathVec.h>
#include <ImathQuat.h>
#include <PyImathFixedArray.h>
#include <PyImathFixedMatrix.h>
#include <PyImathFixedArray2D.h>
#include <PyImathFixedVArray.h>
namespace PyImath {
typedef FixedArray<bool> BoolArray;
typedef FixedArray<signed char> SignedCharArray;
typedef FixedArray<unsigned char> UnsignedCharArray;
typedef FixedArray<short> ShortArray;
typedef FixedArray<unsigned short> UnsignedShortArray;
typedef FixedArray<int> IntArray;
typedef FixedArray<unsigned int> UnsignedIntArray;
typedef FixedArray<float> FloatArray;
typedef FixedArray<double> DoubleArray;
typedef FixedArray<IMATH_NAMESPACE::Quatf> QuatfArray;
typedef FixedArray<IMATH_NAMESPACE::Quatd> QuatdArray;
typedef FixedMatrix<int> IntMatrix;
typedef FixedMatrix<float> FloatMatrix;
typedef FixedMatrix<double> DoubleMatrix;
typedef FixedArray2D<float> FloatArray2D;
typedef FixedArray2D<int> IntArray2D;
typedef FixedArray2D<double> DoubleArray2D;
typedef FixedVArray<int> VIntArray;
}
#endif

View File

@ -0,0 +1,117 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-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 <PyImathAutovectorize.h>
namespace PyImath {
namespace detail {
//
// cheek possible vectorizations to ensure correctness
//
// single argument should be ((false),(true))
//
BOOST_STATIC_ASSERT(( size<possible_vectorizations<1>::type>::type::value == 2 ));
BOOST_STATIC_ASSERT(( size<at_c<possible_vectorizations<1>::type,0>::type>::type::value == 1 ));
BOOST_STATIC_ASSERT(( at_c<at_c<possible_vectorizations<1>::type,0>::type,0>::type::value == false ));
BOOST_STATIC_ASSERT(( size<at_c<possible_vectorizations<1>::type,1>::type>::type::value == 1 ));
BOOST_STATIC_ASSERT(( at_c<at_c<possible_vectorizations<1>::type,1>::type,0>::type::value == true ));
//
// two argument should be ((false,false),(false,true),(true,false),(true,true))
//
BOOST_STATIC_ASSERT(( size<possible_vectorizations<2>::type>::type::value == 4 ));
BOOST_STATIC_ASSERT(( size<at_c<possible_vectorizations<2>::type,0>::type>::type::value == 2 ));
BOOST_STATIC_ASSERT(( at_c<at_c<possible_vectorizations<2>::type,0>::type,0>::type::value == false ));
BOOST_STATIC_ASSERT(( at_c<at_c<possible_vectorizations<2>::type,0>::type,1>::type::value == false ));
BOOST_STATIC_ASSERT(( size<at_c<possible_vectorizations<2>::type,1>::type>::type::value == 2 ));
BOOST_STATIC_ASSERT(( at_c<at_c<possible_vectorizations<2>::type,1>::type,0>::type::value == false ));
BOOST_STATIC_ASSERT(( at_c<at_c<possible_vectorizations<2>::type,1>::type,1>::type::value == true ));
BOOST_STATIC_ASSERT(( size<at_c<possible_vectorizations<2>::type,2>::type>::type::value == 2 ));
BOOST_STATIC_ASSERT(( at_c<at_c<possible_vectorizations<2>::type,2>::type,0>::type::value == true ));
BOOST_STATIC_ASSERT(( at_c<at_c<possible_vectorizations<2>::type,2>::type,1>::type::value == false ));
BOOST_STATIC_ASSERT(( size<at_c<possible_vectorizations<2>::type,3>::type>::type::value == 2 ));
BOOST_STATIC_ASSERT(( at_c<at_c<possible_vectorizations<2>::type,3>::type,0>::type::value == true ));
BOOST_STATIC_ASSERT(( at_c<at_c<possible_vectorizations<2>::type,3>::type,1>::type::value == true ));
BOOST_STATIC_ASSERT(( size<possible_vectorizations<3>::type>::type::value == 8 ));
//
// Check disallow_vectorization for given vectorizable flags
//
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<true_ > >::apply<vector<true_ > >::type::value == false ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<true_ > >::apply<vector<false_> >::type::value == false ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<false_> >::apply<vector<true_ > >::type::value == true ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<false_> >::apply<vector<false_> >::type::value == false ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<true_ , true_ > >::apply<vector<true_ , true_ > >::type::value == false ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<true_ , true_ > >::apply<vector<false_, true_ > >::type::value == false ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<true_ , true_ > >::apply<vector<true_ , false_> >::type::value == false ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<true_ , true_ > >::apply<vector<false_, false_> >::type::value == false ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<true_ , false_> >::apply<vector<true_ , true_ > >::type::value == true ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<true_ , false_> >::apply<vector<false_, true_ > >::type::value == true ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<true_ , false_> >::apply<vector<true_ , false_> >::type::value == false ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<true_ , false_> >::apply<vector<false_, false_> >::type::value == false ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<false_, true_ > >::apply<vector<true_ , true_ > >::type::value == true ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<false_, true_ > >::apply<vector<false_, true_ > >::type::value == false ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<false_, true_ > >::apply<vector<true_ , false_> >::type::value == true ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<false_, true_ > >::apply<vector<false_, false_> >::type::value == false ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<false_, false_> >::apply<vector<true_ , true_ > >::type::value == true ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<false_, false_> >::apply<vector<false_, true_ > >::type::value == true ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<false_, false_> >::apply<vector<true_ , false_> >::type::value == true ));
BOOST_STATIC_ASSERT(( disallow_vectorization<vector<false_, false_> >::apply<vector<false_, false_> >::type::value == false ));
//
// Check allowable_vectorizations, single argument not vectorizable, and two argument second argument vectorizable.
//
typedef allowable_vectorizations<vector<false_> > AV1f;
BOOST_STATIC_ASSERT(( size<AV1f::possible>::type::value == 2 ));
BOOST_STATIC_ASSERT(( at_c<at_c<AV1f::possible,0>::type,0>::type::value == false ));
BOOST_STATIC_ASSERT(( at_c<at_c<AV1f::possible,1>::type,0>::type::value == true ));
BOOST_STATIC_ASSERT(( size<AV1f::type>::type::value == 1 ));
BOOST_STATIC_ASSERT(( size<at_c<AV1f::type,0>::type>::type::value == 1 ));
BOOST_STATIC_ASSERT(( at_c<at_c<AV1f::type,0>::type,0>::type::value == false ));
typedef allowable_vectorizations<vector<false_,true_> > AV2ft;
BOOST_STATIC_ASSERT(( size<AV2ft::type>::type::value == 2 ));
BOOST_STATIC_ASSERT(( size<at_c<AV2ft::type,0>::type>::type::value == 2 ));
BOOST_STATIC_ASSERT(( at_c<at_c<AV2ft::type,0>::type,0>::type::value == false ));
BOOST_STATIC_ASSERT(( at_c<at_c<AV2ft::type,0>::type,1>::type::value == false ));
BOOST_STATIC_ASSERT(( size<at_c<AV2ft::type,1>::type>::type::value == 2 ));
BOOST_STATIC_ASSERT(( at_c<at_c<AV2ft::type,1>::type,0>::type::value == false ));
BOOST_STATIC_ASSERT(( at_c<at_c<AV2ft::type,1>::type,1>::type::value == true ));
} // namespace detail
} // namespace PyImath

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,112 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 <PyImathBasicTypes.h>
#include <Python.h>
#include <boost/python.hpp>
#include <PyImath.h>
#include <PyImathFixedArray.h>
#include <PyImathFixedVArray.h>
using namespace boost::python;
namespace PyImath {
void
register_basicTypes()
{
class_<BoolArray> bclass = BoolArray::register_("Fixed length array of bool");
add_comparison_functions(bclass);
class_<SignedCharArray> scclass = SignedCharArray::register_("Fixed length array of signed chars");
add_arithmetic_math_functions(scclass);
add_mod_math_functions(scclass);
add_comparison_functions(scclass);
add_ordered_comparison_functions(scclass);
class_<UnsignedCharArray> ucclass = UnsignedCharArray::register_("Fixed length array of unsigned chars");
add_arithmetic_math_functions(ucclass);
add_mod_math_functions(ucclass);
add_comparison_functions(ucclass);
add_ordered_comparison_functions(ucclass);
class_<ShortArray> sclass = ShortArray::register_("Fixed length array of shorts");
add_arithmetic_math_functions(sclass);
add_mod_math_functions(sclass);
add_comparison_functions(sclass);
add_ordered_comparison_functions(sclass);
class_<UnsignedShortArray> usclass = UnsignedShortArray::register_("Fixed length array of unsigned shorts");
add_arithmetic_math_functions(usclass);
add_mod_math_functions(usclass);
add_comparison_functions(usclass);
add_ordered_comparison_functions(usclass);
class_<IntArray> iclass = IntArray::register_("Fixed length array of ints");
add_arithmetic_math_functions(iclass);
add_mod_math_functions(iclass);
add_comparison_functions(iclass);
add_ordered_comparison_functions(iclass);
add_explicit_construction_from_type<float>(iclass);
add_explicit_construction_from_type<double>(iclass);
class_<UnsignedIntArray> uiclass = UnsignedIntArray::register_("Fixed length array of unsigned ints");
add_arithmetic_math_functions(uiclass);
add_mod_math_functions(uiclass);
add_comparison_functions(uiclass);
add_ordered_comparison_functions(uiclass);
add_explicit_construction_from_type<float>(uiclass);
add_explicit_construction_from_type<double>(uiclass);
class_<FloatArray> fclass = FloatArray::register_("Fixed length array of floats");
add_arithmetic_math_functions(fclass);
add_pow_math_functions(fclass);
add_comparison_functions(fclass);
add_ordered_comparison_functions(fclass);
add_explicit_construction_from_type<int>(fclass);
add_explicit_construction_from_type<double>(fclass);
class_<DoubleArray> dclass = DoubleArray::register_("Fixed length array of doubles");
add_arithmetic_math_functions(dclass);
add_pow_math_functions(dclass);
add_comparison_functions(dclass);
add_ordered_comparison_functions(dclass);
add_explicit_construction_from_type<int>(dclass);
add_explicit_construction_from_type<float>(dclass);
class_<VIntArray> ivclass = VIntArray::register_("Variable fixed length array of ints");
// Don't add other functionality until its defined better.
}
} // namespace PyImath

View File

@ -0,0 +1,46 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathBasicTypes_h_
#define _PyImathBasicTypes_h_
#include <PyImathExport.h>
namespace PyImath {
PYIMATH_EXPORT void register_basicTypes();
}
#endif

View File

@ -0,0 +1,445 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 "PyImathBox.h"
#include "PyImathVec.h"
#include "PyImathMathExc.h"
#include "PyImathDecorators.h"
#include "PyImathExport.h"
#include <boost/python/make_constructor.hpp>
#include <Iex.h>
#include <ImathBoxAlgo.h>
#include <PyImathTask.h>
#include <vector>
#include "PyImathBoxArrayImpl.h"
namespace PyImath {
using namespace boost::python;
using namespace IMATH_NAMESPACE;
using namespace PyImath;
template <class T> struct BoxName { static const char *value; };
template <> const char *BoxName<IMATH_NAMESPACE::V2s>::value = "Box2s";
template <> const char *BoxName<IMATH_NAMESPACE::V2i>::value = "Box2i";
template <> const char *BoxName<IMATH_NAMESPACE::V2f>::value = "Box2f";
template <> const char *BoxName<IMATH_NAMESPACE::V2d>::value = "Box2d";
template <> const char *BoxName<IMATH_NAMESPACE::V3s>::value = "Box3s";
template <> const char *BoxName<IMATH_NAMESPACE::V3i>::value = "Box3i";
template <> const char *BoxName<IMATH_NAMESPACE::V3f>::value = "Box3f";
template <> const char *BoxName<IMATH_NAMESPACE::V3d>::value = "Box3d";
template <> PYIMATH_EXPORT const char *PyImath::Box2sArray::name() { return "Box2sArray"; }
template <> PYIMATH_EXPORT const char *PyImath::Box2iArray::name() { return "Box2iArray"; }
template <> PYIMATH_EXPORT const char *PyImath::Box2fArray::name() { return "Box2fArray"; }
template <> PYIMATH_EXPORT const char *PyImath::Box2dArray::name() { return "Box2dArray"; }
template <> PYIMATH_EXPORT const char *PyImath::Box3sArray::name() { return "Box3sArray"; }
template <> PYIMATH_EXPORT const char *PyImath::Box3iArray::name() { return "Box3iArray"; }
template <> PYIMATH_EXPORT const char *PyImath::Box3fArray::name() { return "Box3fArray"; }
template <> PYIMATH_EXPORT const char *PyImath::Box3dArray::name() { return "Box3dArray"; }
template <class T>
static Box<T> * box2TupleConstructor1(const tuple &t)
{
if(t.attr("__len__")() == 2)
{
// The constructor was called like this:
// Box2f ((V2f(1,2), V2f(3,4))) or
// Box2f (((1,2), (3,4)))
PyObject *t0Obj = extract <object> (t[0])().ptr();
PyObject *t1Obj = extract <object> (t[1])().ptr();
T t0, t1;
if (V2<typename T::BaseType>::convert (t0Obj, &t0) &&
V2<typename T::BaseType>::convert (t1Obj, &t1))
{
return new Box<T> (t0, t1);
}
// The constructor was called like this:
// Box2f ((1,2))
else
{
T point;
point.x = extract<double>(t[0]);
point.y = extract<double>(t[1]);
return new Box<T>(point);
}
}
else
THROW(IEX_NAMESPACE::LogicExc, "Invalid input to Box tuple constructor");
}
template <class T>
static Box<T> * box2TupleConstructor2(const tuple &t0, const tuple &t1)
{
if(t0.attr("__len__")() == 2 && t1.attr("__len__")() == 2)
{
T point0, point1;
point0.x = extract<double>(t0[0]); point0.y = extract<double>(t0[1]);
point1.x = extract<double>(t1[0]); point1.y = extract<double>(t1[1]);
return new Box<T>(point0, point1);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Invalid input to Box tuple constructor");
}
template <class T, class S>
static Box<T> *boxConstructor(const Box<S> &box)
{
Box<T> *newBox = new Box<T>;
newBox->min = box.min;
newBox->max = box.max;
return newBox;
}
template <class T>
static Box<T> * box3TupleConstructor1(const tuple &t)
{
if(t.attr("__len__")() == 3)
{
// The constructor was called like this:
// Box3f ((1,2,3))
T point;
point.x = extract<double>(t[0]);
point.y = extract<double>(t[1]);
point.z = extract<double>(t[2]);
return new Box<T>(point);
}
else if (t.attr("__len__")() == 2)
{
// The constructor was called like this:
// Box3f ((V3f(1,2,3), V3f(4,5,6))) or
// Box3f (((1,2,3), (4,5,6)))
PyObject *t0Obj = extract <object> (t[0])().ptr();
PyObject *t1Obj = extract <object> (t[1])().ptr();
T t0, t1;
if (V3<typename T::BaseType>::convert (t0Obj, &t0) &&
V3<typename T::BaseType>::convert (t1Obj, &t1))
{
return new Box<T> (t0, t1);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Invalid input to Box tuple constructor");
}
else
THROW(IEX_NAMESPACE::LogicExc, "Invalid input to Box tuple constructor");
}
template <class T>
static Box<T> * box3TupleConstructor2(const tuple &t0, const tuple &t1)
{
if(t0.attr("__len__")() == 3 && t1.attr("__len__")() == 3)
{
T point0, point1;
point0.x = extract<double>(t0[0]);
point0.y = extract<double>(t0[1]);
point0.z = extract<double>(t0[2]);
point1.x = extract<double>(t1[0]);
point1.y = extract<double>(t1[1]);
point1.z = extract<double>(t1[2]);
return new Box<T>(point0, point1);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Invalid input to Box tuple constructor");
}
template <class T>
static std::string Box2_repr(const Box<T> &box)
{
std::stringstream stream;
typename boost::python::return_by_value::apply <T>::type converter;
PyObject *minObj = converter (box.min);
PyObject *minReprObj = PyObject_Repr (minObj);
std::string minReprStr = PyString_AsString (minReprObj);
Py_DECREF (minReprObj);
Py_DECREF (minObj);
PyObject *maxObj = converter (box.max);
PyObject *maxReprObj = PyObject_Repr (maxObj);
std::string maxReprStr = PyString_AsString (maxReprObj);
Py_DECREF (maxReprObj);
Py_DECREF (maxObj);
stream << BoxName<T>::value << "(" << minReprStr << ", " << maxReprStr << ")";
return stream.str();
}
template <class T>
static std::string Box3_repr(const Box<T> &box)
{
std::stringstream stream;
typename boost::python::return_by_value::apply <T>::type converter;
PyObject *minObj = converter (box.min);
PyObject *minReprObj = PyObject_Repr (minObj);
std::string minReprStr = PyString_AsString (minReprObj);
Py_DECREF (minReprObj);
Py_DECREF (minObj);
PyObject *maxObj = converter (box.max);
PyObject *maxReprObj = PyObject_Repr (maxObj);
std::string maxReprStr = PyString_AsString (maxReprObj);
Py_DECREF (maxReprObj);
Py_DECREF (maxObj);
stream << BoxName<T>::value << "(" << minReprStr << ", " << maxReprStr << ")";
return stream.str();
}
template <class T>
static void boxSetMin(IMATH_NAMESPACE::Box<T> &box, const T &m)
{
box.min = m;
}
template <class T>
static void boxSetMax(IMATH_NAMESPACE::Box<T> &box, const T &m)
{
box.max = m;
}
template <class T>
static T
boxMin(IMATH_NAMESPACE::Box<T> &box)
{
return box.min;
}
template <class T>
static T
boxMax(IMATH_NAMESPACE::Box<T> &box)
{
return box.max;
}
template <class T>
struct IntersectsTask : public Task
{
const IMATH_NAMESPACE::Box<T>& box;
const PyImath::FixedArray<T>& points;
PyImath::FixedArray<int>& results;
IntersectsTask(IMATH_NAMESPACE::Box<T>& b, const PyImath::FixedArray<T> &p, PyImath::FixedArray<int> &r)
: box(b), points(p), results(r) {}
void execute(size_t start, size_t end)
{
for(size_t p = start; p < end; ++p)
results[p] = box.intersects(points[p]);
}
};
template <class T>
struct ExtendByTask : public Task
{
std::vector<IMATH_NAMESPACE::Box<T> >& boxes;
const PyImath::FixedArray<T>& points;
ExtendByTask(std::vector<IMATH_NAMESPACE::Box<T> >& b, const PyImath::FixedArray<T> &p)
: boxes(b), points(p) {}
void execute(size_t start, size_t end, int tid)
{
for(size_t p = start; p < end; ++p)
boxes[tid].extendBy(points[p]);
}
void execute(size_t start, size_t end)
{
ASSERT(false, IEX_NAMESPACE::NoImplExc, "Box::ExtendBy execute requires a thread id");
}
};
template <class T>
static void
box_extendBy(IMATH_NAMESPACE::Box<T> &box, const PyImath::FixedArray<T> &points)
{
size_t numBoxes = workers();
std::vector<IMATH_NAMESPACE::Box<T> > boxes(numBoxes);
ExtendByTask<T> task(boxes,points);
dispatchTask(task,points.len());
for (int i=0; i<numBoxes; ++i) {
box.extendBy(boxes[i]);
}
}
template <class T>
PyImath::FixedArray<int>
box_intersects(IMATH_NAMESPACE::Box<T>& box, const PyImath::FixedArray<T>& points)
{
size_t numPoints = points.len();
PyImath::FixedArray<int> mask(numPoints);
IntersectsTask<T> task(box,points,mask);
dispatchTask(task,numPoints);
return mask;
}
template <class T>
class_<IMATH_NAMESPACE::Box<T> >
register_Box2()
{
void (IMATH_NAMESPACE::Box<T>::*extendBy1)(const T&) = &IMATH_NAMESPACE::Box<T>::extendBy;
void (IMATH_NAMESPACE::Box<T>::*extendBy2)(const IMATH_NAMESPACE::Box<T>&) = &IMATH_NAMESPACE::Box<T>::extendBy;
bool (IMATH_NAMESPACE::Box<T>::*intersects1)(const T&) const = &IMATH_NAMESPACE::Box<T>::intersects;
bool (IMATH_NAMESPACE::Box<T>::*intersects2)(const IMATH_NAMESPACE::Box<T>&) const = &IMATH_NAMESPACE::Box<T>::intersects;
const char *name = BoxName<T>::value;
class_<Box<T> > box_class(name);
box_class
.def(init<>("Box() create empty box") )
.def(init<T>("Box(point)create box containing the given point") )
.def(init<T,T>("Box(point,point) create box continaing min and max") )
.def("__init__", make_constructor(box2TupleConstructor1<T>), "Box(point) where point is a python tuple")
.def("__init__", make_constructor(box2TupleConstructor2<T>), "Box(point,point) where point is a python tuple")
.def("__init__", make_constructor(boxConstructor<T, IMATH_NAMESPACE::V2f>))
.def("__init__", make_constructor(boxConstructor<T, IMATH_NAMESPACE::V2d>))
.def("__init__", make_constructor(boxConstructor<T, IMATH_NAMESPACE::V2i>))
.def_readwrite("min",&Box<T>::min)
.def_readwrite("max",&Box<T>::max)
.def("min", &boxMin<T>)
.def("max", &boxMax<T>)
.def(self == self)
.def(self != self)
.def("__repr__", &Box2_repr<T>)
.def("makeEmpty",&Box<T>::makeEmpty,"makeEmpty() make the box empty")
.def("makeInfinite",&Box<T>::makeInfinite,"makeInfinite() make the box cover all space")
.def("extendBy",extendBy1,"extendBy(point) extend the box by a point")
.def("extendBy",box_extendBy<T>,"extendBy(array) extend the box the values in the array")
.def("extendBy",extendBy2,"extendBy(box) extend the box by a box")
.def("size",&Box<T>::size,"size() size of the box")
.def("center",&Box<T>::center,"center() center of the box")
.def("intersects",intersects1,"intersects(point) returns true if the box intersects the given point")
.def("intersects",intersects2,"intersects(box) returns true if the box intersects the given box")
.def("majorAxis",&Box<T>::majorAxis,"majorAxis() major axis of the box")
.def("isEmpty",&Box<T>::isEmpty,"isEmpty() returns true if the box is empty")
.def("isInfinite",&Box<T>::isInfinite,"isInfinite() returns true if the box covers all space")
.def("hasVolume",&Box<T>::hasVolume,"hasVolume() returns true if the box has volume")
.def("setMin",&boxSetMin<T>,"setMin() sets the min value of the box")
.def("setMax",&boxSetMax<T>,"setMax() sets the max value of the box")
;
return box_class;
}
template <class T, class U>
static IMATH_NAMESPACE::Box<T>
mulM44 (const IMATH_NAMESPACE::Box<T> &b, const Matrix44<U> &m)
{
MATH_EXC_ON;
return IMATH_NAMESPACE::transform (b, m);
}
template <class T, class U>
static const IMATH_NAMESPACE::Box<T> &
imulM44 (IMATH_NAMESPACE::Box<T> &b, const Matrix44<U> &m)
{
MATH_EXC_ON;
b = IMATH_NAMESPACE::transform (b, m);
return b;
}
template <class T>
class_<IMATH_NAMESPACE::Box<T> >
register_Box3()
{
void (IMATH_NAMESPACE::Box<T>::*extendBy1)(const T&) = &IMATH_NAMESPACE::Box<T>::extendBy;
void (IMATH_NAMESPACE::Box<T>::*extendBy2)(const IMATH_NAMESPACE::Box<T>&) = &IMATH_NAMESPACE::Box<T>::extendBy;
bool (IMATH_NAMESPACE::Box<T>::*intersects1)(const T&) const = &IMATH_NAMESPACE::Box<T>::intersects;
bool (IMATH_NAMESPACE::Box<T>::*intersects2)(const IMATH_NAMESPACE::Box<T>&) const = &IMATH_NAMESPACE::Box<T>::intersects;
const char *name = BoxName<T>::value;
class_<Box<T> > box_class(name);
box_class
.def(init<>("Box() create empty box") )
.def(init<T>("Box(point)create box containing the given point") )
.def(init<T,T>("Box(point,point) create box continaing min and max") )
.def("__init__", make_constructor(box3TupleConstructor1<T>), "Box(point) where point is a python tuple")
.def("__init__", make_constructor(box3TupleConstructor2<T>), "Box(point,point) where point is a python tuple")
.def("__init__", make_constructor(boxConstructor<T, IMATH_NAMESPACE::V3f>))
.def("__init__", make_constructor(boxConstructor<T, IMATH_NAMESPACE::V3d>))
.def("__init__", make_constructor(boxConstructor<T, IMATH_NAMESPACE::V3i>))
.def_readwrite("min",&Box<T>::min)
.def_readwrite("max",&Box<T>::max)
.def(self == self)
.def(self != self)
.def("__mul__", &mulM44<T, float>)
.def("__mul__", &mulM44<T, double>)
.def("__imul__", &imulM44<T, float>,return_internal_reference<>())
.def("__imul__", &imulM44<T, double>,return_internal_reference<>())
.def("min", &boxMin<T>)
.def("max", &boxMax<T>)
.def("__repr__", &Box3_repr<T>)
.def("makeEmpty",&Box<T>::makeEmpty,"makeEmpty() make the box empty")
.def("makeInfinite",&Box<T>::makeInfinite,"makeInfinite() make the box cover all space")
.def("extendBy",extendBy1,"extendBy(point) extend the box by a point")
.def("extendBy",box_extendBy<T>,"extendBy(array) extend the box the values in the array")
.def("extendBy",extendBy2,"extendBy(box) extend the box by a box")
.def("size",&Box<T>::size,"size() size of the box")
.def("center",&Box<T>::center,"center() center of the box")
.def("intersects",intersects1,"intersects(point) returns true if the box intersects the given point")
.def("intersects",intersects2,"intersects(box) returns true if the box intersects the given box")
.def("intersects",box_intersects<T>, "intersects(array) returns an int array where 0 indicates the point is not in the box and 1 indicates that it is")
.def("majorAxis",&Box<T>::majorAxis,"majorAxis() major axis of the box")
.def("isEmpty",&Box<T>::isEmpty,"isEmpty() returns true if the box is empty")
.def("isInfinite",&Box<T>::isInfinite,"isInfinite() returns true if the box covers all space")
.def("hasVolume",&Box<T>::hasVolume,"hasVolume() returns true if the box has volume")
.def("setMin",&boxSetMin<T>,"setMin() sets the min value of the box")
.def("setMax",&boxSetMax<T>,"setMax() sets the max value of the box")
;
decoratecopy(box_class);
return box_class;
}
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V2s> > register_Box2<IMATH_NAMESPACE::V2s>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V2i> > register_Box2<IMATH_NAMESPACE::V2i>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V2f> > register_Box2<IMATH_NAMESPACE::V2f>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V2d> > register_Box2<IMATH_NAMESPACE::V2d>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V3s> > register_Box3<IMATH_NAMESPACE::V3s>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V3i> > register_Box3<IMATH_NAMESPACE::V3i>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V3f> > register_Box3<IMATH_NAMESPACE::V3f>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V3d> > register_Box3<IMATH_NAMESPACE::V3d>();
}

View File

@ -0,0 +1,229 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathBox_h_
#define _PyImathBox_h_
#include <Python.h>
#include <boost/python.hpp>
#include <ImathBox.h>
#include <PyImathVec.h>
#include <PyImathFixedArray.h>
namespace PyImath {
template <class T> boost::python::class_<IMATH_NAMESPACE::Box<T> > register_Box2();
template <class T> boost::python::class_<IMATH_NAMESPACE::Box<T> > register_Box3();
template <class T> boost::python::class_<FixedArray<IMATH_NAMESPACE::Box<T> > > register_BoxArray();
typedef FixedArray<IMATH_NAMESPACE::Box2s> Box2sArray;
typedef FixedArray<IMATH_NAMESPACE::Box2i> Box2iArray;
typedef FixedArray<IMATH_NAMESPACE::Box2f> Box2fArray;
typedef FixedArray<IMATH_NAMESPACE::Box2d> Box2dArray;
typedef FixedArray<IMATH_NAMESPACE::Box3s> Box3sArray;
typedef FixedArray<IMATH_NAMESPACE::Box3i> Box3iArray;
typedef FixedArray<IMATH_NAMESPACE::Box3f> Box3fArray;
typedef FixedArray<IMATH_NAMESPACE::Box3d> Box3dArray;
//
// Other code in the Zeno code base assumes the existance of a class with the
// same name as the Imath class, and with static functions wrap() and
// convert() to produce a PyImath object from an Imath object and vice-versa,
// respectively. The class Boost generates from the Imath class does not
// have these properties, so we define a companion class here.
// The template argument, T, is the element type for the box (e.g., int,
// float).
template <class T>
class Box2 {
public:
static PyObject * wrap (const IMATH_NAMESPACE::Box< IMATH_NAMESPACE::Vec2<T> > &b);
static int convert (PyObject *p, IMATH_NAMESPACE::Box< IMATH_NAMESPACE::Vec2<T> > *b);
};
template <class T>
class Box3 {
public:
static PyObject * wrap (const IMATH_NAMESPACE::Box< IMATH_NAMESPACE::Vec3<T> > &b);
static int convert (PyObject *p, IMATH_NAMESPACE::Box< IMATH_NAMESPACE::Vec3<T> > *v);
};
template <class T>
PyObject *
Box2<T>::wrap (const IMATH_NAMESPACE::Box< IMATH_NAMESPACE::Vec2<T> > &b)
{
typename boost::python::return_by_value::apply < IMATH_NAMESPACE::Box< IMATH_NAMESPACE::Vec2<T> > >::type converter;
PyObject *p = converter (b);
return p;
}
template <class T>
PyObject *
Box3<T>::wrap (const IMATH_NAMESPACE::Box< IMATH_NAMESPACE::Vec3<T> > &b)
{
typename boost::python::return_by_value::apply < IMATH_NAMESPACE::Box< IMATH_NAMESPACE::Vec3<T> > >::type converter;
PyObject *p = converter (b);
return p;
}
template <class T>
int
Box2<T>::convert (PyObject *p, IMATH_NAMESPACE::Box< IMATH_NAMESPACE::Vec2<T> > *v)
{
boost::python::extract < IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V2i> > extractorV2i (p);
if (extractorV2i.check())
{
IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V2i> b = extractorV2i();
v->min = b.min;
v->max = b.max;
return 1;
}
boost::python::extract < IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V2f> > extractorV2f (p);
if (extractorV2f.check())
{
IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V2f> b = extractorV2f();
v->min = b.min;
v->max = b.max;
return 1;
}
boost::python::extract < IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V2d> > extractorV2d (p);
if (extractorV2d.check())
{
IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V2d> b = extractorV2d();
v->min = b.min;
v->max = b.max;
return 1;
}
boost::python::extract <boost::python::tuple> extractorTuple (p);
if (extractorTuple.check())
{
boost::python::tuple t = extractorTuple();
if (t.attr ("__len__") () == 2)
{
PyObject *minObj =
boost::python::extract <boost::python::object> (t[0])().ptr();
PyObject *maxObj =
boost::python::extract <boost::python::object> (t[1])().ptr();
IMATH_NAMESPACE::Vec2<T> min, max;
if (! V2<T>::convert (minObj, &min))
return 0;
if (! V2<T>::convert (maxObj, &max))
return 0;
v->min = min;
v->max = max;
return 1;
}
}
return 0;
}
template <class T>
int
Box3<T>::convert (PyObject *p, IMATH_NAMESPACE::Box< IMATH_NAMESPACE::Vec3<T> > *v)
{
boost::python::extract < IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V3i> > extractorV3i (p);
if (extractorV3i.check())
{
IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V3i> b = extractorV3i();
v->min = b.min;
v->max = b.max;
return 1;
}
boost::python::extract < IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V3f> > extractorV3f (p);
if (extractorV3f.check())
{
IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V3f> b = extractorV3f();
v->min = b.min;
v->max = b.max;
return 1;
}
boost::python::extract < IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V3d> > extractorV3d (p);
if (extractorV3d.check())
{
IMATH_NAMESPACE::Box<IMATH_NAMESPACE::V3d> b = extractorV3d();
v->min = b.min;
v->max = b.max;
return 1;
}
boost::python::extract <boost::python::tuple> extractorTuple (p);
if (extractorTuple.check())
{
boost::python::tuple t = extractorTuple();
if (t.attr ("__len__") () == 2)
{
PyObject *minObj =
boost::python::extract <boost::python::object> (t[0])().ptr();
PyObject *maxObj =
boost::python::extract <boost::python::object> (t[1])().ptr();
IMATH_NAMESPACE::Vec3<T> min, max;
if (! V3<T>::convert (minObj, &min))
return 0;
if (! V3<T>::convert (maxObj, &max))
return 0;
v->min = min;
v->max = max;
return 1;
}
}
return 0;
}
typedef Box2<int> Box2i;
typedef Box2<float> Box2f;
typedef Box2<double> Box2d;
typedef Box3<int> Box3i;
typedef Box3<float> Box3f;
typedef Box3<double> Box3d;
}
#endif

View File

@ -0,0 +1,51 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 <PyImathBoxArrayImpl.h>
#include <PyImathExport.h>
namespace PyImath {
using namespace boost::python;
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Box2s> > register_BoxArray<IMATH_NAMESPACE::V2s>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Box2i> > register_BoxArray<IMATH_NAMESPACE::V2i>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Box2f> > register_BoxArray<IMATH_NAMESPACE::V2f>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Box2d> > register_BoxArray<IMATH_NAMESPACE::V2d>();
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Box2s PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Box2s>::value() { return IMATH_NAMESPACE::Box2s(); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Box2i PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Box2i>::value() { return IMATH_NAMESPACE::Box2i(); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Box2f PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Box2f>::value() { return IMATH_NAMESPACE::Box2f(); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Box2d PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Box2d>::value() { return IMATH_NAMESPACE::Box2d(); }
}

View File

@ -0,0 +1,50 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 <PyImathBoxArrayImpl.h>
#include <PyImathExport.h>
namespace PyImath {
using namespace boost::python;
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Box3s> > register_BoxArray<IMATH_NAMESPACE::V3s>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Box3i> > register_BoxArray<IMATH_NAMESPACE::V3i>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Box3f> > register_BoxArray<IMATH_NAMESPACE::V3f>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Box3d> > register_BoxArray<IMATH_NAMESPACE::V3d>();
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Box3s PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Box3s>::value() { return IMATH_NAMESPACE::Box3s(); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Box3i PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Box3i>::value() { return IMATH_NAMESPACE::Box3i(); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Box3f PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Box3f>::value() { return IMATH_NAMESPACE::Box3f(); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Box3d PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Box3d>::value() { return IMATH_NAMESPACE::Box3d(); }
}

View File

@ -0,0 +1,108 @@
#ifndef _PyImathBoxArrayImpl_h_
#define _PyImathBoxArrayImpl_h_
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
//
// This .C file was turned into a header file so that instantiations
// of the various Box* types can be spread across multiple files in
// order to work around MSVC limitations.
//
#include <PyImathBox.h>
#include "PyImathDecorators.h"
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/format.hpp>
#include <PyImath.h>
#include <ImathVec.h>
#include <ImathVecAlgo.h>
#include <ImathBox.h>
#include <Iex.h>
#include <PyImathMathExc.h>
#include <PyImathOperators.h>
#include <PyImathVecOperators.h>
namespace PyImath {
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template <class T,int index>
static FixedArray<T>
BoxArray_get(FixedArray<IMATH_NAMESPACE::Box<T> > &va)
{
return index == 0 ?
FixedArray<T>(&va[0].min,va.len(),2*va.stride(),va.handle()) :
FixedArray<T>(&va[0].max,va.len(),2*va.stride(),va.handle());
}
template <class T>
static void
setItemTuple(FixedArray<IMATH_NAMESPACE::Box<T> > &va, Py_ssize_t index, const tuple &t)
{
if(t.attr("__len__")() == 2)
{
Box<T> v;
v.min = extract<T>(t[0]);
v.max = extract<T>(t[1]);
va[va.canonical_index(index)] = v;
}
else
THROW(IEX_NAMESPACE::LogicExc, "tuple of length 2 expected");
}
template <class T>
class_<FixedArray<IMATH_NAMESPACE::Box<T> > >
register_BoxArray()
{
using boost::mpl::true_;
using boost::mpl::false_;
class_<FixedArray<IMATH_NAMESPACE::Box<T> > > boxArray_class = FixedArray<IMATH_NAMESPACE::Box<T> >::register_("Fixed length array of IMATH_NAMESPACE::Box");
boxArray_class
.add_property("min",&BoxArray_get<T,0>)
.add_property("max",&BoxArray_get<T,1>)
.def("__setitem__", &setItemTuple<T>)
;
decoratecopy(boxArray_class);
return boxArray_class;
}
} // namespace PyImath
#endif // _PyImathBoxArrayImpl_h_

View File

@ -0,0 +1,256 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathColor3_h_
#define _PyImathColor3_h_
#include <Python.h>
#include <boost/python.hpp>
#include <PyImath.h>
#include <ImathColor.h>
#include <PyImath.h>
namespace PyImath {
template <class T> boost::python::class_<IMATH_NAMESPACE::Color4<T> > register_Color4();
template <class T> boost::python::class_<PyImath::FixedArray2D<IMATH_NAMESPACE::Color4<T> > > register_Color4Array2D();
template <class T> boost::python::class_<PyImath::FixedArray<IMATH_NAMESPACE::Color4<T> > > register_Color4Array();
template <class T> boost::python::class_<IMATH_NAMESPACE::Color3<T>, boost::python::bases<IMATH_NAMESPACE::Vec3<T> > > register_Color3();
template <class T> boost::python::class_<PyImath::FixedArray<IMATH_NAMESPACE::Color3<T> > > register_Color3Array();
typedef FixedArray2D<IMATH_NAMESPACE::Color4f> Color4fArray;
typedef FixedArray2D<IMATH_NAMESPACE::Color4c> Color4cArray;
typedef FixedArray<IMATH_NAMESPACE::Color4f> C4fArray;
typedef FixedArray<IMATH_NAMESPACE::Color4c> C4cArray;
typedef FixedArray<IMATH_NAMESPACE::Color3f> C3fArray;
typedef FixedArray<IMATH_NAMESPACE::Color3c> C3cArray;
//
// Other code in the Zeno code base assumes the existance of a class with the
// same name as the Imath class, and with static functions wrap() and
// convert() to produce a PyImath object from an Imath object and vice-versa,
// respectively. The class Boost generates from the Imath class does not
// have these properties, so we define a companion class here.
// The template argument, T, is the element type for the color in C++ (e.g., char,
// float). The other argument, U, is how this type is represented in Python
// (e.g., int, float).
template <class T, class U>
class C3 {
public:
static PyObject * wrap (const IMATH_NAMESPACE::Color3<T> &c);
static int convert (PyObject *p, IMATH_NAMESPACE::Color3<T> *v);
};
template <class T, class U>
class C4 {
public:
static PyObject * wrap (const IMATH_NAMESPACE::Color4<T> &c);
static int convert (PyObject *p, IMATH_NAMESPACE::Color4<T> *v);
};
template <class T, class U>
PyObject *
C3<T, U>::wrap (const IMATH_NAMESPACE::Color3<T> &c)
{
typename boost::python::return_by_value::apply < IMATH_NAMESPACE::Color3<T> >::type converter;
PyObject *p = converter (c);
return p;
}
template <class T, class U>
PyObject *
C4<T, U>::wrap (const IMATH_NAMESPACE::Color4<T> &c)
{
typename boost::python::return_by_value::apply < IMATH_NAMESPACE::Color4<T> >::type converter;
PyObject *p = converter (c);
return p;
}
template <class T, class U>
int
C3<T, U>::convert (PyObject *p, IMATH_NAMESPACE::Color3<T> *v)
{
boost::python::extract <IMATH_NAMESPACE::C3c> extractorC3c (p);
if (extractorC3c.check())
{
IMATH_NAMESPACE::C3c c3c = extractorC3c();
v->setValue (U(c3c[0]), U(c3c[1]), U(c3c[2]));
return 1;
}
boost::python::extract <IMATH_NAMESPACE::C3f> extractorC3f (p);
if (extractorC3f.check())
{
IMATH_NAMESPACE::C3f c3f = extractorC3f();
v->setValue (U(c3f[0]), U(c3f[1]), U(c3f[2]));
return 1;
}
boost::python::extract <boost::python::tuple> extractorTuple (p);
if (extractorTuple.check())
{
boost::python::tuple t = extractorTuple();
if (t.attr ("__len__") () == 3)
{
double a = boost::python::extract <double> (t[0]);
double b = boost::python::extract <double> (t[1]);
double c = boost::python::extract <double> (t[2]);
v->setValue (U(a), U(b), U(c));
return 1;
}
}
boost::python::extract <boost::python::list> extractorList (p);
if (extractorList.check())
{
boost::python::list l = extractorList();
if (l.attr ("__len__") () == 3)
{
boost::python::extract <double> extractor0 (l[0]);
boost::python::extract <double> extractor1 (l[1]);
boost::python::extract <double> extractor2 (l[2]);
if (extractor0.check() && extractor1.check() &&
extractor2.check())
{
v->setValue (U(extractor0()), U(extractor1()),
U(extractor2()));
return 1;
}
}
}
boost::python::extract <IMATH_NAMESPACE::V3i> extractorV3i (p);
if (extractorV3i.check())
{
IMATH_NAMESPACE::V3i v3i = extractorV3i();
v->setValue (U(v3i[0]), U(v3i[1]), U(v3i[2]));
return 1;
}
boost::python::extract <IMATH_NAMESPACE::V3f> extractorV3f (p);
if (extractorV3f.check())
{
IMATH_NAMESPACE::V3f v3f = extractorV3f();
v->setValue (U(v3f[0]), U(v3f[1]), U(v3f[2]));
return 1;
}
boost::python::extract <IMATH_NAMESPACE::V3d> extractorV3d (p);
if (extractorV3d.check())
{
IMATH_NAMESPACE::V3d v3d = extractorV3d();
v->setValue (U(v3d[0]), U(v3d[1]), U(v3d[2]));
return 1;
}
return 0;
}
template <class T, class U>
int
C4<T, U>::convert (PyObject *p, IMATH_NAMESPACE::Color4<T> *v)
{
boost::python::extract <IMATH_NAMESPACE::C4c> extractorC4c (p);
if (extractorC4c.check())
{
IMATH_NAMESPACE::C4c c4c = extractorC4c();
v->setValue (U(c4c[0]), U(c4c[1]), U(c4c[2]), U(c4c[3]));
return 1;
}
boost::python::extract <IMATH_NAMESPACE::C4f> extractorC4f (p);
if (extractorC4f.check())
{
IMATH_NAMESPACE::C4f c4f = extractorC4f();
v->setValue (U(c4f[0]), U(c4f[1]), U(c4f[2]), U(c4f[3]));
return 1;
}
boost::python::extract <boost::python::tuple> extractorTuple (p);
if (extractorTuple.check())
{
boost::python::tuple t = extractorTuple();
if (t.attr ("__len__") () == 4)
{
// As with V3<T>, we extract the tuple elements as doubles and
// cast them to Ts in setValue(), to avoid any odd cases where
// extracting them as Ts from the start would fail.
double a = boost::python::extract <double> (t[0]);
double b = boost::python::extract <double> (t[1]);
double c = boost::python::extract <double> (t[2]);
double d = boost::python::extract <double> (t[3]);
v->setValue (U(a), U(b), U(c), U(d));
return 1;
}
}
boost::python::extract <boost::python::list> extractorList (p);
if (extractorList.check())
{
boost::python::list l = extractorList();
if (l.attr ("__len__") () == 4)
{
boost::python::extract <double> extractor0 (l[0]);
boost::python::extract <double> extractor1 (l[1]);
boost::python::extract <double> extractor2 (l[2]);
boost::python::extract <double> extractor3 (l[3]);
if (extractor0.check() && extractor1.check() &&
extractor2.check() && extractor3.check())
{
v->setValue (U(extractor0()), U(extractor1()),
U(extractor2()), U(extractor3()));
return 1;
}
}
}
return 0;
}
typedef C3<float, float> Color3f;
typedef C3<unsigned char, int> Color3c;
typedef Color3f C3f;
typedef Color3c C3c;
typedef C4<float, float> Color4f;
typedef C4<unsigned char, int> Color4c;
typedef Color4f C4f;
typedef Color4c C4c;
}
#endif

View File

@ -0,0 +1,677 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
//
// This .C file was turned into a header file so that instantiations
// of the various V3* types can be spread across multiple files in
// order to work around MSVC limitations.
//
#include <PyImathColor.h>
#include <PyImathVec.h>
#include "PyImathDecorators.h"
#include "PyImathExport.h"
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/format.hpp>
#include <PyImath.h>
#include <PyImathMathExc.h>
#include <ImathVec.h>
#include <ImathColor.h>
#include <ImathColorAlgo.h>
#include <Iex.h>
#include "PyImathColor3ArrayImpl.h"
namespace PyImath {
template <> const char *PyImath::C3cArray::name() { return "C3cArray"; }
template <> const char *PyImath::C3fArray::name() { return "C3fArray"; }
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template <class T> struct Color3Name { static const char *value; };
template<> const char *Color3Name<unsigned char>::value = "Color3c";
template<> const char *Color3Name<float>::value = "Color3f";
// create a new default constructor that initializes Color3<T> to zero.
template <class T>
static Color3<T> * Color3_construct_default()
{
return new Color3<T>(T(0),T(0),T(0));
}
template <class T, class S>
static Color3<T> * Color3_component_construct1(S x, S y, S z)
{
// Assigning a floating point value to an integer type can cause a
// float-point error, which we want to translate into an exception.
MATH_EXC_ON;
if(strcmp(Color3Name<T>::value, "Color3c") == 0)
{
unsigned char r = (unsigned char) x;
unsigned char g = (unsigned char) y;
unsigned char b = (unsigned char) z;
return new Color3<T>(r,g,b);
}
else
return new Color3<T>(T (x), T(y), T(z));
}
template <class T, class S>
static Color3<T> * Color3_component_construct2(S x)
{
MATH_EXC_ON;
if(strcmp(Color3Name<T>::value, "Color3c") == 0)
{
unsigned char u = (unsigned char) x;
return new Color3<T>(u,u,u);
}
else
return new Color3<T>(T(x), T(x), T(x));
}
template <class T, class S>
static Color3<T> * Color3_color_construct(const Color3<S> &c)
{
MATH_EXC_ON;
if(strcmp(Color3Name<T>::value, "Color3c") == 0)
{
unsigned char r = (unsigned char) c.x;
unsigned char g = (unsigned char) c.y;
unsigned char b = (unsigned char) c.z;
return new Color3<T>(r,g,b);
}
else
return new Color3<T>(T (c.x), T(c.y), T(c.z));
}
template <class T, class S>
static Color3<T> * Color3_vector_construct(const Vec3<S> &c)
{
MATH_EXC_ON;
if(strcmp(Color3Name<T>::value, "Color3c") == 0)
{
unsigned char r = (unsigned char) c.x;
unsigned char g = (unsigned char) c.y;
unsigned char b = (unsigned char) c.z;
return new Color3<T>(r,g,b);
}
else
return new Color3<T>(T (c.x), T(c.y), T(c.z));
}
template <class T>
static std::string
color3_str(const Color3<T> &v)
{
std::stringstream stream;
if(strcmp(Color3Name<T>::value, "Color3c") == 0)
{
int r = int(v.x);
int g = int(v.y);
int b = int(v.z);
stream << Color3Name<T>::value << "(" << r << ", " << g << ", " << b << ")";
return stream.str();
}
else
{
stream << Color3Name<T>::value << "(" << v.x << ", " << v.y << ", " << v.z << ")";
return stream.str();
}
}
// Non-specialized repr is same as str
template <class T>
static std::string
color3_repr(const Color3<T> &v)
{
return color3_str(v);
}
// Specialization for float to full precision
template <>
std::string
color3_repr(const Color3<float> &v)
{
return (boost::format("%s(%.9g, %.9g, %.9g)")
% Color3Name<float>::value % v.x % v.y % v.z).str();
}
// No specialization for double, since we don't instantiate Color3d
template <class T>
static Color3<T> * Color3_construct_tuple(const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 3)
{
return new Color3<T>(extract<T>(t[0]), extract<T>(t[1]), extract<T>(t[2]));
}
else
THROW(IEX_NAMESPACE::LogicExc, "Color3 expects tuple of length 3");
}
template <class T>
static Color3<T> * Color3_construct_list(const list &l)
{
MATH_EXC_ON;
if(l.attr("__len__")() == 3)
{
return new Color3<T>(extract<T>(l[0]), extract<T>(l[1]), extract<T>(l[2]));
}
else
THROW(IEX_NAMESPACE::LogicExc, "Color3 expects list of length 3");
}
template <class T>
static const Color3<T> &
iadd(Color3<T> &color, const Color3<T> &color2)
{
MATH_EXC_ON;
return color += color2;
}
template <class T>
static Color3<T>
add(Color3<T> &color, const Color3<T> &color2)
{
MATH_EXC_ON;
return color + color2;
}
template <class T>
static Color3<T>
addTuple(Color3<T> &color, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 3)
return Color3<T>(color.x + extract<T>(t[0]),
color.y + extract<T>(t[1]),
color.z + extract<T>(t[2]));
else
THROW(IEX_NAMESPACE::LogicExc, "Color3 expects tuple of length 3");
}
template <class T>
static Color3<T>
addT(Color3<T> &v, T a)
{
MATH_EXC_ON;
Color3<T> w(v.x + a, v.y + a, v.z + a);
return w;
}
template <class T>
static const Color3<T> &
isub(Color3<T> &color, const Color3<T> &color2)
{
MATH_EXC_ON;
return color -= color2;
}
template <class T>
static Color3<T>
sub(Color3<T> &color, const Color3<T> &color2)
{
MATH_EXC_ON;
return color - color2;
}
template <class T>
static Color3<T>
subtractL(Color3<T> &color, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 3)
return Color3<T>(color.x - extract<T>(t[0]),
color.y - extract<T>(t[1]),
color.z - extract<T>(t[2]));
else
THROW(IEX_NAMESPACE::LogicExc, "Color3 expects tuple of length 3");
}
template <class T>
static Color3<T>
subtractLT(const Color3<T> &color, T a)
{
MATH_EXC_ON;
return Color3<T>(color.x - a,
color.y - a,
color.z - a);
}
template <class T>
static Color3<T>
subtractRT(const Color3<T> &color, T a)
{
MATH_EXC_ON;
return Color3<T>(a - color.x,
a - color.y,
a - color.z);
}
template <class T>
static Color3<T>
subtractR(Color3<T> &color, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 3)
return Color3<T>(extract<T>(t[0]) - color.x,
extract<T>(t[1]) - color.y,
extract<T>(t[2]) - color.z);
else
THROW(IEX_NAMESPACE::LogicExc, "Color3 expects tuple of length 3");
}
template <class T>
static Color3<T>
neg(Color3<T> &color)
{
MATH_EXC_ON;
return -color;
}
template <class T>
static const Color3<T> &
negate(Color3<T> &color)
{
MATH_EXC_ON;
return color.negate();
}
template <class T>
static const Color3<T> &
imul(Color3<T> &color, const Color3<T> &color2)
{
MATH_EXC_ON;
return color *= color2;
}
template <class T>
static const Color3<T> &
imulT(Color3<T> &color, const T &t)
{
MATH_EXC_ON;
return color *= t;
}
template <class T>
static Color3<T>
mul(Color3<T> &color, const Color3<T> &color2)
{
MATH_EXC_ON;
return color * color2;
}
template <class T>
static Color3<T>
mulT(Color3<T> &color, const T &t)
{
MATH_EXC_ON;
return color * t;
}
template <class T>
static Color3<T>
rmulT(Color3<T> &color, const T &t)
{
MATH_EXC_ON;
return t * color;
}
template <class T>
static Color3<T>
mulTuple(Color3<T> &color, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 3)
return Color3<T>(color.x * extract<T>(t[0]),
color.y * extract<T>(t[1]),
color.z * extract<T>(t[2]));
else
THROW(IEX_NAMESPACE::LogicExc, "Color3 expects tuple of length 3");
}
template <class T>
static const Color3<T> &
idiv(Color3<T> &color, const Color3<T> &color2)
{
MATH_EXC_ON;
return color /= color2;
}
template <class T>
static const Color3<T> &
idivT(Color3<T> &color, const T &t)
{
MATH_EXC_ON;
return color /= t;
}
template <class T>
static Color3<T>
div(Color3<T> &color, const Color3<T> &color2)
{
MATH_EXC_ON;
return color / color2;
}
template <class T>
static Color3<T>
divT(Color3<T> &color, const T &t)
{
MATH_EXC_ON;
return color / t;
}
template <class T>
static Color3<T>
divTupleL(Color3<T> &color, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 3)
return Color3<T>(color.x / extract<T>(t[0]),
color.y / extract<T>(t[1]),
color.z / extract<T>(t[2]));
else
THROW(IEX_NAMESPACE::LogicExc, "Color3 expects tuple of length 3");
}
template <class T>
static Color3<T>
divTupleR(Color3<T> &color, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 3)
return Color3<T>(extract<T>(t[0]) / color.x,
extract<T>(t[1]) / color.y,
extract<T>(t[2]) / color.z);
else
THROW(IEX_NAMESPACE::LogicExc, "Color3 expects tuple of length 3");
}
template <class T>
static Color3<T>
divTR(Color3<T> &color, T a)
{
MATH_EXC_ON;
return Color3<T>(a / color.x,
a / color.y,
a / color.z);
}
template <class T>
static Color3<T>
hsv2rgb(Color3<T> &color)
{
MATH_EXC_ON;
return IMATH_NAMESPACE::hsv2rgb(color);
}
template <class T>
static Color3<T>
hsv2rgbTuple(const tuple &t)
{
MATH_EXC_ON;
Color3<T> color;
if(t.attr("__len__")() == 3)
{
color.x = extract<T>(t[0]);
color.y = extract<T>(t[1]);
color.z = extract<T>(t[2]);
return IMATH_NAMESPACE::hsv2rgb(color);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Color3 expects tuple of length 3");
}
template <class T>
static Color3<T>
rgb2hsv(Color3<T> &color)
{
MATH_EXC_ON;
return IMATH_NAMESPACE::rgb2hsv(color);
}
template <class T>
static Color3<T>
rgb2hsvTuple(const tuple &t)
{
MATH_EXC_ON;
Color3<T> color;
if(t.attr("__len__")() == 3)
{
color.x = extract<T>(t[0]);
color.y = extract<T>(t[1]);
color.z = extract<T>(t[2]);
return IMATH_NAMESPACE::rgb2hsv(color);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Color3 expects tuple of length 3");
}
template <class T>
static void
setValue1(Color3<T> &color, const T &a, const T &b, const T &c)
{
MATH_EXC_ON;
color.setValue(a, b, c);
}
template <class T>
static void
setValue2(Color3<T> &color, const Color3<T> &v)
{
MATH_EXC_ON;
color.setValue(v);
}
template <class T>
static void
setValueTuple(Color3<T> &color, const tuple &t)
{
MATH_EXC_ON;
Color3<T> v;
if(t.attr("__len__")() == 3)
{
v.x = extract<T>(t[0]);
v.y = extract<T>(t[1]);
v.z = extract<T>(t[2]);
color.setValue(v);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Color3 expects tuple of length 3");
}
template <class T>
static bool
lessThan(Color3<T> &v, const Color3<T> &w)
{
bool isLessThan = (v.x <= w.x && v.y <= w.y && v.z <= w.z)
&& v != w;
return isLessThan;
}
template <class T>
static bool
greaterThan(Color3<T> &v, const Color3<T> &w)
{
bool isGreaterThan = (v.x >= w.x && v.y >= w.y && v.z >= w.z)
&& v != w;
return isGreaterThan;
}
template <class T>
static bool
lessThanEqual(Color3<T> &v, const Color3<T> &w)
{
bool isLessThanEqual = (v.x <= w.x && v.y <= w.y && v.z <= w.z);
return isLessThanEqual;
}
template <class T>
static bool
greaterThanEqual(Color3<T> &v, const Color3<T> &w)
{
bool isGreaterThanEqual = (v.x >= w.x && v.y >= w.y && v.z >= w.z);
return isGreaterThanEqual;
}
template <class T>
class_<Color3<T>, bases<Vec3<T> > >
register_Color3()
{
class_<Color3<T>, bases<Vec3<T> > > color3_class(Color3Name<T>::value, Color3Name<T>::value,init<Color3<T> >("copy construction"));
color3_class
.def("__init__",make_constructor(Color3_construct_default<T>),"initialize to (0,0,0)")
.def("__init__",make_constructor(Color3_construct_tuple<T>), "initialize to (r,g,b) with a python tuple")
.def("__init__",make_constructor(Color3_construct_list<T>), "initialize to (r,g,b) with a python list")
.def("__init__",make_constructor(Color3_component_construct1<T,float>))
.def("__init__",make_constructor(Color3_component_construct1<T,int>))
.def("__init__",make_constructor(Color3_component_construct2<T,float>))
.def("__init__",make_constructor(Color3_component_construct2<T,int>))
.def("__init__",make_constructor(Color3_color_construct<T,float>))
.def("__init__",make_constructor(Color3_color_construct<T,int>))
.def("__init__",make_constructor(Color3_color_construct<T,unsigned char>))
.def("__init__",make_constructor(Color3_vector_construct<T,float>))
.def("__init__",make_constructor(Color3_vector_construct<T,double>))
.def("__init__",make_constructor(Color3_vector_construct<T,int>))
.def_readwrite("r", &Color3<T>::x)
.def_readwrite("g", &Color3<T>::y)
.def_readwrite("b", &Color3<T>::z)
.def("__str__", &color3_str<T>)
.def("__repr__", &color3_repr<T>)
.def(self == self)
.def(self != self)
.def("__iadd__", &iadd<T>,return_internal_reference<>())
.def("__add__", &add<T>)
.def("__add__", &addTuple<T>)
.def("__add__", &addT<T>)
.def("__radd__", &addTuple<T>)
.def("__radd__", &addT<T>)
.def("__isub__", &isub<T>,return_internal_reference<>())
.def("__sub__", &sub<T>)
.def("__sub__", &subtractL<T>)
.def("__sub__", &subtractLT<T>)
.def("__rsub__", &subtractR<T>)
.def("__rsub__", &subtractRT<T>)
.def("__neg__", &neg<T>)
.def("negate",&negate<T>,return_internal_reference<>(),"component-wise multiplication by -1")
.def("__imul__", &imul<T>,return_internal_reference<>())
.def("__imul__", &imulT<T>,return_internal_reference<>())
.def("__mul__", &mul<T>)
.def("__mul__", &mulT<T>)
.def("__rmul__", &rmulT<T>)
.def("__mul__", &mulTuple<T>)
.def("__rmul__", &mulTuple<T>)
.def("__idiv__", &idiv<T>,return_internal_reference<>())
.def("__idiv__", &idivT<T>,return_internal_reference<>())
.def("__itruediv__", &idiv<T>,return_internal_reference<>())
.def("__itruediv__", &idivT<T>,return_internal_reference<>())
.def("__div__", &div<T>)
.def("__div__", &divT<T>)
.def("__div__", &divTupleL<T>)
.def("__truediv__", &div<T>)
.def("__truediv__", &divT<T>)
.def("__truediv__", &divTupleL<T>)
.def("__rdiv__", &divTupleR<T>)
.def("__rdiv__", &divTR<T>)
.def("__lt__", &lessThan<T>)
.def("__gt__", &greaterThan<T>)
.def("__le__", &lessThanEqual<T>)
.def("__ge__", &greaterThanEqual<T>)
.def("dimensions", &Color3<T>::dimensions,"dimensions() number of dimensions in the color")
.staticmethod("dimensions")
.def("baseTypeEpsilon", &Color3<T>::baseTypeEpsilon,"baseTypeEpsilon() epsilon value of the base type of the color")
.staticmethod("baseTypeEpsilon")
.def("baseTypeMax", &Color3<T>::baseTypeMax,"baseTypeMax() max value of the base type of the color")
.staticmethod("baseTypeMax")
.def("baseTypeMin", &Color3<T>::baseTypeMin,"baseTypeMin() min value of the base type of the color")
.staticmethod("baseTypeMin")
.def("baseTypeSmallest", &Color3<T>::baseTypeSmallest,"baseTypeSmallest() smallest value of the base type of the color")
.staticmethod("baseTypeSmallest")
.def("hsv2rgb", &hsv2rgb<T>,
"C.hsv2rgb() -- returns a new color which "
"is C converted from RGB to HSV")
.def("hsv2rgb", &rgb2hsvTuple<T>)
.def("rgb2hsv", &rgb2hsv<T>,
"C.rgb2hsv() -- returns a new color which "
"is C converted from HSV to RGB")
.def("rgb2hsv", &rgb2hsvTuple<T>)
.def("setValue", &setValue1<T>,
"C1.setValue(C2)\nC1.setValue(a,b,c) -- "
"set C1's elements")
.def("setValue", &setValue2<T>)
.def("setValue", &setValueTuple<T>)
;
decoratecopy(color3_class);
return color3_class;
}
template PYIMATH_EXPORT class_<Color3<float>, bases<Vec3<float> > > register_Color3<float>();
template PYIMATH_EXPORT class_<Color3<unsigned char>, bases<Vec3<unsigned char> > > register_Color3<unsigned char>();
template PYIMATH_EXPORT class_<FixedArray<Color3<float> > > register_Color3Array<float>();
template PYIMATH_EXPORT class_<FixedArray<Color3<unsigned char> > > register_Color3Array<unsigned char>();
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Color3<float> PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Color3<float> >::value()
{ return IMATH_NAMESPACE::Color3<float>(0,0,0); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Color3<unsigned char> PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Color3<unsigned char> >::value()
{ return IMATH_NAMESPACE::Color3<unsigned char>(0,0,0); }
}

View File

@ -0,0 +1,84 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2012, 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathColor3ArrayImpl_h_
#define _PyImathColor3ArrayImpl_h_
//
// This .C file was turned into a header file so that instantiations
// of the various V3* types can be spread across multiple files in
// order to work around MSVC limitations.
//
#include "PyImathDecorators.h"
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/format.hpp>
#include <PyImath.h>
#include <Iex.h>
#include <PyImathMathExc.h>
namespace PyImath {
using namespace boost::python;
using namespace IMATH_NAMESPACE;
// XXX fixme - template this
// really this should get generated automatically...
template <class T,int index>
static FixedArray<T>
Color3Array_get(FixedArray<IMATH_NAMESPACE::Color3<T> > &ca)
{
return FixedArray<T>(&ca[0][index],ca.len(),3*ca.stride(),ca.handle());
}
// Currently we are only exposing the RGBA components.
template <class T>
class_<FixedArray<IMATH_NAMESPACE::Color3<T> > >
register_Color3Array()
{
class_<FixedArray<IMATH_NAMESPACE::Color3<T> > > color3Array_class = FixedArray<IMATH_NAMESPACE::Color3<T> >::register_("Fixed length array of Imath::Color3");
color3Array_class
.add_property("r",&Color3Array_get<T,0>)
.add_property("g",&Color3Array_get<T,1>)
.add_property("b",&Color3Array_get<T,2>)
;
return color3Array_class;
}
} // namespace PyImath
#endif // _PyImathColor3ArrayImpl_h_

View File

@ -0,0 +1,685 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 <PyImathColor.h>
#include "PyImathDecorators.h"
#include "PyImathExport.h"
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/format.hpp>
#include <PyImath.h>
#include <PyImathMathExc.h>
#include <ImathColor.h>
#include <ImathColorAlgo.h>
#include <Iex.h>
#include "PyImathColor4Array2DImpl.h"
#include "PyImathColor4ArrayImpl.h"
namespace PyImath {
template <> const char *PyImath::C4cArray::name() { return "C4cArray"; }
template <> const char *PyImath::C4fArray::name() { return "C4fArray"; }
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template <class T> struct Color4Name { static const char *value; };
template<> const char *Color4Name<unsigned char>::value = "Color4c";
template<> const char *Color4Name<float>::value = "Color4f";
// template<> const char *Color4ArrayName<float>::value() { return "Color4fArray"; }
// template<> const char *Color4ArrayName<unsigned char>::value() { return "Color4cArray"; }
template<> const char *Color4Array2DName<float>::value() { return "Color4fArray2D"; }
template<> const char *Color4Array2DName<unsigned char>::value() { return "Color4cArray2D"; }
// create a new default constructor that initializes Color4<T> to zero.
template <class T>
static Color4<T> * Color4_construct_default()
{
return new Color4<T>(T(0),T(0),T(0),T(0));
}
template <class T, class S>
static Color4<T> * Color4_component_construct1(S x, S y, S z, S w)
{
// Assigning a floating point value to an integer type can cause a
// float-point error, which we want to translate into an exception.
MATH_EXC_ON;
if(strcmp(Color4Name<T>::value, "Color4c") == 0)
{
unsigned char r = (unsigned char) x;
unsigned char g = (unsigned char) y;
unsigned char b = (unsigned char) z;
unsigned char a = (unsigned char) w;
return new Color4<T>(r,g,b,a);
}
else
return new Color4<T>(T(x) , T(y), T(z), T(w));
}
template <class T, class S>
static Color4<T> * Color4_component_construct2(S x)
{
MATH_EXC_ON;
if(strcmp(Color4Name<T>::value, "Color4c") == 0)
{
unsigned char u = (unsigned char) x;
return new Color4<T>(u,u,u,u);
}
else
return new Color4<T>(T(x),T(x),T(x),T(x));
}
template <class T, class S>
static Color4<T> * Color4_color_construct(const Color4<S> &c)
{
MATH_EXC_ON;
if(strcmp(Color4Name<T>::value, "Color4c") == 0)
{
unsigned char r = (unsigned char) c.r;
unsigned char g = (unsigned char) c.g;
unsigned char b = (unsigned char) c.b;
unsigned char a = (unsigned char) c.a;
return new Color4<T>(r,g,b,a);
}
else
return new Color4<T>(T (c.r), T(c.g), T(c.b), T(c.a));
}
template <class T>
static Color4<T> * Color4_construct_tuple(const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 4)
{
return new Color4<T>(extract<T>(t[0]),
extract<T>(t[1]),
extract<T>(t[2]),
extract<T>(t[3]));
}
else
THROW(IEX_NAMESPACE::LogicExc, "Color4 expects tuple of length 4");
}
template <class T>
static Color4<T> * Color4_construct_list(const list &l)
{
MATH_EXC_ON;
if(l.attr("__len__")() == 4)
{
return new Color4<T>(extract<T>(l[0]),
extract<T>(l[1]),
extract<T>(l[2]),
extract<T>(l[3]));
}
else
THROW(IEX_NAMESPACE::LogicExc, "Color4 expects list of length 4");
}
template <class T>
static std::string
color4_str(const Color4<T> &c)
{
std::stringstream stream;
if(strcmp(Color4Name<T>::value, "Color4c") == 0)
{
int r = int(c.r);
int g = int(c.g);
int b = int(c.b);
int a = int(c.a);
stream << Color4Name<T>::value << "(" << r << ", " << g << ", " << b << ", " << a << ")";
return stream.str();
}
else
{
stream << Color4Name<T>::value << "(" << c.r << ", " << c.g << ", " << c.b << ", " << c.a << ")";
return stream.str();
}
}
// Non-specialized repr is same as str
template <class T>
static std::string
color4_repr(const Color4<T> &c)
{
return color4_str(c);
}
// Specialization for float to full precision
template <>
std::string
color4_repr(const Color4<float> &c)
{
return (boost::format("%s(%.9g, %.9g, %.9g, %.9g)")
% Color4Name<float>::value % c.r % c.g % c.b % c.a).str();
}
// No specialization for double, since we don't instantiate Color4d
template <class T>
static Color4<T>
hsv2rgb(Color4<T> &color)
{
MATH_EXC_ON;
return IMATH_NAMESPACE::hsv2rgb(color);
}
template <class T>
static Color4<T>
hsv2rgbTuple(const tuple &t)
{
MATH_EXC_ON;
Color4<T> color;
if(t.attr("__len__")() == 4)
{
color.r = extract<T>(t[0]);
color.g = extract<T>(t[1]);
color.b = extract<T>(t[2]);
color.a = extract<T>(t[3]);
return IMATH_NAMESPACE::hsv2rgb(color);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Color4 expects tuple of length 4");
}
template <class T>
static Color4<T>
rgb2hsv(Color4<T> &color)
{
MATH_EXC_ON;
return IMATH_NAMESPACE::rgb2hsv(color);
}
template <class T>
static Color4<T>
rgb2hsvTuple(const tuple &t)
{
MATH_EXC_ON;
Color4<T> color;
if(t.attr("__len__")() == 4)
{
color.r = extract<T>(t[0]);
color.g = extract<T>(t[1]);
color.b = extract<T>(t[2]);
color.a = extract<T>(t[3]);
return IMATH_NAMESPACE::rgb2hsv(color);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Color4 expects tuple of length 4");
}
template <class T>
static void
setValue1(Color4<T> &color, const T &a, const T &b, const T &c, const T &d)
{
MATH_EXC_ON;
color.setValue(a, b, c, d);
}
template <class T>
static void
setValue2(Color4<T> &color, const Color4<T> &v)
{
MATH_EXC_ON;
color.setValue(v);
}
template <class T>
static void
setValueTuple(Color4<T> &color, const tuple &t)
{
MATH_EXC_ON;
Color4<T> v;
if(t.attr("__len__")() == 4)
{
v.r = extract<T>(t[0]);
v.g = extract<T>(t[1]);
v.b = extract<T>(t[2]);
v.a = extract<T>(t[3]);
color.setValue(v);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Color4 expects tuple of length 4");
}
template <class T>
static const Color4<T> &
iadd(Color4<T> &color, const Color4<T> &color2)
{
MATH_EXC_ON;
return color += color2;
}
template <class T>
static Color4<T>
add(Color4<T> &color, const Color4<T> &color2)
{
MATH_EXC_ON;
return color + color2;
}
template <class T>
static Color4<T>
addTuple(Color4<T> &color, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 4)
return Color4<T>(color.r + extract<T>(t[0]),
color.g + extract<T>(t[1]),
color.b + extract<T>(t[2]),
color.a + extract<T>(t[3]));
else
THROW(IEX_NAMESPACE::LogicExc, "Color4 expects tuple of length 4");
}
template <class T>
static Color4<T>
addT(Color4<T> &v, T a)
{
MATH_EXC_ON;
Color4<T> w(v.r + a, v.g + a, v.b + a, v.a + a);
return w;
}
template <class T>
static const Color4<T> &
isub(Color4<T> &color, const Color4<T> &color2)
{
MATH_EXC_ON;
return color -= color2;
}
template <class T>
static Color4<T>
sub(Color4<T> &color, const Color4<T> &color2)
{
MATH_EXC_ON;
return color - color2;
}
template <class T>
static Color4<T>
subtractL(Color4<T> &color, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 4)
return Color4<T>(color.r - extract<T>(t[0]),
color.g - extract<T>(t[1]),
color.b - extract<T>(t[2]),
color.a - extract<T>(t[3]));
else
THROW(IEX_NAMESPACE::LogicExc, "Color4 expects tuple of length 4");
}
template <class T>
static Color4<T>
subtractR(Color4<T> &color, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 4)
return Color4<T>(extract<T>(t[0]) - color.r,
extract<T>(t[1]) - color.g,
extract<T>(t[2]) - color.b,
extract<T>(t[3]) - color.a);
else
THROW(IEX_NAMESPACE::LogicExc, "Color4 expects tuple of length 4");
}
template <class T>
static Color4<T>
subtractLT(const Color4<T> &color, T a)
{
MATH_EXC_ON;
return Color4<T>(color.r - a,
color.g - a,
color.b - a,
color.a - a);
}
template <class T>
static Color4<T>
subtractRT(const Color4<T> &color, T a)
{
MATH_EXC_ON;
return Color4<T>(a - color.r,
a - color.g,
a - color.b,
a - color.a);
}
template <class T>
static Color4<T>
neg(Color4<T> &color)
{
MATH_EXC_ON;
return -color;
}
template <class T>
static const Color4<T> &
negate(Color4<T> &color)
{
MATH_EXC_ON;
return color.negate();
}
template <class T>
static const Color4<T> &
imul(Color4<T> &color, const Color4<T> &color2)
{
MATH_EXC_ON;
return color *= color2;
}
template <class T>
static const Color4<T> &
imulT(Color4<T> &color, const T &t)
{
MATH_EXC_ON;
return color *= t;
}
template <class T>
static Color4<T>
mul(Color4<T> &color, const Color4<T> &color2)
{
MATH_EXC_ON;
return color * color2;
}
template <class T>
static Color4<T>
mulT(Color4<T> &color, const T &t)
{
MATH_EXC_ON;
return color * t;
}
template <class T>
static Color4<T>
rmulT(Color4<T> &color, const T &t)
{
MATH_EXC_ON;
return t * color;
}
template <class T>
static Color4<T>
mulTuple(Color4<T> &color, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 4)
return Color4<T>(color.r * extract<T>(t[0]),
color.g * extract<T>(t[1]),
color.b * extract<T>(t[2]),
color.a * extract<T>(t[3]));
else
THROW(IEX_NAMESPACE::LogicExc, "Color4 expects tuple of length 4");
}
template <class T>
static const Color4<T> &
idiv(Color4<T> &color, const Color4<T> &color2)
{
MATH_EXC_ON;
return color /= color2;
}
template <class T>
static const Color4<T> &
idivT(Color4<T> &color, const T &t)
{
MATH_EXC_ON;
return color /= t;
}
template <class T>
static Color4<T>
div(Color4<T> &color, const Color4<T> &color2)
{
MATH_EXC_ON;
return color / color2;
}
template <class T>
static Color4<T>
divT(Color4<T> &color, const T &t)
{
MATH_EXC_ON;
return color / t;
}
template <class T>
static Color4<T>
divTupleL(Color4<T> &color, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 4)
return Color4<T>(color.r / extract<T>(t[0]),
color.g / extract<T>(t[1]),
color.b / extract<T>(t[2]),
color.a / extract<T>(t[3]));
else
THROW(IEX_NAMESPACE::LogicExc, "Color4 expects tuple of length 4");
}
template <class T>
static Color4<T>
divTupleR(Color4<T> &color, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 4)
return Color4<T>(extract<T>(t[0]) / color.r,
extract<T>(t[1]) / color.g,
extract<T>(t[2]) / color.b,
extract<T>(t[3]) / color.a);
else
THROW(IEX_NAMESPACE::LogicExc, "Color4 expects tuple of length 4");
}
template <class T>
static Color4<T>
divTR(Color4<T> &color, T a)
{
MATH_EXC_ON;
return Color4<T>(a / color.r,
a / color.g,
a / color.b,
a / color.a);
}
template <class T>
static bool
lessThan(Color4<T> &v, const Color4<T> &w)
{
bool isLessThan = (v.r <= w.r && v.g <= w.g && v.b <= w.b && v.a <= w.a)
&& v != w;
return isLessThan;
}
template <class T>
static bool
greaterThan(Color4<T> &v, const Color4<T> &w)
{
bool isGreaterThan = (v.r >= w.r && v.g >= w.g && v.b >= w.b && v.a >= w.a)
&& v != w;
return isGreaterThan;
}
template <class T>
static bool
lessThanEqual(Color4<T> &v, const Color4<T> &w)
{
bool isLessThanEqual = (v.r <= w.r && v.g <= w.g && v.b <= w.b && v.a <= w.a);
return isLessThanEqual;
}
template <class T>
static bool
greaterThanEqual(Color4<T> &v, const Color4<T> &w)
{
bool isGreaterThanEqual = (v.r >= w.r && v.g >= w.g && v.b >= w.b) && v.a >= w.a;
return isGreaterThanEqual;
}
template <class T>
class_<Color4<T> >
register_Color4()
{
typedef PyImath::StaticFixedArray<Color4<T>,T,4> Color4_helper;
void (IMATH_NAMESPACE::Color4<T>::*getValue1)(Color4<T> &) const = &IMATH_NAMESPACE::Color4<T>::getValue;
void (IMATH_NAMESPACE::Color4<T>::*getValue2)(T &, T &, T &, T &) const = &IMATH_NAMESPACE::Color4<T>::getValue;
class_<Color4<T> > color4_class(Color4Name<T>::value, Color4Name<T>::value,init<Color4<T> >("copy construction"));
color4_class
.def("__init__",make_constructor(Color4_construct_default<T>),"initialize to (0,0,0,0)")
.def("__init__",make_constructor(Color4_construct_tuple<T>), "initialize to (r,g,b,a) with a python tuple")
.def("__init__",make_constructor(Color4_construct_list<T>), "initialize to (r,g,b,a) with a python list")
.def("__init__",make_constructor(Color4_component_construct1<T,float>))
.def("__init__",make_constructor(Color4_component_construct1<T,int>))
.def("__init__",make_constructor(Color4_component_construct2<T,float>))
.def("__init__",make_constructor(Color4_component_construct2<T,int>))
.def("__init__",make_constructor(Color4_color_construct<T,float>))
.def("__init__",make_constructor(Color4_color_construct<T,int>))
.def("__init__",make_constructor(Color4_color_construct<T,unsigned char>))
.def_readwrite("r", &Color4<T>::r)
.def_readwrite("g", &Color4<T>::g)
.def_readwrite("b", &Color4<T>::b)
.def_readwrite("a", &Color4<T>::a)
.def("__str__", &color4_str<T>)
.def("__repr__", &color4_repr<T>)
.def(self == self)
.def(self != self)
.def("__iadd__", &iadd<T>,return_internal_reference<>())
.def("__add__", &add<T>)
.def("__add__", &addTuple<T>)
.def("__add__", &addT<T>)
.def("__radd__", &addTuple<T>)
.def("__radd__", &addT<T>)
.def("__isub__", &isub<T>,return_internal_reference<>())
.def("__sub__", &sub<T>)
.def("__sub__", &subtractL<T>)
.def("__sub__", &subtractLT<T>)
.def("__rsub__", &subtractR<T>)
.def("__rsub__", &subtractRT<T>)
.def("__neg__", &neg<T>)
.def("negate",&negate<T>,return_internal_reference<>(),"component-wise multiplication by -1")
.def("__imul__", &imul<T>,return_internal_reference<>())
.def("__imul__", &imulT<T>,return_internal_reference<>())
.def("__mul__", &mul<T>)
.def("__mul__", &mulT<T>)
.def("__rmul__", &mulT<T>)
.def("__mul__", &mulTuple<T>)
.def("__rmul__", &mulTuple<T>)
.def("__idiv__", &idiv<T>,return_internal_reference<>())
.def("__idiv__", &idivT<T>,return_internal_reference<>())
.def("__itruediv__", &idiv<T>,return_internal_reference<>())
.def("__itruediv__", &idivT<T>,return_internal_reference<>())
.def("__div__", &div<T>)
.def("__div__", &divT<T>)
.def("__div__", &divTupleL<T>)
.def("__truediv__", &div<T>)
.def("__truediv__", &divT<T>)
.def("__truediv__", &divTupleL<T>)
.def("__rdiv__", &divTupleR<T>)
.def("__rdiv__", &divTR<T>)
.def("__lt__", &lessThan<T>)
.def("__gt__", &greaterThan<T>)
.def("__le__", &lessThanEqual<T>)
.def("__ge__", &greaterThanEqual<T>)
.def("__len__", Color4_helper::len)
.def("__getitem__", Color4_helper::getitem,return_value_policy<copy_non_const_reference>())
.def("__setitem__", Color4_helper::setitem)
.def("dimensions", &Color4<T>::dimensions,"dimensions() number of dimensions in the color")
.staticmethod("dimensions")
.def("baseTypeEpsilon", &Color4<T>::baseTypeEpsilon,"baseTypeEpsilon() epsilon value of the base type of the color")
.staticmethod("baseTypeEpsilon")
.def("baseTypeMax", &Color4<T>::baseTypeMax,"baseTypeMax() max value of the base type of the color")
.staticmethod("baseTypeMax")
.def("baseTypeMin", &Color4<T>::baseTypeMin,"baseTypeMin() min value of the base type of the color")
.staticmethod("baseTypeMin")
.def("baseTypeSmallest", &Color4<T>::baseTypeSmallest,"baseTypeSmallest() smallest value of the base type of the color")
.staticmethod("baseTypeSmallest")
.def("__repr__",&color4_repr<T>)
.def("hsv2rgb", &hsv2rgb<T>,
"C.hsv2rgb() -- returns a new color which "
"is C converted from RGB to HSV")
.def("hsv2rgb", &rgb2hsvTuple<T>)
.def("rgb2hsv", &rgb2hsv<T>,
"C.rgb2hsv() -- returns a new color which "
"is C converted from HSV to RGB")
.def("rgb2hsv", &rgb2hsvTuple<T>)
.def("setValue", &setValue1<T>,
"C1.setValue(C2)\nC1.setValue(a,b,c) -- "
"set C1's elements")
.def("setValue", &setValue2<T>)
.def("setValue", &setValueTuple<T>)
.def("getValue", getValue1, "getValue()")
.def("getValue", getValue2)
;
decoratecopy(color4_class);
return color4_class;
}
template PYIMATH_EXPORT class_<Color4<float> > register_Color4<float>();
template PYIMATH_EXPORT class_<Color4<unsigned char> > register_Color4<unsigned char>();
template PYIMATH_EXPORT class_<FixedArray<Color4<float> > > register_Color4Array<float>();
template PYIMATH_EXPORT class_<FixedArray<Color4<unsigned char> > > register_Color4Array<unsigned char>();
template PYIMATH_EXPORT class_<FixedArray2D<Color4<float> > > register_Color4Array2D<float>();
template PYIMATH_EXPORT class_<FixedArray2D<Color4<unsigned char> > > register_Color4Array2D<unsigned char>();
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Color4<float> PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Color4<float> >::value()
{ return IMATH_NAMESPACE::Color4<float>(0,0,0, 0); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Color4<unsigned char> PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Color4<unsigned char> >::value()
{ return IMATH_NAMESPACE::Color4<unsigned char>(0,0,0,0); }
}

View File

@ -0,0 +1,595 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathColor4Array2DImpl_h_
#define _PyImathColor4Array2DImpl_h_
//
// This .C file was turned into a header file so that instantiations
// of the various V3* types can be spread across multiple files in
// order to work around MSVC limitations.
//
// #include <PyImathVec.h>
#include "PyImathDecorators.h"
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/format.hpp>
#include <PyImath.h>
// #include <ImathVec.h>
// #include <ImathVecAlgo.h>
#include <Iex.h>
#include <PyImathMathExc.h>
namespace PyImath {
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template <class T> struct Color4Array2DName { static const char *value(); };
// XXX fixme - template this
// really this should get generated automatically...
template <class T,int index>
static FixedArray2D<T>
Color4Array2D_get(FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va)
{
return FixedArray2D<T>(&va(0,0)[index], va.len().x,va.len().y, 4*va.stride().x, va.stride().y, va.handle());
}
// template <class T>
// static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
// Color4Array_cross0(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &vb)
// {
// PY_IMATH_LEAVE_PYTHON;
// IMATH_NAMESPACE::Vec2<size_t> len = va.match_dimension(vb);
// FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
// for (size_t i = 0; i < len; ++i)
// f(i,j) = va(i,j).cross(vb(i,j));
// return f;
// }
//
// template <class T>
// static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
// Color4Array_cross1(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const IMATH_NAMESPACE::Color4<T> &vb)
// {
// PY_IMATH_LEAVE_PYTHON;
// IMATH_NAMESPACE::Vec2<size_t> len = va.len();
// FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
// for (size_t i = 0; i < len; ++i)
// f(i,j) = va(i,j).cross(vb);
// return f;
// }
//
// template <class T>
// static FixedArray2D<T>
// Color4Array_dot0(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &vb)
// {
// PY_IMATH_LEAVE_PYTHON;
// IMATH_NAMESPACE::Vec2<size_t> len = va.match_dimension(vb);
// FixedArray2D<T> f(len);
// for (size_t i = 0; i < len; ++i)
// f(i,j) = va(i,j).dot(vb(i,j));
// return f;
// }
//
// template <class T>
// static FixedArray2D<T>
// Color4Array_dot1(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const IMATH_NAMESPACE::Color4<T> &vb)
// {
// PY_IMATH_LEAVE_PYTHON;
// IMATH_NAMESPACE::Vec2<size_t> len = va.len();
// FixedArray2D<T> f(len);
// for (size_t i = 0; i < len; ++i)
// f(i,j) = va(i,j).dot(vb);
// return f;
// }
// template <class T>
// static FixedArray2D<T>
// Color4Array_length(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va)
// {
// PY_IMATH_LEAVE_PYTHON;
// IMATH_NAMESPACE::Vec2<size_t> len = va.len();
// FixedArray2D<T> f(len);
// for (size_t i = 0; i < len; ++i)
// f(i,j) = va(i,j).length();
// return f;
// }
//
// template <class T>
// static FixedArray2D<T>
// Color4Array_length2(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va)
// {
// PY_IMATH_LEAVE_PYTHON;
// IMATH_NAMESPACE::Vec2<size_t> len = va.len();
// FixedArray2D<T> f(len);
// for (size_t i = 0; i < len; ++i)
// f(i,j) = va(i,j).length2();
// return f;
// }
//
// template <class T>
// static FixedArray2D<IMATH_NAMESPACE::Color4<T> > &
// Color4Array_normalize(FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va)
// {
// PY_IMATH_LEAVE_PYTHON;
// IMATH_NAMESPACE::Vec2<size_t> len = va.len();
// for (size_t i = 0; i < len; ++i)
// va(i,j).normalize();
// return va;
// }
//
// template <class T> static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
// Color4Array_normalized(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va)
// {
// PY_IMATH_LEAVE_PYTHON;
// IMATH_NAMESPACE::Vec2<size_t> len = va.len();
// FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
// for (size_t i = 0; i < len; ++i)
// f(i,j) = va(i,j).normalized();
// return f;
// }
//
template <class T>
static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
Color4Array_mulT(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, T t)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.len();
FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
f(i,j) = va(i,j) * t;
return f;
}
//
// template <class T, class U>
// static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
// Color4Array_mulM44(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const IMATH_NAMESPACE::Matrix44<U> &m)
// {
// PY_IMATH_LEAVE_PYTHON;
// IMATH_NAMESPACE::Vec2<size_t> len = va.len();
// FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
// for (size_t i = 0; i < len; ++i)
// f(i,j) = va(i,j) * m;
// return f;
// }
//
template <class T>
static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
Color4Array_mulArrayT(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const FixedArray2D<T> &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.match_dimension(vb);
FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
f(i,j) = va(i,j) * vb(i,j);
return f;
}
template <class T>
static const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &
Color4Array_imulT(FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, T t)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.len();
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
va(i,j) *= t;
return va;
}
template <class T>
static const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &
Color4Array_imulArrayT(FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const FixedArray2D<T> &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.match_dimension(vb);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
va(i,j) *= vb(i,j);
return va;
}
template <class T>
static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
Color4Array_divT(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, T t)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.len();
FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
f(i,j) = va(i,j) / t;
return f;
}
template <class T>
static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
Color4Array_divArrayT(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const FixedArray2D<T> &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.match_dimension(vb);
FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
f(i,j) = va(i,j) / vb(i,j);
return f;
}
template <class T>
static const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &
Color4Array_idivT(FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, T t)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.len();
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
va(i,j) /= t;
return va;
}
template <class T>
static const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &
Color4Array_idivArrayT(FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const FixedArray2D<T> &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.match_dimension(vb);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
va(i,j) /= vb(i,j);
return va;
}
template <class T>
static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
Color4Array_add(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.match_dimension(vb);
FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
f(i,j) = va(i,j) + vb(i,j);
return f;
}
template <class T>
static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
Color4Array_addColor(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const IMATH_NAMESPACE::Color4<T> &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.len();
FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
f(i,j) = va(i,j) + vb;
return f;
}
template <class T>
static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
Color4Array_sub(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.match_dimension(vb);
FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
f(i,j) = va(i,j) - vb(i,j);
return f;
}
template <class T>
static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
Color4Array_subColor(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const IMATH_NAMESPACE::Color4<T> &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.len();
FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
f(i,j) = va(i,j) - vb;
return f;
}
template <class T>
static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
Color4Array_rsubColor(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const IMATH_NAMESPACE::Color4<T> &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.len();
FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
f(i,j) = vb - va(i,j);
return f;
}
template <class T>
static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
Color4Array_mul(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.match_dimension(vb);
FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
f(i,j) = va(i,j) * vb(i,j);
return f;
}
template <class T>
static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
Color4Array_mulColor(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const IMATH_NAMESPACE::Color4<T> &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.len();
FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
f(i,j) = va(i,j) * vb;
return f;
}
template <class T>
static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
Color4Array_div(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.match_dimension(vb);
FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
f(i,j) = va(i,j) / vb(i,j);
return f;
}
template <class T>
static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
Color4Array_divColor(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const IMATH_NAMESPACE::Color4<T> &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.len();
FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
f(i,j) = va(i,j) / vb;
return f;
}
template <class T>
static FixedArray2D<IMATH_NAMESPACE::Color4<T> >
Color4Array_neg(const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.len();
FixedArray2D<IMATH_NAMESPACE::Color4<T> > f(len);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
f(i,j) = -va(i,j);
return f;
}
template <class T>
static const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &
Color4Array_iadd(FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.match_dimension(vb);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
va(i,j) += vb(i,j);
return va;
}
template <class T>
static const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &
Color4Array_iaddColor(FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const IMATH_NAMESPACE::Color4<T> &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.len();
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
va(i,j) += vb;
return va;
}
template <class T>
static const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &
Color4Array_isub(FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.match_dimension(vb);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
va(i,j) -= vb(i,j);
return va;
}
template <class T>
static const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &
Color4Array_isubColor(FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const IMATH_NAMESPACE::Color4<T> &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.len();
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
va(i,j) -= vb;
return va;
}
template <class T>
static const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &
Color4Array_imul(FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.match_dimension(vb);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
va(i,j) *= vb(i,j);
return va;
}
template <class T>
static const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &
Color4Array_imulColor(FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const IMATH_NAMESPACE::Color4<T> &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.len();
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
va(i,j) *= vb;
return va;
}
template <class T>
static const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &
Color4Array_idiv(FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.match_dimension(vb);
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
va(i,j) /= vb(i,j);
return va;
}
template <class T>
static const FixedArray2D<IMATH_NAMESPACE::Color4<T> > &
Color4Array_idivColor(FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const IMATH_NAMESPACE::Color4<T> &vb)
{
PY_IMATH_LEAVE_PYTHON;
IMATH_NAMESPACE::Vec2<size_t> len = va.len();
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
va(i,j) /= vb;
return va;
}
template <class T>
static void
setItemTuple(FixedArray2D<IMATH_NAMESPACE::Color4<T> > &va, const tuple &index, const tuple &t)
{
if(t.attr("__len__")() == 4 && index.attr("__len__")() == 2)
{
Color4<T> v;
v.r = extract<T>(t[0]);
v.g = extract<T>(t[1]);
v.b = extract<T>(t[2]);
v.a = extract<T>(t[3]);
va(va.canonical_index(extract<Py_ssize_t>(index[0]),va.len()[0]),
va.canonical_index(extract<Py_ssize_t>(index[1]),va.len()[1])) = v;
}
else
THROW(IEX_NAMESPACE::LogicExc, "tuple of length 4 expected");
}
template <class T>
class_<FixedArray2D<IMATH_NAMESPACE::Color4<T> > >
register_Color4Array2D()
{
class_<FixedArray2D<IMATH_NAMESPACE::Color4<T> > > color4Array2D_class =
FixedArray2D<IMATH_NAMESPACE::Color4<T> >::register_(Color4Array2DName<T>::value(),"Fixed length 2d array of IMATH_NAMESPACE::Color4");
color4Array2D_class
.add_property("r",&Color4Array2D_get<T,0>)
.add_property("g",&Color4Array2D_get<T,1>)
.add_property("b",&Color4Array2D_get<T,2>)
.add_property("a",&Color4Array2D_get<T,3>)
// .def("dot",&Color4Array_dot0<T>)
// .def("dot",&Color4Array_dot1<T>)
// .def("cross", &Color4Array_cross0<T>)
// .def("cross", &Color4Array_cross1<T>)
// .def("length", &Color4Array_length<T>)
// .def("length2", &Color4Array_length2<T>)
// .def("normalize", &Color4Array_normalize<T>,return_internal_reference<>())
// .def("normalized", &Color4Array_normalized<T>)
.def("__setitem__", &setItemTuple<T>)
.def("__mul__", &Color4Array_mulT<T>)
// .def("__mul__", &Color4Array_mulM44<T, float>)
// .def("__mul__", &Color4Array_mulM44<T, double>)
.def("__rmul__", &Color4Array_mulT<T>)
.def("__mul__", &Color4Array_mulArrayT<T>)
.def("__rmul__", &Color4Array_mulArrayT<T>)
.def("__imul__", &Color4Array_imulT<T>,return_internal_reference<>())
.def("__imul__", &Color4Array_imulArrayT<T>,return_internal_reference<>())
.def("__div__", &Color4Array_divT<T>)
.def("__div__", &Color4Array_divArrayT<T>)
.def("__truediv__", &Color4Array_divT<T>)
.def("__truediv__", &Color4Array_divArrayT<T>)
.def("__idiv__", &Color4Array_idivT<T>,return_internal_reference<>())
.def("__idiv__", &Color4Array_idivArrayT<T>,return_internal_reference<>())
.def("__itruediv__", &Color4Array_idivT<T>,return_internal_reference<>())
.def("__itruediv__", &Color4Array_idivArrayT<T>,return_internal_reference<>())
.def("__add__",&Color4Array_add<T>)
.def("__add__",&Color4Array_addColor<T>)
.def("__radd__",&Color4Array_addColor<T>)
.def("__sub__",&Color4Array_sub<T>)
.def("__sub__",&Color4Array_subColor<T>)
.def("__rsub__",&Color4Array_rsubColor<T>)
.def("__mul__",&Color4Array_mul<T>)
.def("__mul__",&Color4Array_mulColor<T>)
.def("__rmul__",&Color4Array_mulColor<T>)
.def("__div__",&Color4Array_div<T>)
.def("__div__",&Color4Array_divColor<T>)
.def("__truediv__",&Color4Array_div<T>)
.def("__truediv__",&Color4Array_divColor<T>)
.def("__neg__",&Color4Array_neg<T>)
.def("__iadd__",&Color4Array_iadd<T>, return_internal_reference<>())
.def("__iadd__",&Color4Array_iaddColor<T>, return_internal_reference<>())
.def("__isub__",&Color4Array_isub<T>, return_internal_reference<>())
.def("__isub__",&Color4Array_isubColor<T>, return_internal_reference<>())
.def("__imul__",&Color4Array_imul<T>, return_internal_reference<>())
.def("__imul__",&Color4Array_imulColor<T>, return_internal_reference<>())
.def("__idiv__",&Color4Array_idiv<T>, return_internal_reference<>())
.def("__idiv__",&Color4Array_idivColor<T>, return_internal_reference<>())
.def("__itruediv__",&Color4Array_idiv<T>, return_internal_reference<>())
.def("__itruediv__",&Color4Array_idivColor<T>, return_internal_reference<>())
;
add_comparison_functions(color4Array2D_class);
decoratecopy(color4Array2D_class);
return color4Array2D_class;
}
} // namespace PyImath
#endif // _PyImathColor4ArrayImpl_h_

View File

@ -0,0 +1,85 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathColor4ArrayImpl_h_
#define _PyImathColor4ArrayImpl_h_
//
// This .C file was turned into a header file so that instantiations
// of the various V3* types can be spread across multiple files in
// order to work around MSVC limitations.
//
#include "PyImathDecorators.h"
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/format.hpp>
#include <PyImath.h>
#include <Iex.h>
#include <PyImathMathExc.h>
namespace PyImath {
using namespace boost::python;
using namespace IMATH_NAMESPACE;
// XXX fixme - template this
// really this should get generated automatically...
template <class T,int index>
static FixedArray<T>
Color4Array_get(FixedArray<IMATH_NAMESPACE::Color4<T> > &ca)
{
return FixedArray<T>(&ca[0][index],ca.len(),4*ca.stride(),ca.handle());
}
// Currently we are only exposing the RGBA components.
template <class T>
class_<FixedArray<IMATH_NAMESPACE::Color4<T> > >
register_Color4Array()
{
class_<FixedArray<IMATH_NAMESPACE::Color4<T> > > color4Array_class = FixedArray<IMATH_NAMESPACE::Color4<T> >::register_("Fixed length array of IMATH_NAMESPACE::Color4");
color4Array_class
.add_property("r",&Color4Array_get<T,0>)
.add_property("g",&Color4Array_get<T,1>)
.add_property("b",&Color4Array_get<T,2>)
.add_property("a",&Color4Array_get<T,3>)
;
return color4Array_class;
}
} // namespace PyImath
#endif // _PyImathColor4ArrayImpl_h_

View File

@ -0,0 +1,74 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2008-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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_PYIMATH_DECORATORS_H
#define INCLUDED_PYIMATH_DECORATORS_H
#include <boost/python.hpp>
namespace PyImath
{
// These function add __copy__ and __deepcopy__ methods
// to python classes by simply wrapping the copy constructors
// This interface is needed for using these classes with
// the python copy module.
template <class T>
static T
copy(const T& x)
{
return T(x);
}
template <class T>
static T
deepcopy(const T& x, boost::python::dict&)
{
return copy(x);
}
template <class T, class X1, class X2, class X3>
boost::python::class_<T,X1,X2,X3>&
decoratecopy(boost::python::class_<T,X1,X2,X3>& cls)
{
cls.def("__copy__",&copy<T>);
cls.def("__deepcopy__",&deepcopy<T>);
return cls;
}
} // namespace PyImath
#endif // INCLUDED_PYIMATH_DECORATORS_H

View File

@ -0,0 +1,806 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 <PyImathEuler.h>
#include "PyImathDecorators.h"
#include "PyImathExport.h"
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/format.hpp>
#include <PyImath.h>
#include <PyImathMathExc.h>
#include <ImathVec.h>
#include <Iex.h>
#include <PyImathOperators.h>
// XXX incomplete array wrapping, docstrings missing
namespace PyImath {
template<> const char *PyImath::EulerfArray::name() { return "EulerfArray"; }
template<> const char *PyImath::EulerdArray::name() { return "EulerdArray"; }
}
namespace PyImath {
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template <class T> struct EulerName { static const char *value; };
template<> const char *EulerName<float>::value = "Eulerf";
template<> const char *EulerName<double>::value = "Eulerd";
template <class T>
static std::string nameOfOrder(typename IMATH_NAMESPACE::Euler<T>::Order order)
{
switch(order)
{
case IMATH_NAMESPACE::Euler<T>::XYZ:
return "EULER_XYZ";
case IMATH_NAMESPACE::Euler<T>::XZY:
return "EULER_XZY";
case IMATH_NAMESPACE::Euler<T>::YZX:
return "EULER_YZX";
case IMATH_NAMESPACE::Euler<T>::YXZ:
return "EULER_YXZ";
case IMATH_NAMESPACE::Euler<T>::ZXY:
return "EULER_ZXY";
case IMATH_NAMESPACE::Euler<T>::ZYX:
return "EULER_ZYX";
case IMATH_NAMESPACE::Euler<T>::XZX:
return "EULER_XZX";
case IMATH_NAMESPACE::Euler<T>::XYX:
return "EULER_XYX";
case IMATH_NAMESPACE::Euler<T>::YXY:
return "EULER_YXY";
case IMATH_NAMESPACE::Euler<T>::YZY:
return "EULER_YZY";
case IMATH_NAMESPACE::Euler<T>::ZYZ:
return "EULER_ZYZ";
case IMATH_NAMESPACE::Euler<T>::ZXZ:
return "EULER_ZXZ";
case IMATH_NAMESPACE::Euler<T>::XYZr:
return "EULER_XYZr";
case IMATH_NAMESPACE::Euler<T>::XZYr:
return "EULER_XZYr";
case IMATH_NAMESPACE::Euler<T>::YZXr:
return "EULER_YZXr";
case IMATH_NAMESPACE::Euler<T>::YXZr:
return "EULER_YXZr";
case IMATH_NAMESPACE::Euler<T>::ZXYr:
return "EULER_ZXYr";
case IMATH_NAMESPACE::Euler<T>::ZYXr:
return "EULER_ZYXr";
case IMATH_NAMESPACE::Euler<T>::XZXr:
return "EULER_XZXr";
case IMATH_NAMESPACE::Euler<T>::XYXr:
return "EULER_XYXr";
case IMATH_NAMESPACE::Euler<T>::YXYr:
return "EULER_YXYr";
case IMATH_NAMESPACE::Euler<T>::YZYr:
return "EULER_YZYr";
case IMATH_NAMESPACE::Euler<T>::ZYZr:
return "EULER_ZYZr";
case IMATH_NAMESPACE::Euler<T>::ZXZr:
return "EULER_ZXZr";
}
return "";
}
template <class T>
static std::string Euler_str(const Euler<T> &e)
{
std::stringstream stream;
stream << EulerName<T>::value << "(" << e.x << ", " << e.y << ", " << e.z << ", "
<< nameOfOrder<T> (e.order()) << ")";
return stream.str();
}
// Non-specialized repr is same as str
template <class T>
static std::string Euler_repr(const Euler<T> &e)
{
return Euler_str(e);
}
// Specialization for float to full precision
template <>
std::string Euler_repr(const Euler<float> &e)
{
return (boost::format("%s(%.9g, %.9g, %.9g, %s)")
% EulerName<float>::value
% e.x % e.y % e.z
% nameOfOrder<float>(e.order()).c_str()).str();
}
// Specialization for double to full precision
template <>
std::string Euler_repr(const Euler<double> &e)
{
return (boost::format("%s(%.17g, %.17g, %.17g, %s)")
% EulerName<double>::value
% e.x % e.y % e.z
% nameOfOrder<double>(e.order()).c_str()).str();
}
template <class T>
static bool
equal(const Euler<T> &e0, const Euler<T> &e1)
{
if(e0.x == e1.x && e0.y == e1.y && e0.z == e1.z && (e0.order())==(e1.order()))
return true;
else
return false;
}
template <class T>
static bool
notequal(const Euler<T> &e0, const Euler<T> &e1)
{
if(e0.x != e1.x || e0.y != e1.y || e0.z != e1.z || (e0.order()) != (e1.order()))
{
return true;
}
else
return false;
}
template <class T>
static IMATH_NAMESPACE::Vec3 <int> getAngleOrder(Euler <T> &euler)
{
int i, j, k;
euler.angleOrder(i, j, k);
return IMATH_NAMESPACE::Vec3 <int> (i, j, k);
}
template <class T>
static void
setXYZTuple(Euler<T> &euler, const tuple &t)
{
MATH_EXC_ON;
Vec3<T> v;
if(t.attr("__len__")() == 3)
{
v.x = extract<T>(t[0]);
v.y = extract<T>(t[1]);
v.z = extract<T>(t[2]);
euler.setXYZVector(v);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Color3 expects tuple of length 3");
}
// needed to convert Eulerf::Order to Euler<T>::Order
template <class T>
static typename Euler<T>::Order interpretOrder(typename IMATH_NAMESPACE::Eulerf::Order order)
{
typename Euler<T>::Order o = Euler<T>::XYZ;
switch(order)
{
case IMATH_NAMESPACE::Eulerf::XYZ:
{
o = Euler<T>::XYZ;
}break;
case IMATH_NAMESPACE::Eulerf::XZY:
{
o = Euler<T>::XZY;
}break;
case IMATH_NAMESPACE::Eulerf::YZX:
{
o = Euler<T>::YZX;
}break;
case IMATH_NAMESPACE::Eulerf::YXZ:
{
o = Euler<T>::YXZ;
}break;
case IMATH_NAMESPACE::Eulerf::ZXY:
{
o = Euler<T>::ZXY;
}break;
case IMATH_NAMESPACE::Eulerf::ZYX:
{
o = Euler<T>::ZYX;
}break;
case IMATH_NAMESPACE::Eulerf::XZX:
{
o = Euler<T>::XZX;
}break;
case IMATH_NAMESPACE::Eulerf::XYX:
{
o = Euler<T>::XYX;
}break;
case IMATH_NAMESPACE::Eulerf::YXY:
{
o = Euler<T>::YXY;
}break;
case IMATH_NAMESPACE::Eulerf::YZY:
{
o = Euler<T>::YZY;
}break;
case IMATH_NAMESPACE::Eulerf::ZYZ:
{
o = Euler<T>::ZYZ;
}break;
case IMATH_NAMESPACE::Eulerf::ZXZ:
{
o = Euler<T>::ZXZ;
}break;
case IMATH_NAMESPACE::Eulerf::XYZr:
{
o = Euler<T>::XYZr;
}break;
case IMATH_NAMESPACE::Eulerf::XZYr:
{
o = Euler<T>::XZYr;
}break;
case IMATH_NAMESPACE::Eulerf::YZXr:
{
o = Euler<T>::YZXr;
}break;
case IMATH_NAMESPACE::Eulerf::YXZr:
{
o = Euler<T>::YXZr;
}break;
case IMATH_NAMESPACE::Eulerf::ZXYr:
{
o = Euler<T>::ZXYr;
}break;
case IMATH_NAMESPACE::Eulerf::ZYXr:
{
o = Euler<T>::ZYXr;
}break;
case IMATH_NAMESPACE::Eulerf::XZXr:
{
o = Euler<T>::XZXr;
}break;
case IMATH_NAMESPACE::Eulerf::XYXr:
{
o = Euler<T>::XYXr;
}break;
case IMATH_NAMESPACE::Eulerf::YXYr:
{
o = Euler<T>::YXYr;
}break;
case IMATH_NAMESPACE::Eulerf::YZYr:
{
o = Euler<T>::YZYr;
}break;
case IMATH_NAMESPACE::Eulerf::ZYZr:
{
o = Euler<T>::ZYZr;
}break;
case IMATH_NAMESPACE::Eulerf::ZXZr:
{
o = Euler<T>::ZXZr;
}break;
}
return o;
}
// needed to convert Eulerf::Axis to Euler<T>::Axis
template <class T>
static typename Euler<T>::Axis interpretAxis(typename IMATH_NAMESPACE::Eulerf::Axis axis)
{
if (axis == IMATH_NAMESPACE::Eulerf::X)
return Euler<T>::X;
else if (axis == IMATH_NAMESPACE::Eulerf::Y)
return Euler<T>::Y;
else
return Euler<T>::Z;
}
template <class T>
static Euler<T> *
eulerConstructor1(const Vec3<T> &v, typename IMATH_NAMESPACE::Eulerf::Order order)
{
typename Euler<T>::Order o = interpretOrder<T>(order);
return new Euler<T>(v, o);
}
template <class T>
static Euler<T> *
eulerConstructor1a(const Vec3<T> &v)
{
return eulerConstructor1 (v, IMATH_NAMESPACE::Eulerf::Default);
}
template <class T>
static Euler<T> *
eulerConstructor1b(const Vec3<T> &v, int iorder)
{
typename Euler<T>::Order o = typename Euler<T>::Order (iorder);
return new Euler<T>(v, o);
}
template <class T>
static Euler<T> *
eulerConstructor2(T i, T j, T k, typename IMATH_NAMESPACE::Eulerf::Order order)
{
typename Euler<T>::Order o = interpretOrder<T>(order);
return new Euler<T>(i, j, k, o);
}
template <class T>
static Euler<T> *
eulerConstructor2a(T i, T j, T k)
{
return eulerConstructor2 (i, j, k, IMATH_NAMESPACE::Eulerf::Default);
}
template <class T>
static Euler<T> *
eulerConstructor2b(T i, T j, T k, int iorder)
{
typename Euler<T>::Order o = typename Euler<T>::Order (iorder);
return new Euler<T>(i, j, k, o);
}
template <class T>
static Euler<T> *
eulerConstructor3(const Matrix33<T> &mat, typename IMATH_NAMESPACE::Eulerf::Order order)
{
typename Euler<T>::Order o = interpretOrder<T>(order);
return new Euler<T>(mat, o);
}
template <class T>
static Euler<T> *
eulerConstructor3a(const Matrix33<T> &mat)
{
return eulerConstructor3 (mat, IMATH_NAMESPACE::Eulerf::Default);
}
template <class T>
static Euler<T> *
eulerConstructor3b(const Matrix33<T> &mat, int iorder)
{
typename Euler<T>::Order o = typename Euler<T>::Order (iorder);
return new Euler<T>(mat, o);
}
template <class T>
static Euler<T> *
eulerConstructor4(const Matrix44<T> &mat, typename IMATH_NAMESPACE::Eulerf::Order order)
{
typename Euler<T>::Order o = interpretOrder<T>(order);
return new Euler<T>(mat, o);
}
template <class T>
static Euler<T> *
eulerConstructor4a(const Matrix44<T> &mat)
{
return eulerConstructor4 (mat, IMATH_NAMESPACE::Eulerf::Default);
}
template <class T>
static Euler<T> *
eulerConstructor4b(const Matrix44<T> &mat, int iorder)
{
typename Euler<T>::Order o = typename Euler<T>::Order (iorder);
return new Euler<T>(mat, o);
}
template <class T>
static Euler<T> *
eulerConstructor5(typename IMATH_NAMESPACE::Eulerf::Order order)
{
typename Euler<T>::Order o = interpretOrder<T>(order);
return new Euler<T>(o);
}
template <class T>
static Euler<T> *
eulerConstructor5a()
{
typename Euler<T>::Order o = interpretOrder<T>(IMATH_NAMESPACE::Eulerf::Default);
return new Euler<T>(o);
}
template <class T>
static Euler<T> *
eulerConstructor5b(int iorder)
{
typename Euler<T>::Order o = typename Euler<T>::Order (iorder);
return new Euler<T>(o);
}
template <class T>
static Euler<T> *
eulerConstructor6(T x, T y, T z)
{
return new Euler<T>(Vec3<T>(x,y,z));
}
template <class T>
static Euler<T> *
eulerConstructor7(const Quat<T> &quat, typename IMATH_NAMESPACE::Eulerf::Order order)
{
Euler<T> *e = eulerConstructor5<T>(order);
e->extract(quat);
return e;
}
template <class T>
static Euler<T> *
eulerConstructor7a(const Quat<T> &quat)
{
return eulerConstructor7(quat, IMATH_NAMESPACE::Eulerf::Default);
}
template <class T>
static Euler<T> *
eulerConstructor7b(const Quat<T> &quat, int iorder)
{
Euler<T> *e = eulerConstructor5b<T>(iorder);
e->extract(quat);
return e;
}
template <class T, class S>
static Euler<T> *
eulerConversionConstructor(const Euler<S> &euler)
{
MATH_EXC_ON;
Euler<T> *e = new Euler<T>;
*e = euler;
return e;
}
template <class T>
static void
eulerMakeNear(Euler<T> &euler, Euler<T> &target)
{
MATH_EXC_ON;
euler.makeNear (target);
}
template <class T>
static void
eulerSetOrder(Euler<T> &euler, typename IMATH_NAMESPACE::Eulerf::Order order)
{
typename Euler<T>::Order o = interpretOrder<T>(order);
euler.setOrder (o);
}
template <class T>
static void
eulerSet(Euler<T> &euler, IMATH_NAMESPACE::Eulerf::Axis axis, int relative, int parityEven, int firstRepeats)
{
MATH_EXC_ON;
typename Euler<T>::Axis a = interpretAxis<T>(axis);
euler.set (a, relative, parityEven, firstRepeats);
}
template <class T>
static void
extract1(Euler<T> &euler, const Matrix33<T> &m)
{
MATH_EXC_ON;
euler.extract(m);
}
template <class T>
static void
extract2(Euler<T> &euler, const Matrix44<T> &m)
{
MATH_EXC_ON;
euler.extract(m);
}
template <class T>
static void
extract3(Euler<T> &euler, const Quat<T> &q)
{
MATH_EXC_ON;
euler.extract(q);
}
template <class T>
static Matrix33<T>
toMatrix33(Euler<T> &euler)
{
MATH_EXC_ON;
return euler.toMatrix33();
}
template <class T>
static Matrix44<T>
toMatrix44(Euler<T> &euler)
{
MATH_EXC_ON;
return euler.toMatrix44();
}
template <class T>
static Quat<T>
toQuat(Euler<T> &euler)
{
MATH_EXC_ON;
return euler.toQuat();
}
template <class T>
static Vec3<T>
toXYZVector(Euler<T> &euler)
{
MATH_EXC_ON;
return euler.toXYZVector();
}
template <class T>
class_<Euler<T>,bases<IMATH_NAMESPACE::Vec3<T> > >
register_Euler()
{
class_<Euler<T>,bases<Vec3<T> > > euler_class(EulerName<T>::value,EulerName<T>::value,init<Euler<T> >("copy construction"));
euler_class
.def(init<>("imath Euler default construction"))
.def("__init__", make_constructor(eulerConstructor1<T>))
.def("__init__", make_constructor(eulerConstructor1a<T>))
.def("__init__", make_constructor(eulerConstructor1b<T>))
.def("__init__", make_constructor(eulerConstructor2<T>))
.def("__init__", make_constructor(eulerConstructor2a<T>))
.def("__init__", make_constructor(eulerConstructor2b<T>))
.def("__init__", make_constructor(eulerConstructor3<T>),
"Euler-from-matrix construction assumes, but does\n"
"not verify, that the matrix includes no shear or\n"
"non-uniform scaling. If necessary, you can fix\n"
"the matrix by calling the removeScalingAndShear()\n"
"function.\n")
.def("__init__", make_constructor(eulerConstructor3a<T>))
.def("__init__", make_constructor(eulerConstructor3b<T>))
.def("__init__", make_constructor(eulerConstructor4<T>))
.def("__init__", make_constructor(eulerConstructor4a<T>))
.def("__init__", make_constructor(eulerConstructor4b<T>))
.def("__init__", make_constructor(eulerConstructor5<T>))
.def("__init__", make_constructor(eulerConstructor5a<T>))
.def("__init__", make_constructor(eulerConstructor5b<T>))
.def("__init__", make_constructor(eulerConstructor6<T>))
.def("__init__", make_constructor(eulerConstructor7<T>))
.def("__init__", make_constructor(eulerConstructor7a<T>))
.def("__init__", make_constructor(eulerConstructor7b<T>))
.def("__init__", make_constructor(eulerConversionConstructor<T, float>))
.def("__init__", make_constructor(eulerConversionConstructor<T, double>))
.def("angleOrder", &getAngleOrder<T>, "angleOrder() set the angle order")
.def("frameStatic", &Euler<T>::frameStatic,
"e.frameStatic() -- returns true if the angles of e\n"
"are measured relative to a set of fixed axes,\n"
"or false if the angles of e are measured relative to\n"
"each other\n")
.def("initialAxis", &Euler<T>::initialAxis,
"e.initialAxis() -- returns the initial rotation\n"
"axis of e (EULER_X_AXIS, EULER_Y_AXIS, EULER_Z_AXIS)")
.def("initialRepeated", &Euler<T>::initialRepeated,
"e.initialRepeated() -- returns 1 if the initial\n"
"rotation axis of e is repeated (for example,\n"
"e.order() == EULER_XYX); returns 0 if the initial\n"
"rotation axis is not repeated.\n")
.def("makeNear", &eulerMakeNear<T>,
"e.makeNear(t) -- adjusts Euler e so that it\n"
"represents the same rotation as before, but the\n"
"individual angles of e differ from the angles of\n"
"t by as little as possible.\n"
"This method might not make sense if e.order()\n"
"and t.order() are different\n")
.def("order", &Euler<T>::order,
"e.order() -- returns the rotation order in e\n"
"(EULER_XYZ, EULER_XZY, ...)")
.def("parityEven", &Euler<T>::parityEven,
"e.parityEven() -- returns the parity of the\n"
"axis permutation of e\n")
.def("set", &eulerSet<T>,
"e.set(i,r,p,f) -- sets the rotation order in e\n"
"according to the following flags:\n"
"\n"
" i initial axis (EULER_X_AXIS,\n"
" EULER_Y_AXIS or EULER_Z_AXIS)\n"
"\n"
" r rotation angles are measured relative\n"
" to each other (r == 1), or relative to a\n"
" set of fixed axes (r == 0)\n"
"\n"
" p parity of axis permutation is even (r == 1)\n"
" or odd (r == 0)\n"
"\n"
" f first rotation axis is repeated (f == 1)\n"
" or not repeated (f == 0)\n")
.def("setOrder", &eulerSetOrder<T>,
"e.setOrder(o) -- sets the rotation order in e\n"
"to o (EULER_XYZ, EULER_XZY, ...)")
.def("setXYZVector", &Euler<T>::setXYZVector,
"e.setXYZVector(v) -- sets the three rotation\n"
"angles in e to v[0], v[1], v[2]")
.def("setXYZVector", &setXYZTuple<T>)
.def("extract", &extract1<T>,
"e.extract(m) -- extracts the rotation component\n"
"from 3x3 matrix m and stores the result in e.\n"
"Assumes that m does not contain shear or non-\n"
"uniform scaling. If necessary, you can fix m\n"
"by calling m.removeScalingAndShear().")
.def("extract", &extract2<T>,
"e.extract(m) -- extracts the rotation component\n"
"from 4x4 matrix m and stores the result in e.\n"
"Assumes that m does not contain shear or non-\n"
"uniform scaling. If necessary, you can fix m\n"
"by calling m.removeScalingAndShear().")
.def("extract", &extract3<T>,
"e.extract(q) -- extracts the rotation component\n"
"from quaternion q and stores the result in e")
.def("toMatrix33", &toMatrix33<T>, "e.toMatrix33() -- converts e into a 3x3 matrix\n")
.def("toMatrix44", &toMatrix44<T>, "e.toMatrix44() -- converts e into a 4x4 matrix\n")
.def("toQuat", &toQuat<T>, "e.toQuat() -- converts e into a quaternion\n")
.def("toXYZVector", &toXYZVector<T>,
"e.toXYZVector() -- converts e into an XYZ\n"
"rotation vector")
.def("__str__", &Euler_str<T>)
.def("__repr__", &Euler_repr<T>)
.def("__eq__", &equal<T>)
.def("__ne__", &notequal<T>)
;
// fill in the Euler scope
{
scope euler_scope(euler_class);
enum_<typename Euler<T>::Order> euler_order("Order");
euler_order
.value("XYZ",Euler<T>::XYZ)
.value("XZY",Euler<T>::XZY)
.value("YZX",Euler<T>::YZX)
.value("YXZ",Euler<T>::YXZ)
.value("ZXY",Euler<T>::ZXY)
.value("ZYX",Euler<T>::ZYX)
.value("XZX",Euler<T>::XZX)
.value("XYX",Euler<T>::XYX)
.value("YXY",Euler<T>::YXY)
.value("YZY",Euler<T>::YZY)
.value("ZYZ",Euler<T>::ZYZ)
.value("ZXZ",Euler<T>::ZXZ)
.value("XYZr",Euler<T>::XYZr)
.value("XZYr",Euler<T>::XZYr)
.value("YZXr",Euler<T>::YZXr)
.value("YXZr",Euler<T>::YXZr)
.value("ZXYr",Euler<T>::ZXYr)
.value("ZYXr",Euler<T>::ZYXr)
.value("XZXr",Euler<T>::XZXr)
.value("XYXr",Euler<T>::XYXr)
.value("YXYr",Euler<T>::YXYr)
.value("YZYr",Euler<T>::YZYr)
.value("ZYZr",Euler<T>::ZYZr)
.value("ZXZr",Euler<T>::ZXZr)
// don't export these, they're not really part of the public interface
//.value("Legal",Euler<T>::Legal)
//.value("Min",Euler<T>::Min)
//.value("Max",Euler<T>::Max)
// handle Default seperately since boost sets up a 1-1 mapping for enum values
//.value("Default",Euler<T>::Default)
.export_values()
;
// just set it to the XYZ value manually
euler_scope.attr("Default") = euler_scope.attr("XYZ");
enum_<typename Euler<T>::Axis>("Axis")
.value("X",Euler<T>::X)
.value("Y",Euler<T>::Y)
.value("Z",Euler<T>::Z)
.export_values()
;
enum_<typename Euler<T>::InputLayout>("InputLayout")
.value("XYZLayout",Euler<T>::XYZLayout)
.value("IJKLayout",Euler<T>::IJKLayout)
.export_values()
;
}
decoratecopy(euler_class);
return euler_class;
}
// XXX fixme - template this
// really this should get generated automatically...
/*
template <class T,int index>
static FixedArray<T>
EulerArray_get(FixedArray<IMATH_NAMESPACE::Euler<T> > &qa)
{
return FixedArray<T>( &(qa[0].r)+index, qa.len(), 4*qa.stride());
}
*/
template <class T>
static FixedArray<IMATH_NAMESPACE::Euler<T> > *
EulerArray_eulerConstructor7a(const FixedArray<IMATH_NAMESPACE::Quat<T> > &q)
{
MATH_EXC_ON;
size_t len = q.len();
FixedArray<IMATH_NAMESPACE::Euler<T> >* result = new FixedArray<IMATH_NAMESPACE::Euler<T> >(len);
for (size_t i = 0; i < len; ++i) {
(*result)[i].extract(q[i]);
}
return result;
}
template <class T>
class_<FixedArray<IMATH_NAMESPACE::Euler<T> > >
register_EulerArray()
{
class_<FixedArray<IMATH_NAMESPACE::Euler<T> > > eulerArray_class = FixedArray<IMATH_NAMESPACE::Euler<T> >::register_("Fixed length array of IMATH_NAMESPACE::Euler");
eulerArray_class
//.add_property("x",&EulerArray_get<T,1>)
//.add_property("y",&EulerArray_get<T,2>)
//.add_property("z",&EulerArray_get<T,3>)
.def("__init__", make_constructor(EulerArray_eulerConstructor7a<T>))
;
add_comparison_functions(eulerArray_class);
PyImath::add_explicit_construction_from_type<IMATH_NAMESPACE::Matrix33<T> >(eulerArray_class);
PyImath::add_explicit_construction_from_type<IMATH_NAMESPACE::Matrix44<T> >(eulerArray_class);
return eulerArray_class;
}
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Euler<float>,bases<IMATH_NAMESPACE::Vec3<float> > > register_Euler<float>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Euler<double>,bases<IMATH_NAMESPACE::Vec3<double> > > register_Euler<double>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Euler<float> > > register_EulerArray<float>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Euler<double> > > register_EulerArray<double>();
}
namespace PyImath {
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Euler<float> FixedArrayDefaultValue<IMATH_NAMESPACE::Euler<float> >::value() { return IMATH_NAMESPACE::Euler<float>(); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Euler<double> FixedArrayDefaultValue<IMATH_NAMESPACE::Euler<double> >::value() { return IMATH_NAMESPACE::Euler<double>(); }
}

View File

@ -0,0 +1,112 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathEuler_h_
#define _PyImathEuler_h_
#include <Python.h>
#include <boost/python.hpp>
#include <PyImath.h>
#include <ImathEuler.h>
#include <ImathVec.h>
#include <PyImath.h>
namespace PyImath {
template <class T> boost::python::class_<IMATH_NAMESPACE::Euler<T>,boost::python::bases<IMATH_NAMESPACE::Vec3<T> > > register_Euler();
template <class T> boost::python::class_<PyImath::FixedArray<IMATH_NAMESPACE::Euler<T> > > register_EulerArray();
typedef FixedArray<IMATH_NAMESPACE::Eulerf> EulerfArray;
typedef FixedArray<IMATH_NAMESPACE::Eulerd> EulerdArray;
//
// Other code in the Zeno code base assumes the existance of a class with the
// same name as the Imath class, and with static functions wrap() and
// convert() to produce a PyImath object from an Imath object and vice-versa,
// respectively. The class Boost generates from the Imath class does not
// have these properties, so we define a companion class here.
// The template argument, T, is the element type for the axis vector
// (e.g.,float, double).
template <class T>
class E {
public:
static PyObject * wrap (const IMATH_NAMESPACE::Euler<T> &e);
static int convert (PyObject *p, IMATH_NAMESPACE::Euler<T> *v);
};
template <class T>
PyObject *
E<T>::wrap (const IMATH_NAMESPACE::Euler<T> &e)
{
typename boost::python::return_by_value::apply < IMATH_NAMESPACE::Euler<T> >::type converter;
PyObject *p = converter (e);
return p;
}
template <class T>
int
E<T>::convert (PyObject *p, IMATH_NAMESPACE::Euler<T> *v)
{
boost::python::extract <IMATH_NAMESPACE::Eulerf> extractorEf (p);
if (extractorEf.check())
{
IMATH_NAMESPACE::Eulerf e = extractorEf();
v->x = T(e.x);
v->y = T(e.y);
v->z = T(e.z);
v->setOrder (typename IMATH_NAMESPACE::Euler<T>::Order (e.order()));
return 1;
}
boost::python::extract <IMATH_NAMESPACE::Eulerd> extractorEd (p);
if (extractorEd.check())
{
IMATH_NAMESPACE::Eulerd e = extractorEd();
v->x = T(e.x);
v->y = T(e.y);
v->z = T(e.z);
v->setOrder (typename IMATH_NAMESPACE::Euler<T>::Order (e.order()));
return 1;
}
return 0;
}
typedef E<float> Eulerf;
typedef E<double> Eulerd;
}
#endif

View File

@ -0,0 +1,63 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef PYIMATH_EXPORT_H
#define PYIMATH_EXPORT_H
#if defined(PLATFORM_WINDOWS)
# if defined(PLATFORM_BUILD_STATIC)
# define PYIMATH_EXPORT_DEFINITION
# define PYIMATH_IMPORT_DEFINITION
# else
# define PYIMATH_EXPORT_DEFINITION __declspec(dllexport)
# define PYIMATH_IMPORT_DEFINITION __declspec(dllimport)
# endif
#else // linux/macos
# if defined(PLATFORM_VISIBILITY_AVAILABLE)
# define PYIMATH_EXPORT_DEFINITION __attribute__((visibility("default")))
# define PYIMATH_IMPORT_DEFINITION
# else
# define PYIMATH_EXPORT_DEFINITION
# define PYIMATH_IMPORT_DEFINITION
# endif
#endif
#if defined(PYIMATH_EXPORTS) // create library
# define PYIMATH_EXPORT PYIMATH_EXPORT_DEFINITION
#else // use library
# define PYIMATH_EXPORT PYIMATH_IMPORT_DEFINITION
#endif
#endif // #ifndef PYIMATHEXPORT_H

View File

@ -0,0 +1,52 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-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 "PyImathFixedArray.h"
#include <PyImathExport.h>
namespace PyImath {
template <> PYIMATH_EXPORT bool FixedArrayDefaultValue<bool>::value() { return false; }
template <> PYIMATH_EXPORT signed char FixedArrayDefaultValue<signed char>::value() { return 0; }
template <> PYIMATH_EXPORT unsigned char FixedArrayDefaultValue<unsigned char>::value() { return 0; }
template <> PYIMATH_EXPORT short FixedArrayDefaultValue<short>::value() { return 0; }
template <> PYIMATH_EXPORT unsigned short FixedArrayDefaultValue<unsigned short>::value() { return 0; }
template <> PYIMATH_EXPORT int FixedArrayDefaultValue<int>::value() { return 0; }
template <> PYIMATH_EXPORT unsigned int FixedArrayDefaultValue<unsigned int>::value() { return 0; }
template <> PYIMATH_EXPORT float FixedArrayDefaultValue<float>::value() { return 0; }
template <> PYIMATH_EXPORT double FixedArrayDefaultValue<double>::value() { return 0; }
//int alloc_count = 0;
}

View File

@ -0,0 +1,548 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathFixedArray_h_
#define _PyImathFixedArray_h_
#include <boost/python.hpp>
#include <boost/operators.hpp>
#include <boost/shared_array.hpp>
#include <boost/any.hpp>
#include <Iex.h>
#include <iostream>
#include <IexMathFloatExc.h>
#include <PyImathUtil.h>
#define PY_IMATH_LEAVE_PYTHON IEX_NAMESPACE::MathExcOn mathexcon (IEX_NAMESPACE::IEEE_OVERFLOW | \
IEX_NAMESPACE::IEEE_DIVZERO | \
IEX_NAMESPACE::IEEE_INVALID); \
PyImath::PyReleaseLock pyunlock;
namespace PyImath {
//
// Utility class for a runtime-specified fixed length array type in python
//
template <class T>
struct FixedArrayDefaultValue
{
static T value();
};
enum Uninitialized {UNINITIALIZED};
template <class T>
class FixedArray
{
T * _ptr;
size_t _length;
size_t _stride;
// this handle optionally stores a shared_array to allocated array data
// so that everything is freed properly on exit.
boost::any _handle;
boost::shared_array<size_t> _indices; // non-NULL iff I'm a masked reference
size_t _unmaskedLength;
public:
typedef T BaseType;
FixedArray(T *ptr, Py_ssize_t length, Py_ssize_t stride = 1)
: _ptr(ptr), _length(length), _stride(stride), _handle(), _unmaskedLength(0)
{
if (length < 0)
{
throw IEX_NAMESPACE::LogicExc("Fixed array length must be non-negative");
}
if (stride <= 0)
{
throw IEX_NAMESPACE::LogicExc("Fixed array stride must be positive");
}
// nothing
}
FixedArray(T *ptr, Py_ssize_t length, Py_ssize_t stride, boost::any handle)
: _ptr(ptr), _length(length), _stride(stride), _handle(handle), _unmaskedLength(0)
{
if (_length < 0)
{
throw IEX_NAMESPACE::LogicExc("Fixed array length must be non-negative");
}
if (stride <= 0)
{
throw IEX_NAMESPACE::LogicExc("Fixed array stride must be positive");
}
// nothing
}
explicit FixedArray(Py_ssize_t length)
: _ptr(0), _length(length), _stride(1), _handle(), _unmaskedLength(0)
{
if (_length < 0) {
throw IEX_NAMESPACE::LogicExc("Fixed array length must be non-negative");
}
boost::shared_array<T> a(new T[length]);
T tmp = FixedArrayDefaultValue<T>::value();
for (size_t i=0; i<length; ++i) a[i] = tmp;
_handle = a;
_ptr = a.get();
}
FixedArray(Py_ssize_t length,Uninitialized)
: _ptr(0), _length(length), _stride(1), _handle(), _unmaskedLength(0)
{
if (_length < 0) {
throw IEX_NAMESPACE::LogicExc("Fixed array length must be non-negative");
}
boost::shared_array<T> a(new T[length]);
_handle = a;
_ptr = a.get();
}
FixedArray(const T &initialValue, Py_ssize_t length)
: _ptr(0), _length(length), _stride(1), _handle(), _unmaskedLength(0)
{
if (_length < 0) {
throw IEX_NAMESPACE::LogicExc("Fixed array length must be non-negative");
}
boost::shared_array<T> a(new T[length]);
for (size_t i=0; i<length; ++i) a[i] = initialValue;
_handle = a;
_ptr = a.get();
}
FixedArray(FixedArray& f, const FixedArray<int>& mask)
: _ptr(f._ptr), _stride(f._stride), _handle(f._handle)
{
if (f.isMaskedReference())
{
throw IEX_NAMESPACE::NoImplExc("Masking an already-masked FixedArray not supported yet (SQ27000)");
}
size_t len = f.match_dimension(mask);
_unmaskedLength = len;
size_t reduced_len = 0;
for (size_t i = 0; i < len; ++i)
if (mask[i])
reduced_len++;
_indices.reset(new size_t[reduced_len]);
for (size_t i = 0, j = 0; i < len; ++i)
{
if (mask[i])
{
_indices[j] = i;
j++;
}
}
_length = reduced_len;
}
template <class S>
explicit FixedArray(const FixedArray<S> &other)
: _ptr(0), _length(other.len()), _stride(1), _handle(), _unmaskedLength(other.unmaskedLength())
{
boost::shared_array<T> a(new T[_length]);
for (size_t i=0; i<_length; ++i) a[i] = T(other[i]);
_handle = a;
_ptr = a.get();
if (_unmaskedLength)
{
_indices.reset(new size_t[_length]);
for (size_t i = 0; i < _length; ++i)
_indices[i] = other.raw_ptr_index(i);
}
}
FixedArray(const FixedArray &other)
: _ptr(other._ptr), _length(other._length), _stride(other._stride),
_handle(other._handle),
_indices(other._indices),
_unmaskedLength(other._unmaskedLength)
{
}
const FixedArray &
operator = (const FixedArray &other)
{
if (&other == this) return *this;
_ptr = other._ptr;
_length = other._length;
_stride = other._stride;
_handle = other._handle;
_unmaskedLength = other._unmaskedLength;
_indices = other._indices;
return *this;
}
~FixedArray()
{
// nothing
}
const boost::any & handle() { return _handle; }
//
// Make an index suitable for indexing into an array in c++ from
// a python index, which can be negative for indexing relative to
// the end of an array
//
size_t canonical_index(Py_ssize_t index) const
{
if (index < 0) index += _length;
if (index >= _length || index < 0) {
PyErr_SetString(PyExc_IndexError, "Index out of range");
boost::python::throw_error_already_set();
}
return index; // still a virtual index if this is a masked reference array
}
void extract_slice_indices(PyObject *index, size_t &start, size_t &end, Py_ssize_t &step, size_t &slicelength) const
{
if (PySlice_Check(index)) {
PySliceObject *slice = reinterpret_cast<PySliceObject *>(index);
Py_ssize_t s,e,sl;
if (PySlice_GetIndicesEx(slice,_length,&s,&e,&step,&sl) == -1) {
boost::python::throw_error_already_set();
}
// e can be -1 if the iteration is backwards with a negative slice operator [::-n] (n > 0).
if (s < 0 || e < -1 || sl < 0) {
throw IEX_NAMESPACE::LogicExc("Slice extraction produced invalid start, end, or length indices");
}
start = s;
end = e;
slicelength = sl;
} else if (PyInt_Check(index)) {
size_t i = canonical_index(PyInt_AsSsize_t(index));
start = i; end = i+1; step = 1; slicelength = 1;
} else {
PyErr_SetString(PyExc_TypeError, "Object is not a slice");
boost::python::throw_error_already_set();
}
}
// return_internal_reference doesn't seem to work with non-class types
typedef typename boost::mpl::if_<boost::is_class<T>,T&,T>::type get_type;
get_type getitem(Py_ssize_t index) { return (*this)[canonical_index(index)]; }
typedef typename boost::mpl::if_<boost::is_class<T>,const T&,T>::type get_type_const;
get_type_const getitem(Py_ssize_t index) const { return (*this)[canonical_index(index)]; }
FixedArray getslice(PyObject *index) const
{
size_t start=0, end=0, slicelength=0;
Py_ssize_t step;
extract_slice_indices(index,start,end,step,slicelength);
FixedArray f(slicelength);
if (_indices)
{
for (size_t i=0; i<slicelength; ++i)
f._ptr[i] = _ptr[raw_ptr_index(start+i*step)*_stride];
}
else
{
for (size_t i=0; i<slicelength; ++i)
f._ptr[i] = _ptr[(start+i*step)*_stride];
}
return f;
}
FixedArray getslice_mask(const FixedArray<int>& mask)
{
FixedArray f(*this, mask);
return f;
}
void
setitem_scalar(PyObject *index, const T &data)
{
size_t start=0, end=0, slicelength=0;
Py_ssize_t step;
extract_slice_indices(index,start,end,step,slicelength);
if (_indices)
{
for (size_t i=0; i<slicelength; ++i)
_ptr[raw_ptr_index(start+i*step)*_stride] = data;
}
else
{
for (size_t i=0; i<slicelength; ++i)
_ptr[(start+i*step)*_stride] = data;
}
}
void
setitem_scalar_mask(const FixedArray<int> &mask, const T &data)
{
size_t len = match_dimension(mask, false);
if (_indices)
{
for (size_t i = 0; i < len; ++i)
_ptr[raw_ptr_index(i)*_stride] = data;
}
else
{
for (size_t i=0; i<len; ++i)
if (mask[i]) _ptr[i*_stride] = data;
}
}
void
setitem_vector(PyObject *index, const FixedArray &data)
{
size_t start=0, end=0, slicelength=0;
Py_ssize_t step;
extract_slice_indices(index,start,end,step,slicelength);
// we have a valid range of indices
if (data.len() != slicelength) {
PyErr_SetString(PyExc_IndexError, "Dimensions of source do not match destination");
boost::python::throw_error_already_set();
}
if (_indices)
{
for (size_t i=0; i<slicelength; ++i)
_ptr[raw_ptr_index(start+i*step)*_stride] = data[i];
}
else
{
for (size_t i=0; i<slicelength; ++i)
_ptr[(start+i*step)*_stride] = data[i];
}
}
void
setitem_vector_mask(const FixedArray<int> &mask, const FixedArray &data)
{
// We could relax this but this restriction if there's a good
// enough reason too.
if (_indices)
{
throw IEX_NAMESPACE::ArgExc("We don't support setting item masks for masked reference arrays.");
}
size_t len = match_dimension(mask);
if (data.len() == len)
{
for (size_t i = 0; i < len; ++i)
if (mask[i]) _ptr[i*_stride] = data[i];
}
else
{
size_t count = 0;
for (size_t i = 0; i < len; ++i)
if (mask[i]) count++;
if (data.len() != count) {
throw IEX_NAMESPACE::ArgExc("Dimensions of source data do not match destination either masked or unmasked");
}
Py_ssize_t dataIndex = 0;
for (size_t i = 0; i < len; ++i)
{
if (mask[i])
{
_ptr[i*_stride] = data[dataIndex];
dataIndex++;
}
}
}
}
// exposed as Py_ssize_t for compatilbity with standard python sequences
Py_ssize_t len() const { return _length; }
size_t stride() const { return _stride; }
// no bounds checking on i!
T& operator [] (size_t i)
{
return _ptr[(_indices ? raw_ptr_index(i) : i) * _stride];
}
// no bounds checking on i!
const T& operator [] (size_t i) const
{
return _ptr[(_indices ? raw_ptr_index(i) : i) * _stride];
}
// no mask conversion or bounds checking on i!
T& direct_index(size_t i)
{
return _ptr[i*_stride];
}
// no mask conversion or bounds checking on i!
const T& direct_index (size_t i) const
{
return _ptr[i*_stride];
}
bool isMaskedReference() const {return _indices.get() != 0;}
size_t unmaskedLength() const {return _unmaskedLength;}
// Conversion of indices to raw pointer indices.
// This should only be called when this is a masked reference.
// No safety checks done for performance.
size_t raw_ptr_index(size_t i) const
{
assert(isMaskedReference());
assert(i < _length);
assert(_indices[i] >= 0 && _indices[i] < _unmaskedLength);
return _indices[i];
}
static boost::python::class_<FixedArray<T> > register_(const char *doc)
{
// a little tricky, but here we go - class types return internal references
// but fundemental types just get copied. this typedef sets up the appropriate
// call policy for each type.
typedef typename boost::mpl::if_<
boost::is_class<T>,
boost::python::return_internal_reference<>,
boost::python::default_call_policies>::type call_policy;
typedef typename boost::mpl::if_<
boost::is_class<T>,
boost::python::return_value_policy<boost::python::copy_const_reference>,
boost::python::default_call_policies>::type const_call_policy;
//typename FixedArray<T>::get_type (FixedArray<T>::*nonconst_getitem)(Py_ssize_t)= &FixedArray<T>::getitem;
//typename FixedArray<T>::get_type_const (FixedArray<T>::*const_getitem)(Py_ssize_t) = &FixedArray<T>::getitem;
typename FixedArray<T>::get_type (FixedArray<T>::*nonconst_getitem)(Py_ssize_t)= &FixedArray<T>::getitem;
typename FixedArray<T>::get_type_const (FixedArray<T>::*const_getitem)(Py_ssize_t) const = &FixedArray<T>::getitem;
boost::python::class_<FixedArray<T> > c(name(),doc, boost::python::init<size_t>("construct an array of the specified length initialized to the default value for the type"));
c
.def(boost::python::init<const FixedArray<T> &>("construct an array with the same values as the given array"))
.def(boost::python::init<const T &,size_t>("construct an array of the specified length initialized to the specified default value"))
.def("__getitem__", &FixedArray<T>::getslice)
.def("__getitem__", &FixedArray<T>::getslice_mask)
.def("__getitem__", const_getitem, const_call_policy())
.def("__getitem__", nonconst_getitem, call_policy())
.def("__setitem__", &FixedArray<T>::setitem_scalar)
.def("__setitem__", &FixedArray<T>::setitem_scalar_mask)
.def("__setitem__", &FixedArray<T>::setitem_vector)
.def("__setitem__", &FixedArray<T>::setitem_vector_mask)
.def("__len__",&FixedArray<T>::len)
.def("ifelse",&FixedArray<T>::ifelse_scalar)
.def("ifelse",&FixedArray<T>::ifelse_vector)
;
return c;
}
template <class T2>
size_t match_dimension(const FixedArray<T2> &a1, bool strictComparison = true) const
{
if (len() == a1.len())
return len();
bool throwExc = false;
if (strictComparison)
throwExc = true;
else if (_indices)
{
if (_unmaskedLength != a1.len())
throwExc = true;
}
else
throwExc = true;
if (throwExc)
{
throw IEX_NAMESPACE::ArgExc("Dimensions of source do not match destination");
}
return len();
}
FixedArray<T> ifelse_vector(const FixedArray<int> &choice, const FixedArray<T> &other) {
size_t len = match_dimension(choice);
match_dimension(other);
FixedArray<T> tmp(len); // should use default construction but V3f doens't initialize
for (size_t i=0; i < len; ++i) tmp[i] = choice[i] ? (*this)[i] : other[i];
return tmp;
}
FixedArray<T> ifelse_scalar(const FixedArray<int> &choice, const T &other) {
size_t len = match_dimension(choice);
FixedArray<T> tmp(len); // should use default construction but V3f doens't initialize
for (size_t i=0; i < len; ++i) tmp[i] = choice[i] ? (*this)[i] : other;
return tmp;
}
// Instantiations of fixed ararys must implement this static member
static const char *name();
};
//
// Helper struct for arary indexing with a known compile time length
//
template <class Container, class Data>
struct IndexAccessDefault {
typedef Data & result_type;
static Data & apply(Container &c, size_t i) { return c[i]; }
};
template <class Container, class Data, int Length, class IndexAccess = IndexAccessDefault<Container,Data> >
struct StaticFixedArray
{
static Py_ssize_t len(const Container &) { return Length; }
static typename IndexAccess::result_type getitem(Container &c, Py_ssize_t index) { return IndexAccess::apply(c,canonical_index(index)); }
static void setitem(Container &c, Py_ssize_t index, const Data &data) { IndexAccess::apply(c,canonical_index(index)) = data; }
static size_t canonical_index(Py_ssize_t index)
{
if (index < 0) index += Length;
if (index < 0 || index >= Length) {
PyErr_SetString(PyExc_IndexError, "Index out of range");
boost::python::throw_error_already_set();
}
return index;
}
};
}
#endif // _PyImathFixedArray_h_

View File

@ -0,0 +1,802 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathFixedArray2D_h_
#define _PyImathFixedArray2D_h_
#include <boost/python.hpp>
#include <boost/operators.hpp>
#include <boost/shared_array.hpp>
#include <boost/any.hpp>
#include <Iex.h>
#include <iostream>
#include "PyImathFixedArray.h"
#include "PyImathOperators.h"
#include <ImathVec.h>
namespace PyImath {
template <class T>
class FixedArray2D
{
T * _ptr;
IMATH_NAMESPACE::Vec2<size_t> _length;
IMATH_NAMESPACE::Vec2<size_t> _stride;
size_t _size; //flattened size of the array
// this handle optionally stores a shared_array to allocated array data
// so that everything is freed properly on exit.
boost::any _handle;
public:
FixedArray2D(T *ptr, Py_ssize_t lengthX, Py_ssize_t lengthY, Py_ssize_t strideX = 1)
: _ptr(ptr), _length(lengthX, lengthY), _stride(strideX, lengthX), _handle()
{
if (lengthX < 0 || lengthY < 0)
throw IEX_NAMESPACE::LogicExc("Fixed array 2d lengths must be non-negative");
if (strideX <= 0)
throw IEX_NAMESPACE::LogicExc("Fixed array 2d strides must be positive");
initializeSize();
//std::cout << "fixed array external construct" << std::endl;
// nothing
}
FixedArray2D(T *ptr, Py_ssize_t lengthX, Py_ssize_t lengthY, Py_ssize_t strideX, Py_ssize_t strideY)
: _ptr(ptr), _length(lengthX, lengthY), _stride(strideX, strideY), _handle()
{
if (lengthX < 0 || lengthY < 0)
throw IEX_NAMESPACE::LogicExc("Fixed array 2d lengths must be non-negative");
if (strideX <= 0 || strideY < 0)
throw IEX_NAMESPACE::LogicExc("Fixed array 2d strides must be positive");
initializeSize();
//std::cout << "fixed array external construct" << std::endl;
// nothing
}
FixedArray2D(T *ptr, Py_ssize_t lengthX, Py_ssize_t lengthY, Py_ssize_t strideX, Py_ssize_t strideY, boost::any handle)
: _ptr(ptr), _length(lengthX, lengthY), _stride(strideX, strideY), _handle(handle)
{
initializeSize();
//std::cout << "fixed array external construct with handle" << std::endl;
// nothing
}
explicit FixedArray2D(Py_ssize_t lengthX, Py_ssize_t lengthY)
: _ptr(0), _length(lengthX, lengthY), _stride(1, lengthX), _handle()
{
if (lengthX < 0 || lengthY < 0)
throw IEX_NAMESPACE::LogicExc("Fixed array 2d lengths must be non-negative");
initializeSize();
T tmp = FixedArrayDefaultValue<T>::value();
boost::shared_array<T> a(new T[_size]);
for (size_t i=0; i<_size; ++i) a[i] = tmp;
_handle = a;
_ptr = a.get();
}
explicit FixedArray2D(const IMATH_NAMESPACE::V2i& length)
: _ptr(0), _length(length), _stride(1, length.x), _handle()
{
if (length.x < 0 || length.y < 0)
throw IEX_NAMESPACE::LogicExc("Fixed array 2d lengths must be non-negative");
initializeSize();
T tmp = FixedArrayDefaultValue<T>::value();
boost::shared_array<T> a(new T[_size]);
for (size_t i=0; i<_size; ++i) a[i] = tmp;
_handle = a;
_ptr = a.get();
}
FixedArray2D(const T &initialValue, Py_ssize_t lengthX, Py_ssize_t lengthY)
: _ptr(0), _length(lengthX, lengthY), _stride(1, lengthX), _handle()
{
if (lengthX < 0 || lengthY < 0)
throw IEX_NAMESPACE::LogicExc("Fixed array 2d lengths must be non-negative");
initializeSize();
boost::shared_array<T> a(new T[_size]);
for (size_t i=0; i<_size; ++i) a[i] = initialValue;
_handle = a;
_ptr = a.get();
}
void initializeSize()
{
_size = _length.x*_length.y;
}
template <class S>
explicit FixedArray2D(const FixedArray2D<S> &other)
: _ptr(0), _length(other.len()), _stride(1, other.len().x), _handle()
{
initializeSize();
boost::shared_array<T> a(new T[_size]);
size_t z = 0;
for (size_t j = 0; j < _length.y; ++j)
for (size_t i = 0; i < _length.x; ++i)
a[z++] = T(other(i,j));
_handle = a;
_ptr = a.get();
}
FixedArray2D(const FixedArray2D &other)
: _ptr(other._ptr), _length(other._length), _stride(other._stride), _size(other._size), _handle(other._handle)
{
//std::cout << "fixed array copy consturct construct" << std::endl;
// nothing
}
const FixedArray2D &
operator = (const FixedArray2D &other)
{
if (&other == this) return *this;
//std::cout << "fixed array assign" << std::endl;
_ptr = other._ptr;
_length = other._length;
_stride = other._stride;
_handle = other._handle;
_size = _length.x*_length.y;
return *this;
}
~FixedArray2D()
{
//std::cout << "fixed array delete" << std::endl;
}
const boost::any & handle() { return _handle; }
size_t canonical_index(Py_ssize_t index, size_t length) const
{
if (index < 0) index += length;
if (index >= length || index < 0) {
PyErr_SetString(PyExc_IndexError, "Index out of range");
boost::python::throw_error_already_set();
}
return index;
}
void extract_slice_indices(PyObject *index, size_t length, size_t &start, size_t &end, Py_ssize_t &step, size_t &slicelength) const
{
if (PySlice_Check(index)) {
PySliceObject *slice = reinterpret_cast<PySliceObject *>(index);
Py_ssize_t s, e, sl;
if (PySlice_GetIndicesEx(slice,length,&s,&e,&step,&sl) == -1) {
boost::python::throw_error_already_set();
}
if (s < 0 || e < 0 || sl < 0) {
throw IEX_NAMESPACE::LogicExc("Slice extraction produced invalid start, end, or length indices");
}
start = s;
end = e;
slicelength = sl;
} else if (PyInt_Check(index)) {
size_t i = canonical_index(PyInt_AsSsize_t(index), length);
start = i; end = i+1; step = 1; slicelength = 1;
} else {
PyErr_SetString(PyExc_TypeError, "Object is not a slice");
boost::python::throw_error_already_set();
}
//std::cout << "Slice indices are " << start << " " << end << " " << step << " " << slicelength << std::endl;
}
// return_internal_reference doesn't seem to work with non-class types
typedef typename boost::mpl::if_<boost::is_class<T>,T&,T>::type get_type;
// get_type getitem(Py_ssize_t index) const { return _ptr[canonical_index(index)*_stride]; }
//FIXME: const does not work here with at least IMATH_NAMESPACE::Color4, why it works for V3fArray?
get_type getitem(Py_ssize_t i, Py_ssize_t j) //const
{
return (*this)(canonical_index(i, _length.x), canonical_index(j, _length.y));
}
//FIXME: anyway to seperate 2:3,4:5 from 2,4? we'd like to return int for the second one, and also 1d array for 2, 4:5 or 2:3, 4
FixedArray2D getslice(PyObject *index) const
{
if (PyTuple_Check(index) && PyTuple_Size(index) == 2)
{
size_t startx=0, endx=0, slicelengthx=0;
size_t starty=0, endy=0, slicelengthy=0;
Py_ssize_t stepx=0;
Py_ssize_t stepy=0;
extract_slice_indices(PyTuple_GetItem(index, 0),_length.x,startx,endx,stepx,slicelengthx);
extract_slice_indices(PyTuple_GetItem(index, 1),_length.y,starty,endy,stepy,slicelengthy);
FixedArray2D f(slicelengthx, slicelengthy);
for (size_t j=0,z=0; j<slicelengthy; j++)
for (size_t i=0; i<slicelengthx; ++i)
f._ptr[z++] = (*this)(startx+i*stepx, starty+j*stepy);
return f;
}
else
{
PyErr_SetString(PyExc_TypeError, "Slice syntax error");
boost::python::throw_error_already_set();
}
return FixedArray2D(0,0);
}
//FIXME: for 2D array, cannot reduce the size, or maybe returning 1D array?
FixedArray2D getslice_mask(const FixedArray2D<int> &mask) const
{
// size_t len = match_dimension(mask);
// size_t slicelength = 0;
// for (size_t i=0; i<len; ++i) if (mask[i]) slicelength++;
// FixedArray2D f(slicelength, _length.y);
// for (size_t i=0,z=0; i<len; ++i) {
// if (mask[i]) {
// for (size_t j = 0; j < _length.y; j++)
// f._ptr[z++] = (*this)(i,j);
// }
// }
// return f;
IMATH_NAMESPACE::Vec2<size_t> len = match_dimension(mask);
FixedArray2D f(len);
for (size_t j=0; j<len.y; j++)
for (size_t i=0; i<len.x; i++)
if (mask(i,j))
f(i,j) = (*this)(i,j);
return f;
}
// void setitem(const boost::python::tuple& index, const T &data)
// {
// Py_ssize_t i = boost::python::extract<Py_ssize_t>(index[0]);
// Py_ssize_t j = boost::python::extract<Py_ssize_t>(index[1]);
// (*this)(i,j) = data;
// }
void
setitem_scalar(PyObject *index, const T &data)
{
if (!PyTuple_Check(index) || PyTuple_Size(index) != 2)
{
PyErr_SetString(PyExc_TypeError, "Slice syntax error");
boost::python::throw_error_already_set();
}
size_t startx=0, endx=0, slicelengthx=0;
size_t starty=0, endy=0, slicelengthy=0;
Py_ssize_t stepx=0;
Py_ssize_t stepy=0;
extract_slice_indices(PyTuple_GetItem(index, 0),_length.x,startx,endx,stepx,slicelengthx);
extract_slice_indices(PyTuple_GetItem(index, 1),_length.y,starty,endy,stepy,slicelengthy);
for (size_t j=0; j<slicelengthy; j++)
for (size_t i=0; i<slicelengthx; ++i)
(*this)(startx+i*stepx, starty+j*stepy) = data;
}
void
setitem_scalar_mask(const FixedArray2D<int> &mask, const T &data)
{
IMATH_NAMESPACE::Vec2<size_t> len = match_dimension(mask);
for (size_t j = 0; j < len.y; j++)
for (size_t i=0; i<len.x; ++i)
if (mask(i,j))
(*this)(i,j) = data;
}
void
setitem_vector(PyObject *index, const FixedArray2D &data)
{
//TODO:sanity check
size_t startx=0, endx=0, slicelengthx=0;
size_t starty=0, endy=0, slicelengthy=0;
Py_ssize_t stepx=0;
Py_ssize_t stepy=0;
extract_slice_indices(PyTuple_GetItem(index, 0),_length.x,startx,endx,stepx,slicelengthx);
extract_slice_indices(PyTuple_GetItem(index, 1),_length.y,starty,endy,stepy,slicelengthy);
// we have a valid range of indices
if (data.len() != IMATH_NAMESPACE::Vec2<size_t>(slicelengthx, slicelengthy)) {
PyErr_SetString(PyExc_IndexError, "Dimensions of source do not match destination");
boost::python::throw_error_already_set();
}
for (size_t i=0; i<slicelengthx; ++i)
for (size_t j=0; j<slicelengthy; ++j)
(*this)(startx+i*stepx, starty+j*stepy) = data(i,j);
}
void
setitem_vector_mask(const FixedArray2D<int> &mask, const FixedArray2D &data)
{
IMATH_NAMESPACE::Vec2<size_t> len = match_dimension(mask);
if (data.len() == len) {
for (size_t j = 0; j < len.y; j++)
for (size_t i=0; i<len.x; ++i)
if (mask(i,j))
(*this)(i,j) = data(i,j);
} else {
PyErr_SetString(PyExc_IndexError, "Dimensions of source data do not match destination");
boost::python::throw_error_already_set();
}
}
void
setitem_array1d_mask(const FixedArray2D<int> &mask, const FixedArray<T> &data)
{
IMATH_NAMESPACE::Vec2<size_t> len = match_dimension(mask);
if (data.len() == len.x*len.y) {
for (size_t j = 0, z = 0; j < len.y; j++)
for (size_t i=0; i<len.x; ++i, ++z)
if (mask(i,j))
(*this)(i,j) = data[z];
} else {
size_t count = 0;
for (size_t j = 0, z = 0; j < len.y; j++)
for (size_t i=0; i<len.x; ++i, ++z)
if (mask(i,j)) count++;
if (data.len() != count) {
PyErr_SetString(PyExc_IndexError, "Dimensions of source data do not match destination either masked or unmasked");
boost::python::throw_error_already_set();
}
for (size_t j = 0, z = 0; j < len.y; j++)
for (size_t i=0; i<len.x; ++i)
if (mask(i,j))
(*this)(i,j) = data[z++];
}
}
void
setitem_array1d(PyObject *index, const FixedArray<T> &data)
{
//TODO:sanity check
size_t startx=0, endx=0, slicelengthx=0;
size_t starty=0, endy=0, slicelengthy=0;
Py_ssize_t stepx=0;
Py_ssize_t stepy=0;
extract_slice_indices(PyTuple_GetItem(index, 0),_length.x,startx,endx,stepx,slicelengthx);
extract_slice_indices(PyTuple_GetItem(index, 1),_length.y,starty,endy,stepy,slicelengthy);
// we have a valid range of indices
if (data.len() != slicelengthx*slicelengthy) {
PyErr_SetString(PyExc_IndexError, "Dimensions of source data do not match destination");
boost::python::throw_error_already_set();
}
for (size_t j=0, z=0; j<slicelengthy; ++j)
for (size_t i=0; i<slicelengthx; ++i, ++z)
(*this)(startx+i*stepx, starty+j*stepy) = data[z];
}
IMATH_NAMESPACE::Vec2<size_t> len() const { return _length; }
IMATH_NAMESPACE::Vec2<size_t> stride() const { return _stride; }
T & operator () (size_t i, size_t j) { return _ptr[_stride.x*(j*_stride.y + i)]; }
const T & operator () (size_t i, size_t j) const { return _ptr[_stride.x*(j*_stride.y + i)]; }
size_t totalLen() const { return _size; }
boost::python::tuple size() const
{
return boost::python::make_tuple(_length.x, _length.y);
}
static boost::python::class_<FixedArray2D<T> > register_(const char *name, const char *doc)
{
// a little tricky, but here we go - class types return internal references
// but fundemental types just get copied. this typedef sets up the appropriate
// call policy for each type.
typedef typename boost::mpl::if_<
boost::is_class<T>,
boost::python::return_internal_reference<>,
boost::python::default_call_policies>::type call_policy;
boost::python::class_<FixedArray2D<T> > c(name,doc, boost::python::init<size_t, size_t>(
"construct an array of the specified length initialized to the default value for the type"));
c
.def(boost::python::init<const FixedArray2D<T> &>("construct an array with the same values as the given array"))
.def(boost::python::init<const T &,size_t,size_t>("construct an array of the specified length initialized to the specified default value"))
.def("__getitem__", &FixedArray2D<T>::getslice)
.def("__getitem__", &FixedArray2D<T>::getslice_mask)
// .def("__getitem__", &FixedArray2D<T>::getitem, call_policy())
.def("item", &FixedArray2D<T>::getitem, call_policy())
// .def("__setitem__", &FixedArray2D<T>::setitem)
.def("__setitem__", &FixedArray2D<T>::setitem_scalar)
.def("__setitem__", &FixedArray2D<T>::setitem_scalar_mask)
.def("__setitem__", &FixedArray2D<T>::setitem_vector)
.def("__setitem__", &FixedArray2D<T>::setitem_vector_mask)
.def("__setitem__", &FixedArray2D<T>::setitem_array1d)
.def("__setitem__", &FixedArray2D<T>::setitem_array1d_mask)
.def("__len__",&FixedArray2D<T>::totalLen)
.def("size",&FixedArray2D<T>::size)
.def("ifelse",&FixedArray2D<T>::ifelse_scalar)
.def("ifelse",&FixedArray2D<T>::ifelse_vector)
;
return c;
}
// template <class T2>
// size_t match_dimension(const FixedArray<T2> &a1) const
// {
// if (_length.x != a1.len()) {
// PyErr_SetString(PyExc_IndexError, "Dimensions of source do not match destination");
// boost::python::throw_error_already_set();
// }
// return _length.x;
// }
template <class T2>
IMATH_NAMESPACE::Vec2<size_t> match_dimension(const FixedArray2D<T2> &a1) const
{
if (len() != a1.len()) {
PyErr_SetString(PyExc_IndexError, "Dimensions of source do not match destination");
boost::python::throw_error_already_set();
}
return len();
}
FixedArray2D<T> ifelse_vector(const FixedArray2D<int> &choice, const FixedArray2D<T> &other) {
IMATH_NAMESPACE::Vec2<size_t> len = match_dimension(choice);
match_dimension(other);
FixedArray2D<T> tmp(len); // should use default construction but V3f doens't initialize
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
tmp(i,j) = choice(i,j) ? (*this)(i,j) : other(i,j);
return tmp;
}
FixedArray2D<T> ifelse_scalar(const FixedArray2D<int> &choice, const T &other) {
IMATH_NAMESPACE::Vec2<size_t> len = match_dimension(choice);
FixedArray2D<T> tmp(len); // should use default construction but V3f doens't initialize
for (size_t j = 0; j < len.y; ++j)
for (size_t i = 0; i < len.x; ++i)
tmp(i,j) = choice(i,j) ? (*this)(i,j) : other;
return tmp;
}
};
// unary operation application
template <template <class,class> class Op, class T1, class Ret>
FixedArray2D<Ret> apply_array2d_unary_op(const FixedArray2D<T1> &a1)
{
IMATH_NAMESPACE::Vec2<size_t> len = a1.len();
FixedArray2D<Ret> retval(len.x,len.y);
for (int j=0; j<len.y; ++j) {
for (int i=0;i<len.x;++i) {
retval(i,j) = Op<T1,Ret>::apply(a1(i,j));
}
}
return retval;
}
// binary operation application
template <template <class,class,class> class Op, class T1, class T2, class Ret>
FixedArray2D<Ret> apply_array2d_array2d_binary_op(const FixedArray2D<T1> &a1, const FixedArray2D<T2> &a2)
{
IMATH_NAMESPACE::Vec2<size_t> len = a1.match_dimension(a2);
FixedArray2D<Ret> retval(len.x,len.y);
for (int j=0; j<len.y; ++j) {
for (int i=0;i<len.x;++i) {
retval(i,j) = Op<T1,T2,Ret>::apply(a1(i,j),a2(i,j));
}
}
return retval;
}
template <template <class,class,class> class Op, class T1, class T2, class Ret>
FixedArray2D<Ret> apply_array2d_scalar_binary_op(const FixedArray2D<T1> &a1, const T2 &a2)
{
IMATH_NAMESPACE::Vec2<size_t> len = a1.len();
FixedArray2D<Ret> retval(len.x,len.y);
for (int j=0; j<len.y; ++j) {
for (int i=0;i<len.x;++i) {
retval(i,j) = Op<T1,T2,Ret>::apply(a1(i,j),a2);
}
}
return retval;
}
template <template <class,class,class> class Op, class T1, class T2, class Ret>
FixedArray2D<Ret> apply_array2d_scalar_binary_rop(const FixedArray2D<T1> &a1, const T2 &a2)
{
IMATH_NAMESPACE::Vec2<size_t> len = a1.len();
FixedArray2D<Ret> retval(len.x,len.y);
for (int j=0; j<len.y; ++j) {
for (int i=0;i<len.x;++i) {
retval(i,j) = Op<T2,T1,Ret>::apply(a2,a1(i,j));
}
}
return retval;
}
// in-place binary operation application
template <template <class,class> class Op, class T1, class T2>
FixedArray2D<T1> & apply_array2d_array2d_ibinary_op(FixedArray2D<T1> &a1, const FixedArray2D<T2> &a2)
{
IMATH_NAMESPACE::Vec2<size_t> len = a1.match_dimension(a2);
for (int j=0; j<len.y; ++j) {
for (int i=0;i<len.x;++i) {
Op<T1,T2>::apply(a1(i,j),a2(i,j));
}
}
return a1;
}
// in-place binary operation application
template <template <class,class> class Op, class T1, class T2>
FixedArray2D<T1> & apply_array2d_scalar_ibinary_op(FixedArray2D<T1> &a1, const T2 &a2)
{
IMATH_NAMESPACE::Vec2<size_t> len = a1.len();
for (int j=0; j<len.y; ++j) {
for (int i=0;i<len.x;++i) {
Op<T1,T2>::apply(a1(i,j),a2);
}
}
return a1;
}
// PyObject* PyNumber_Add( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> operator + (const FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_binary_op<op_add,T,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> operator + (const FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_binary_op<op_add,T,T,T>(a0,v1); }
template <class T> static FixedArray2D<T> operator + (const T &v1, const FixedArray2D<T> &a0) { return a0+v1; }
// PyObject* PyNumber_Subtract( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> operator - (const FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_binary_op<op_sub,T,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> operator - (const FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_binary_op<op_sub,T,T,T>(a0,v1); }
template <class T> static FixedArray2D<T> operator - (const T &v1, const FixedArray2D<T> &a0) { return apply_array2d_scalar_binary_op<op_rsub,T,T,T>(a0,v1); }
// PyObject* PyNumber_Multiply( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> operator * (const FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_binary_op<op_mul,T,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> operator * (const FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_binary_op<op_mul,T,T,T>(a0,v1); }
template <class T> static FixedArray2D<T> operator * (const T &v1, const FixedArray2D<T> &a0) { return a0*v1; }
// PyObject* PyNumber_Divide( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> operator / (const FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_binary_op<op_div,T,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> operator / (const FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_binary_op<op_div,T,T,T>(a0,v1); }
// no reversed scalar/array2d divide - no meaning
// PyObject* PyNumber_FloorDivide( PyObject *o1, PyObject *o2)
// PyObject* PyNumber_TrueDivide( PyObject *o1, PyObject *o2)
// PyObject* PyNumber_Remainder( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> operator % (const FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_binary_op<op_mod,T,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> operator % (const FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_binary_op<op_mod,T,T,T>(a0,v1); }
// no reversed scalar%array2d remainder - no meaning
// PyObject* PyNumber_Divmod( PyObject *o1, PyObject *o2)
// PyObject* PyNumber_Power( PyObject *o1, PyObject *o2, PyObject *o3)
template <class T> static FixedArray2D<T> pow_array2d_array2d (const FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_binary_op<op_pow,T,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> pow_array2d_scalar (const FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_binary_op<op_pow,T,T,T>(a0,v1); }
// no reversed scalar/array2d pow - no meaning
// PyObject* PyNumber_Negative( PyObject *o)
template <class T> static FixedArray2D<T> operator - (const FixedArray2D<T> &a0) { return apply_array2d_unary_op<op_neg,T,T>(a0); }
// PyObject* PyNumber_Positive( PyObject *o)
// PyObject* PyNumber_Absolute( PyObject *o)
template <class T> static FixedArray2D<T> abs (const FixedArray2D<T> &a0) { return apply_array2d_unary_op<op_abs,T,T>(a0); }
// PyObject* PyNumber_Invert( PyObject *o)
template <class T> static FixedArray2D<T> operator ~ (const FixedArray2D<T> &a0) { return apply_array2d_unary_op<op_inverse,T,T>(a0); }
// PyObject* PyNumber_Lshift( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> operator << (const FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_binary_op<op_lshift,T,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> operator << (const FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_binary_op<op_lshift,T,T,T>(a0,v1); }
// no reversed
// PyObject* PyNumber_Rshift( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> operator >> (const FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_binary_op<op_rshift,T,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> operator >> (const FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_binary_op<op_rshift,T,T,T>(a0,v1); }
// no reversed
// PyObject* PyNumber_And( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> operator & (const FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_binary_op<op_bitand,T,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> operator & (const FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_binary_op<op_bitand,T,T,T>(a0,v1); }
template <class T> static FixedArray2D<T> operator & (const T &v1, const FixedArray2D<T> &a0) { return a0&v1; }
// PyObject* PyNumber_Xor( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> operator ^ (const FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_binary_op<op_xor,T,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> operator ^ (const FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_binary_op<op_xor,T,T,T>(a0,v1); }
template <class T> static FixedArray2D<T> operator ^ (const T &v1, const FixedArray2D<T> &a0) { return a0^v1; }
// PyObject* PyNumber_Or( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> operator | (const FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_binary_op<op_bitor,T,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> operator | (const FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_binary_op<op_bitor,T,T,T>(a0,v1); }
template <class T> static FixedArray2D<T> operator | (const T &v1, const FixedArray2D<T> &a0) { return a0|v1; }
// PyObject* PyNumber_InPlaceAdd( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> & operator += (FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_ibinary_op<op_iadd,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> & operator += (FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_ibinary_op<op_iadd,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceSubtract( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> & operator -= (FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_ibinary_op<op_isub,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> & operator -= (FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_ibinary_op<op_isub,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceMultiply( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> & operator *= (FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_ibinary_op<op_imul,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> & operator *= (FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_ibinary_op<op_imul,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceDivide( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> & operator /= (FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_ibinary_op<op_idiv,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> & operator /= (FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_ibinary_op<op_idiv,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceFloorDivide( PyObject *o1, PyObject *o2)
// not implemented
// PyObject* PyNumber_InPlaceTrueDivide( PyObject *o1, PyObject *o2)
// not implemented
// PyObject* PyNumber_InPlaceRemainder( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> & operator %= (FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_ibinary_op<op_imod,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> & operator %= (FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_ibinary_op<op_imod,T,T>(a0,v1); }
// PyObject* PyNumber_InPlacePower( PyObject *o1, PyObject *o2, PyObject *o3)
template <class T> static FixedArray2D<T> & ipow_array2d_array2d (FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_ibinary_op<op_ipow,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> & ipow_array2d_scalar (FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_ibinary_op<op_ipow,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceLshift( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> & operator <<= (FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_ibinary_op<op_ilshift,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> & operator <<= (FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_ibinary_op<op_ilshift,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceRshift( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> & operator >>= (FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_ibinary_op<op_irshift,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> & operator >>= (FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_ibinary_op<op_irshift,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceAnd( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> & operator &= (FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_ibinary_op<op_ibitand,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> & operator &= (FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_ibinary_op<op_ibitand,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceXor( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> & operator ^= (FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_ibinary_op<op_ixor,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> & operator ^= (FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_ibinary_op<op_ixor,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceOr( PyObject *o1, PyObject *o2)
template <class T> static FixedArray2D<T> & operator |= (FixedArray2D<T> &a0, const FixedArray2D<T> &a1) { return apply_array2d_array2d_ibinary_op<op_ibitor,T,T>(a0,a1); }
template <class T> static FixedArray2D<T> & operator |= (FixedArray2D<T> &a0, const T &v1) { return apply_array2d_scalar_ibinary_op<op_ibitor,T,T>(a0,v1); }
template <class T>
static void add_arithmetic_math_functions(boost::python::class_<FixedArray2D<T> > &c) {
using namespace boost::python;
c
.def("__add__",&apply_array2d_array2d_binary_op<op_add,T,T,T>)
.def("__add__",&apply_array2d_scalar_binary_op<op_add,T,T,T>)
.def("__radd__",&apply_array2d_scalar_binary_rop<op_add,T,T,T>)
.def("__sub__",&apply_array2d_array2d_binary_op<op_sub,T,T,T>)
.def("__sub__",&apply_array2d_scalar_binary_op<op_sub,T,T,T>)
.def("__rsub__",&apply_array2d_scalar_binary_op<op_rsub,T,T,T>)
.def("__mul__",&apply_array2d_array2d_binary_op<op_mul,T,T,T>)
.def("__mul__",&apply_array2d_scalar_binary_op<op_mul,T,T,T>)
.def("__rmul__",&apply_array2d_scalar_binary_rop<op_mul,T,T,T>)
.def("__div__",&apply_array2d_array2d_binary_op<op_div,T,T,T>)
.def("__div__",&apply_array2d_scalar_binary_op<op_div,T,T,T>)
.def("__truediv__",&apply_array2d_array2d_binary_op<op_div,T,T,T>)
.def("__truediv__",&apply_array2d_scalar_binary_op<op_div,T,T,T>)
.def("__neg__",&apply_array2d_unary_op<op_neg,T,T>)
.def("__iadd__",&apply_array2d_array2d_ibinary_op<op_iadd,T,T>,return_internal_reference<>())
.def("__iadd__",&apply_array2d_scalar_ibinary_op<op_iadd,T,T>,return_internal_reference<>())
.def("__isub__",&apply_array2d_array2d_ibinary_op<op_isub,T,T>,return_internal_reference<>())
.def("__isub__",&apply_array2d_scalar_ibinary_op<op_isub,T,T>,return_internal_reference<>())
.def("__imul__",&apply_array2d_array2d_ibinary_op<op_imul,T,T>,return_internal_reference<>())
.def("__imul__",&apply_array2d_scalar_ibinary_op<op_imul,T,T>,return_internal_reference<>())
.def("__idiv__",&apply_array2d_array2d_ibinary_op<op_idiv,T,T>,return_internal_reference<>())
.def("__idiv__",&apply_array2d_scalar_ibinary_op<op_idiv,T,T>,return_internal_reference<>())
.def("__itruediv__",&apply_array2d_array2d_ibinary_op<op_idiv,T,T>,return_internal_reference<>())
.def("__itruediv__",&apply_array2d_scalar_ibinary_op<op_idiv,T,T>,return_internal_reference<>())
;
}
template <class T>
static void add_pow_math_functions(boost::python::class_<FixedArray2D<T> > &c) {
using namespace boost::python;
c
.def("__pow__",&apply_array2d_array2d_binary_op<op_pow,T,T,T>)
.def("__pow__",&apply_array2d_scalar_binary_op<op_pow,T,T,T>)
.def("__rpow__",&apply_array2d_scalar_binary_rop<op_rpow,T,T,T>)
.def("__ipow__",&apply_array2d_array2d_ibinary_op<op_ipow,T,T>,return_internal_reference<>())
.def("__ipow__",&apply_array2d_scalar_ibinary_op<op_ipow,T,T>,return_internal_reference<>())
;
}
template <class T>
static void add_mod_math_functions(boost::python::class_<FixedArray2D<T> > &c) {
using namespace boost::python;
c
.def("__mod__",&apply_array2d_array2d_binary_op<op_mod,T,T,T>)
.def("__mod__",&apply_array2d_scalar_binary_op<op_mod,T,T,T>)
.def("__imod__",&apply_array2d_array2d_ibinary_op<op_imod,T,T>,return_internal_reference<>())
.def("__imod__",&apply_array2d_scalar_ibinary_op<op_imod,T,T>,return_internal_reference<>())
;
}
template <class T>
static void add_shift_math_functions(boost::python::class_<FixedArray2D<T> > &c) {
using namespace boost::python;
c
.def("__lshift__",&apply_array2d_array2d_binary_op<op_lshift,T,T,T>)
.def("__lshift__",&apply_array2d_scalar_binary_op<op_lshift,T,T,T>)
.def("__ilshift__",&apply_array2d_array2d_ibinary_op<op_ilshift,T,T>,return_internal_reference<>())
.def("__ilshift__",&apply_array2d_scalar_ibinary_op<op_ilshift,T,T>,return_internal_reference<>())
.def("__rshift__",&apply_array2d_array2d_binary_op<op_rshift,T,T,T>)
.def("__rshift__",&apply_array2d_scalar_binary_op<op_rshift,T,T,T>)
.def("__irshift__",&apply_array2d_array2d_ibinary_op<op_irshift,T,T>,return_internal_reference<>())
.def("__irshift__",&apply_array2d_scalar_ibinary_op<op_irshift,T,T>,return_internal_reference<>())
;
}
template <class T>
static void add_bitwise_math_functions(boost::python::class_<FixedArray2D<T> > &c) {
using namespace boost::python;
c
.def("__and__",&apply_array2d_array2d_binary_op<op_bitand,T,T,T>)
.def("__and__",&apply_array2d_scalar_binary_op<op_bitand,T,T,T>)
.def("__iand__",&apply_array2d_array2d_ibinary_op<op_ibitand,T,T>,return_internal_reference<>())
.def("__iand__",&apply_array2d_scalar_ibinary_op<op_ibitand,T,T>,return_internal_reference<>())
.def("__or__",&apply_array2d_array2d_binary_op<op_bitor,T,T,T>)
.def("__or__",&apply_array2d_scalar_binary_op<op_bitor,T,T,T>)
.def("__ior__",&apply_array2d_array2d_ibinary_op<op_ibitor,T,T>,return_internal_reference<>())
.def("__ior__",&apply_array2d_scalar_ibinary_op<op_ibitor,T,T>,return_internal_reference<>())
.def("__xor__",&apply_array2d_array2d_binary_op<op_xor,T,T,T>)
.def("__xor__",&apply_array2d_scalar_binary_op<op_xor,T,T,T>)
.def("__ixor__",&apply_array2d_array2d_ibinary_op<op_ixor,T,T>,return_internal_reference<>())
.def("__ixor__",&apply_array2d_scalar_ibinary_op<op_ixor,T,T>,return_internal_reference<>())
;
}
template <class T>
static void add_comparison_functions(boost::python::class_<FixedArray2D<T> > &c) {
using namespace boost::python;
c
.def("__eq__",&apply_array2d_array2d_binary_op<op_eq,T,T,int>)
.def("__eq__",&apply_array2d_scalar_binary_op<op_eq,T,T,int>)
.def("__ne__",&apply_array2d_array2d_binary_op<op_ne,T,T,int>)
.def("__ne__",&apply_array2d_scalar_binary_op<op_ne,T,T,int>)
;
}
template <class T>
static void add_ordered_comparison_functions(boost::python::class_<FixedArray2D<T> > &c) {
using namespace boost::python;
c
.def("__lt__",&apply_array2d_array2d_binary_op<op_lt,T,T,int>)
.def("__lt__",&apply_array2d_scalar_binary_op<op_lt,T,T,int>)
.def("__gt__",&apply_array2d_array2d_binary_op<op_gt,T,T,int>)
.def("__gt__",&apply_array2d_scalar_binary_op<op_gt,T,T,int>)
.def("__le__",&apply_array2d_array2d_binary_op<op_le,T,T,int>)
.def("__le__",&apply_array2d_scalar_binary_op<op_le,T,T,int>)
.def("__ge__",&apply_array2d_array2d_binary_op<op_ge,T,T,int>)
.def("__ge__",&apply_array2d_scalar_binary_op<op_ge,T,T,int>)
;
}
template <class S,class T>
static void add_explicit_construction_from_type(boost::python::class_<FixedArray2D<T> > &c) {
using namespace boost::python;
c.def(boost::python::init<FixedArray2D<S> >("copy contents of other array into this one"));
}
}
#endif

View File

@ -0,0 +1,535 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathFixedMatrix_h_
#define _PyImathFixedMatrix_h_
#include <boost/python.hpp>
#include <iostream>
#include "PyImathFixedArray.h"
#include "PyImathOperators.h"
namespace PyImath {
//
// Utility class for a runtime-specified fixed sized matrix type in python
//
template <class T>
class FixedMatrix
{
T * _ptr;
int _rows;
int _cols;
int _rowStride;
int _colStride;
int * _refcount; // refcount if allocated, null if externally allocated
public:
FixedMatrix(T *ptr, int rows, int cols, int rowStride = 1, int colStride = 1)
: _ptr(ptr), _rows(rows), _cols(cols),
_rowStride(rowStride), _colStride(colStride), _refcount(0)
{
// nothing
}
FixedMatrix(int rows, int cols)
: _ptr(new T[rows*cols]), _rows(rows), _cols(cols),
_rowStride(1), _colStride(1), _refcount(new int(1))
{
// nothing
}
FixedMatrix(const FixedMatrix &other)
: _ptr(other._ptr), _rows(other._rows), _cols(other._cols),
_rowStride(other._rowStride), _colStride(other._colStride),
_refcount(other._refcount)
{
if (_refcount) *_refcount += 1;
}
const FixedMatrix &
operator = (const FixedMatrix &other)
{
if (&other == this) return *this;
unref();
_ptr = other._ptr;
_rows = other._rows;
_cols = other._cols;
_rowStride = other._rowStride;
_colStride = other._colStride;
_refcount = other._refcount;
if (_refcount) *_refcount += 1;
return *this;
}
void
unref()
{
if (_refcount) {
*_refcount -= 1;
if (*_refcount == 0) {
delete [] _ptr;
delete _refcount;
}
}
_ptr = 0;
_rows = 0;
_cols = 0;
_rowStride = 0;
_colStride = 0;
_refcount = 0;
}
~FixedMatrix()
{
unref();
}
int convert_index(int index) const
{
if (index < 0) index += _rows;
if (index >= _rows || index < 0) {
PyErr_SetString(PyExc_IndexError, "Index out of range");
boost::python::throw_error_already_set();
}
return index;
}
void extract_slice_indices(PyObject *index, Py_ssize_t &start, Py_ssize_t &end, Py_ssize_t &step, Py_ssize_t &slicelength) const
{
if (PySlice_Check(index)) {
PySliceObject *slice = reinterpret_cast<PySliceObject *>(index);
if (PySlice_GetIndicesEx(slice,_rows,&start,&end,&step,&slicelength) == -1) {
boost::python::throw_error_already_set();
}
} else if (PyInt_Check(index)) {
int i = convert_index(PyInt_AS_LONG(index));
start = i; end = i+1; step = 1; slicelength = 1;
} else {
PyErr_SetString(PyExc_TypeError, "Object is not a slice");
boost::python::throw_error_already_set();
}
//std::cout << "Slice indices are " << start << " " << end << " " << step << " " << slicelength << std::endl;
}
const FixedArray<T> * getitem(int index) const
{
return new FixedArray<T>(const_cast<T *>(&_ptr[convert_index(index)*_rowStride*_cols*_colStride]),_cols,_colStride);
}
FixedMatrix getslice(PyObject *index) const
{
Py_ssize_t start, end, step, slicelength;
extract_slice_indices(index,start,end,step,slicelength);
FixedMatrix f(slicelength,_cols);
for (int i=0; i<slicelength; ++i) {
for (int j=0; j<_cols; ++j) {
f.element(i,j) = element((start+i*step),j);
}
}
return f;
}
void
setitem_scalar(PyObject *index, const T &data)
{
Py_ssize_t start, end, step, slicelength;
extract_slice_indices(index,start,end,step,slicelength);
for (int i=0; i<slicelength; ++i) {
for (int j = 0; j < _cols; ++j) {
element(start+i*step,j) = data;
}
}
}
void
setitem_vector(PyObject *index, const FixedArray<T> &data)
{
Py_ssize_t start, end, step, slicelength;
extract_slice_indices(index,start,end,step,slicelength);
if (data.len() != _cols) {
PyErr_SetString(PyExc_IndexError, "Dimensions of source do not match destination");
boost::python::throw_error_already_set();
}
for (int i=0; i<slicelength; ++i) {
for (int j = 0; j < _cols; ++j) {
element(start+i*step,j) = data[j];
}
}
}
void
setitem_matrix(PyObject *index, const FixedMatrix &data)
{
Py_ssize_t start, end, step, slicelength;
extract_slice_indices(index,start,end,step,slicelength);
// we have a valid range of indices
if (data.rows() != slicelength || data.cols() != cols()) {
PyErr_SetString(PyExc_IndexError, "Dimensions of source do not match destination");
boost::python::throw_error_already_set();
}
for (int i=0; i<slicelength; ++i) {
for (int j=0; j<cols(); ++j) {
element(start+i*step,j) = data.element(i,j);
}
}
}
int rows() const { return _rows; }
int cols() const { return _cols; }
int rowStride() const { return _rowStride; }
int colStride() const { return _colStride; }
T & element(int i, int j) { return _ptr[i*_rowStride*_cols*_colStride+j*_colStride]; }
const T & element(int i, int j) const { return _ptr[i*_rowStride*_cols*_colStride+j*_colStride]; }
FixedArray<T> operator [] (int i) { return FixedArray<T>(&_ptr[i*_rowStride*_cols*_colStride],_cols,_colStride); }
const FixedArray<T> operator [] (int i) const { return FixedArray<T>(const_cast<T *>(&_ptr[i*_rowStride*_cols*_colStride]),_cols,_colStride); }
static boost::python::class_<FixedMatrix<T> > register_(const char *name, const char *doc)
{
boost::python::class_<FixedMatrix<T> > c(name,doc, boost::python::init<int,int>("return an unitialized array of the specified rows and cols"));
c
.def("__getitem__", &FixedMatrix<T>::getslice)
.def("__getitem__", &FixedMatrix<T>::getitem, boost::python::return_internal_reference<>())
.def("__setitem__", &FixedMatrix<T>::setitem_scalar)
.def("__setitem__", &FixedMatrix<T>::setitem_vector)
.def("__setitem__", &FixedMatrix<T>::setitem_matrix)
.def("__len__",&FixedMatrix<T>::rows)
.def("rows",&FixedMatrix<T>::rows)
.def("columns",&FixedMatrix<T>::cols)
;
return c;
}
template <class T2>
int match_dimension(const FixedMatrix<T2> &a1) const
{
if (rows() != a1.rows() || cols() != a1.cols()) {
PyErr_SetString(PyExc_IndexError, "Dimensions of source do not match destination");
boost::python::throw_error_already_set();
}
return rows();
}
};
// unary operation application
template <template <class,class> class Op, class T1, class Ret>
FixedMatrix<Ret> apply_matrix_unary_op(const FixedMatrix<T1> &a1)
{
int rows = a1.rows();
int cols = a1.cols();
FixedMatrix<Ret> retval(rows,cols);
for (int i=0;i<rows;++i) for (int j=0; j<cols; ++j) {
retval.element(i,j) = Op<T1,Ret>::apply(a1.element(i,j));
}
return retval;
}
// binary operation application
template <template <class,class,class> class Op, class T1, class T2, class Ret>
FixedMatrix<Ret> apply_matrix_matrix_binary_op(const FixedMatrix<T1> &a1, const FixedMatrix<T2> &a2)
{
int rows = a1.match_dimension(a2);
int cols = a1.cols();
FixedMatrix<Ret> retval(rows,cols);
for (int i=0;i<rows;++i) for (int j=0; j<cols; ++j) {
retval.element(i,j) = Op<T1,T2,Ret>::apply(a1.element(i,j),a2.element(i,j));
}
return retval;
}
template <template <class,class,class> class Op, class T1, class T2, class Ret>
FixedMatrix<Ret> apply_matrix_scalar_binary_op(const FixedMatrix<T1> &a1, const T2 &a2)
{
int rows = a1.rows();
int cols = a1.cols();
FixedMatrix<Ret> retval(rows,cols);
for (int i=0;i<rows;++i) for (int j=0; j<cols; ++j) {
retval.element(i,j) = Op<T1,T2,Ret>::apply(a1.element(i,j),a2);
}
return retval;
}
template <template <class,class,class> class Op, class T1, class T2, class Ret>
FixedMatrix<Ret> apply_matrix_scalar_binary_rop(const FixedMatrix<T1> &a1, const T2 &a2)
{
int rows = a1.rows();
int cols = a1.cols();
FixedMatrix<Ret> retval(rows,cols);
for (int i=0;i<rows;++i) for (int j=0; j<cols; ++j) {
retval.element(i,j) = Op<T2,T1,Ret>::apply(a2,a1.element(i,j));
}
return retval;
}
// in-place binary operation application
template <template <class,class> class Op, class T1, class T2>
FixedMatrix<T1> & apply_matrix_matrix_ibinary_op(FixedMatrix<T1> &a1, const FixedMatrix<T2> &a2)
{
int rows = a1.match_dimension(a2);
int cols = a1.cols();
for (int i=0;i<rows;++i) for (int j=0; j<cols; ++j) {
Op<T1,T2>::apply(a1.element(i,j),a2.element(i,j));
}
return a1;
}
// in-place binary operation application
template <template <class,class> class Op, class T1, class T2>
FixedMatrix<T1> & apply_matrix_scalar_ibinary_op(FixedMatrix<T1> &a1, const T2 &a2)
{
int rows = a1.rows();
int cols = a1.cols();
for (int i=0;i<rows;++i) for (int j=0; j<cols; ++j) {
Op<T1,T2>::apply(a1.element(i,j),a2);
}
return a1;
}
// PyObject* PyNumber_Add( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> operator + (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_add,T,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> operator + (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_add,T,T,T>(a0,v1); }
template <class T> static FixedMatrix<T> operator + (const T &v1, const FixedMatrix<T> &a0) { return a0+v1; }
// PyObject* PyNumber_Subtract( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> operator - (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_sub,T,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> operator - (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_sub,T,T,T>(a0,v1); }
template <class T> static FixedMatrix<T> operator - (const T &v1, const FixedMatrix<T> &a0) { return apply_matrix_scalar_binary_op<op_rsub,T,T,T>(a0,v1); }
// PyObject* PyNumber_Multiply( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> operator * (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_mul,T,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> operator * (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_mul,T,T,T>(a0,v1); }
template <class T> static FixedMatrix<T> operator * (const T &v1, const FixedMatrix<T> &a0) { return a0*v1; }
// PyObject* PyNumber_Divide( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> operator / (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_div,T,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> operator / (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_div,T,T,T>(a0,v1); }
// no reversed scalar/matrix divide - no meaning
// PyObject* PyNumber_FloorDivide( PyObject *o1, PyObject *o2)
// PyObject* PyNumber_TrueDivide( PyObject *o1, PyObject *o2)
// PyObject* PyNumber_Remainder( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> operator % (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_mod,T,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> operator % (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_mod,T,T,T>(a0,v1); }
// no reversed scalar%matrix remainder - no meaning
// PyObject* PyNumber_Divmod( PyObject *o1, PyObject *o2)
// PyObject* PyNumber_Power( PyObject *o1, PyObject *o2, PyObject *o3)
template <class T> static FixedMatrix<T> pow_matrix_matrix (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_pow,T,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> pow_matrix_scalar (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_pow,T,T,T>(a0,v1); }
// no reversed scalar/matrix pow - no meaning
// PyObject* PyNumber_Negative( PyObject *o)
template <class T> static FixedMatrix<T> operator - (const FixedMatrix<T> &a0) { return apply_matrix_unary_op<op_neg,T,T>(a0); }
// PyObject* PyNumber_Positive( PyObject *o)
// PyObject* PyNumber_Absolute( PyObject *o)
template <class T> static FixedMatrix<T> abs (const FixedMatrix<T> &a0) { return apply_matrix_unary_op<op_abs,T,T>(a0); }
// PyObject* PyNumber_Invert( PyObject *o)
template <class T> static FixedMatrix<T> operator ~ (const FixedMatrix<T> &a0) { return apply_matrix_unary_op<op_inverse,T,T>(a0); }
// PyObject* PyNumber_Lshift( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> operator << (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_lshift,T,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> operator << (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_lshift,T,T,T>(a0,v1); }
// no reversed
// PyObject* PyNumber_Rshift( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> operator >> (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_rshift,T,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> operator >> (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_rshift,T,T,T>(a0,v1); }
// no reversed
// PyObject* PyNumber_And( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> operator & (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_bitand,T,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> operator & (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_bitand,T,T,T>(a0,v1); }
template <class T> static FixedMatrix<T> operator & (const T &v1, const FixedMatrix<T> &a0) { return a0&v1; }
// PyObject* PyNumber_Xor( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> operator ^ (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_xor,T,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> operator ^ (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_xor,T,T,T>(a0,v1); }
template <class T> static FixedMatrix<T> operator ^ (const T &v1, const FixedMatrix<T> &a0) { return a0^v1; }
// PyObject* PyNumber_Or( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> operator | (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_bitor,T,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> operator | (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_bitor,T,T,T>(a0,v1); }
template <class T> static FixedMatrix<T> operator | (const T &v1, const FixedMatrix<T> &a0) { return a0|v1; }
// PyObject* PyNumber_InPlaceAdd( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> & operator += (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_iadd,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> & operator += (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_iadd,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceSubtract( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> & operator -= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_isub,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> & operator -= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_isub,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceMultiply( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> & operator *= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_imul,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> & operator *= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_imul,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceDivide( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> & operator /= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_idiv,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> & operator /= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_idiv,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceFloorDivide( PyObject *o1, PyObject *o2)
// not implemented
// PyObject* PyNumber_InPlaceTrueDivide( PyObject *o1, PyObject *o2)
// not implemented
// PyObject* PyNumber_InPlaceRemainder( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> & operator %= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_imod,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> & operator %= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_imod,T,T>(a0,v1); }
// PyObject* PyNumber_InPlacePower( PyObject *o1, PyObject *o2, PyObject *o3)
template <class T> static FixedMatrix<T> & ipow_matrix_matrix (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_ipow,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> & ipow_matrix_scalar (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_ipow,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceLshift( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> & operator <<= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_ilshift,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> & operator <<= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_ilshift,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceRshift( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> & operator >>= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_irshift,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> & operator >>= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_irshift,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceAnd( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> & operator &= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_ibitand,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> & operator &= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_ibitand,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceXor( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> & operator ^= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_ixor,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> & operator ^= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_ixor,T,T>(a0,v1); }
// PyObject* PyNumber_InPlaceOr( PyObject *o1, PyObject *o2)
template <class T> static FixedMatrix<T> & operator |= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_ibitor,T,T>(a0,a1); }
template <class T> static FixedMatrix<T> & operator |= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_ibitor,T,T>(a0,v1); }
template <class T>
static void add_arithmetic_math_functions(boost::python::class_<FixedMatrix<T> > &c) {
using namespace boost::python;
c
.def("__add__",&apply_matrix_matrix_binary_op<op_add,T,T,T>)
.def("__add__",&apply_matrix_scalar_binary_op<op_add,T,T,T>)
.def("__radd__",&apply_matrix_scalar_binary_rop<op_add,T,T,T>)
.def("__sub__",&apply_matrix_matrix_binary_op<op_sub,T,T,T>)
.def("__sub__",&apply_matrix_scalar_binary_op<op_sub,T,T,T>)
.def("__rsub__",&apply_matrix_scalar_binary_op<op_rsub,T,T,T>)
.def("__mul__",&apply_matrix_matrix_binary_op<op_mul,T,T,T>)
.def("__mul__",&apply_matrix_scalar_binary_op<op_mul,T,T,T>)
.def("__rmul__",&apply_matrix_scalar_binary_rop<op_mul,T,T,T>)
.def("__div__",&apply_matrix_matrix_binary_op<op_div,T,T,T>)
.def("__div__",&apply_matrix_scalar_binary_op<op_div,T,T,T>)
.def("__truediv__",&apply_matrix_matrix_binary_op<op_div,T,T,T>)
.def("__truediv__",&apply_matrix_scalar_binary_op<op_div,T,T,T>)
.def("__neg__",&apply_matrix_unary_op<op_neg,T,T>)
.def("__iadd__",&apply_matrix_matrix_ibinary_op<op_iadd,T,T>,return_internal_reference<>())
.def("__iadd__",&apply_matrix_scalar_ibinary_op<op_iadd,T,T>,return_internal_reference<>())
.def("__isub__",&apply_matrix_matrix_ibinary_op<op_isub,T,T>,return_internal_reference<>())
.def("__isub__",&apply_matrix_scalar_ibinary_op<op_isub,T,T>,return_internal_reference<>())
.def("__imul__",&apply_matrix_matrix_ibinary_op<op_imul,T,T>,return_internal_reference<>())
.def("__imul__",&apply_matrix_scalar_ibinary_op<op_imul,T,T>,return_internal_reference<>())
.def("__idiv__",&apply_matrix_matrix_ibinary_op<op_idiv,T,T>,return_internal_reference<>())
.def("__idiv__",&apply_matrix_scalar_ibinary_op<op_idiv,T,T>,return_internal_reference<>())
.def("__itruediv__",&apply_matrix_matrix_ibinary_op<op_idiv,T,T>,return_internal_reference<>())
.def("__itruediv__",&apply_matrix_scalar_ibinary_op<op_idiv,T,T>,return_internal_reference<>())
;
}
template <class T>
static void add_pow_math_functions(boost::python::class_<FixedMatrix<T> > &c) {
using namespace boost::python;
c
.def("__pow__",&pow_matrix_scalar<T>)
.def("__pow__",&pow_matrix_matrix<T>)
.def("__ipow__",&ipow_matrix_scalar<T>,return_internal_reference<>())
.def("__ipow__",&ipow_matrix_matrix<T>,return_internal_reference<>())
;
}
template <class T>
static void add_mod_math_functions(boost::python::class_<FixedMatrix<T> > &c) {
using namespace boost::python;
c
.def(self % self)
.def(self % other<T>())
.def(self %= self)
.def(self %= other<T>())
;
}
template <class T>
static void add_shift_math_functions(boost::python::class_<FixedMatrix<T> > &c) {
using namespace boost::python;
c
.def(self << self)
.def(self << other<T>())
.def(self <<= self)
.def(self <<= other<T>())
.def(self >> self)
.def(self >> other<T>())
.def(self >>= self)
.def(self >>= other<T>())
;
}
template <class T>
static void add_bitwise_math_functions(boost::python::class_<FixedMatrix<T> > &c) {
using namespace boost::python;
c
.def(self & self)
.def(self & other<T>())
.def(self &= self)
.def(self &= other<T>())
.def(self | self)
.def(self | other<T>())
.def(self |= self)
.def(self |= other<T>())
.def(self ^ self)
.def(self ^ other<T>())
.def(self ^= self)
.def(self ^= other<T>())
;
}
}
#endif

View File

@ -0,0 +1,564 @@
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2013, 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 <PyImathFixedVArray.h>
#include <boost/python.hpp>
#include <boost/shared_array.hpp>
#include <boost/any.hpp>
#include <Iex.h>
#include <PyImathExport.h>
namespace PyImath {
template <class T>
FixedVArray<T>::FixedVArray (std::vector<T>* ptr, Py_ssize_t length,
Py_ssize_t stride)
: _ptr(ptr), _length(length), _stride(stride),
_handle(), _unmaskedLength(0)
{
if (length < 0)
{
throw IEX_NAMESPACE::ArgExc("Fixed array length must be non-negative");
}
if (stride <= 0)
{
throw IEX_NAMESPACE::ArgExc("Fixed array stride must be positive");
}
// Nothing else to do (pointer given, so we have the data)
}
template <class T>
FixedVArray<T>::FixedVArray (std::vector<T>* ptr, Py_ssize_t length,
Py_ssize_t stride, boost::any handle)
: _ptr(ptr), _length(length), _stride(stride),
_handle(handle), _unmaskedLength(0)
{
if (length < 0)
{
throw IEX_NAMESPACE::ArgExc("Fixed array length must be non-negative");
}
if (stride <= 0)
{
throw IEX_NAMESPACE::ArgExc("Fixed array stride must be positive");
}
// Nothing else to do (pointer given, so we have the data)
}
template <class T>
FixedVArray<T>::FixedVArray(Py_ssize_t length)
: _ptr(0), _length(length), _stride(1), _handle(), _unmaskedLength(0)
{
if (length < 0)
{
throw IEX_NAMESPACE::ArgExc("Fixed array length must be non-negative");
}
boost::shared_array<std::vector<T> > a(new std::vector<T>[length]);
// Initial vectors in the array will be zero-length.
_handle = a;
_ptr = a.get();
}
// template <class T>
// FixedVArray<T>::FixedVArray(Py_ssize_t length, Uninitialized)
// : _ptr(0), _length(length), _stride(1), _handle(), _unmaskedLength(0)
// {
// if (length < 0)
// {
// throw IEX_NAMESPACE::ArgExc("Fixed array length must be non-negative");
// }
//
// boost::shared_array<std::vector<T> > a(new std::vector<T>[length]);
// _handle = a;
// _ptr = a.get();
// }
template <class T>
FixedVArray<T>::FixedVArray(const T& initialValue, Py_ssize_t length)
: _ptr(0), _length(length), _stride(1), _handle(), _unmaskedLength(0)
{
if (length < 0)
{
throw IEX_NAMESPACE::ArgExc("Fixed array length must be non-negative");
}
boost::shared_array<std::vector<T> > a(new std::vector<T>[length]);
for (size_t i = 0; i < length; ++i)
{
a[i].push_back (initialValue);
}
_handle = a;
_ptr = a.get();
}
template <class T>
FixedVArray<T>::FixedVArray(FixedVArray<T>& other, const FixedArray<int>& mask)
: _ptr(other._ptr), _stride(other._stride), _handle(other._handle)
{
if (other.isMaskedReference())
{
throw IEX_NAMESPACE::NoImplExc
("Masking an already-masked FixedVArray is not supported yet (SQ27000)");
}
size_t len = other.match_dimension (mask);
_unmaskedLength = len;
size_t reduced_len = 0;
for (size_t i = 0; i < len; ++i)
{
if (mask[i])
{
reduced_len++;
}
}
_indices.reset (new size_t[reduced_len]);
for (size_t i = 0, j = 0; i < len; ++i)
{
if (mask[i])
{
_indices[j] = i;
j++;
}
}
_length = reduced_len;
}
// template <class S>
// explicit FixedVArray(const FixedVArray<S> &other) // AAJ (WHAT DOES THE TEMPLATE LOOK LIKE?)
// {
// }
template <class T>
FixedVArray<T>::FixedVArray(const FixedVArray<T>& other)
: _ptr(other._ptr), _length(other._length), _stride(other._stride),
_handle(other._handle), _indices(other._indices),
_unmaskedLength(other._unmaskedLength)
{
// Nothing.
}
template <class T>
const FixedVArray<T> &
FixedVArray<T>::operator = (const FixedVArray<T>& other) // AAJ (WHY SHALLOW COPY)
{
if (&other == this)
return *this;
_ptr = other._ptr;
_length = other._length;
_stride = other._stride;
_handle = other._handle;
_unmaskedLength = other._unmaskedLength;
_indices = other._indices;
return *this;
}
template <class T>
FixedVArray<T>::~FixedVArray() // AAJ (NOT DELETED BECAUSE SHARED ARRAY THAT HANDLE HAS?)
{
// Nothing.
}
template <class T>
std::vector<T>&
FixedVArray<T>::operator [] (size_t i)
{
return _ptr[(_indices ? raw_ptr_index(i) : i) * _stride];
}
template <class T>
const std::vector<T>&
FixedVArray<T>::operator [] (size_t i) const
{
return _ptr[(_indices ? raw_ptr_index(i) : i) * _stride];
}
namespace {
//
// Make an index suitable for indexing into an array in c++
// from a python index, which can be negative for indexing
// relative to the end of an array.
//
size_t
canonical_index (Py_ssize_t index, const size_t& totalLength)
{
if (index < 0)
{
index += totalLength;
}
if (index >= totalLength || index < 0)
{
PyErr_SetString (PyExc_IndexError, "Index out of range");
boost::python::throw_error_already_set();
}
return index; // still a 'virtual' index if this is a masked reference array
}
void
extract_slice_indices (PyObject* index, size_t& start, size_t& end,
Py_ssize_t& step, size_t& sliceLength,
const size_t& totalLength)
{
if (PySlice_Check (index))
{
PySliceObject* slice = reinterpret_cast<PySliceObject *>(index);
Py_ssize_t s, e, sl;
if (PySlice_GetIndicesEx(slice, totalLength, &s, &e, &step, &sl) == -1)
{
boost::python::throw_error_already_set();
}
if (s < 0 || e < -1 || sl < 0)
{
throw IEX_NAMESPACE::LogicExc
("Slice extraction produced invalid start, end, or length indices");
}
start = s;
end = e;
sliceLength = sl;
}
else if (PyInt_Check (index))
{
size_t i = canonical_index (PyInt_AsSsize_t(index), totalLength);
start = i;
end = i + 1;
step = 1;
sliceLength = 1;
}
else
{
PyErr_SetString (PyExc_TypeError, "Object is not a slice");
boost::python::throw_error_already_set();
}
}
} // namespace
// template <class T>
// typename boost::mpl::if_<boost::is_class<T>,T&,T>::type
// FixedVArray<T>::getitem (Py_ssize_t index)
// {
// return (*this)[canonical_index (index, _length)];
// }
//
// template <class T>
// typename boost::mpl::if_<boost::is_class<T>,const T&,T>::type
// FixedVArray<T>::getitem (Py_ssize_t index) const
// {
// return (*this)[canonical_index (index, _length)];
// }
template <class T>
FixedVArray<T>
FixedVArray<T>::getslice (PyObject* index) const
{
size_t start = 0;
size_t end = 0;
size_t sliceLength = 0;
Py_ssize_t step;
extract_slice_indices (index, start, end, step, sliceLength, _length);
FixedVArray<T> f(sliceLength);
if (_indices)
{
for (size_t i = 0; i < sliceLength; ++i)
{
f._ptr[i] = _ptr[raw_ptr_index(start + i*step)*_stride];
}
}
else
{
for (size_t i = 0; i < sliceLength; ++i)
{
f._ptr[i] = _ptr[(start + i*step)*_stride];
}
}
return f;
}
template <class T>
FixedVArray<T>
FixedVArray<T>::getslice_mask (const FixedArray<int>& mask)
{
return FixedVArray<T> (*this, mask);
}
// template <class T>
// void
// FixedVArray<T>::setitem_scalar (PyObject* index, const T& data)
// {
// size_t start = 0;
// size_t end = 0;
// size_t sliceLength = 0;
// Py_ssize_t step;
// extract_slice_indices (index, start, end, step, sliceLength, _length);
//
// if (_indices)
// {
// for (size_t i = 0; i < sliceLength; ++i)
// {
// _ptr[raw_ptr_index(start + i*step)*_stride] = data;
// }
// }
// else
// {
// for (size_t i = 0; i < sliceLength; ++i)
// {
// _ptr[(start + i*step)*_stride] = data;
// }
// }
// }
//
// template <class T>
// void
// FixedVArray<T>::setitem_scalar_mask (const FixedArray<int>& mask, const T& data)
// {
// size_t len = match_dimension(mask, false);
//
// if (_indices)
// {
// for (size_t i = 0; i < len; ++i)
// {
// // We don't need to actually look at 'mask' because
// // match_dimensions has already forced some expected condition.
// _ptr[raw_ptr_index(i)*_stride] = data;
// }
// }
// else
// {
// for (size_t i = 0; i < len; ++i)
// {
// if (mask[i])
// {
// _ptr[i*_stride] = data;
// }
// }
// }
// }
template <class T>
void
FixedVArray<T>::setitem_vector (PyObject* index, const FixedVArray<T>& data)
{
size_t start = 0;
size_t end = 0;
size_t sliceLength = 0;
Py_ssize_t step;
extract_slice_indices (index, start, end, step, sliceLength, _length);
if (data.len() != sliceLength)
{
PyErr_SetString (PyExc_IndexError,
"Dimensions of source do not match destination");
boost::python::throw_error_already_set();
}
if (_indices)
{
for (size_t i = 0; i < sliceLength; ++i)
{
_ptr[raw_ptr_index(start + i*step)*_stride] = data[i];
}
}
else
{
for (size_t i = 0; i < sliceLength; ++i)
{
_ptr[(start + i*step)*_stride] = data[i];
}
}
}
template <class T>
void
FixedVArray<T>::setitem_vector_mask (const FixedArray<int>& mask,
const FixedVArray<T>& data)
{
// This restriction could be removed if there is a compelling use-case.
if (_indices)
{
throw IEX_NAMESPACE::ArgExc
("We don't support setting item masks for masked reference arrays");
}
size_t len = match_dimension(mask);
if (data.len() == len)
{
for (size_t i = 0; i < len; ++i)
{
if (mask[i])
{
_ptr[i*_stride] = data[i];
}
}
}
else
{
size_t count = 0;
for (size_t i = 0; i < len; ++i)
{
if (mask[i])
{
count++;
}
}
if (data.len() != count)
{
throw IEX_NAMESPACE::ArgExc
("Dimensions of source data do not match destination "
"either masked or unmasked");
}
Py_ssize_t dataIndex = 0;
for (size_t i = 0; i < len; ++i)
{
if (mask[i])
{
_ptr[i*_stride] = data[dataIndex];
dataIndex++;
}
}
}
}
// template <class T>
// FixedVArray<T>
// FixedVArray<T>::ifelse_scalar(const FixedArray<int>& choice, const T& other)
// {
// size_t len = match_dimension (choice);
//
// FixedVArray<T> tmp(len);
// for (size_t i = 0; i < len; ++i)
// {
// tmp[i] = choice[i] ? (*this)[i] : other;
// }
//
// return tmp;
// }
template <class T>
FixedVArray<T>
FixedVArray<T>::ifelse_vector(const FixedArray<int>& choice,
const FixedVArray<T>& other)
{
size_t len = match_dimension (choice);
match_dimension (other);
FixedVArray<T> tmp(len);
for (size_t i = 0; i < len; ++i)
{
tmp[i] = choice[i] ? (*this)[i] : other[i];
}
return tmp;
}
template <class T>
size_t
FixedVArray<T>::raw_ptr_index (size_t i) const
{
assert (isMaskedReference());
assert (i < _length);
assert (_indices[i] >= 0 && _indices[i] < _unmaskedLength);
return _indices[i];
}
// static
template <class T>
boost::python::class_<FixedVArray<T> >
FixedVArray<T>::register_(const char* doc)
{
// // See 'PyImathFixedArray.h' for some explanation.
// typedef typename boost::mpl::if_<
// boost::is_class<T>,
// boost::python::return_internal_reference<>,
// boost::python::default_call_policies>::type call_policy;
// typedef typename boost::mpl::if_<
// boost::is_class<T>,
// boost::python::return_value_policy<boost::python::copy_const_reference>,
// boost::python::default_call_policies>::type const_call_policy;
//
// typename FixedVArray<T>::get_type (FixedVArray<T>::*nonconst_getitem)(Py_ssize_t) =
// &FixedVArray<T>::getitem;
//
// typename FixedVArray<T>::get_type_const (FixedVArray<T>::*const_getitem)(Py_ssize_t) const =
// &FixedVArray<T>::getitem;
boost::python::class_<FixedVArray<T> > c (name(), doc,
boost::python::init<size_t>("Construct a variable array of the "
"specified length initialized to the default value for the given type"));
c.def(boost::python::init<const FixedVArray<T> &>("Construct a variable array with the same values as the given array"))
.def(boost::python::init<const T &, size_t>("Construct a variable array of the specified length initialized to the specified default value"))
.def("__getitem__", &FixedVArray<T>::getslice)
.def("__getitem__", &FixedVArray<T>::getslice_mask)
.def("__setitem__", &FixedVArray<T>::setitem_vector)
.def("__setitem__", &FixedVArray<T>::setitem_vector_mask)
.def("__len__", &FixedVArray<T>::len)
.def("ifelse", &FixedVArray<T>::ifelse_vector)
;
// .def("__setitem__", &FixedVArray<T>::setitem_scalar)
// .def("__setitem__", &FixedVArray<T>::setitem_scalar_mask)
// .def("__getitem__", const_getitem, const_call_policy())
// .def("__getitem__", nonconst_getitem, call_policy())
// .def("ifelse", &FixedVArray<T>::ifelse_scalar)
return c;
}
// ---- Explicit Class Instantiation ---------------------------------
template class PYIMATH_EXPORT FixedVArray<int>;
} // namespace PyImath

View File

@ -0,0 +1,207 @@
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2013, 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathFixedVArray_h_
#define _PyImathFixedVArray_h_
#include <boost/python.hpp>
#include <boost/any.hpp>
#include <vector>
#include <PyImathFixedArray.h>
namespace PyImath {
template <class T>
class FixedVArray
{
// This class (at least for now) holds a std::vector of 'T' types.
// This will give us the 'variable' part of the array. Generally,
// we will initially support only a very small subset of accessor
// methods before the semantics are fully defined. Currently, the
// VArray semantics are defined in the 'varraySemantics.txt' file.
std::vector<T> * _ptr;
size_t _length;
size_t _stride;
// This handle optionally stores a shared_array to allocated array data
// so that everything is freed properly on exit.
boost::any _handle;
boost::shared_array<size_t> _indices; // non-NULL if we're a masked reference
size_t _unmaskedLength;
public:
typedef T BaseType;
FixedVArray (std::vector<T>* ptr, Py_ssize_t length,
Py_ssize_t stride = 1);
FixedVArray (std::vector<T>* ptr, Py_ssize_t length,
Py_ssize_t stride, boost::any handle);
explicit FixedVArray (Py_ssize_t length);
// Not needed. vector-lengths are zero (uninitialized) by default.
// FixedVArray (Py_ssize_t length, Uninitialized);
FixedVArray (const T& initialValue, Py_ssize_t length);
FixedVArray (FixedVArray<T>& f, const FixedArray<int>& mask);
// template <class S>
// explicit FixedVArray (const FixedVArray<S> &other);
FixedVArray (const FixedVArray<T>& other);
const FixedVArray& operator = (const FixedVArray<T>& other);
~FixedVArray();
// ----------------
const boost::any& handle() { return _handle; }
Py_ssize_t len() const { return _length; }
size_t stride() const { return _stride; }
bool isMaskedReference() const { return _indices.get() != 0; }
size_t unmaskedLength() const { return _unmaskedLength; }
std::vector<T>& operator [] (size_t i);
const std::vector<T>& operator [] (size_t i) const;
// ----------------
// typedef typename boost::mpl::if_<boost::is_class<T>,T&,T>::type get_type;
// get_type getitem (Py_ssize_t index);
//
// typedef typename boost::mpl::if_<boost::is_class<T>,const T&,T>::type get_type_const;
// get_type_const getitem (Py_ssize_t index) const;
// ----------------
FixedVArray<T> getslice (PyObject* index) const; // AAJ: Question about 'FixedArray' version
FixedVArray<T> getslice_mask (const FixedArray<int>& mask);
// void setitem_scalar (PyObject* index, const T& data);
// void setitem_scalar_mask (const FixedArray<int>& mask, const T& data);
void setitem_vector (PyObject* index, const FixedVArray<T>& data);
void setitem_vector_mask (const FixedArray<int>& mask, const FixedVArray<T>& data);
// FixedVArray<T> ifelse_scalar(const FixedArray<int>& choice, const T& other);
FixedVArray<T> ifelse_vector(const FixedArray<int>& choice, const FixedVArray<T>& other);
// ----------------
static boost::python::class_<FixedVArray<T> > register_(const char* doc);
// Instantiations of fixed variable arrays must implement this static member.
static const char* name();
template <class T2>
size_t match_dimension (const FixedArray<T2>& mask,
bool strictComparison = true) const
{
if (len() == mask.len())
{
return len();
}
bool throwExc = false;
if (strictComparison)
{
throwExc = true;
}
else if (_indices)
{
if (_unmaskedLength != mask.len())
{
throwExc = true;
}
}
else
{
throwExc = true;
}
if (throwExc)
{
throw IEX_NAMESPACE::ArgExc("Dimensions of source do not match destination");
}
return len();
}
size_t match_dimension (const FixedVArray<T>& other,
bool strictComparison = true) const
{
if (len() == other.len())
{
return len();
}
bool throwExc = false;
if (strictComparison)
{
throwExc = true;
}
else if (_indices)
{
if (_unmaskedLength != other.len())
{
throwExc = true;
}
}
else
{
throwExc = true;
}
if (throwExc)
{
throw IEX_NAMESPACE::ArgExc("Dimensions of source do not match destination");
}
return len();
}
protected:
size_t raw_ptr_index (size_t i) const;
};
} // namespace PyImath
#endif // _PyImathFixedVArray_h_

View File

@ -0,0 +1,521 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 <PyImathFrustum.h>
#include "PyImathDecorators.h"
#include "PyImathExport.h"
#include <Python.h>
#include <boost/python.hpp>
#include <boost/format.hpp>
#include <PyImath.h>
#include <PyImathMathExc.h>
#include <PyImathVec.h>
#include <Iex.h>
namespace PyImath{
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template <class T> struct FrustumName {static const char *value;};
template <> const char *FrustumName<float>::value = "Frustumf";
template <> const char *FrustumName<double>::value = "Frustumd";
template <class T> struct FrustumTestName {static const char *value;};
template <> const char *FrustumTestName<float>::value = "FrustumTestf";
template <> const char *FrustumTestName<double>::value = "FrustumTestd";
template <class T>
static std::string Frustum_repr(const Frustum<T> &f)
{
std::stringstream stream;
stream << FrustumName<T>::value << "(" << f.nearPlane() << ", " << f.farPlane() << ", "
<< f.left() << ", " << f.right() << ", " << f.top() << ", "
<< f.bottom() << ", " << f.orthographic() << ")";
return stream.str();
}
template <class T>
static void
modifyNearAndFar(Frustum<T> &f, T nearPlane, T farPlane)
{
MATH_EXC_ON;
f.modifyNearAndFar (nearPlane, farPlane);
}
template <class T>
static T
fovx(Frustum<T> &f)
{
MATH_EXC_ON;
return f.fovx();
}
template <class T>
static T
fovy(Frustum<T> &f)
{
MATH_EXC_ON;
return f.fovy();
}
template <class T>
static T
aspect(Frustum<T> &f)
{
MATH_EXC_ON;
return f.aspect();
}
template <class T>
static Matrix44<T>
projectionMatrix(Frustum<T> &f)
{
MATH_EXC_ON;
return f.projectionMatrix();
}
template <class T>
static Frustum<T>
window (Frustum<T> &f, T l, T r, T b, T t)
{
MATH_EXC_ON;
return f.window(l, r, b, t);
}
template <class T>
static Line3<T>
projectScreenToRay (Frustum<T> &f, const Vec2<T> &p)
{
MATH_EXC_ON;
return f.projectScreenToRay(p);
}
template <class T>
static Line3<T>
projectScreenToRayTuple(Frustum<T> &f, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 2)
{
Vec2<T> point;
point.x = extract<T>(t[0]);
point.y = extract<T>(t[1]);
return f.projectScreenToRay(point);
}
else
THROW(IEX_NAMESPACE::LogicExc, "projectScreenToRay expects tuple of length 2");
}
template <class T>
static Vec2<T>
projectPointToScreen (Frustum<T> &f, const Vec3<T> &p)
{
MATH_EXC_ON;
return f.projectPointToScreen(p);
}
template <class T>
static Vec2<T>
projectPointToScreenTuple(Frustum<T> &f, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 3)
{
Vec3<T> point;
point.x = extract<T>(t[0]);
point.y = extract<T>(t[1]);
point.z = extract<T>(t[2]);
return f.projectPointToScreen(point);
}
else
THROW(IEX_NAMESPACE::LogicExc, "projectPointToScreen expects tuple of length 3");
}
template <class T>
static Vec2<T>
projectPointToScreenObj(Frustum<T> &f, const object &o)
{
MATH_EXC_ON;
Vec3<T> v;
if (PyImath::V3<T>::convert (o.ptr(), &v))
return f.projectPointToScreen(v);
else
THROW(IEX_NAMESPACE::LogicExc, "projectPointToScreen expects tuple of length 3");
}
template <class T>
static T
ZToDepth(Frustum<T> &f, long z, long min, long max)
{
MATH_EXC_ON;
return f.ZToDepth(z, min, max);
}
template <class T>
static T
normalizedZToDepth(Frustum<T> &f, T z)
{
MATH_EXC_ON;
return f.normalizedZToDepth(z);
}
template <class T>
static long
DepthToZ(Frustum<T> &f, T depth, long min, long max)
{
MATH_EXC_ON;
return f.DepthToZ(depth, min, max);
}
template <class T>
static T
worldRadius(Frustum<T> &f, const Vec3<T> &p, T radius)
{
MATH_EXC_ON;
return f.worldRadius(p, radius);
}
template <class T>
static T
worldRadiusTuple(Frustum<T> &f, const tuple &t, T radius)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 3)
{
Vec3<T> point;
point.x = extract<T>(t[0]);
point.y = extract<T>(t[1]);
point.z = extract<T>(t[2]);
return f.worldRadius(point, radius);
}
else
THROW(IEX_NAMESPACE::LogicExc, "worldRadius expects tuple of length 3");
}
template <class T>
static T
screenRadius(Frustum<T> &f, const Vec3<T> &p, T radius)
{
MATH_EXC_ON;
return f.screenRadius(p, radius);
}
template <class T>
static T
screenRadiusTuple(Frustum<T> &f, const tuple &t, T radius)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 3)
{
Vec3<T> point;
point.x = extract<T>(t[0]);
point.y = extract<T>(t[1]);
point.z = extract<T>(t[2]);
return f.screenRadius(point, radius);
}
else
THROW(IEX_NAMESPACE::LogicExc, "screenRadius expects tuple of length 3");
}
template <class T>
static void
planes1(Frustum<T> &f, Plane3<T> *p)
{
MATH_EXC_ON;
f.planes(p);
}
template <class T>
static void
planes2(Frustum<T> &f, Plane3<T> *p, const Matrix44<T> &m)
{
MATH_EXC_ON;
f.planes(p, m);
}
template <class T>
static tuple
planes3(Frustum<T> &f, const Matrix44<T> &mat)
{
MATH_EXC_ON;
IMATH_NAMESPACE::Plane3<T> p[6];
f.planes(p,mat);
tuple t = make_tuple(p[0],p[1],p[2],p[3],p[4],p[5]);
return t;
}
template <class T>
static tuple
planes4(Frustum<T> &f)
{
MATH_EXC_ON;
IMATH_NAMESPACE::Plane3<T> p[6];
f.planes(p);
tuple t = make_tuple(p[0],p[1],p[2],p[3],p[4],p[5]);
return t;
}
template <class T>
class_<Frustum<T> >
register_Frustum()
{
void (IMATH_NAMESPACE::Frustum<T>::*set1)(T,T,T,T,T,T,bool) = &IMATH_NAMESPACE::Frustum<T>::set;
void (IMATH_NAMESPACE::Frustum<T>::*set2)(T,T,T,T,T) = &IMATH_NAMESPACE::Frustum<T>::set;
const char *name = FrustumName<T>::value;
class_< Frustum<T> > frustum_class(name,name,init<Frustum<T> >("copy construction"));
frustum_class
.def(init<>("Frustum() default construction"))
.def(init<T,T,T,T,T,T,bool>("Frustum(nearPlane,farPlane,left,right,top,bottom,ortho) construction"))
.def(init<T,T,T,T,T>("Frustum(nearPlane,farPlane,fovx,fovy,aspect) construction"))
.def(self == self)
.def(self != self)
.def("__repr__",&Frustum_repr<T>)
.def("set", set1,
"F.set(nearPlane, farPlane, left, right, top, bottom, "
"[ortho])\n"
"F.set(nearPlane, farPlane, fovx, fovy, aspect) "
" -- sets the entire state of "
"frustum F as specified. Only one of "
"fovx or fovy may be non-zero.")
.def("set", set2)
.def("modifyNearAndFar", &modifyNearAndFar<T>,
"F.modifyNearAndFar(nearPlane, farPlane) -- modifies "
"the already-valid frustum F as specified")
.def("setOrthographic", &Frustum<T>::setOrthographic,
"F.setOrthographic(b) -- modifies the "
"already-valid frustum F to be orthographic "
"or not")
.def("nearPlane", &Frustum<T>::nearPlane,
"F.nearPlane() -- returns the coordinate of the "
"near clipping plane of frustum F")
.def("farPlane", &Frustum<T>::farPlane,
"F.farPlane() -- returns the coordinate of the "
"far clipping plane of frustum F")
// The following two functions provide backwards compatibility
// with the previous API for this class.
.def("near", &Frustum<T>::nearPlane,
"F.near() -- returns the coordinate of the "
"near clipping plane of frustum F")
.def("far", &Frustum<T>::farPlane,
"F.far() -- returns the coordinate of the "
"far clipping plane of frustum F")
.def("left", &Frustum<T>::left,
"F.left() -- returns the left coordinate of "
"the near clipping window of frustum F")
.def("right", &Frustum<T>::right,
"F.right() -- returns the right coordinate of "
"the near clipping window of frustum F")
.def("top", &Frustum<T>::top,
"F.top() -- returns the top coordinate of "
"the near clipping window of frustum F")
.def("bottom", &Frustum<T>::bottom,
"F.bottom() -- returns the bottom coordinate "
"of the near clipping window of frustum F")
.def("orthographic", &Frustum<T>::orthographic,
"F.orthographic() -- returns whether frustum "
"F is orthographic or not")
.def("planes", planes1<T>,
"F.planes([M]) -- returns a sequence of 6 "
"Plane3s, the sides of the frustum F "
"(top, right, bottom, left, nearPlane, farPlane), "
"optionally transformed by the matrix M "
"if specified")
.def("planes", planes2<T>)
.def("planes", planes3<T>)
.def("planes", planes4<T>)
.def("fovx", &fovx<T>,
"F.fovx() -- derives and returns the "
"x field of view (in radians) for frustum F")
.def("fovy", &fovy<T>,
"F.fovy() -- derives and returns the "
"y field of view (in radians) for frustum F")
.def("aspect", &aspect<T>,
"F.aspect() -- derives and returns the "
"aspect ratio for frustum F")
.def("projectionMatrix", &projectionMatrix<T>,
"F.projectionMatrix() -- derives and returns "
"the projection matrix for frustum F")
.def("window", &window<T>,
"F.window(l,r,b,t) -- takes a rectangle in "
"the screen space (i.e., -1 <= l <= r <= 1, "
"-1 <= b <= t <= 1) of F and returns a new "
"Frustum whose near clipping-plane window "
"is that rectangle in local space")
.def("projectScreenToRay", &projectScreenToRay<T>,
"F.projectScreenToRay(V) -- returns a Line3 "
"through V, a V2 point in screen space")
.def("projectScreenToRay", &projectScreenToRayTuple<T>)
.def("projectPointToScreen", &projectPointToScreen<T>,
"F.projectPointToScreen(V) -- returns the "
"projection of V3 V into screen space")
.def("projectPointToScreen", &projectPointToScreenTuple<T>)
.def("projectPointToScreen", &projectPointToScreenObj<T>)
.def("ZToDepth", &ZToDepth<T>,
"F.ZToDepth(z, zMin, zMax) -- returns the "
"depth (Z in the local space of the "
"frustum F) corresponding to z (a result of "
"transformation by F's projection matrix) "
"after normalizing z to be between zMin "
"and zMax")
.def("normalizedZToDepth", &normalizedZToDepth<T>,
"F.normalizedZToDepth(z) -- returns the "
"depth (Z in the local space of the "
"frustum F) corresponding to z (a result of "
"transformation by F's projection matrix), "
"which is assumed to have been normalized "
"to [-1, 1]")
.def("DepthToZ", &DepthToZ<T>,
"F.DepthToZ(depth, zMin, zMax) -- converts "
"depth (Z in the local space of the frustum "
"F) to z (a result of transformation by F's "
"projection matrix) which is normalized to "
"[zMin, zMax]")
.def("worldRadius", &worldRadius<T>,
"F.worldRadius(V, r) -- returns the radius "
"in F's local space corresponding to the "
"point V and radius r in screen space")
.def("worldRadius", &worldRadiusTuple<T>)
.def("screenRadius", &screenRadius<T>,
"F.screenRadius(V, r) -- returns the radius "
"in screen space corresponding to "
"the point V and radius r in F's local "
"space")
.def("screenRadius", &screenRadiusTuple<T>)
;
decoratecopy(frustum_class);
return frustum_class;
}
template <class T,class T2>
struct IsVisibleTask : public Task
{
const IMATH_NAMESPACE::FrustumTest<T>& frustumTest;
const PyImath::FixedArray<T2>& points;
PyImath::FixedArray<int>& results;
IsVisibleTask(const IMATH_NAMESPACE::FrustumTest<T>& ft, const PyImath::FixedArray<T2> &p, PyImath::FixedArray<int> &r)
: frustumTest(ft), points(p), results(r) {}
void execute(size_t start, size_t end)
{
for(size_t p = start; p < end; ++p)
results[p] = frustumTest.isVisible(IMATH_NAMESPACE::Vec3<T>(points[p]));
}
};
template <class T,class T2>
PyImath::FixedArray<int>
frustumTest_isVisible(IMATH_NAMESPACE::FrustumTest<T>& ft, const PyImath::FixedArray<T2>& points)
{
size_t numPoints = points.len();
PyImath::FixedArray<int> mask(numPoints);
IsVisibleTask<T,T2> task(ft,points,mask);
dispatchTask(task,numPoints);
return mask;
}
template <class T>
class_<FrustumTest<T> >
register_FrustumTest()
{
const char *name = FrustumTestName<T>::value;
bool (FrustumTest<T>::*isVisibleS)(const Sphere3<T> &) const = &FrustumTest<T>::isVisible;
bool (FrustumTest<T>::*isVisibleB)(const Box<Vec3<T> > &) const = &FrustumTest<T>::isVisible;
bool (FrustumTest<T>::*isVisibleV)(const Vec3<T> &) const = &FrustumTest<T>::isVisible;
bool (FrustumTest<T>::*completelyContainsS)(const Sphere3<T> &) const = &FrustumTest<T>::completelyContains;
bool (FrustumTest<T>::*completelyContainsB)(const Box<Vec3<T> > &) const = &FrustumTest<T>::completelyContains;
class_< FrustumTest<T> > frustumtest_class(name,name,init<const IMATH_NAMESPACE::Frustum<T>&,const IMATH_NAMESPACE::Matrix44<T>&>("create a frustum test object from a frustum and transform"));
frustumtest_class
.def("isVisible",isVisibleS)
.def("isVisible",isVisibleB)
.def("isVisible",isVisibleV)
.def("isVisible",&frustumTest_isVisible<T,IMATH_NAMESPACE::V3f>)
.def("completelyContains",completelyContainsS)
.def("completelyContains",completelyContainsB)
;
decoratecopy(frustumtest_class);
return frustumtest_class;
}
template PYIMATH_EXPORT class_<Frustum<float> > register_Frustum<float>();
template PYIMATH_EXPORT class_<Frustum<double> > register_Frustum<double>();
template PYIMATH_EXPORT class_<FrustumTest<float> > register_FrustumTest<float>();
template PYIMATH_EXPORT class_<FrustumTest<double> > register_FrustumTest<double>();
}

View File

@ -0,0 +1,106 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathFrustum_h_
#define _PyImathFrustum_h_
#include <Python.h>
#include <boost/python.hpp>
//#include <PyImath.h>
#include <ImathFrustum.h>
#include <ImathFrustumTest.h>
#include <PyImath.h>
namespace PyImath {
template <class T> boost::python::class_<IMATH_NAMESPACE::Frustum<T> > register_Frustum();
template <class T> boost::python::class_<IMATH_NAMESPACE::FrustumTest<T> > register_FrustumTest();
//
// Other code in the Zeno code base assumes the existance of a class with the
// same name as the Imath class, and with static functions wrap() and
// convert() to produce a PyImath object from an Imath object and vice-versa,
// respectively. The class Boost generates from the Imath class does not
// have these properties, so we define a companion class here.
// The template argument, T, is the element type (e.g.,float, double).
template <class T>
class F {
public:
static PyObject * wrap (const IMATH_NAMESPACE::Frustum<T> &f);
static int convert (PyObject *p, IMATH_NAMESPACE::Frustum<T> *f);
};
template <class T>
PyObject *
F<T>::wrap (const IMATH_NAMESPACE::Frustum<T> &f)
{
typename boost::python::return_by_value::apply < IMATH_NAMESPACE::Frustum<T> >::type converter;
PyObject *p = converter (f);
return p;
}
template <class T>
int
F<T>::convert (PyObject *p, IMATH_NAMESPACE::Frustum<T> *f)
{
boost::python::extract <IMATH_NAMESPACE::Frustumf> extractorEf (p);
if (extractorEf.check())
{
IMATH_NAMESPACE::Frustumf e = extractorEf();
f->set (T(e.nearPlane()), T(e.farPlane()), T(e.left()), T(e.right()),
T(e.top()), T(e.bottom()), e.orthographic());
return 1;
}
boost::python::extract <IMATH_NAMESPACE::Frustumd> extractorEd (p);
if (extractorEd.check())
{
IMATH_NAMESPACE::Frustumd e = extractorEd();
f->set (T(e.nearPlane()), T(e.farPlane()), T(e.left()), T(e.right()),
T(e.top()), T(e.bottom()), e.orthographic());
return 1;
}
return 0;
}
typedef F<float> Frustumf;
typedef F<double> Frustumd;
}
#endif

View File

@ -0,0 +1,462 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 <PyImathFun.h>
#include <PyImathDecorators.h>
#include <PyImathExport.h>
#include <PyImathAutovectorize.h>
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/format.hpp>
#include <ImathVec.h>
#include <ImathMatrixAlgo.h>
#include <ImathFun.h>
namespace PyImath {
using namespace boost::python;
using namespace PyImath;
namespace {
template <class T>
struct rotationXYZWithUpDir_op
{
static IMATH_NAMESPACE::Vec3<T>
apply(const IMATH_NAMESPACE::Vec3<T> &from, const IMATH_NAMESPACE::Vec3<T> &to,
const IMATH_NAMESPACE::Vec3<T> &up)
{
IMATH_NAMESPACE::Vec3<T> retval;
IMATH_NAMESPACE::extractEulerXYZ(IMATH_NAMESPACE::rotationMatrixWithUpDir(from,to,up),retval);
return retval;
}
};
template <class T>
struct abs_op
{
static T
apply(T value)
{
return IMATH_NAMESPACE::abs<T>(value);
}
};
template <class T>
struct sign_op
{
static T
apply(T value)
{
return IMATH_NAMESPACE::sign<T>(value);
}
};
template <class T>
struct log_op
{
static T
apply(T value)
{
return ::log(value);
}
};
template <class T>
struct log10_op
{
static T
apply(T value)
{
return ::log10(value);
}
};
template <class T>
struct lerp_op
{
static T
apply(T a, T b, T t)
{
return IMATH_NAMESPACE::lerp<T>(a,b,t);
}
};
template <class T>
struct ulerp_op
{
static T
apply(T a, T b, T t)
{
return IMATH_NAMESPACE::ulerp<T>(a,b,t);
}
};
template <class T>
struct lerpfactor_op
{
static T
apply(T a, T b, T t)
{
return IMATH_NAMESPACE::lerpfactor<T>(a,b,t);
}
};
template <class T>
struct clamp_op
{
static T
apply(T value, T low, T high)
{
return IMATH_NAMESPACE::clamp<T>(value,low,high);
}
};
template <class T>
struct cmp_op
{
static T
apply(T value)
{
return IMATH_NAMESPACE::cmp<T>(value);
}
};
template <class T>
struct cmpt_op
{
static T
apply(T value)
{
return IMATH_NAMESPACE::cmpt<T>(value);
}
};
template <class T>
struct iszero_op
{
static T
apply(T value)
{
return IMATH_NAMESPACE::iszero<T>(value);
}
};
template <class T>
struct equal_op
{
static T
apply(T value)
{
return IMATH_NAMESPACE::equal<T>(value);
}
};
template <class T>
struct floor_op
{
static int
apply(T value)
{
return IMATH_NAMESPACE::floor<T>(value);
}
};
template <class T>
struct ceil_op
{
static int
apply(T value)
{
return IMATH_NAMESPACE::ceil<T>(value);
}
};
template <class T>
struct trunc_op
{
static int
apply(T value)
{
return IMATH_NAMESPACE::trunc<T>(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<abs_op<int>,boost::mpl::true_>(
"abs",
"return the absolute value of 'value'",
(arg("value")));
PyImath::generate_bindings<abs_op<float>,boost::mpl::true_>(
"abs",
"return the absolute value of 'value'",
(arg("value")));
PyImath::generate_bindings<abs_op<double>,boost::mpl::true_>(
"abs",
"return the absolute value of 'value'",
(arg("value")));
PyImath::generate_bindings<sign_op<int>,boost::mpl::true_>(
"sign",
"return 1 or -1 based on the sign of 'value'",
(arg("value")));
PyImath::generate_bindings<sign_op<float>,boost::mpl::true_>(
"sign",
"return 1 or -1 based on the sign of 'value'",
(arg("value")));
PyImath::generate_bindings<sign_op<double>,boost::mpl::true_>(
"sign",
"return 1 or -1 based on the sign of 'value'",
(arg("value")));
PyImath::generate_bindings<log_op<float>,boost::mpl::true_>(
"log",
"return the natural log of 'value'",
(arg("value")));
PyImath::generate_bindings<log_op<double>,boost::mpl::true_>(
"log",
"return the natural log of 'value'",
(arg("value")));
PyImath::generate_bindings<log10_op<float>,boost::mpl::true_>(
"log10",
"return the base 10 log of 'value'",
(arg("value")));
PyImath::generate_bindings<log10_op<double>,boost::mpl::true_>(
"log10",
"return the base 10 log of 'value'",
(arg("value")));
PyImath::generate_bindings<lerp_op<float>,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<lerp_op<double>,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<lerpfactor_op<float>,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<lerpfactor_op<double>,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<clamp_op<int>,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<clamp_op<float>,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<clamp_op<double>,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<float>);
def("cmp", IMATH_NAMESPACE::cmp<double>);
def("cmpt", IMATH_NAMESPACE::cmpt<float>);
def("cmpt", IMATH_NAMESPACE::cmpt<double>);
def("iszero", IMATH_NAMESPACE::iszero<float>);
def("iszero", IMATH_NAMESPACE::iszero<double>);
def("equal", IMATH_NAMESPACE::equal<float, float, float>);
def("equal", IMATH_NAMESPACE::equal<double, double, double>);
PyImath::generate_bindings<floor_op<float>,boost::mpl::true_>(
"floor",
"return the closest integer less than or equal to 'value'",
(arg("value")));
PyImath::generate_bindings<floor_op<double>,boost::mpl::true_>(
"floor",
"return the closest integer less than or equal to 'value'",
(arg("value")));
PyImath::generate_bindings<ceil_op<float>,boost::mpl::true_>(
"ceil",
"return the closest integer greater than or equal to 'value'",
(arg("value")));
PyImath::generate_bindings<ceil_op<double>,boost::mpl::true_>(
"ceil",
"return the closest integer greater than or equal to 'value'",
(arg("value")));
PyImath::generate_bindings<trunc_op<float>,boost::mpl::true_>(
"trunc",
"return the closest integer with magnitude less than or equal to 'value'",
(arg("value")));
PyImath::generate_bindings<trunc_op<double>,boost::mpl::true_>(
"trunc",
"return the closest integer with magnitude less than or equal to 'value'",
(arg("value")));
PyImath::generate_bindings<divs_op,boost::mpl::true_,boost::mpl::true_>(
"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_op,boost::mpl::true_,boost::mpl::true_>(
"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_op,boost::mpl::true_,boost::mpl::true_>(
"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_op,boost::mpl::true_,boost::mpl::true_>(
"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_op,boost::mpl::true_,boost::mpl::true_>(
"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_op,boost::mpl::true_,boost::mpl::true_>(
"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<rotationXYZWithUpDir_op<float>,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

View File

@ -0,0 +1,46 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathFun_h_
#define _PyImathFun_h_
#include <PyImathExport.h>
namespace PyImath {
PYIMATH_EXPORT void register_functions();
}
#endif

View File

@ -0,0 +1,587 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 <PyImathLine.h>
#include "PyImathDecorators.h"
#include "PyImathExport.h"
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/format.hpp>
#include <PyImath.h>
#include <PyImathVec.h>
#include <PyImathMathExc.h>
#include <ImathLineAlgo.h>
#include <ImathMatrix.h>
#include <Iex.h>
namespace PyImath{
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template <class T> struct LineName {static const char *value;};
template <> const char *LineName<float>::value = "Line3f";
template <> const char *LineName<double>::value = "Line3d";
template <class T>
static Line3<T> *
Line3_construct_default()
{
Vec3<T> point1(T (0), T(0), T(0));
Vec3<T> point2(T (1), T(0), T(0));
return new Line3<T>(point1, point2);
}
template <class T>
static Line3<T> *
Line3_tuple_construct(const tuple &t0, const tuple &t1)
{
Vec3<T> v0, v1;
if(t0.attr("__len__")() == 3 && t1.attr("__len__")() == 3)
{
v0.x = extract<T>(t0[0]);
v0.y = extract<T>(t0[1]);
v0.z = extract<T>(t0[2]);
v1.x = extract<T>(t1[0]);
v1.y = extract<T>(t1[1]);
v1.z = extract<T>(t1[2]);
return new Line3<T>(v0, v1);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Line3 expects tuple of length 3");
}
template <class T, class S>
static Line3<T> *
Line3_line_construct(const Line3<S> &line)
{
Line3<T> *l = new Line3<T>;
l->pos = line.pos;
l->dir = line.dir;
return l;
}
template <class T>
static void
set1(Line3<T> &line, const Vec3<T> &p0, const Vec3<T> &p1)
{
MATH_EXC_ON;
line.set (p0, p1);
}
template <class T>
static void
setTuple(Line3<T> &line, const tuple &t0, const tuple &t1)
{
MATH_EXC_ON;
Vec3<T> v0, v1;
if(t0.attr("__len__")() == 3 && t1.attr("__len__")() == 3)
{
v0.x = extract<T>(t0[0]);
v0.y = extract<T>(t0[1]);
v0.z = extract<T>(t0[2]);
v1.x = extract<T>(t1[0]);
v1.y = extract<T>(t1[1]);
v1.z = extract<T>(t1[2]);
line.set(v0, v1);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Line3 expects tuple of length 3");
}
template <class T>
static Vec3<T>
pointAt(Line3<T> &line, T t)
{
MATH_EXC_ON;
return line.operator()(t);
}
template <class T>
static T
distanceTo1(Line3<T> &line, Vec3<T> &p)
{
MATH_EXC_ON;
return line.distanceTo(p);
}
template <class T>
static T
distanceTo2(Line3<T> &line, Line3<T> &other)
{
MATH_EXC_ON;
return line.distanceTo(other);
}
template <class T>
static T
distanceToTuple(Line3<T> line, const tuple &t)
{
Vec3<T> v;
if(t.attr("__len__")() == 3)
{
v.x = extract<T>(t[0]);
v.y = extract<T>(t[1]);
v.z = extract<T>(t[2]);
return line.distanceTo(v);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Line3 expects tuple of length 3");
}
template <class T>
static Vec3<T>
closestPointTo1(Line3<T> line, const Vec3<T> &p)
{
MATH_EXC_ON;
return line.closestPointTo(p);
}
template <class T>
static Vec3<T>
closestPointTo2(Line3<T> line, const Line3<T> &other)
{
MATH_EXC_ON;
return line.closestPointTo(other);
}
template <class T>
static Vec3<T>
closestPointToTuple(Line3<T> line, const tuple &t)
{
MATH_EXC_ON;
Vec3<T> v;
if(t.attr("__len__")() == 3)
{
v.x = extract<T>(t[0]);
v.y = extract<T>(t[1]);
v.z = extract<T>(t[2]);
return line.closestPointTo(v);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Line3 expects tuple of length 3");
}
template <class T>
static Vec3<T>
getPosition(Line3<T> &line)
{
return line.pos;
}
template <class T>
static void
setPosition(Line3<T> &line, const Vec3<T> &pos)
{
line.pos = pos;
}
template <class T>
static void
setPositionTuple(Line3<T> &line, const tuple &t)
{
Vec3<T> pos;
if(t.attr("__len__")() == 3)
{
pos.x = extract<T>(t[0]);
pos.y = extract<T>(t[1]);
pos.z = extract<T>(t[2]);
line.pos = pos;
}
else
THROW(IEX_NAMESPACE::LogicExc, "Line3 expects tuple of length 3");
}
template <class T>
static Vec3<T>
getDirection(Line3<T> &line)
{
return line.dir;
}
template <class T>
static void
setDirection(Line3<T> &line, const Vec3<T> &dir)
{
MATH_EXC_ON;
line.dir = dir.normalized();
}
template <class T>
static void
setDirectionTuple(Line3<T> &line, const tuple &t)
{
MATH_EXC_ON;
Vec3<T> dir;
if(t.attr("__len__")() == 3)
{
dir.x = extract<T>(t[0]);
dir.y = extract<T>(t[1]);
dir.z = extract<T>(t[2]);
line.dir = dir.normalized();
}
else
THROW(IEX_NAMESPACE::LogicExc, "Line3 expects tuple of length 3");
}
template <class T>
static void
closestPoints1(Line3<T> &line1, const Line3<T> &line2, Vec3<T> &p0, Vec3<T> &p1)
{
MATH_EXC_ON;
IMATH_NAMESPACE::closestPoints(line1, line2, p0, p1);
}
template <class T>
static tuple
closestPoints2(Line3<T> &line1, const Line3<T> &line2)
{
MATH_EXC_ON;
Vec3<T> p0, p1;
IMATH_NAMESPACE::closestPoints(line1, line2, p0, p1);
tuple p0Tuple = make_tuple(p0.x,p0.y,p0.z);
tuple p1Tuple = make_tuple(p1.x,p1.y,p1.z);
#if !defined(_MSC_VER) || (_MSC_VER <= 1200)
tuple t = make_tuple(p0Tuple, p1Tuple);
return t;
#else
list v3;
v3.append(p0Tuple);
v3.append(p1Tuple);
return tuple(v3);
#endif
}
template <class T>
static Vec3<T>
closestVertex(Line3<T> &line, const Vec3<T> &v0, const Vec3<T> &v1, const Vec3<T> &v2)
{
MATH_EXC_ON;
return IMATH_NAMESPACE::closestVertex(v0, v1, v2, line);
}
template <class T>
static Vec3<T>
closestVertexTuple(Line3<T> &line, const tuple &t0, const tuple &t1, const tuple &t2)
{
MATH_EXC_ON;
if(t0.attr("__len__")() == 3 && t1.attr("__len__")() == 3 && t2.attr("__len__")() == 3)
{
Vec3<T> v0, v1, v2;
v0.x = extract<T>(t0[0]);
v0.y = extract<T>(t0[1]);
v0.z = extract<T>(t0[2]);
v1.x = extract<T>(t1[0]);
v1.y = extract<T>(t1[1]);
v1.z = extract<T>(t1[2]);
v2.x = extract<T>(t2[0]);
v2.y = extract<T>(t2[1]);
v2.z = extract<T>(t2[2]);
return IMATH_NAMESPACE::closestVertex(v0, v1, v2, line);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Line3 expects tuple of length 3");
}
template <class T>
static bool
intersect1(Line3<T> &line, const Vec3<T> &v0, const Vec3<T> &v1, const Vec3<T> &v2,
Vec3<T> &pt, Vec3<T> &barycentric, bool &front)
{
MATH_EXC_ON;
return IMATH_NAMESPACE::intersect(line, v0, v1, v2, pt, barycentric, front);
}
template <class T>
static object
intersect2(Line3<T> &line, const Vec3<T> &v0, const Vec3<T> &v1, const Vec3<T> &v2)
{
MATH_EXC_ON;
Vec3<T> pt, bar;
bool front;
if(IMATH_NAMESPACE::intersect(line, v0, v1, v2, pt, bar, front))
{
tuple t = make_tuple(pt, bar, front);
return t;
}
else
{
return object();
}
}
template <class T>
static tuple
intersectTuple(Line3<T> &line, const tuple &t0, const tuple &t1, const tuple &t2)
{
if(t0.attr("__len__")() == 3 && t1.attr("__len__")() == 3 && t2.attr("__len__")() == 3)
{
Vec3<T> v0, v1, v2, pt, bar;
bool front;
v0.x = extract<T>(t0[0]);
v0.y = extract<T>(t0[1]);
v0.z = extract<T>(t0[2]);
v1.x = extract<T>(t1[0]);
v1.y = extract<T>(t1[1]);
v1.z = extract<T>(t1[2]);
v2.x = extract<T>(t2[0]);
v2.y = extract<T>(t2[1]);
v2.z = extract<T>(t2[2]);
if(IMATH_NAMESPACE::intersect(line, v0, v1, v2, pt, bar, front))
{
tuple t = make_tuple(pt, bar, front);
return t;
}
else
{
tuple t;
return t;
}
}
else
THROW(IEX_NAMESPACE::LogicExc, "Line3 expects tuple of length 3");
}
template <class T>
static Vec3<T>
rotatePoint(Line3<T> &line, const Vec3<T> &p, const T &r)
{
MATH_EXC_ON;
return IMATH_NAMESPACE::rotatePoint(p, line, r);
}
template <class T>
static Vec3<T>
rotatePointTuple(Line3<T> &line, const tuple &t, const T &r)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 3)
{
Vec3<T> p;
p.x = extract<T>(t[0]);
p.y = extract<T>(t[1]);
p.z = extract<T>(t[2]);
return IMATH_NAMESPACE::rotatePoint(p, line, r);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Line3 expects tuple of length 3");
}
template <class T>
static std::string Line3_repr(const Line3<T> &v)
{
Vec3<T> v1 = v.pos;
Vec3<T> v2 = v.pos + v.dir;
PyObject *v1Obj = V3<T>::wrap (v1);
PyObject *v1ReprObj = PyObject_Repr (v1Obj);
std::string v1ReprStr = PyString_AsString (v1ReprObj);
Py_DECREF (v1ReprObj);
Py_DECREF (v1Obj);
PyObject *v2Obj = V3<T>::wrap (v2);
PyObject *v2ReprObj = PyObject_Repr (v2Obj);
std::string v2ReprStr = PyString_AsString (v2ReprObj);
Py_DECREF (v2ReprObj);
Py_DECREF (v2Obj);
std::stringstream stream;
stream << LineName<T>::value << "(" << v1ReprStr << ", " << v2ReprStr << ")";
return stream.str();
}
template <class T>
static bool
equal(const Line3<T> &l1, const Line3<T> &l2)
{
if(l1.pos == l2.pos && l1.dir == l2.dir)
return true;
else
return false;
}
template <class T>
static bool
notequal(const Line3<T> &l1, const Line3<T> &l2)
{
if(l1.pos != l2.pos || l1.dir != l2.dir)
return true;
else
return false;
}
template <class T>
class_<Line3<T> >
register_Line()
{
const char *name = LineName<T>::value;
class_<Line3<T> > line_class(name);
line_class
.def("__init__", make_constructor(Line3_construct_default<T>), "initialize point to (0,0,0) and direction to (1,0,0)")
.def("__init__", make_constructor(Line3_tuple_construct<T>))
.def("__init__", make_constructor(Line3_line_construct<T,float>))
.def("__init__", make_constructor(Line3_line_construct<T,double>))
.def(init<const Vec3<float> &, const Vec3<float> &>("Line3(point1, point2) construction"))
.def(init<const Vec3<double> &, const Vec3<double> &>("Line3(point1, point2) construction"))
.def(self * Matrix44<T>())
.def("__eq__", &equal<T>)
.def("__ne__", &notequal<T>)
.def_readwrite("pos", &Line3<T>::pos)
.def_readwrite("dir", &Line3<T>::dir)
.def("pos", &getPosition<T>,
"l.pos() -- returns the start point of line l")
.def("dir", &getDirection<T>,
"l.dir() -- returns the direction of line l\n")
.def("setPos", &setPosition<T>,
"l.setPos(p) -- sets the start point of line l to p")
.def("setPos", &setPositionTuple<T>)
.def("setDir", &setDirection<T>,
"l.setDir(d) -- sets the direction of line l\n"
"to d.normalized().\n")
.def("setDir", &setDirectionTuple<T>)
.def("set", &set1<T>,
"l.set(p1, p2) -- sets the start point\n"
"and direction of line l by calling\n"
" l.setPos (p1)\n"
" l.setDir (p2 - p1)\n")
.def("set", &setTuple<T>)
.def("pointAt", &pointAt<T>,
"l.pointAt(t) -- returns l.pos() + t * l.dir()")
.def("distanceTo", &distanceTo1<T>,
"l.distanceTo(p) -- returns the distance from\n"
" line l to point p\n")
.def("distanceTo", &distanceTo2<T>,
"l1.distanceTo(l2) -- returns the distance from\n"
" line l1 to line l2\n")
.def("distanceTo", &distanceToTuple<T>)
.def("closestPointTo", &closestPointTo1<T>,
"l.closestPointTo(p) -- returns the point on\n"
" line l that is closest to point p\n"
"\n")
.def("closestPointTo", &closestPointToTuple<T>)
.def("closestPointTo", &closestPointTo2<T>,
"l1.closestPointTo(l2) -- returns the point on\n"
" line l1 that is closest to line l2\n")
.def("closestPoints", &closestPoints1<T>,
"l1.closestPoints(l2,p0,p1)")
.def("closestPoints", &closestPoints2<T>,
"l1.closestPoints(l2) -- returns a tuple with\n"
"two points:\n"
" (l1.closestPoint(l2), l2.closestPoint(l1)\n")
.def("closestTriangleVertex", &closestVertex<T>,
"l.closestTriangleVertex(v0, v1, v2) -- returns\n"
"a copy of v0, v1, or v2, depending on which is\n"
"closest to line l.\n")
.def("closestTriangleVertex", &closestVertexTuple<T>)
.def("intersectWithTriangle", &intersect2<T>)
.def("intersectWithTriangle", &intersect1<T>,
"l.intersectWithTriangle(v0, v1, v2) -- computes the\n"
"intersection of line l and triangle (v0, v1, v2).\n"
"\n"
"If the line and the triangle do not intersect,\n"
"None is returned.\n"
""
"If the line and the triangle intersect, a tuple\n"
"(p, b, f) is returned:\n"
"\n"
" p intersection point in 3D space\n"
"\n"
" b intersection point in barycentric coordinates\n"
"\n"
" f 1 if the line hits the triangle from the\n"
" front (((v2-v1) % (v1-v2)) ^ l.dir() < 0),\n"
" 0 if the line hits the trianble from the\n"
" back\n"
"\n")
.def("intersectWithTriangle", &intersectTuple<T>)
.def("rotatePoint", &rotatePoint<T>,
"l.rotatePoint(p,r) -- rotates point p around\n"
"line by angle r (in radians), and returns the\n"
"result (p is not modified)\n")
.def("rotatePoint", &rotatePointTuple<T>)
.def("__repr__",&Line3_repr<T>)
;
decoratecopy(line_class);
return line_class;
}
template PYIMATH_EXPORT class_<Line3<float> > register_Line<float>();
template PYIMATH_EXPORT class_<Line3<double> > register_Line<double>();
} // namespace PyImath

View File

@ -0,0 +1,103 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathLine_h_
#define _PyImathLine_h_
#include <Python.h>
#include <boost/python.hpp>
#include <ImathLine.h>
#include <PyImath.h>
namespace PyImath {
template <class T> boost::python::class_<IMATH_NAMESPACE::Line3<T> > register_Line();
//
// Other code in the Zeno code base assumes the existance of a class with the
// same name as the Imath class, and with static functions wrap() and
// convert() to produce a PyImath object from an Imath object and vice-versa,
// respectively. The class Boost generates from the Imath class does not
// have these properties, so we define a companion class here.
// The template argument, T, is the element type (e.g.,float, double).
template <class T>
class L3 {
public:
static PyObject * wrap (const IMATH_NAMESPACE::Line3<T> &l);
static int convert (PyObject *p, IMATH_NAMESPACE::Line3<T> *l);
};
template <class T>
PyObject *
L3<T>::wrap (const IMATH_NAMESPACE::Line3<T> &l)
{
typename boost::python::return_by_value::apply < IMATH_NAMESPACE::Line3<T> >::type converter;
PyObject *p = converter (l);
return p;
}
template <class T>
int
L3<T>::convert (PyObject *p, IMATH_NAMESPACE::Line3<T> *l)
{
boost::python::extract <IMATH_NAMESPACE::Line3f> extractorLf (p);
if (extractorLf.check())
{
IMATH_NAMESPACE::Line3f e = extractorLf();
l->pos.setValue (e.pos);
l->dir.setValue (e.dir);
return 1;
}
boost::python::extract <IMATH_NAMESPACE::Line3d> extractorLd (p);
if (extractorLd.check())
{
IMATH_NAMESPACE::Line3d e = extractorLd();
l->pos.setValue (e.pos);
l->dir.setValue (e.dir);
return 1;
}
return 0;
}
typedef L3<float> Line3f;
typedef L3<double> Line3d;
}
#endif

View File

@ -0,0 +1,59 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 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 <PyImathM44Array.h>
#include <PyImathMatrix.h>
#include <PyImathExport.h>
namespace PyImath {
template<> PYIMATH_EXPORT const char*
M44dArray::name()
{
return "M44dArray";
}
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Matrix44<double>
FixedArrayDefaultValue<IMATH_NAMESPACE::Matrix44<double> >::value()
{
return IMATH_NAMESPACE::Matrix44<double>();
}
template<> PYIMATH_EXPORT const char*
M44ArrayName<IMATH_NAMESPACE::M44d>::value()
{
return "M44dArray";
}
} // namespace PyImath

View File

@ -0,0 +1,72 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathM44Array_h_
#define _PyImathM44Array_h_
#include <boost/python.hpp>
#include <ImathMatrix.h>
#include <PyImathOperators.h>
namespace PyImath {
using namespace boost::python;
template <class T> struct M44ArrayName { static const char *value(); };
template <class T>
static void
setM44ArrayItem(FixedArray<IMATH_NAMESPACE::Matrix44<T> > &ma,
Py_ssize_t index,
const IMATH_NAMESPACE::Matrix44<T> &m)
{
ma[ma.canonical_index(index)] = m;
}
template <class T>
class_<FixedArray<IMATH_NAMESPACE::Matrix44<T> > >
register_M44Array()
{
class_<FixedArray<IMATH_NAMESPACE::Matrix44<T> > > m44Array_class = FixedArray<IMATH_NAMESPACE::Matrix44<T> >::register_("Fixed length array of IMATH_NAMESPACE::M44");
m44Array_class
.def("__setitem__", &setM44ArrayItem<T>)
;
return m44Array_class;
}
} // namespace PyImath
#endif // _PyImathM44Array_h_

View File

@ -0,0 +1,44 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathMathExc_h_
#define _PyImathMathExc_h_
#include <IexMathFloatExc.h>
#define MATH_EXC_ON IEX_NAMESPACE::MathExcOn mathexcon (IEX_NAMESPACE::IEEE_OVERFLOW | \
IEX_NAMESPACE::IEEE_DIVZERO | \
IEX_NAMESPACE::IEEE_INVALID)
#endif

View File

@ -0,0 +1,187 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathMatrix_h_
#define _PyImathMatrix_h_
#include <Python.h>
#include <boost/python.hpp>
#include <PyImath.h>
#include <ImathMatrix.h>
#include <ImathMatrixAlgo.h>
#include <PyImath.h>
namespace PyImath {
template <class T> boost::python::class_<IMATH_NAMESPACE::Matrix33<T> > register_Matrix33();
template <class T> boost::python::class_<IMATH_NAMESPACE::Matrix44<T> > register_Matrix44();
template <class T> boost::python::class_<FixedArray<IMATH_NAMESPACE::Matrix44<T> > > register_M44Array();
template <class T> boost::python::class_<FixedArray<IMATH_NAMESPACE::Matrix33<T> > > register_M33Array();
typedef FixedArray<IMATH_NAMESPACE::Matrix33<float> > M33fArray;
typedef FixedArray<IMATH_NAMESPACE::Matrix33<double> > M33dArray;
typedef FixedArray<IMATH_NAMESPACE::Matrix44<float> > M44fArray;
typedef FixedArray<IMATH_NAMESPACE::Matrix44<double> > M44dArray;
//
// Other code in the Zeno code base assumes the existance of a class with the
// same name as the Imath class, and with static functions wrap() and
// convert() to produce a PyImath object from an Imath object and vice-versa,
// respectively. The class Boost generates from the Imath class does not
// have these properties, so we define a companion class here.
// The template argument, T, is the element type (e.g.,float, double).
template <class T>
class M33 {
public:
static PyObject * wrap (const IMATH_NAMESPACE::Matrix33<T> &m);
static int convert (PyObject *p, IMATH_NAMESPACE::Matrix33<T> *m);
};
template <class T>
class M44 {
public:
static PyObject * wrap (const IMATH_NAMESPACE::Matrix44<T> &m);
static int convert (PyObject *p, IMATH_NAMESPACE::Matrix44<T> *m);
};
template <class T>
PyObject *
M33<T>::wrap (const IMATH_NAMESPACE::Matrix33<T> &m)
{
typename boost::python::return_by_value::apply < IMATH_NAMESPACE::Matrix33<T> >::type converter;
PyObject *p = converter (m);
return p;
}
template <class T>
PyObject *
M44<T>::wrap (const IMATH_NAMESPACE::Matrix44<T> &m)
{
typename boost::python::return_by_value::apply < IMATH_NAMESPACE::Matrix44<T> >::type converter;
PyObject *p = converter (m);
return p;
}
template <class T>
int
M33<T>::convert (PyObject *p, IMATH_NAMESPACE::Matrix33<T> *m)
{
boost::python::extract <IMATH_NAMESPACE::M33f> extractorMf (p);
if (extractorMf.check())
{
IMATH_NAMESPACE::M33f e = extractorMf();
m->setValue (e);
return 1;
}
boost::python::extract <IMATH_NAMESPACE::M33d> extractorMd (p);
if (extractorMd.check())
{
IMATH_NAMESPACE::M33d e = extractorMd();
m->setValue (e);
return 1;
}
return 0;
}
template <class T>
int
M44<T>::convert (PyObject *p, IMATH_NAMESPACE::Matrix44<T> *m)
{
boost::python::extract <IMATH_NAMESPACE::M44f> extractorMf (p);
if (extractorMf.check())
{
IMATH_NAMESPACE::M44f e = extractorMf();
m->setValue (e);
return 1;
}
boost::python::extract <IMATH_NAMESPACE::M44d> extractorMd (p);
if (extractorMd.check())
{
IMATH_NAMESPACE::M44d e = extractorMd();
m->setValue (e);
return 1;
}
return 0;
}
template <class Matrix>
boost::python::tuple
jacobiEigensolve(const Matrix& m)
{
typedef typename Matrix::BaseType T;
typedef typename Matrix::BaseVecType Vec;
// For the C++ version, we just assume that the passed-in matrix is
// symmetric, but we assume that many of our script users are less
// sophisticated and might get tripped up by this. Also, the cost
// of doing this check is likely miniscule compared to the Pythonic
// overhead.
// Give a fairly generous tolerance to account for possible epsilon drift:
const int d = Matrix::dimensions();
const T tol = std::sqrt(IMATH_NAMESPACE::limits<T>::epsilon());
for (int i = 0; i < d; ++i)
{
for (int j = i+1; j < d; ++j)
{
const T Aij = m[i][j],
Aji = m[j][i];
ASSERT (std::abs(Aij - Aji) < tol,
IEX_NAMESPACE::ArgExc,
"Symmetric eigensolve requires a symmetric matrix (matrix[i][j] == matrix[j][i]).");
}
}
Matrix tmp = m;
Matrix Q;
Vec S;
IMATH_NAMESPACE::jacobiEigenSolver (tmp, S, Q);
return boost::python::make_tuple (Q, S);
}
typedef M33<float> M33f;
typedef M33<double> M33d;
typedef M44<float> M44f;
typedef M44<double> M44d;
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,330 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathOperators_h_
#define _PyImathOperators_h_
#include <PyImathFixedArray.h>
#include <PyImathAutovectorize.h>
namespace PyImath {
template <class T1, class T2=T1, class Ret=T1>
struct op_add {
static inline Ret apply(const T1 &a, const T2 &b) { return a+b; }
};
template <class T1, class T2=T1, class Ret=T1>
struct op_sub {
static inline Ret apply(const T1 &a, const T2 &b) { return a-b; }
};
template <class T1, class T2=T1, class Ret=T1>
struct op_rsub {
static inline Ret apply(const T1 &a, const T2 &b) { return b-a; }
};
template <class T1, class T2=T1, class Ret=T1>
struct op_mul {
static inline Ret apply(const T1 &a, const T2 &b) { return a*b; }
};
template <class T1, class T2=T1, class Ret=T1>
struct op_div {
static inline Ret apply(const T1 &a, const T2 &b) { return a/b; }
};
template <class T1, class T2=T1, class Ret=T1>
struct op_mod {
static inline Ret apply(const T1 &a, const T2 &b) { return a%b; }
};
template <class T1, class T2=T1, class Ret=T1>
struct op_pow {
static inline Ret apply(const T1 &a, const T2 &b) { return std::pow(a,b); }
};
template <class T1, class T2=T1, class Ret=T1>
struct op_rpow {
static inline Ret apply(const T1 &a, const T2 &b) { return std::pow(b,a); }
};
template <class T1, class Ret=T1>
struct op_neg {
static inline Ret apply(const T1 &a) { return -a; }
};
template <class T1, class Ret=T1>
struct op_abs {
static inline Ret apply(const T1 &a) { return std::abs(a); }
};
template <class T1, class Ret=T1>
struct op_inverse {
static inline Ret apply(const T1 &a) { return ~a; }
};
template <class T1, class T2=T1, class Ret=T1>
struct op_lshift {
static inline Ret apply(const T1 &a, const T2 &b) { return a << b; }
};
template <class T1, class T2=T1, class Ret=T1>
struct op_rshift {
static inline Ret apply(const T1 &a, const T2 &b) { return a >> b; }
};
template <class T1, class T2=T1, class Ret=T1>
struct op_bitand {
static inline Ret apply(const T1 &a, const T2 &b) { return a & b; }
};
template <class T1, class T2=T1, class Ret=T1>
struct op_xor {
static inline Ret apply(const T1 &a, const T2 &b) { return a ^ b; }
};
template <class T1, class T2=T1, class Ret=T1>
struct op_bitor {
static inline Ret apply(const T1 &a, const T2 &b) { return a | b; }
};
template <class T1, class T2=T1>
struct op_iadd {
static inline void apply(T1 &a, const T2 &b) { a += b; }
};
template <class T1, class T2=T1>
struct op_isub {
static inline void apply(T1 &a, const T2 &b) { a -= b; }
};
template <class T1, class T2=T1>
struct op_imul {
static inline void apply(T1 &a, const T2 &b) { a *= b; }
};
template <class T1, class T2=T1>
struct op_idiv {
static inline void apply(T1 &a, const T2 &b) { a /= b; }
};
template <class T1, class T2=T1>
struct op_imod {
static inline void apply(T1 &a, const T2 &b) { a %= b; }
};
template <class T1, class T2=T1>
struct op_ipow {
static inline void apply(T1 &a, const T2 &b) { a = std::pow(a,b); }
};
template <class T1, class T2=T1>
struct op_ilshift {
static inline void apply(T1 &a, const T2 &b) { a <<= b; }
};
template <class T1, class T2=T1>
struct op_irshift {
static inline void apply(T1 &a, const T2 &b) { a >>= b; }
};
template <class T1, class T2=T1>
struct op_ixor {
static inline void apply(T1 &a, const T2 &b) { a ^= b; }
};
template <class T1, class T2=T1>
struct op_ibitand {
static inline void apply(T1 &a, const T2 &b) { a &= b; }
};
template <class T1, class T2=T1>
struct op_ibitor {
static inline void apply(T1 &a, const T2 &b) { a |= b; }
};
// the logical function return values default to 'int' for use
// as mask arrays.
template <class T1, class T2=T1, class Ret=int>
struct op_lt {
static inline Ret apply(const T1 &a, const T2 &b) { return a < b; }
};
template <class T1, class T2=T1, class Ret=int>
struct op_gt {
static inline Ret apply(const T1 &a, const T2 &b) { return a > b; }
};
template <class T1, class T2=T1, class Ret=int>
struct op_le {
static inline Ret apply(const T1 &a, const T2 &b) { return a <= b; }
};
template <class T1, class T2=T1, class Ret=int>
struct op_ge {
static inline Ret apply(const T1 &a, const T2 &b) { return a >= b; }
};
template <class T1, class T2=T1, class Ret=int>
struct op_eq {
static inline Ret apply(const T1 &a, const T2 &b) { return a == b; }
};
template <class T1, class T2=T1, class Ret=int>
struct op_ne {
static inline Ret apply(const T1 &a, const T2 &b) { return a != b; }
};
template <class T>
static T fa_reduce(const FixedArray<T> &a) {
T tmp(T(0)); // should use default construction but V3f doens't initialize
size_t len = a.len();
for (size_t i=0; i < len; ++i) tmp += a[i];
return tmp;
}
template <class T>
static T fa_min(const FixedArray<T> &a) {
T tmp(T(0));
size_t len = a.len();
if (len > 0)
tmp = a[0];
for (size_t i=1; i < len; ++i)
if (a[i] < tmp)
tmp = a[i];
return tmp;
}
template <class T>
static T fa_max(const FixedArray<T> &a) {
T tmp(T(0));
size_t len = a.len();
if (len > 0)
tmp = a[0];
for (size_t i=1; i < len; ++i)
if (a[i] > tmp)
tmp = a[i];
return tmp;
}
template <class T>
static void add_arithmetic_math_functions(boost::python::class_<FixedArray<T> > &c) {
using boost::mpl::true_;
using boost::mpl::false_;
generate_member_bindings<op_add<T>, true_ >(c,"__add__", "self+x", boost::python::args("x"));
generate_member_bindings<op_add<T>, false_>(c,"__radd__","x+self", boost::python::args("x"));
generate_member_bindings<op_sub<T>, true_ >(c,"__sub__", "self-x", boost::python::args("x"));
generate_member_bindings<op_rsub<T>,false_>(c,"__rsub__","x-self", boost::python::args("x"));
generate_member_bindings<op_mul<T>, true_ >(c,"__mul__", "self*x", boost::python::args("x"));
generate_member_bindings<op_mul<T>, false_>(c,"__rmul__","x*self", boost::python::args("x"));
generate_member_bindings<op_div<T>, true_ >(c,"__div__", "self/x", boost::python::args("x"));
generate_member_bindings<op_div<T>, true_ >(c,"__truediv__", "self/x", boost::python::args("x"));
generate_member_bindings<op_neg<T> >(c,"__neg__", "-x");
generate_member_bindings<op_iadd<T>,true_ >(c,"__iadd__","self+=x",boost::python::args("x"));
generate_member_bindings<op_isub<T>,true_ >(c,"__isub__","self-=x",boost::python::args("x"));
generate_member_bindings<op_imul<T>,true_ >(c,"__imul__","self*=x",boost::python::args("x"));
generate_member_bindings<op_idiv<T>,true_ >(c,"__idiv__","self/=x",boost::python::args("x"));
generate_member_bindings<op_idiv<T>,true_ >(c,"__itruediv__","self/=x",boost::python::args("x"));
c.def("reduce",&fa_reduce<T>);
}
template <class T>
static void add_reduction_functions(boost::python::class_<FixedArray<T> > &c) {
c.def("min",&fa_min<T>);
c.def("max",&fa_max<T>);
}
template <class T>
static void add_pow_math_functions(boost::python::class_<FixedArray<T> > &c) {
using boost::mpl::true_;
using boost::mpl::false_;
generate_member_bindings<op_pow<T>, true_ >(c,"__pow__", "self**x", boost::python::args("x"));
generate_member_bindings<op_rpow<T>,false_>(c,"__rpow__","x**self", boost::python::args("x"));
generate_member_bindings<op_ipow<T>,true_ >(c,"__ipow__","x**=self",boost::python::args("x"));
}
template <class T>
static void add_mod_math_functions(boost::python::class_<FixedArray<T> > &c) {
using boost::mpl::true_;
generate_member_bindings<op_mod<T>, true_>(c,"__mod__", "self%x", boost::python::args("x"));
generate_member_bindings<op_imod<T>,true_>(c,"__imod__","self%=x",boost::python::args("x"));
}
template <class T>
static void add_shift_math_functions(boost::python::class_<FixedArray<T> > &c) {
using boost::mpl::true_;
generate_member_bindings<op_lshift<T>, true_>(c,"__lshift__", "self<<x", boost::python::args("x"));
generate_member_bindings<op_ilshift<T>,true_>(c,"__ilshift__","self<<=x",boost::python::args("x"));
generate_member_bindings<op_rshift<T>, true_>(c,"__rshift__", "self>>x", boost::python::args("x"));
generate_member_bindings<op_irshift<T>,true_>(c,"__irshift__","self>>=x",boost::python::args("x"));
}
template <class T>
static void add_bitwise_math_functions(boost::python::class_<FixedArray<T> > &c) {
using boost::mpl::true_;
generate_member_bindings<op_bitand<T>, true_>(c,"__and__", "self&x", boost::python::args("x"));
generate_member_bindings<op_ibitand<T>,true_>(c,"__iand__","self&=x",boost::python::args("x"));
generate_member_bindings<op_bitor<T>, true_>(c,"__or__", "self|x", boost::python::args("x"));
generate_member_bindings<op_ibitor<T>, true_>(c,"__ior__", "self|=x",boost::python::args("x"));
generate_member_bindings<op_xor<T>, true_>(c,"__xor__", "self^x", boost::python::args("x"));
generate_member_bindings<op_ixor<T>, true_>(c,"__ixor__","self^=x",boost::python::args("x"));
}
template <class T>
static void add_comparison_functions(boost::python::class_<FixedArray<T> > &c) {
using boost::mpl::true_;
generate_member_bindings<op_eq<T>, true_>(c,"__eq__","self==x",boost::python::args("x"));
generate_member_bindings<op_ne<T>, true_>(c,"__ne__","self!=x",boost::python::args("x"));
}
template <class T>
static void add_ordered_comparison_functions(boost::python::class_<FixedArray<T> > &c) {
using boost::mpl::true_;
generate_member_bindings<op_lt<T>, true_>(c,"__lt__","self<x", boost::python::args("x"));
generate_member_bindings<op_le<T>, true_>(c,"__le__","self<=x",boost::python::args("x"));
generate_member_bindings<op_gt<T>, true_>(c,"__gt__","self>x", boost::python::args("x"));
generate_member_bindings<op_ge<T>, true_>(c,"__ge__","self>=x",boost::python::args("x"));
}
template <class S,class T>
static void add_explicit_construction_from_type(boost::python::class_<FixedArray<T> > &c) {
using namespace boost::python;
c.def(init<FixedArray<S> >("copy contents of other array into this one"));
}
}
#endif // _PyImathOperators_h_

View File

@ -0,0 +1,609 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 <PyImathPlane.h>
#include "PyImathDecorators.h"
#include "PyImathExport.h"
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/format.hpp>
#include <PyImath.h>
#include <PyImathVec.h>
#include <PyImathMathExc.h>
#include <Iex.h>
namespace PyImath{
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template <class T> struct PlaneName {static const char *value;};
template <> const char *PlaneName<float>::value = "Plane3f";
template <> const char *PlaneName<double>::value = "Plane3d";
template <class T>
static Plane3<T> *Plane3_construct_default()
{
Vec3<T> normal(T (1), T (0), T (0));
return new Plane3<T>(normal, T (0));
}
template <class T>
static Plane3<T> *Plane3_plane_construct(const object &planeObj)
{
MATH_EXC_ON;
extract < Plane3<float> > ef (planeObj);
extract < Plane3<double> > ed (planeObj);
Plane3<T> *p = 0;
if (ef.check())
{
Plane3<float> efp = ef();
p = new Plane3<T>;
p->normal = efp.normal;
p->distance = efp.distance;
}
else if (ed.check())
{
Plane3<double> edp = ed();
p = new Plane3<T>;
p->normal = edp.normal;
p->distance = edp.distance;
}
else
{
THROW(IEX_NAMESPACE::LogicExc, "invalid parameter passed to Plane constructor");
}
return p;
}
template <class T>
static Plane3<T> *Plane3_tuple_constructor1(const tuple &t, T distance)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 3)
{
Vec3<T> normal;
normal.x = extract<T>(t[0]);
normal.y = extract<T>(t[1]);
normal.z = extract<T>(t[2]);
return new Plane3<T>(normal, distance);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Plane3 expects tuple of length 3");
}
template <class T>
static Plane3<T> *Plane3_tuple_constructor2(const tuple &t0, const tuple &t1)
{
MATH_EXC_ON;
if(t0.attr("__len__")() == 3 && t1.attr("__len__")() == 3)
{
Vec3<T> point, normal;
point.x = extract<T>(t0[0]);
point.y = extract<T>(t0[1]);
point.z = extract<T>(t0[2]);
normal.x = extract<T>(t1[0]);
normal.y = extract<T>(t1[1]);
normal.z = extract<T>(t1[2]);
return new Plane3<T>(point, normal);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Plane3 expects tuples of length 3");
}
template <class T>
static Plane3<T> *Plane3_tuple_constructor3(const tuple &t0, const tuple &t1, const tuple &t2)
{
MATH_EXC_ON;
if(t0.attr("__len__")() == 3 && t1.attr("__len__")() == 3 && t2.attr("__len__")() == 3)
{
Vec3<T> point0, point1, point2;
point0.x = extract<T>(t0[0]);
point0.y = extract<T>(t0[1]);
point0.z = extract<T>(t0[2]);
point1.x = extract<T>(t1[0]);
point1.y = extract<T>(t1[1]);
point1.z = extract<T>(t1[2]);
point2.x = extract<T>(t2[0]);
point2.y = extract<T>(t2[1]);
point2.z = extract<T>(t2[2]);
return new Plane3<T>(point0, point1, point2);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Plane3 expects tuple of length 3");
}
template <class T>
static Plane3<T>
mul (const Plane3<T> &plane, const Matrix44<T> &M)
{
MATH_EXC_ON;
return plane * M;
}
template <class T>
static void
set1 (Plane3<T> &plane, const Vec3<T> &v, T t)
{
MATH_EXC_ON;
plane.set (v, t);
}
template <class T>
static void
set2 (Plane3<T> &plane, const Vec3<T> &v1, const Vec3<T> &v2)
{
MATH_EXC_ON;
plane.set (v1, v2);
}
template <class T>
static void
set3 (Plane3<T> &plane, const Vec3<T> &v1, const Vec3<T> &v2, const Vec3<T> &v3)
{
MATH_EXC_ON;
plane.set (v1, v2, v3);
}
template <class T>
static std::string Plane3_str(const Plane3<T> &plane)
{
std::stringstream stream;
PyObject *normalObj = V3<T>::wrap (plane.normal);
PyObject *normalReprObj = PyObject_Repr (normalObj);
std::string normalReprStr = PyString_AsString (normalReprObj);
Py_DECREF (normalReprObj);
Py_DECREF (normalObj);
stream << PlaneName<T>::value << "(" << normalReprStr << ", "
<< plane.distance << ")";
return stream.str();
}
// Non-specialized repr is same as str
template <class T>
static std::string Plane3_repr(const Plane3<T> &plane)
{
return Plane3_str(plane);
}
// Specialization for float to full precision
template <>
std::string Plane3_repr(const Plane3<float> &plane)
{
PyObject *normalObj = V3<float>::wrap (plane.normal);
PyObject *normalReprObj = PyObject_Repr (normalObj);
std::string normalReprStr = PyString_AsString (normalReprObj);
Py_DECREF (normalReprObj);
Py_DECREF (normalObj);
return (boost::format("%s(%s, %.9g)")
% PlaneName<float>::value
% normalReprStr.c_str()
% plane.distance).str();
}
// Specialization for double to full precision
template <>
std::string Plane3_repr(const Plane3<double> &plane)
{
PyObject *normalObj = V3<double>::wrap (plane.normal);
PyObject *normalReprObj = PyObject_Repr (normalObj);
std::string normalReprStr = PyString_AsString (normalReprObj);
Py_DECREF (normalReprObj);
Py_DECREF (normalObj);
return (boost::format("%s(%s, %.17g)")
% PlaneName<double>::value
% normalReprStr.c_str()
% plane.distance).str();
}
template <class T>
static T
distance(Plane3<T> &plane)
{
return plane.distance;
}
template <class T>
static Vec3<T>
normal(Plane3<T> &plane)
{
return plane.normal;
}
template <class T>
static void
setNormal(Plane3<T> &plane, const Vec3<T> &normal)
{
MATH_EXC_ON;
plane.normal = normal.normalized();
}
template <class T>
static void
setDistance(Plane3<T> &plane, const T &distance)
{
plane.distance = distance;
}
template <class T, class S>
static object intersectT(const Plane3<T> &plane, const Line3<S> &line)
{
MATH_EXC_ON;
T param;
Line3<T> l;
l.pos = line.pos;
l.dir = line.dir;
if(plane.intersectT(l, param))
return object(param);
return object();
}
template <class T>
static bool
intersect2(const Plane3<T> &plane, const Line3<T> &line, Vec3<T> &intersection)
{
MATH_EXC_ON;
return plane.intersect(line, intersection);
}
template <class T, class S>
static object
intersect1(const Plane3<T> &plane, const Line3<S> &line)
{
MATH_EXC_ON;
Vec3<T> intersection;
Line3<T> l;
l.pos = line.pos;
l.dir = line.dir;
if(plane.intersect(l, intersection))
return object(intersection);
return object();
}
template <class T>
static void
setTuple1(Plane3<T> &plane, const tuple &t, T distance)
{
MATH_EXC_ON;
if(t.attr("__len__")() == 3)
{
Vec3<T> normal;
normal.x = extract<T>(t[0]);
normal.y = extract<T>(t[1]);
normal.z = extract<T>(t[2]);
plane.set(normal, distance);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Plane3 expects tuple of length 3");
}
template <class T>
static void
setTuple2(Plane3<T> &plane, const tuple &t0, const tuple &t1)
{
MATH_EXC_ON;
if(t0.attr("__len__")() == 3 && t1.attr("__len__")() == 3)
{
Vec3<T> point, normal;
point.x = extract<T>(t0[0]);
point.y = extract<T>(t0[1]);
point.z = extract<T>(t0[2]);
normal.x = extract<T>(t1[0]);
normal.y = extract<T>(t1[1]);
normal.z = extract<T>(t1[2]);
plane.set(point, normal);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Plane3 expects tuples of length 3");
}
template <class T>
static void
setTuple3(Plane3<T> &plane, const tuple &t0, const tuple &t1, const tuple &t2)
{
MATH_EXC_ON;
if(t0.attr("__len__")() == 3 && t1.attr("__len__")() == 3 && t2.attr("__len__")() == 3)
{
Vec3<T> point0, point1, point2;
point0.x = extract<T>(t0[0]);
point0.y = extract<T>(t0[1]);
point0.z = extract<T>(t0[2]);
point1.x = extract<T>(t1[0]);
point1.y = extract<T>(t1[1]);
point1.z = extract<T>(t1[2]);
point2.x = extract<T>(t2[0]);
point2.y = extract<T>(t2[1]);
point2.z = extract<T>(t2[2]);
plane.set(point0, point1, point2);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Plane3 expects tuple of length 3");
}
template <class T>
static Vec3<T>
reflectPoint(Plane3<T> &plane, const Vec3<T> &p)
{
MATH_EXC_ON;
return plane.reflectPoint(p);
}
template <class T>
static Vec3<T>
reflectPointTuple(Plane3<T> &plane, const tuple &t)
{
MATH_EXC_ON;
Vec3<T> point;
if(t.attr("__len__")() == 3)
{
point.x = extract<T>(t[0]);
point.y = extract<T>(t[1]);
point.z = extract<T>(t[2]);
return plane.reflectPoint(point);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Plane3 expects tuple of length 3");
}
template <class T>
static T
distanceTo(Plane3<T> &plane, const Vec3<T> &v)
{
MATH_EXC_ON;
return plane.distanceTo(v);
}
template <class T>
static T
distanceToTuple(Plane3<T> &plane, const tuple &t)
{
MATH_EXC_ON;
Vec3<T> point;
if(t.attr("__len__")() == 3)
{
point.x = extract<T>(t[0]);
point.y = extract<T>(t[1]);
point.z = extract<T>(t[2]);
return plane.distanceTo(point);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Plane3 expects tuple of length 3");
}
template <class T>
static Vec3<T>
reflectVector(Plane3<T> &plane, const Vec3<T> &v)
{
MATH_EXC_ON;
return plane.reflectVector(v);
}
template <class T>
static Vec3<T>
reflectVectorTuple(Plane3<T> &plane, const tuple &t)
{
MATH_EXC_ON;
Vec3<T> point;
if(t.attr("__len__")() == 3)
{
point.x = extract<T>(t[0]);
point.y = extract<T>(t[1]);
point.z = extract<T>(t[2]);
return plane.reflectVector(point);
}
else
THROW(IEX_NAMESPACE::LogicExc, "Plane3 expects tuple of length 3");
}
template <class T>
static bool
equal(const Plane3<T> &p1, const Plane3<T> &p2)
{
if(p1.normal == p2.normal && p1.distance == p2.distance)
return true;
else
return false;
}
template <class T>
static bool
notequal(const Plane3<T> &p1, const Plane3<T> &p2)
{
if(p1.normal != p2.normal || p1.distance != p2.distance)
return true;
else
return false;
}
template <class T>
static Plane3<T>
negate(const Plane3<T> &plane)
{
MATH_EXC_ON;
Plane3<T> p;
p.set(-plane.normal, -plane.distance);
return p;
}
template <class T>
class_<Plane3<T> >
register_Plane()
{
const char *name = PlaneName<T>::value;
class_< Plane3<T> > plane_class(name);
plane_class
.def("__init__",make_constructor(Plane3_construct_default<T>),"initialize normal to (1,0,0), distance to 0")
.def("__init__",make_constructor(Plane3_tuple_constructor1<T>))
.def("__init__",make_constructor(Plane3_tuple_constructor2<T>))
.def("__init__",make_constructor(Plane3_tuple_constructor3<T>))
.def("__init__",make_constructor(Plane3_plane_construct<T>))
.def(init<const Vec3<T> &, T>("Plane3(normal, distance) construction"))
.def(init<const Vec3<T> &, const Vec3<T> &>("Plane3(point, normal) construction"))
.def(init<const Vec3<T> &, const Vec3<T> &, const Vec3<T> &>("Plane3(point1, point2, point3) construction"))
.def("__eq__", &equal<T>)
.def("__ne__", &notequal<T>)
.def("__mul__", &mul<T>)
.def("__neg__", &negate<T>)
.def("__str__", &Plane3_str<T>)
.def("__repr__", &Plane3_repr<T>)
.def_readwrite("normal", &Plane3<T>::normal)
.def_readwrite("distance", &Plane3<T>::distance)
.def("normal", &normal<T>, "normal()",
"pl.normal() -- returns the normal of plane pl")
.def("distance", &distance<T>, "distance()",
"pl.distance() -- returns the signed distance\n"
"of plane pl from the coordinate origin")
.def("setNormal", &setNormal<T>, "setNormal()",
"pl.setNormal(n) -- sets the normal of plane\n"
"pl to n.normalized()")
.def("setDistance", &setDistance<T>, "setDistance()",
"pl.setDistance(d) -- sets the signed distance\n"
"of plane pl from the coordinate origin to d")
.def("set", &set1<T>, "set()",
"pl.set(n,d) -- sets the normal and the signed\n"
" distance of plane pl to n and d\n"
"\n"
"pl.set(p,n) -- sets the normal of plane pl to\n"
" n.normalized() and adjusts the distance of\n"
" pl from the coordinate origin so that pl\n"
" passes through point p\n"
"\n"
"pl.set(p1,p2,p3) -- sets the normal of plane pl\n"
" to (p2-p1)%(p3-p1)).normalized(), and adjusts\n"
" the distance of pl from the coordinate origin\n"
" so that pl passes through points p1, p2 and p3")
.def("set", &set2<T>, "set()")
.def("set", &set3<T>, "set()")
.def("set", &setTuple1<T>, "set()")
.def("set", &setTuple2<T>, "set()")
.def("set", &setTuple3<T>, "set()")
.def("intersect", &intersect2<T>,
"pl.intersect(ln, pt) -- returns true if the line intersects\n"
"the plane, false if it doesn't. The point where plane\n"
"pl and line ln intersect is stored in pt")
.def("intersect", &intersect1<T,float>,
"pl.intersect(ln) -- returns the point where plane\n"
"pl and line ln intersect, or None if pl and ln do\n"
"not intersect")
.def("intersect", &intersect1<T,double>,
"pl.intersect(ln) -- returns the point where plane\n"
"pl and line ln intersect, or None if pl and ln do\n"
"not intersect")
.def("intersectT", &intersectT<T, float>,
"pl.intersectT(ln) -- computes the intersection,\n"
"i, of plane pl and line ln, and returns t, so that\n"
"ln.pos() + t * ln.dir() == i.\n"
"If pl and ln do not intersect, pl.intersectT(ln)\n"
"returns None.\n")
.def("intersectT", &intersectT<T,double>)
.def("distanceTo", &distanceTo<T>, "distanceTo()",
"pl.distanceTo(p) -- returns the signed distance\n"
"between plane pl and point p (positive if p is\n"
"on the side of pl where the pl's normal points)\n")
.def("distanceTo", &distanceToTuple<T>)
.def("reflectPoint", &reflectPoint<T>, "reflectPoint()",
"pl.reflectPoint(p) -- returns the image,\n"
"q, of point p after reflection on plane pl:\n"
"the distance between p and q is twice the\n"
"distance between p and pl, and the line from\n"
"p to q is parallel to pl's normal.")
.def("reflectPoint", &reflectPointTuple<T>)
.def("reflectVector", &reflectVector<T>, "reflectVector()",
"pl.reflectVector(v) -- returns the direction\n"
"of a ray with direction v after reflection on\n"
"plane pl")
.def("reflectVector", &reflectVectorTuple<T>)
;
decoratecopy(plane_class);
return plane_class;
}
template PYIMATH_EXPORT class_<Plane3<float> > register_Plane<float>();
template PYIMATH_EXPORT class_<Plane3<double> > register_Plane<double>();
} //namespace PyIMath

View File

@ -0,0 +1,103 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathPlane_h_
#define _PyImathPlane_h_
#include <Python.h>
#include <boost/python.hpp>
#include <ImathPlane.h>
#include <PyImath.h>
namespace PyImath {
template <class T> boost::python::class_<IMATH_NAMESPACE::Plane3<T> > register_Plane();
//
// Other code in the Zeno code base assumes the existance of a class with the
// same name as the Imath class, and with static functions wrap() and
// convert() to produce a PyImath object from an Imath object and vice-versa,
// respectively. The class Boost generates from the Imath class does not
// have these properties, so we define a companion class here.
// The template argument, T, is the element type (e.g.,float, double).
template <class T>
class P3 {
public:
static PyObject * wrap (const IMATH_NAMESPACE::Plane3<T> &pl);
static int convert (PyObject *p, IMATH_NAMESPACE::Plane3<T> *pl);
};
template <class T>
PyObject *
P3<T>::wrap (const IMATH_NAMESPACE::Plane3<T> &pl)
{
typename boost::python::return_by_value::apply < IMATH_NAMESPACE::Plane3<T> >::type converter;
PyObject *p = converter (pl);
return p;
}
template <class T>
int
P3<T>::convert (PyObject *p, IMATH_NAMESPACE::Plane3<T> *pl)
{
boost::python::extract <IMATH_NAMESPACE::Plane3f> extractorPf (p);
if (extractorPf.check())
{
IMATH_NAMESPACE::Plane3f e = extractorPf();
pl->normal.setValue (e.normal);
pl->distance = T(e.distance);
return 1;
}
boost::python::extract <IMATH_NAMESPACE::Plane3d> extractorPd (p);
if (extractorPd.check())
{
IMATH_NAMESPACE::Plane3d e = extractorPd();
pl->normal.setValue (e.normal);
pl->distance = T(e.distance);
return 1;
}
return 0;
}
typedef P3<float> Plane3f;
typedef P3<double> Plane3d;
}
#endif

View File

@ -0,0 +1,962 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 <PyImathQuat.h>
#include <PyImathExport.h>
#include "PyImathDecorators.h"
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/format.hpp>
#include <PyImath.h>
#include <PyImathMathExc.h>
#include <ImathVec.h>
#include <ImathMatrixAlgo.h>
#include <ImathEuler.h>
#include <PyImathOperators.h>
// XXX incomplete array wrapping, docstrings missing
namespace PyImath {
template <> const char *PyImath::QuatfArray::name() { return "QuatfArray"; }
template <> const char *PyImath::QuatdArray::name() { return "QuatdArray"; }
}
namespace PyImath {
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template <class T> struct QuatName { static const char *value; };
template<> const char *QuatName<float>::value = "Quatf";
template<> const char *QuatName<double>::value = "Quatd";
template <class T>
static std::string Quat_str(const Quat<T> &v)
{
std::stringstream stream;
stream << QuatName<T>::value << "(" << v[0] << ", " << v[1] << ", "
<< v[2] << ", " << v[3] << ")";
return stream.str();
}
// Non-specialized repr is same as str
template <class T>
static std::string Quat_repr(const Quat<T> &v)
{
return Quat_str(v);
}
// Specialization for float to full precision
template <>
std::string Quat_repr(const Quat<float> &v)
{
return (boost::format("%s(%.9g, %.9g, %.9g, %.9g)")
% QuatName<float>::value
% v[0] % v[1] % v[2] % v[3]).str();
}
// Specialization for double to full precision
template <>
std::string Quat_repr(const Quat<double> &v)
{
return (boost::format("%s(%.17g, %.17g, %.17g, %.17g)")
% QuatName<double>::value
% v[0] % v[1] % v[2] % v[3]).str();
}
template <class T>
static Quat<T> &
invert(Quat<T> &quat)
{
MATH_EXC_ON;
return quat.invert();
}
template <class T>
static Quat<T>
inverse(Quat<T> &quat)
{
MATH_EXC_ON;
return quat.inverse();
}
template <class T>
static Quat<T> &
normalize(Quat<T> &quat)
{
MATH_EXC_ON;
return quat.normalize();
}
template <class T>
static Quat<T>
normalized(Quat<T> &quat)
{
MATH_EXC_ON;
return quat.normalized();
}
template <class T>
static T
length (Quat<T> &quat)
{
MATH_EXC_ON;
return quat.length();
}
template <class T>
static Quat<T> &
setAxisAngle(Quat<T> &quat, const Vec3<T> &axis, T radians)
{
MATH_EXC_ON;
return quat.setAxisAngle(axis, radians);
}
template <class T>
static Quat<T> &
setRotation(Quat<T> &quat, const Vec3<T> &from, const Vec3<T> &to)
{
MATH_EXC_ON;
return quat.setRotation(from, to);
}
template <class T>
static T
angle (Quat<T> &quat)
{
MATH_EXC_ON;
return quat.angle();
}
template <class T>
static Vec3<T>
axis (Quat<T> &quat)
{
MATH_EXC_ON;
return quat.axis();
}
template <class T>
static Matrix33<T>
toMatrix33 (Quat<T> &quat)
{
MATH_EXC_ON;
return quat.toMatrix33();
}
template <class T>
static Matrix44<T>
toMatrix44 (Quat<T> &quat)
{
MATH_EXC_ON;
return quat.toMatrix44();
}
template <class T>
static Quat<T>
log(Quat<T> &quat)
{
MATH_EXC_ON;
return quat.log();
}
template <class T>
static Quat<T>
exp(Quat<T> &quat)
{
MATH_EXC_ON;
return quat.exp();
}
template <class T>
static void
setR(Quat<T> &quat, const double &r)
{
quat.r = r;
}
template <class T>
static void
setV(Quat<T> &quat, const Vec3<T> &v)
{
quat.v = v;
}
template <class T>
static void
extract(Quat<T> &quat, const Matrix44<T> &mat)
{
MATH_EXC_ON;
Quat<T> q = IMATH_NAMESPACE::extractQuat(mat);
quat.r = q.r;
quat.v = q.v;
}
template <class T>
static T scalar(Quat<T> &quat)
{
return quat.r;
}
template <class T>
static Vec3<T> vector(Quat<T> &quat)
{
return quat.v;
}
template <class T>
static Quat<T>
slerp(const Quat<T> &quat, const Quat<T> &other, T t)
{
MATH_EXC_ON;
return IMATH_NAMESPACE::slerp (quat, other, t);
}
template <class T>
static const Quat<T> &
imul (Quat<T> &quat, const Quat<T> &other)
{
MATH_EXC_ON;
return quat *= other;
}
template <class T>
static const Quat<T> &
imulT (Quat<T> &quat, T t)
{
MATH_EXC_ON;
return quat *= t;
}
template <class T>
static const Quat<T> &
idiv (Quat<T> &quat, const Quat<T> &other)
{
MATH_EXC_ON;
return quat /= other;
}
template <class T>
static const Quat<T> &
idivT (Quat<T> &quat, T t)
{
MATH_EXC_ON;
return quat /= t;
}
template <class T>
static const Quat<T> &
iadd (Quat<T> &quat, const Quat<T> &other)
{
MATH_EXC_ON;
return quat += other;
}
template <class T>
static const Quat<T> &
isub (Quat<T> &quat, const Quat<T> &other)
{
MATH_EXC_ON;
return quat -= other;
}
template <class T>
static Matrix33<T>
rmulM33(Quat<T> &quat, Matrix33<T> &m)
{
MATH_EXC_ON;
return m * quat;
}
template <class T>
static Matrix33<T>
mulM33(Quat<T> &quat, Matrix33<T> &m)
{
MATH_EXC_ON;
return quat * m;
}
template <class T>
static Quat<T>
mul(Quat<T> &quat, Quat<T> &other)
{
MATH_EXC_ON;
return quat * other;
}
template <class T>
static Quat<T>
div(Quat<T> &quat, Quat<T> &other)
{
MATH_EXC_ON;
return quat / other;
}
template <class T>
static Quat<T>
divT(Quat<T> &quat, T t)
{
MATH_EXC_ON;
return quat / t;
}
template <class T>
static Quat<T>
mulT(Quat<T> &quat, T t)
{
MATH_EXC_ON;
return quat * t;
}
template <class T>
static Quat<T>
add(Quat<T> &quat, Quat<T> &other)
{
MATH_EXC_ON;
return quat + other;
}
template <class T>
static Quat<T>
sub(Quat<T> &quat, Quat<T> &other)
{
MATH_EXC_ON;
return quat - other;
}
template <class T>
static Quat<T>
neg(Quat<T> &quat)
{
MATH_EXC_ON;
return -quat;
}
template <class T>
static Quat<T>
conj(Quat<T> &quat)
{
MATH_EXC_ON;
return ~quat;
}
template <class T>
static T
dot(Quat<T> &quat, Quat<T> &other)
{
MATH_EXC_ON;
return quat ^ other;
}
template <class T>
static Vec3<T>
rmulVec3(Quat<T> &quat, const Vec3<T> &v)
{
MATH_EXC_ON;
return v * quat.toMatrix44();
}
template <class T>
static FixedArray< Vec3<T> >
rmulVec3Array(Quat<T> &quat, const FixedArray< Vec3<T> > &a)
{
MATH_EXC_ON;
Matrix44<T> m = quat.toMatrix44();
size_t len = a.len();
FixedArray< Vec3<T> > r(len);
for (size_t i = 0; i < len; i++)
r[i] = a[i] * m;
return r;
}
template <class T>
static Quat<T> *
quatConstructor1(const Euler<T> &euler)
{
MATH_EXC_ON;
return new Quat<T>(euler.toQuat());
}
template <class T>
static Quat<T> *
quatConstructor2(const Matrix33<T> &mat)
{
MATH_EXC_ON;
return new Quat<T>(Euler<T>(mat).toQuat());
}
template <class T>
static Quat<T> *
quatConstructor3(const Matrix44<T> &mat)
{
MATH_EXC_ON;
return new Quat<T>(Euler<T>(mat).toQuat());
}
template <class T>
class_<Quat<T> >
register_Quat()
{
class_<Quat<T> > quat_class(QuatName<T>::value, QuatName<T>::value,init<Quat<T> >("copy construction"));
quat_class
.def(init<>("imath Quat initialization") )
.def(init<Quat<float> >("imath Quat copy initialization") )
.def(init<Quat<double> >("imath Quat copy initialization") )
.def(init<T,T,T,T>("make Quat from components") )
.def(init<T, Vec3<T> >("make Quat from components") )
.def("__init__", make_constructor(quatConstructor1<T>))
.def("__init__", make_constructor(quatConstructor2<T>))
.def("__init__", make_constructor(quatConstructor3<T>))
.def("identity",&Quat<T>::identity)
.def("invert",&invert<T>,return_internal_reference<>(),
"q.invert() -- inverts quaternion q\n"
"(modifying q); returns q")
.def("inverse",&inverse<T>,
"q.inverse() -- returns the inverse of\n"
"quaternion q; q is not modified\n")
.def("normalize",&normalize<T>,return_internal_reference<>(),
"q.normalize() -- normalizes quaternion q\n"
"(modifying q); returns q")
.def("normalized",&normalized<T>,
"q.normalized() -- returns a normalized version\n"
"of quaternion q; q is not modified\n")
.def("length",&length<T>)
.def("setAxisAngle",&setAxisAngle<T>,return_internal_reference<>(),
"q.setAxisAngle(x,r) -- sets the value of\n"
"quaternion q so that q represents a rotation\n"
"of r radians around axis x")
.def("setRotation",&setRotation<T>,return_internal_reference<>(),
"q.setRotation(v,w) -- sets the value of\n"
"quaternion q so that rotating vector v by\n"
"q produces vector w")
.def("angle",&angle<T>,
"q.angle() -- returns the rotation angle\n"
"(in radians) represented by quaternion q")
.def("axis",&axis<T>,
"q.axis() -- returns the rotation axis\n"
"represented by quaternion q")
.def("toMatrix33",&toMatrix33<T>,
"q.toMatrix33() -- returns a 3x3 matrix that\n"
"represents the same rotation as quaternion q")
.def("toMatrix44",&toMatrix44<T>,
"q.toMatrix44() -- returns a 4x4 matrix that\n"
"represents the same rotation as quaternion q")
.def("log",&log<T>)
.def("exp",&exp<T>)
.def_readwrite("v",&Quat<T>::v)
.def_readwrite("r",&Quat<T>::r)
.def("v", &vector<T>,
"q.v() -- returns the v (vector) component\n"
"of quaternion q")
.def("r", &scalar<T>,
"q.r() -- returns the r (scalar) component\n"
"of quaternion q")
.def("setR", &setR<T>,
"q.setR(s) -- sets the r (scalar) component\n"
"of quaternion q to s")
.def("setV", &setV<T>,
"q.setV(w) -- sets the v (vector) component\n"
"of quaternion q to w")
.def("extract", &extract<T>,
"q.extract(m) -- extracts the rotation component\n"
"from 4x4 matrix m and stores the result in q")
.def("slerp", &slerp<T>,
"q.slerp(p,t) -- performs sperical linear\n"
"interpolation between quaternions q and p:\n"
"q.slerp(p,0) returns q; q.slerp(p,1) returns p.\n"
"q and p must be normalized\n")
.def("__str__",Quat_str<T>)
.def("__repr__",Quat_repr<T>)
.def ("__imul__", &imul<T>, return_internal_reference<>())
.def ("__imul__", &imulT<T>, return_internal_reference<>())
.def ("__idiv__", idiv<T>, return_internal_reference<>())
.def ("__idiv__", &idivT<T>, return_internal_reference<>())
.def ("__itruediv__", idiv<T>, return_internal_reference<>())
.def ("__itruediv__", &idivT<T>, return_internal_reference<>())
.def ("__iadd__", &iadd<T>, return_internal_reference<>())
.def ("__isub__", &isub<T>, return_internal_reference<>())
.def(self == self)
.def(self != self)
.def ("__rmul__", &rmulM33<T>)
.def ("__mul__", &mulM33<T>)
.def ("__mul__", &mul<T>)
.def ("__div__", &div<T>)
.def ("__div__", &divT<T>)
.def ("__truediv__", &div<T>)
.def ("__truediv__", &divT<T>)
.def ("__mul__", &mulT<T>)
.def ("__rmul__", &mulT<T>)
.def ("__add__", &add<T>)
.def ("__sub__", &sub<T>)
.def ("__neg__", &neg<T>)
.def ("__invert__", &conj<T>)
.def ("__xor__", &dot<T>)
.def ("__rmul__", &rmulVec3<T>)
.def ("__rmul__", &rmulVec3Array<T>)
;
decoratecopy(quat_class);
return quat_class;
}
// XXX fixme - template this
// really this should get generated automatically...
template <class T,int index>
static FixedArray<T>
QuatArray_get(FixedArray<IMATH_NAMESPACE::Quat<T> > &qa)
{
return FixedArray<T>( &(qa[0].r)+index, qa.len(), 4*qa.stride(), qa.handle());
}
template <class T>
struct QuatArray_SetRotationTask : public Task
{
const FixedArray<IMATH_NAMESPACE::Vec3<T> > &from;
const FixedArray<IMATH_NAMESPACE::Vec3<T> > &to;
FixedArray<IMATH_NAMESPACE::Quat<T> > &result;
QuatArray_SetRotationTask (const FixedArray<IMATH_NAMESPACE::Vec3<T> > &fromIn,
const FixedArray<IMATH_NAMESPACE::Vec3<T> > &toIn,
FixedArray<IMATH_NAMESPACE::Quat<T> > &resultIn)
: from (fromIn), to (toIn), result (resultIn) {}
void execute (size_t start, size_t end)
{
for (size_t i = start; i < end; ++i)
result[i].setRotation (from[i], to[i]);
}
};
template <class T> static void
QuatArray_setRotation (FixedArray<IMATH_NAMESPACE::Quat<T> > &va,
const FixedArray<IMATH_NAMESPACE::Vec3<T> > &from,
const FixedArray<IMATH_NAMESPACE::Vec3<T> > &to)
{
MATH_EXC_ON;
size_t len = va.match_dimension(from);
va.match_dimension(to);
QuatArray_SetRotationTask<T> task (from, to, va);
dispatchTask (task, len);
}
template <class T>
struct QuatArray_OrientToVectors : public Task
{
const FixedArray<IMATH_NAMESPACE::Vec3<T> > &forward;
const FixedArray<IMATH_NAMESPACE::Vec3<T> > &up;
FixedArray<IMATH_NAMESPACE::Quat<T> > &result;
bool alignForward;
QuatArray_OrientToVectors (const FixedArray<IMATH_NAMESPACE::Vec3<T> > &forwardIn,
const FixedArray<IMATH_NAMESPACE::Vec3<T> > &upIn,
FixedArray<IMATH_NAMESPACE::Quat<T> > &resultIn,
bool alignForwardIn)
: forward (forwardIn), up (upIn), result (resultIn),
alignForward (alignForwardIn) {}
void execute (size_t start, size_t end)
{
Vec3<T> f(0), u(0);
Euler<T> eu(0,0,0);
const Vec3<T> fRef(1,0,0);
for (size_t i = start; i < end; ++i)
{
if (alignForward)
{
f = forward[i].normalized();
u = up[i] - f.dot(up[i])*f;
u.normalize();
}
else
{
u = up[i].normalized();
f = forward[i] - u.dot(forward[i])*u;
f.normalize();
}
extractEulerXYZ (rotationMatrixWithUpDir (fRef, f, u), eu);
result[i] = eu.toQuat();
}
}
};
template <class T> static void
QuatArray_orientToVectors (FixedArray<IMATH_NAMESPACE::Quat<T> > &va,
const FixedArray<IMATH_NAMESPACE::Vec3<T> > &forward,
const FixedArray<IMATH_NAMESPACE::Vec3<T> > &up,
bool alignForward)
{
MATH_EXC_ON;
size_t len = va.match_dimension(forward);
va.match_dimension(up);
QuatArray_OrientToVectors<T> task (forward, up, va, alignForward);
dispatchTask (task, len);
}
template <class T>
struct QuatArray_Axis : public Task
{
const FixedArray<IMATH_NAMESPACE::Quat<T> > &va;
FixedArray<IMATH_NAMESPACE::Vec3<T> > &result;
QuatArray_Axis (const FixedArray<IMATH_NAMESPACE::Quat<T> > &vaIn,
FixedArray<IMATH_NAMESPACE::Vec3<T> > &resultIn)
: va (vaIn), result (resultIn) {}
void execute (size_t start, size_t end)
{
for (size_t i = start; i < end; ++i)
result[i] = va[i].axis();
}
};
template <class T> static FixedArray<IMATH_NAMESPACE::Vec3<T> >
QuatArray_axis(const FixedArray<IMATH_NAMESPACE::Quat<T> > &va)
{
MATH_EXC_ON;
size_t len = va.len();
FixedArray<IMATH_NAMESPACE::Vec3<T> > retval (Py_ssize_t(len), UNINITIALIZED);
QuatArray_Axis<T> task (va, retval);
dispatchTask (task, len);
return retval;
}
template <class T>
struct QuatArray_Angle : public Task
{
const FixedArray<IMATH_NAMESPACE::Quat<T> > &va;
FixedArray<T> &result;
QuatArray_Angle (const FixedArray<IMATH_NAMESPACE::Quat<T> > &vaIn,
FixedArray<T> &resultIn)
: va (vaIn), result (resultIn) {}
void execute (size_t start, size_t end)
{
for (size_t i = start; i < end; ++i)
result[i] = va[i].angle();
}
};
template <class T> static FixedArray<T>
QuatArray_angle(const FixedArray<IMATH_NAMESPACE::Quat<T> > &va)
{
MATH_EXC_ON;
size_t len = va.len();
FixedArray<T> retval (Py_ssize_t(len), UNINITIALIZED);
QuatArray_Angle<T> task (va, retval);
dispatchTask (task, len);
return retval;
}
template <class T>
struct QuatArray_RmulVec3 : public Task
{
const FixedArray<IMATH_NAMESPACE::Quat<T> > &a;
const Vec3<T> &v;
FixedArray<Vec3<T> > &r;
QuatArray_RmulVec3 (const FixedArray<IMATH_NAMESPACE::Quat<T> > &aIn,
const Vec3<T> &vIn, FixedArray<Vec3<T> > &rIn)
: a (aIn), v (vIn), r (rIn) {}
void execute(size_t start, size_t end)
{
for (size_t i = start; i < end; ++i)
{
Matrix44<T> m = a[i].toMatrix44();
r[i] = v * m;
}
}
};
template <class T>
static FixedArray< Vec3<T> >
QuatArray_rmulVec3 (const FixedArray< IMATH_NAMESPACE::Quat<T> > &a, const Vec3<T> &v)
{
MATH_EXC_ON;
size_t len = a.len();
FixedArray< Vec3<T> > r (Py_ssize_t(len), UNINITIALIZED);
QuatArray_RmulVec3<T> task (a, v, r);
dispatchTask (task, len);
return r;
}
template <class T>
struct QuatArray_RmulVec3Array : public Task
{
const FixedArray<IMATH_NAMESPACE::Quat<T> > &a;
const FixedArray<Vec3<T> > &b;
FixedArray<Vec3<T> > &r;
QuatArray_RmulVec3Array (const FixedArray<IMATH_NAMESPACE::Quat<T> > &aIn,
const FixedArray<Vec3<T> > &bIn,
FixedArray<Vec3<T> > &rIn)
: a (aIn), b (bIn), r (rIn) {}
void execute(size_t start, size_t end)
{
for (size_t i = start; i < end; ++i)
{
Matrix44<T> m = a[i].toMatrix44();
r[i] = b[i] * m;
}
}
};
template <class T>
static FixedArray< Vec3<T> >
QuatArray_rmulVec3Array (const FixedArray< IMATH_NAMESPACE::Quat<T> > &a,
const FixedArray< Vec3<T> > &b)
{
MATH_EXC_ON;
size_t len = a.match_dimension(b);
FixedArray< Vec3<T> > r (Py_ssize_t(len), UNINITIALIZED);
QuatArray_RmulVec3Array<T> task (a, b, r);
dispatchTask (task, len);
return r;
}
template <class T>
struct QuatArray_SetAxisAngle : public Task
{
const FixedArray<IMATH_NAMESPACE::Vec3<T> > &axis;
const FixedArray<T> &angles;
FixedArray<IMATH_NAMESPACE::Quat<T> > &quats;
QuatArray_SetAxisAngle (const FixedArray<IMATH_NAMESPACE::Vec3<T> > &axisIn,
const FixedArray<T> &anglesIn,
FixedArray<IMATH_NAMESPACE::Quat<T> > &quatsIn)
: axis (axisIn), angles (anglesIn), quats (quatsIn) {}
void execute(size_t start, size_t end)
{
for (size_t i = start; i < end; ++i)
{
quats[i].setAxisAngle (axis[i], angles[i]);
}
}
};
template <class T>
static void
QuatArray_setAxisAngle (FixedArray< IMATH_NAMESPACE::Quat<T> > &quats,
const FixedArray< IMATH_NAMESPACE::Vec3<T> > &axis,
const FixedArray<T> &angles)
{
MATH_EXC_ON;
size_t len = quats.match_dimension(axis);
quats.match_dimension(angles);
QuatArray_SetAxisAngle<T> task (axis, angles, quats);
dispatchTask (task, len);
}
template <class T>
struct QuatArray_SetEulerXYZ : public Task
{
const FixedArray<IMATH_NAMESPACE::Vec3<T> > &rot;
FixedArray<IMATH_NAMESPACE::Quat<T> > &quats;
QuatArray_SetEulerXYZ (const FixedArray<IMATH_NAMESPACE::Vec3<T> > &rotIn,
FixedArray<IMATH_NAMESPACE::Quat<T> > &quatsIn)
: rot (rotIn), quats (quatsIn) {}
void execute (size_t start, size_t end)
{
for (size_t i = start; i < end; ++i)
{
Eulerf e(rot[i]);
quats[i] = e.toQuat();
}
}
};
template <class T>
static void
QuatArray_setEulerXYZ (FixedArray< IMATH_NAMESPACE::Quat<T> > &quats,
const FixedArray< IMATH_NAMESPACE::Vec3<T> > &rot)
{
MATH_EXC_ON;
size_t len = quats.match_dimension(rot);
QuatArray_SetEulerXYZ<T> task (rot, quats);
dispatchTask (task, len);
}
template <class T>
struct QuatArray_Mul : public Task
{
const FixedArray<IMATH_NAMESPACE::Quat<T> > &q1;
const FixedArray<IMATH_NAMESPACE::Quat<T> > &q2;
FixedArray<IMATH_NAMESPACE::Quat<T> > &result;
QuatArray_Mul (const FixedArray<IMATH_NAMESPACE::Quat<T> > &q1In,
const FixedArray<IMATH_NAMESPACE::Quat<T> > &q2In,
FixedArray<IMATH_NAMESPACE::Quat<T> > &resultIn)
: q1 (q1In), q2 (q2In), result (resultIn) {}
void execute (size_t start, size_t end)
{
for (size_t i = start; i < end; ++i)
{
result[i] = q1[i] * q2[i];
}
}
};
template <class T>
static FixedArray< IMATH_NAMESPACE::Quat<T> >
QuatArray_mul(const FixedArray< IMATH_NAMESPACE::Quat<T> > &q1,
const FixedArray< IMATH_NAMESPACE::Quat<T> > &q2)
{
MATH_EXC_ON;
size_t len = q1.match_dimension(q2);
FixedArray< IMATH_NAMESPACE::Quat<T> > result (Py_ssize_t(len), UNINITIALIZED);
QuatArray_Mul<T> task (q1, q2, result);
dispatchTask (task, len);
return result;
}
template <class T>
struct QuatArray_QuatConstructor1 : public Task
{
const FixedArray<IMATH_NAMESPACE::Euler<T> > &euler;
FixedArray<IMATH_NAMESPACE::Quat<T> > &result;
QuatArray_QuatConstructor1 (const FixedArray<IMATH_NAMESPACE::Euler<T> > &eulerIn,
FixedArray<IMATH_NAMESPACE::Quat<T> > &resultIn)
: euler (eulerIn), result (resultIn) {}
void execute (size_t start, size_t end)
{
for (size_t i = start; i < end; ++i)
{
result[i] = euler[i].toQuat();
}
}
};
template <class T>
static FixedArray<IMATH_NAMESPACE::Quat<T> > *
QuatArray_quatConstructor1(const FixedArray<IMATH_NAMESPACE::Euler<T> > &e)
{
MATH_EXC_ON;
size_t len = e.len();
FixedArray<IMATH_NAMESPACE::Quat<T> >* result =
new FixedArray<IMATH_NAMESPACE::Quat<T> > (Py_ssize_t(len), UNINITIALIZED);
QuatArray_QuatConstructor1<T> task (e, *result);
dispatchTask (task, len);
return result;
}
template <class T>
class_<FixedArray<IMATH_NAMESPACE::Quat<T> > >
register_QuatArray()
{
class_<FixedArray<IMATH_NAMESPACE::Quat<T> > > quatArray_class = FixedArray<IMATH_NAMESPACE::Quat<T> >::register_("Fixed length array of IMATH_NAMESPACE::Quat");
quatArray_class
.add_property("r",&QuatArray_get<T,0>)
.add_property("x",&QuatArray_get<T,1>)
.add_property("y",&QuatArray_get<T,2>)
.add_property("z",&QuatArray_get<T,3>)
.def("setRotation", &QuatArray_setRotation<T>,
"set rotation angles for each quat",
(args("from", "to")))
.def("orientToVectors", &QuatArray_orientToVectors<T>,
"Sets the orientations to match the given forward and up vectors, "
"matching the forward vector exactly if 'alignForward' is True, matching "
"the up vector exactly if 'alignForward' is False. If the vectors are "
"already orthogonal, both vectors will be matched exactly.",
(args("forward", "up", "alignForward")))
.def("axis", &QuatArray_axis<T>,
"get rotation axis for each quat")
.def("angle", &QuatArray_angle<T>,
"get rotation angle about the axis returned by axis() for each quat")
.def("setAxisAngle", &QuatArray_setAxisAngle<T>,
"set the quaternion arrays from a given axis and angle",
(args("axis", "angle")))
.def("setEulerXYZ", &QuatArray_setEulerXYZ<T>,
"set the quaternion arrays from a given euler XYZ angle vector",
(args("euler")))
.def("__mul__", &QuatArray_mul<T>)
.def("__rmul__", &QuatArray_rmulVec3<T>)
.def("__rmul__", &QuatArray_rmulVec3Array<T>)
.def("__init__", make_constructor(QuatArray_quatConstructor1<T>))
;
add_comparison_functions(quatArray_class);
decoratecopy(quatArray_class);
return quatArray_class;
}
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Quat<float> > register_Quat<float>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Quat<double> > register_Quat<double>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Quat<float> > > register_QuatArray<float>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Quat<double> > > register_QuatArray<double>();
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Quat<float> FixedArrayDefaultValue<IMATH_NAMESPACE::Quat<float> >::value() { return IMATH_NAMESPACE::Quat<float>(); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Quat<double> FixedArrayDefaultValue<IMATH_NAMESPACE::Quat<double> >::value() { return IMATH_NAMESPACE::Quat<double>(); }
}

View File

@ -0,0 +1,147 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathQuat_h_
#define _PyImathQuat_h_
#include <Python.h>
#include <boost/python.hpp>
#include <PyImath.h>
#include <ImathQuat.h>
#include <ImathVec.h>
#include <PyImath.h>
namespace PyImath {
template <class T> boost::python::class_<IMATH_NAMESPACE::Quat<T> > register_Quat();
template <class T> boost::python::class_<PyImath::FixedArray<IMATH_NAMESPACE::Quat<T> > > register_QuatArray();
typedef FixedArray<IMATH_NAMESPACE::Quatf> QuatfArray;
typedef FixedArray<IMATH_NAMESPACE::Quatd> QuatdArray;
}
template <class T> inline IMATH_NAMESPACE::Vec3<T> operator * (const IMATH_NAMESPACE::Vec3<T> &v, const IMATH_NAMESPACE::Quat<T> &q) { return v * q.toMatrix33(); }
template <class T> static PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> >
operator *(const IMATH_NAMESPACE::Vec3<T> &va, const PyImath::FixedArray<IMATH_NAMESPACE::Quat<T> > &vb)
{ size_t len = vb.len(); PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > f(len); for (size_t i = 0; i < len; ++i) f[i] = va * vb[i]; return f; }
template <class T> static PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> >
operator *(const PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > &va, const IMATH_NAMESPACE::Quat<T> &vb)
{ size_t len = va.len(); PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > f(len); for (size_t i = 0; i < len; ++i) f[i] = va[i] * vb; return f; }
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> >
operator * (const PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > &va, const PyImath::FixedArray<IMATH_NAMESPACE::Quat<T> > &vb)
{ size_t len = va.match_dimension(vb); PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > f(len); for (size_t i = 0; i < len; ++i) f[i] = va[i] * vb[i]; return f; }
//
namespace PyImath {
// Other code in the Zeno code base assumes the existance of a class with the
// same name as the Imath class, and with static functions wrap() and
// convert() to produce a PyImath object from an Imath object and vice-versa,
// respectively. The class Boost generates from the Imath class does not
// have these properties, so we define a companion class here.
// The template argument, T, is the element type (e.g.,float, double).
template <class T>
class Q {
public:
static PyObject * wrap (const IMATH_NAMESPACE::Quat<T> &q);
static int convert (PyObject *p, IMATH_NAMESPACE::Quat<T> *q);
};
template <class T>
PyObject *
Q<T>::wrap (const IMATH_NAMESPACE::Quat<T> &q)
{
typename boost::python::return_by_value::apply < IMATH_NAMESPACE::Quat<T> >::type converter;
PyObject *p = converter (q);
return p;
}
template <class T>
int
Q<T>::convert (PyObject *p, IMATH_NAMESPACE::Quat<T> *q)
{
boost::python::extract <IMATH_NAMESPACE::Quatf> extractorQf (p);
if (extractorQf.check())
{
IMATH_NAMESPACE::Quatf qf = extractorQf();
q->r = T(qf.r);
q->v.setValue (qf.v);
return 1;
}
boost::python::extract <IMATH_NAMESPACE::Quatd> extractorQd (p);
if (extractorQd.check())
{
IMATH_NAMESPACE::Quatd qd = extractorQd();
q->r = T(qd.r);
q->v.setValue (qd.v);
return 1;
}
boost::python::extract <boost::python::tuple> extractorTuple (p);
if (extractorTuple.check())
{
boost::python::tuple t = extractorTuple();
if (t.attr ("__len__") () == 4)
{
// Extracting the tuple elements as doubles and casting them to
// Ts in setValue() works better than extracting them as Ts from
// the start.
double r = boost::python::extract <double> (t[0]);
double x = boost::python::extract <double> (t[1]);
double y = boost::python::extract <double> (t[2]);
double z = boost::python::extract <double> (t[3]);
q->r = T(r);
q->v.setValue (T(x), T(y), T(z));
return 1;
}
}
return 0;
}
typedef Q<float> Quatf;
typedef Q<double> Quatd;
}
#endif

View File

@ -0,0 +1,353 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 <PyImathRandom.h>
#include "PyImathDecorators.h"
#include <Python.h>
#include <boost/python.hpp>
#include <boost/format.hpp>
#include <boost/python/make_constructor.hpp>
#include <PyImath.h>
#include <PyImathMathExc.h>
#include <PyImathFixedArray.h>
namespace PyImath{
using namespace boost::python;
template <class Rand, class T>
static T
nextf2 (Rand &rand, T min, T max)
{
MATH_EXC_ON;
return rand.nextf(min, max);
}
template <class Rand>
static float
nextGauss (Rand &rand)
{
MATH_EXC_ON;
return gaussRand(rand);
}
template <class T, class Rand>
static IMATH_NAMESPACE::Vec3<T> nextGaussSphere(Rand &rand, const IMATH_NAMESPACE::Vec3<T> &v)
{
MATH_EXC_ON;
return IMATH_NAMESPACE::gaussSphereRand<IMATH_NAMESPACE::Vec3<T>,Rand>(rand);
}
template <class T, class Rand>
static IMATH_NAMESPACE::Vec2<T> nextGaussSphere(Rand &rand, const IMATH_NAMESPACE::Vec2<T> &v)
{
MATH_EXC_ON;
return IMATH_NAMESPACE::gaussSphereRand<IMATH_NAMESPACE::Vec2<T>,Rand>(rand);
}
template <class T, class Rand>
static IMATH_NAMESPACE::Vec3<T> nextHollowSphere(Rand &rand, const IMATH_NAMESPACE::Vec3<T> &v)
{
MATH_EXC_ON;
return IMATH_NAMESPACE::hollowSphereRand<IMATH_NAMESPACE::Vec3<T>,Rand>(rand);
}
template <class T, class Rand>
static IMATH_NAMESPACE::Vec2<T> nextHollowSphere(Rand &rand, const IMATH_NAMESPACE::Vec2<T> &v)
{
MATH_EXC_ON;
return IMATH_NAMESPACE::hollowSphereRand<IMATH_NAMESPACE::Vec2<T>,Rand>(rand);
}
template <class T, class Rand>
static IMATH_NAMESPACE::Vec3<T> nextSolidSphere(Rand &rand, const IMATH_NAMESPACE::Vec3<T> &v)
{
MATH_EXC_ON;
return IMATH_NAMESPACE::solidSphereRand<IMATH_NAMESPACE::Vec3<T>,Rand>(rand);
}
template <class T, class Rand>
static IMATH_NAMESPACE::Vec2<T> nextSolidSphere(Rand &rand, const IMATH_NAMESPACE::Vec2<T> &v)
{
MATH_EXC_ON;
return IMATH_NAMESPACE::solidSphereRand<IMATH_NAMESPACE::Vec2<T>,Rand>(rand);
}
template <class Rand>
static Rand *Rand_constructor1(unsigned long int seed)
{
return new Rand(seed);
}
template <class Rand>
static Rand *Rand_constructor2(Rand rand)
{
Rand *r = new Rand();
*r = rand;
return r;
}
template <class T, class Rand>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> >
hollowSphereRand(Rand &rand, int num)
{
MATH_EXC_ON;
PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > retval(num);
for (int i=0; i<num; ++i) {
retval[i] = IMATH_NAMESPACE::hollowSphereRand<IMATH_NAMESPACE::Vec3<T>,Rand>(rand);
}
return retval;
}
template <class T, class Rand>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> >
solidSphereRand(Rand &rand, int num)
{
MATH_EXC_ON;
PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > retval(num);
for (int i=0; i<num; ++i) {
retval[i] = IMATH_NAMESPACE::solidSphereRand<IMATH_NAMESPACE::Vec3<T>,Rand>(rand);
}
return retval;
}
class_<IMATH_NAMESPACE::Rand32>
register_Rand32()
{
float (IMATH_NAMESPACE::Rand32::*nextf1)(void) = &IMATH_NAMESPACE::Rand32::nextf;
IMATH_NAMESPACE::Vec3<float> (*nextGaussSphere1)(IMATH_NAMESPACE::Rand32 &, const IMATH_NAMESPACE::Vec3<float> &v) = &nextGaussSphere<float,IMATH_NAMESPACE::Rand32>;
IMATH_NAMESPACE::Vec3<double> (*nextGaussSphere2)(IMATH_NAMESPACE::Rand32 &, const IMATH_NAMESPACE::Vec3<double> &v) = &nextGaussSphere<double,IMATH_NAMESPACE::Rand32>;
IMATH_NAMESPACE::Vec2<float> (*nextGaussSphere3)(IMATH_NAMESPACE::Rand32 &, const IMATH_NAMESPACE::Vec2<float> &v) = &nextGaussSphere<float,IMATH_NAMESPACE::Rand32>;
IMATH_NAMESPACE::Vec2<double> (*nextGaussSphere4)(IMATH_NAMESPACE::Rand32 &, const IMATH_NAMESPACE::Vec2<double> &v) = &nextGaussSphere<double,IMATH_NAMESPACE::Rand32>;
IMATH_NAMESPACE::Vec3<float> (*nextHollowSphere1)(IMATH_NAMESPACE::Rand32 &, const IMATH_NAMESPACE::Vec3<float> &v) = &nextHollowSphere<float,IMATH_NAMESPACE::Rand32>;
IMATH_NAMESPACE::Vec3<double> (*nextHollowSphere2)(IMATH_NAMESPACE::Rand32 &, const IMATH_NAMESPACE::Vec3<double> &v) = &nextHollowSphere<double,IMATH_NAMESPACE::Rand32>;
IMATH_NAMESPACE::Vec2<float> (*nextHollowSphere3)(IMATH_NAMESPACE::Rand32 &, const IMATH_NAMESPACE::Vec2<float> &v) = &nextHollowSphere<float,IMATH_NAMESPACE::Rand32>;
IMATH_NAMESPACE::Vec2<double> (*nextHollowSphere4)(IMATH_NAMESPACE::Rand32 &, const IMATH_NAMESPACE::Vec2<double> &v) = &nextHollowSphere<double,IMATH_NAMESPACE::Rand32>;
IMATH_NAMESPACE::Vec3<float> (*nextSolidSphere1)(IMATH_NAMESPACE::Rand32 &, const IMATH_NAMESPACE::Vec3<float> &v) = &nextSolidSphere<float,IMATH_NAMESPACE::Rand32>;
IMATH_NAMESPACE::Vec3<double> (*nextSolidSphere2)(IMATH_NAMESPACE::Rand32 &, const IMATH_NAMESPACE::Vec3<double> &v) = &nextSolidSphere<double,IMATH_NAMESPACE::Rand32>;
IMATH_NAMESPACE::Vec2<float> (*nextSolidSphere3)(IMATH_NAMESPACE::Rand32 &, const IMATH_NAMESPACE::Vec2<float> &v) = &nextSolidSphere<float,IMATH_NAMESPACE::Rand32>;
IMATH_NAMESPACE::Vec2<double> (*nextSolidSphere4)(IMATH_NAMESPACE::Rand32 &, const IMATH_NAMESPACE::Vec2<double> &v) = &nextSolidSphere<double,IMATH_NAMESPACE::Rand32>;
class_< IMATH_NAMESPACE::Rand32 > rand32_class("Rand32");
rand32_class
.def(init<>("default construction"))
.def("__init__", make_constructor(Rand_constructor1<IMATH_NAMESPACE::Rand32>))
.def("__init__", make_constructor(Rand_constructor2<IMATH_NAMESPACE::Rand32>))
.def("init", &IMATH_NAMESPACE::Rand32::init,
"r.init(i) -- initialize with integer "
"seed i")
.def("nexti", &IMATH_NAMESPACE::Rand32::nexti,
"r.nexti() -- return the next integer "
"value in the uniformly-distributed "
"sequence")
.def("nextf", nextf1,
"r.nextf() -- return the next floating-point "
"value in the uniformly-distributed "
"sequence\n"
"r.nextf(float, float) -- return the next floating-point "
"value in the uniformly-distributed "
"sequence")
.def("nextf", &nextf2 <IMATH_NAMESPACE::Rand32, float>)
.def("nextb", &IMATH_NAMESPACE::Rand32::nextb,
"r.nextb() -- return the next boolean "
"value in the uniformly-distributed "
"sequence")
.def("nextGauss", &nextGauss<IMATH_NAMESPACE::Rand32>,
"r.nextGauss() -- returns the next "
"floating-point value in the normally "
"(Gaussian) distributed sequence")
.def("nextGaussSphere", nextGaussSphere1,
"r.nextGaussSphere(v) -- returns the next "
"point whose distance from the origin "
"has a normal (Gaussian) distribution with "
"mean 0 and variance 1. The vector "
"argument, v, specifies the dimension "
"and number type.")
.def("nextGaussSphere", nextGaussSphere2)
.def("nextGaussSphere", nextGaussSphere3)
.def("nextGaussSphere", nextGaussSphere4)
.def("nextHollowSphere", nextHollowSphere1,
"r.nextHollowSphere(v) -- return the next "
"point uniformly distributed on the surface "
"of a sphere of radius 1 centered at the "
"origin. The vector argument, v, specifies "
"the dimension and number type.")
.def("nextHollowSphere", nextHollowSphere2)
.def("nextHollowSphere", nextHollowSphere3)
.def("nextHollowSphere", nextHollowSphere4)
.def("nextSolidSphere", nextSolidSphere1,
"r.nextSolidSphere(v) -- return the next "
"point uniformly distributed in a sphere "
"of radius 1 centered at the origin. The "
"vector argument, v, specifies the "
"dimension and number type.")
.def("nextSolidSphere", nextSolidSphere2)
.def("nextSolidSphere", nextSolidSphere3)
.def("nextSolidSphere", nextSolidSphere4)
;
def("hollowSphereRand",&hollowSphereRand<float,IMATH_NAMESPACE::Rand32>,"hollowSphereRand(randObj,num) return XYZ vectors uniformly "
"distributed across the surface of a sphere generated from the given Rand32 object",
args("randObj","num"));
def("solidSphereRand",&solidSphereRand<float,IMATH_NAMESPACE::Rand32>,"solidSphereRand(randObj,num) return XYZ vectors uniformly "
"distributed through the volume of a sphere generated from the given Rand32 object",
args("randObj","num"));
decoratecopy(rand32_class);
return rand32_class;
}
class_<IMATH_NAMESPACE::Rand48>
register_Rand48()
{
double (IMATH_NAMESPACE::Rand48::*nextf1)(void) = &IMATH_NAMESPACE::Rand48::nextf;
IMATH_NAMESPACE::Vec3<float> (*nextGaussSphere1)(IMATH_NAMESPACE::Rand48 &, const IMATH_NAMESPACE::Vec3<float> &v) = &nextGaussSphere<float,IMATH_NAMESPACE::Rand48>;
IMATH_NAMESPACE::Vec3<double> (*nextGaussSphere2)(IMATH_NAMESPACE::Rand48 &, const IMATH_NAMESPACE::Vec3<double> &v) = &nextGaussSphere<double,IMATH_NAMESPACE::Rand48>;
IMATH_NAMESPACE::Vec2<float> (*nextGaussSphere3)(IMATH_NAMESPACE::Rand48&, const IMATH_NAMESPACE::Vec2<float> &v) = &nextGaussSphere<float,IMATH_NAMESPACE::Rand48>;
IMATH_NAMESPACE::Vec2<double> (*nextGaussSphere4)(IMATH_NAMESPACE::Rand48 &, const IMATH_NAMESPACE::Vec2<double> &v) = &nextGaussSphere<double,IMATH_NAMESPACE::Rand48>;
IMATH_NAMESPACE::Vec3<float> (*nextHollowSphere1)(IMATH_NAMESPACE::Rand48 &, const IMATH_NAMESPACE::Vec3<float> &v) = &nextHollowSphere<float,IMATH_NAMESPACE::Rand48>;
IMATH_NAMESPACE::Vec3<double> (*nextHollowSphere2)(IMATH_NAMESPACE::Rand48 &, const IMATH_NAMESPACE::Vec3<double> &v) = &nextHollowSphere<double,IMATH_NAMESPACE::Rand48>;
IMATH_NAMESPACE::Vec2<float> (*nextHollowSphere3)(IMATH_NAMESPACE::Rand48 &, const IMATH_NAMESPACE::Vec2<float> &v) = &nextHollowSphere<float,IMATH_NAMESPACE::Rand48>;
IMATH_NAMESPACE::Vec2<double> (*nextHollowSphere4)(IMATH_NAMESPACE::Rand48 &, const IMATH_NAMESPACE::Vec2<double> &v) = &nextHollowSphere<double,IMATH_NAMESPACE::Rand48>;
IMATH_NAMESPACE::Vec3<float> (*nextSolidSphere1)(IMATH_NAMESPACE::Rand48 &, const IMATH_NAMESPACE::Vec3<float> &v) = &nextSolidSphere<float,IMATH_NAMESPACE::Rand48>;
IMATH_NAMESPACE::Vec3<double> (*nextSolidSphere2)(IMATH_NAMESPACE::Rand48 &, const IMATH_NAMESPACE::Vec3<double> &v) = &nextSolidSphere<double,IMATH_NAMESPACE::Rand48>;
IMATH_NAMESPACE::Vec2<float> (*nextSolidSphere3)(IMATH_NAMESPACE::Rand48&, const IMATH_NAMESPACE::Vec2<float> &v) = &nextSolidSphere<float,IMATH_NAMESPACE::Rand48>;
IMATH_NAMESPACE::Vec2<double> (*nextSolidSphere4)(IMATH_NAMESPACE::Rand48 &, const IMATH_NAMESPACE::Vec2<double> &v) = &nextSolidSphere<double,IMATH_NAMESPACE::Rand48>;
class_< IMATH_NAMESPACE::Rand48 > rand48_class("Rand48");
rand48_class
.def(init<>("default construction"))
.def("__init__", make_constructor(Rand_constructor1<IMATH_NAMESPACE::Rand48>))
.def("__init__", make_constructor(Rand_constructor2<IMATH_NAMESPACE::Rand48>))
.def("init", &IMATH_NAMESPACE::Rand48::init,
"r.init(i) -- initialize with integer "
"seed i")
.def("nexti", &IMATH_NAMESPACE::Rand48::nexti,
"r.nexti() -- return the next integer "
"value in the uniformly-distributed "
"sequence")
.def("nextf", nextf1,
"r.nextf() -- return the next double "
"value in the uniformly-distributed "
"sequence\n"
"r.nextf(double,double) -- return the next double "
"value in the uniformly-distributed "
"sequence")
.def("nextf", &nextf2 <IMATH_NAMESPACE::Rand48, double>)
.def("nextb", &IMATH_NAMESPACE::Rand48::nextb,
"r.nextb() -- return the next boolean "
"value in the uniformly-distributed "
"sequence")
.def("nextGauss", &nextGauss<IMATH_NAMESPACE::Rand48>,
"r.nextGauss() -- returns the next "
"floating-point value in the normally "
"(Gaussian) distributed sequence")
.def("nextGaussSphere", nextGaussSphere1,
"r.nextGaussSphere(v) -- returns the next "
"point whose distance from the origin "
"has a normal (Gaussian) distribution with "
"mean 0 and variance 1. The vector "
"argument, v, specifies the dimension "
"and number type.")
.def("nextGaussSphere", nextGaussSphere2)
.def("nextGaussSphere", nextGaussSphere3)
.def("nextGaussSphere", nextGaussSphere4)
.def("nextHollowSphere", nextHollowSphere1,
"r.nextHollowSphere(v) -- return the next "
"point uniformly distributed on the surface "
"of a sphere of radius 1 centered at the "
"origin. The vector argument, v, specifies "
"the dimension and number type.")
.def("nextHollowSphere", nextHollowSphere2)
.def("nextHollowSphere", nextHollowSphere3)
.def("nextHollowSphere", nextHollowSphere4)
.def("nextSolidSphere", nextSolidSphere1,
"r.nextSolidSphere(v) -- return the next "
"point uniformly distributed in a sphere "
"of radius 1 centered at the origin. The "
"vector argument, v, specifies the "
"dimension and number type.")
.def("nextSolidSphere", nextSolidSphere2)
.def("nextSolidSphere", nextSolidSphere3)
.def("nextSolidSphere", nextSolidSphere4)
;
decoratecopy(rand48_class);
return rand48_class;
}
//
PyObject *
Rand32::wrap (const IMATH_NAMESPACE::Rand32 &r)
{
boost::python::return_by_value::apply <IMATH_NAMESPACE::Rand32>::type converter;
PyObject *p = converter (r);
return p;
}
PyObject *
Rand48::wrap (const IMATH_NAMESPACE::Rand48 &r)
{
boost::python::return_by_value::apply <IMATH_NAMESPACE::Rand48>::type converter;
PyObject *p = converter (r);
return p;
}
} //namespace PyIMath

View File

@ -0,0 +1,63 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathRandom_h_
#define _PyImathRandom_h_
#include <Python.h>
#include "PyImathExport.h"
#include <boost/python.hpp>
#include <ImathRandom.h>
namespace PyImath {
PYIMATH_EXPORT boost::python::class_<IMATH_NAMESPACE::Rand32> register_Rand32();
PYIMATH_EXPORT boost::python::class_<IMATH_NAMESPACE::Rand48> register_Rand48();
class PYIMATH_EXPORT Rand32
{
public:
static PyObject * wrap (const IMATH_NAMESPACE::Rand32 &r);
};
class PYIMATH_EXPORT Rand48
{
public:
static PyObject * wrap (const IMATH_NAMESPACE::Rand48 &r);
};
}
#endif

View File

@ -0,0 +1,585 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 <PyImathShear.h>
#include <PyImathPlane.h>
#include "PyImathDecorators.h"
#include "PyImathExport.h"
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/format.hpp>
#include <PyImath.h>
#include <PyImathMathExc.h>
#include <Iex.h>
namespace PyImath{
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template <class T> struct ShearName {static const char *value;};
template <> const char *ShearName<float>::value = "Shear6f";
template <> const char *ShearName<double>::value = "Shear6d";
template <class T>
static std::string Shear_str(const Shear6<T> &v)
{
std::stringstream stream;
stream << ShearName<T>::value << "("
<< v[0] << ", " << v[1] << ", " << v[2] << ", "
<< v[3] << ", " << v[4] << ", " << v[5] << ")";
return stream.str();
}
// Non-specialized repr is same as str
template <class T>
static std::string Shear_repr(const Shear6<T> &v)
{
return Shear_str(v);
}
// Specialization for float to full precision
template <>
std::string Shear_repr(const Shear6<float> &v)
{
return (boost::format("%s(%.9g, %.9g, %.9g, %.9g, %.9g, %.9g)")
% ShearName<float>::value
% v[0] % v[1] % v[2]
% v[3] % v[4] % v[5]).str();
}
// Specialization for double to full precision
template <>
std::string Shear_repr(const Shear6<double> &v)
{
return (boost::format("%s(%.17g, %.17g, %.17g, %.17g, %.17g, %.17g)")
% ShearName<double>::value
% v[0] % v[1] % v[2]
% v[3] % v[4] % v[5]).str();
}
template <class T>
static Shear6<T> * shearTupleConstructor(tuple t)
{
if(t.attr("__len__")() == 3){
return new Shear6<T>(extract<T>(t[0]), extract<T>(t[1]), extract<T>(t[2]),
T(0), T(0), T(0));
}
else if(t.attr("__len__")() == 6){
return new Shear6<T>(extract<T>(t[0]), extract<T>(t[1]), extract<T>(t[2]),
extract<T>(t[3]), extract<T>(t[4]), extract<T>(t[5]));
}
else
THROW(IEX_NAMESPACE::LogicExc, "Shear6 expects tuple of length 3 or 6");
}
template <class T>
static Shear6<T> * shearConstructor1(T a)
{
return new Shear6<T>(a, a, a, a, a, a);
}
template <class T, class S>
static Shear6<T> * shearConversionConstructor(const Shear6<S> &shear)
{
Shear6<T> *s = new Shear6<T>;
*s = shear;
return s;
}
template <class T>
static const Shear6<T> &
iadd(Shear6<T> &shear, const Shear6<T> &other)
{
MATH_EXC_ON;
return shear += other;
}
template <class T>
static Shear6<T>
add(const Shear6<T> &shear, const Shear6<T> &other)
{
MATH_EXC_ON;
return shear + other;
}
template <class T>
static const Shear6<T> &
isub(Shear6<T> &shear, const Shear6<T> &other)
{
MATH_EXC_ON;
return shear -= other;
}
template <class T>
static Shear6<T>
sub(const Shear6<T> &shear, const Shear6<T> &other)
{
MATH_EXC_ON;
return shear - other;
}
template <class T>
static Shear6<T>
neg(const Shear6<T> &shear)
{
MATH_EXC_ON;
return -shear;
}
template <class T>
static const Shear6<T> &
imul(Shear6<T> &shear, const Shear6<T> &other)
{
MATH_EXC_ON;
return shear *= other;
}
template <class T>
static const Shear6<T> &
imulT(Shear6<T> &shear, T t)
{
MATH_EXC_ON;
return shear *= t;
}
template <class T>
static Shear6<T>
mul(const Shear6<T> &shear, const Shear6<T> &other)
{
MATH_EXC_ON;
return shear * other;
}
template <class T>
static Shear6<T>
mulT(const Shear6<T> &shear, T t)
{
MATH_EXC_ON;
return shear * t;
}
template <class T>
static const Shear6<T> &
idiv(Shear6<T> &shear, const Shear6<T> &other)
{
MATH_EXC_ON;
return shear /= other;
}
template <class T>
static const Shear6<T> &
idivT(Shear6<T> &shear, T t)
{
MATH_EXC_ON;
return shear /= t;
}
template <class T>
static Shear6<T>
div(const Shear6<T> &shear, const Shear6<T> &other)
{
MATH_EXC_ON;
return shear / other;
}
template <class T>
static Shear6<T>
divT(const Shear6<T> &shear, T t)
{
MATH_EXC_ON;
return shear / t;
}
template <class T>
static Shear6<T>
subtract1(Shear6<T> &v, tuple t)
{
MATH_EXC_ON;
Shear6<T> w;
if(t.attr("__len__")() == 6){
w[0] = v[0] - extract<T>(t[0]);
w[1] = v[1] - extract<T>(t[1]);
w[2] = v[2] - extract<T>(t[2]);
w[3] = v[3] - extract<T>(t[3]);
w[4] = v[4] - extract<T>(t[4]);
w[5] = v[5] - extract<T>(t[5]);
}
else
THROW(IEX_NAMESPACE::LogicExc, "tuple must have length of 6");
return w;
}
template <class T>
static Shear6<T>
subtract2(Shear6<T> &v, tuple t)
{
MATH_EXC_ON;
Shear6<T> w;
if(t.attr("__len__")() == 6){
w[0] = extract<T>(t[0]) - v[0];
w[1] = extract<T>(t[1]) - v[1];
w[2] = extract<T>(t[2]) - v[2];
w[3] = extract<T>(t[3]) - v[3];
w[4] = extract<T>(t[4]) - v[4];
w[5] = extract<T>(t[5]) - v[5];
}
else
THROW(IEX_NAMESPACE::LogicExc, "tuple must have length of 6");
return w;
}
template <class T>
static Shear6<T>
subtractT1(Shear6<T> &v, T a)
{
MATH_EXC_ON;
Shear6<T> w;
w[0] = v[0] - a;
w[1] = v[1] - a;
w[2] = v[2] - a;
w[3] = v[3] - a;
w[4] = v[4] - a;
w[5] = v[5] - a;
return w;
}
template <class T>
static Shear6<T>
subtractT2(Shear6<T> &v, T a)
{
MATH_EXC_ON;
Shear6<T> w;
w[0] = a - v[0];
w[1] = a - v[1];
w[2] = a - v[2];
w[3] = a - v[3];
w[4] = a - v[4];
w[5] = a - v[5];
return w;
}
template <class T>
static Shear6<T>
addTuple(Shear6<T> &v, tuple t)
{
MATH_EXC_ON;
Shear6<T> w;
if(t.attr("__len__")() == 6){
w[0] = v[0] + extract<T>(t[0]);
w[1] = v[1] + extract<T>(t[1]);
w[2] = v[2] + extract<T>(t[2]);
w[3] = v[3] + extract<T>(t[3]);
w[4] = v[4] + extract<T>(t[4]);
w[5] = v[5] + extract<T>(t[5]);
}
else
THROW(IEX_NAMESPACE::LogicExc, "tuple must have length of 6");
return w;
}
template <class T>
static Shear6<T>
addT(Shear6<T> &v, T a)
{
MATH_EXC_ON;
Shear6<T> w;
w[0] = v[0] + a;
w[1] = v[1] + a;
w[2] = v[2] + a;
w[3] = v[3] + a;
w[4] = v[4] + a;
w[5] = v[5] + a;
return w;
}
template <class T>
static Shear6<T>
multTuple(Shear6<T> &v, tuple t)
{
MATH_EXC_ON;
Shear6<T> w;
if(t.attr("__len__")() == 6){
w[0] = v[0] * extract<T>(t[0]);
w[1] = v[1] * extract<T>(t[1]);
w[2] = v[2] * extract<T>(t[2]);
w[3] = v[3] * extract<T>(t[3]);
w[4] = v[4] * extract<T>(t[4]);
w[5] = v[5] * extract<T>(t[5]);
}
else
THROW(IEX_NAMESPACE::LogicExc, "tuple must have length of 6");
return w;
}
template <class T>
static Shear6<T>
rdiv(Shear6<T> &v, T a)
{
MATH_EXC_ON;
Shear6<T> w;
if(v != Shear6<T>()){
w[0] = a/v[0];
w[1] = a/v[1];
w[2] = a/v[2];
w[3] = a/v[3];
w[4] = a/v[4];
w[5] = a/v[5];
}
else
THROW(IEX_NAMESPACE::LogicExc, "Division by Zero");
return w;
}
template <class T>
static Shear6<T>
divTuple(Shear6<T> &v, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() != 6)
THROW(IEX_NAMESPACE::LogicExc, "Shear6 expects tuple of length 6");
Shear6<T> w;
for(int i = 0; i < 6; ++i)
{
T a = extract<T>(t[i]);
if(a != T (0))
w[i] = v[i] / a;
else
THROW(IEX_NAMESPACE::LogicExc, "Division by Zero");
}
return w;
}
template <class T>
static Shear6<T>
rdivTuple(Shear6<T> &v, const tuple &t)
{
MATH_EXC_ON;
if(t.attr("__len__")() != 6)
THROW(IEX_NAMESPACE::LogicExc, "Shear6 expects tuple of length 6");
Shear6<T> w;
for(int i = 0; i < 6; ++i)
{
T a = extract<T>(t[i]);
if(v[i] != T (0))
w[i] = a / v[i];
else
THROW(IEX_NAMESPACE::LogicExc, "Division by Zero");
}
return w;
}
template <class T>
static bool
lessThan(Shear6<T> &v, const Shear6<T> &w)
{
bool isLessThan = (v[0] <= w[0] && v[1] <= w[1] && v[2] <= w[2]
&& v[3] <= w[3] && v[4] <= w[4] && v[5] <= w[5])
&& v != w;
return isLessThan;
}
template <class T>
static bool
greaterThan(Shear6<T> &v, const Shear6<T> &w)
{
bool isGreaterThan = (v[0] >= w[0] && v[1] >= w[1] && v[2] >= w[2]
&& v[3] >= w[3] && v[4] >= w[4] && v[5] >= w[5])
&& v != w;
return isGreaterThan;
}
template <class T>
static bool
lessThanEqual(Shear6<T> &v, const Shear6<T> &w)
{
bool isLessThanEqual = (v[0] <= w[0] && v[1] <= w[1] && v[2] <= w[2]
&& v[3] <= w[3] && v[4] <= w[4] && v[5] <= w[5]);
return isLessThanEqual;
}
template <class T>
static bool
greaterThanEqual(Shear6<T> &v, const Shear6<T> &w)
{
bool isGreaterThanEqual = (v[0] >= w[0] && v[1] >= w[1] && v[2] >= w[2]
&& v[3] >= w[3] && v[4] >= w[4] && v[5] >= w[5]);
return isGreaterThanEqual;
}
template <class T>
static T
getitem(Shear6<T> &shear, int i)
{
return shear[i];
}
template <class T>
static void
setitem(Shear6<T> &shear, int i, T a)
{
if(i < 0 || i > 5)
THROW(IEX_NAMESPACE::LogicExc, "Index out of range");
shear[i] = a;
}
template <class T>
static int
len(Shear6<T> &shear)
{
return 6;
}
template <class T>
class_<Shear6<T> >
register_Shear()
{
const char *name = ShearName<T>::value;
void (IMATH_NAMESPACE::Shear6<T>::*setValue1)(T,T,T,T,T,T) = &IMATH_NAMESPACE::Shear6<T>::setValue;
void (IMATH_NAMESPACE::Shear6<T>::*setValue2)(const Shear6<T> &) = &IMATH_NAMESPACE::Shear6<T>::setValue;
void (IMATH_NAMESPACE::Shear6<T>::*getValue1)(Shear6<T> &) const = &IMATH_NAMESPACE::Shear6<T>::getValue;
class_<Shear6<T> > shear_class(name, name, init<Shear6<T> >("copy construction"));
shear_class
.def(init<>("default construction: (0 0 0 0 0 0)"))
.def(init<T,T,T>("Shear(XY,XZ,YZ) construction: (XY XZ YZ 0 0 0)"))
.def(init<const Vec3<float> &>("Shear(v) construction: (v.x v.y v.z 0 0 0)"))
.def(init<const Vec3<double> &>("Shear(v) construction: (v.x v.y v.z 0 0 0)"))
.def(init<const Vec3<int> &>("Shear(v) construction: (v.x v.y v.z 0 0 0)"))
.def(init<T,T,T,T,T,T>("Shear(XY, XZ, YZ, YX, ZX, ZY) construction"))
.def("__init__", make_constructor(shearConstructor1<T>))
.def("__init__", make_constructor(shearTupleConstructor<T>),"Construction from tuple")
.def("__init__", make_constructor(shearConversionConstructor<T,float>))
.def("__init__", make_constructor(shearConversionConstructor<T,double>))
.def("__init__", make_constructor(shearConversionConstructor<T,int>))
.def("__iadd__",&iadd<T>,return_internal_reference<>())
.def("__add__",&add<T>)
.def("__isub__",&isub<T>,return_internal_reference<>())
.def("__sub__",&sub<T>)
.def("__neg__",&neg<T>)
.def("__imul__",&imul<T>,return_internal_reference<>())
.def("__imul__",&imulT<T>,return_internal_reference<>())
.def("__mul__",&mul<T>)
.def("__mul__",&mulT<T>)
.def("__rmul__",&mulT<T>)
.def("__idiv__",&idiv<T>,return_internal_reference<>())
.def("__idiv__",&idivT<T>,return_internal_reference<>())
.def("__itruediv__",&idiv<T>,return_internal_reference<>())
.def("__itruediv__",&idivT<T>,return_internal_reference<>())
.def("__div__",&div<T>)
.def("__div__",&divT<T>)
.def("__truediv__",&div<T>)
.def("__truediv__",&divT<T>)
.def(self == self)
.def(self != self)
.def("__str__",&Shear_str<T>)
.def("__repr__",&Shear_repr<T>)
.def("setValue", setValue1)
.def("setValue", setValue2)
.def("getValue", getValue1)
.def("negate", &Shear6<T>::negate, return_internal_reference<>())
.def("baseTypeMin", &Shear6<T>::baseTypeMin)
.staticmethod("baseTypeMin")
.def("baseTypeMax", &Shear6<T>::baseTypeMax)
.staticmethod("baseTypeMax")
.def("baseTypeSmallest", &Shear6<T>::baseTypeSmallest)
.staticmethod("baseTypeSmallest")
.def("baseTypeEpsilon", &Shear6<T>::baseTypeEpsilon)
.staticmethod("baseTypeEpsilon")
.def("equalWithAbsError", &Shear6<T>::equalWithAbsError)
.def("equalWithRelError", &Shear6<T>::equalWithRelError)
.def("__sub__", &subtract1<T>)
.def("__sub__", &subtractT1<T>)
.def("__rsub__", &subtract2<T>)
.def("__rsub__", &subtractT2<T>)
.def("__add__", &addTuple<T>)
.def("__add__", &addT<T>)
.def("__radd__", &addTuple<T>)
.def("__radd__", &addT<T>)
.def("__mul__", &multTuple<T>)
.def("__rmul__", &multTuple<T>)
.def("__div__", &divTuple<T>)
.def("__truediv__", &divTuple<T>)
.def("__rdiv__", &rdiv<T>)
.def("__rdiv__", &rdivTuple<T>)
.def("__lt__", &lessThan<T>)
.def("__gt__", &greaterThan<T>)
.def("__le__", &lessThanEqual<T>)
.def("__ge__", &greaterThanEqual<T>)
.def("__getitem__", &getitem<T>)
.def("__setitem__", &setitem<T>)
.def("__len__", &len<T>)
;
decoratecopy(shear_class);
return shear_class;
}
template PYIMATH_EXPORT class_<Shear6<float> > register_Shear();
template PYIMATH_EXPORT class_<Shear6<double> > register_Shear();
}//namespace PyIMath

View File

@ -0,0 +1,154 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathShear_h_
#define _PyImathShear_h_
#include <Python.h>
#include <boost/python.hpp>
#include <ImathShear.h>
namespace PyImath {
template <class T> boost::python::class_<IMATH_NAMESPACE::Shear6<T> > register_Shear();
//
// Other code in the Zeno code base assumes the existance of a class with the
// same name as the Imath class, and with static functions wrap() and
// convert() to produce a PyImath object from an Imath object and vice-versa,
// respectively. The class Boost generates from the Imath class does not
// have these properties, so we define a companion class here.
// The template argument, T, is the element type (e.g.,float, double).
template <class T>
class S6 {
public:
static PyObject * wrap (const IMATH_NAMESPACE::Shear6<T> &s);
static int convert (PyObject *p, IMATH_NAMESPACE::Shear6<T> *s);
};
template <class T>
PyObject *
S6<T>::wrap (const IMATH_NAMESPACE::Shear6<T> &s)
{
typename boost::python::return_by_value::apply < IMATH_NAMESPACE::Shear6<T> >::type converter;
PyObject *p = converter (s);
return p;
}
template <class T>
int
S6<T>::convert (PyObject *p, IMATH_NAMESPACE::Shear6<T> *s)
{
boost::python::extract <IMATH_NAMESPACE::Shear6f> extractorShear6f (p);
if (extractorShear6f.check())
{
IMATH_NAMESPACE::Shear6f s6f = extractorShear6f();
float xy, xz, yz, yx, zx, zy;
s6f.getValue (xy, xz, yz, yx, zx, zy);
s->setValue(T(xy), T(xz), T(yz), T(yx), T(zx), T(zy));
return 1;
}
boost::python::extract <IMATH_NAMESPACE::Shear6d> extractorShear6d (p);
if (extractorShear6d.check())
{
IMATH_NAMESPACE::Shear6d s6d = extractorShear6d();
double xy, xz, yz, yx, zx, zy;
s6d.getValue (xy, xz, yz, yx, zx, zy);
s->setValue(T(xy), T(xz), T(yz), T(yx), T(zx), T(zy));
return 1;
}
boost::python::extract <boost::python::tuple> extractorTuple (p);
if (extractorTuple.check())
{
boost::python::tuple t = extractorTuple();
if (t.attr ("__len__") () == 3)
{
double xy = boost::python::extract <double> (t[0]);
double xz = boost::python::extract <double> (t[1]);
double yz = boost::python::extract <double> (t[2]);
s->setValue (T(xy), T(xz), T(yz), T(0), T(0), T(0));
return 1;
}
else if (t.attr ("__len__") () == 6)
{
double xy = boost::python::extract <double> (t[0]);
double xz = boost::python::extract <double> (t[1]);
double yz = boost::python::extract <double> (t[2]);
double yx = boost::python::extract <double> (t[3]);
double zx = boost::python::extract <double> (t[4]);
double zy = boost::python::extract <double> (t[5]);
s->setValue (T(xy), T(xz), T(yz), T(yx), T(zx), T(zy));
return 1;
}
}
boost::python::extract <IMATH_NAMESPACE::V3i> extractorV3i (p);
if (extractorV3i.check())
{
IMATH_NAMESPACE::V3i v3i = extractorV3i();
s->setValue (T(v3i[0]), T(v3i[1]), T(v3i[2]), T(0), T(0), T(0));
return 1;
}
boost::python::extract <IMATH_NAMESPACE::V3f> extractorV3f (p);
if (extractorV3f.check())
{
IMATH_NAMESPACE::V3f v3f = extractorV3f();
s->setValue (T(v3f[0]), T(v3f[1]), T(v3f[2]), T(0), T(0), T(0));
return 1;
}
boost::python::extract <IMATH_NAMESPACE::V3d> extractorV3d (p);
if (extractorV3d.check())
{
IMATH_NAMESPACE::V3d v3d = extractorV3d();
s->setValue (T(v3d[0]), T(v3d[1]), T(v3d[2]), T(0), T(0), T(0));
return 1;
}
return 0;
}
typedef S6<float> Shear6f;
typedef S6<double> Shear6d;
}
#endif

View File

@ -0,0 +1,336 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2009-2012, 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 <PyImathStringArrayRegister.h>
#include <PyImathStringArray.h>
#include <PyImathExport.h>
namespace PyImath {
using namespace boost::python;
template<class T>
StringArrayT<T>* StringArrayT<T>::createDefaultArray(size_t length)
{
return StringArrayT<T>::createUniformArray(T(), length);
}
template<class T>
StringArrayT<T>* StringArrayT<T>::createUniformArray(const T& initialValue, size_t length)
{
typedef boost::shared_array<StringTableIndex> StringTableIndexArrayPtr;
typedef boost::shared_ptr<StringTableT<T> > StringTablePtr;
BOOST_STATIC_ASSERT(boost::is_pod<StringTableIndex>::value);
StringTableIndexArrayPtr indexArray(reinterpret_cast<StringTableIndex*>(new char[sizeof(StringTableIndex)*length]));
StringTablePtr table(new StringTableT<T>);
const StringTableIndex index = table->intern(initialValue);
for(size_t i=0; i<length; ++i)
indexArray[i] = index;
return new StringArrayT<T>(*table, indexArray.get(), length, 1, indexArray, table);
}
template<class T>
StringArrayT<T>* StringArrayT<T>::createFromRawArray(const T* rawArray, size_t length)
{
typedef boost::shared_array<StringTableIndex> StringTableIndexArrayPtr;
typedef boost::shared_ptr<StringTableT<T> > StringTablePtr;
BOOST_STATIC_ASSERT(boost::is_pod<StringTableIndex>::value);
StringTableIndexArrayPtr indexArray(reinterpret_cast<StringTableIndex*>(new char[sizeof(StringTableIndex)*length]));
StringTablePtr table(new StringTableT<T>);
for(size_t i=0; i<length; ++i)
indexArray[i] = table->intern(rawArray[i]);
return new StringArrayT<T>(*table, indexArray.get(), length, 1, indexArray, table);
}
template<class T>
StringArrayT<T>::StringArrayT(StringTableT<T> &table, StringTableIndex *ptr, size_t length, size_t stride, boost::any tableHandle)
: super(ptr,length,stride), _table(table), _tableHandle(tableHandle)
{
// nothing
}
template<class T>
StringArrayT<T>::StringArrayT(StringTableT<T> &table, StringTableIndex *ptr, size_t length, size_t stride, boost::any handle, boost::any tableHandle)
: super(ptr,length,stride,handle), _table(table), _tableHandle(tableHandle)
{
// nothing
}
template<class T>
StringArrayT<T>*
StringArrayT<T>::getslice_string(PyObject *index) const
{
typedef boost::shared_array<StringTableIndex> StringTableIndexArrayPtr;
typedef boost::shared_ptr<StringTableT<T> > StringTablePtr;
BOOST_STATIC_ASSERT(boost::is_pod<StringTableIndex>::value);
size_t start=0, end=0, slicelength=0;
Py_ssize_t step;
extract_slice_indices(index,start,end,step,slicelength);
StringTableIndexArrayPtr indexArray(reinterpret_cast<StringTableIndex*>(new char[sizeof(StringTableIndex)*slicelength]));
StringTablePtr table(new StringTableT<T>);
for(size_t i=0; i<slicelength; ++i)
indexArray[i] = table->intern(getitem_string(start+i*step));
return new StringArrayT<T>(*table, indexArray.get(), slicelength, 1, indexArray, table);
}
template<class T>
void
StringArrayT<T>::setitem_string_scalar(PyObject *index, const T &data)
{
size_t start=0, end=0, slicelength=0;
Py_ssize_t step;
extract_slice_indices(index,start,end,step,slicelength);
StringTableIndex di = _table.intern(data);
for (size_t i=0; i<slicelength; ++i) {
(*this)[start+i*step] = di;
}
}
template<class T>
void
StringArrayT<T>::setitem_string_scalar_mask(const FixedArray<int> &mask, const T &data)
{
size_t len = match_dimension(mask);
StringTableIndex di = _table.intern(data);
for (size_t i=0; i<len; ++i) {
if (mask[i]) (*this)[i] = di;
}
}
template<class T>
void
StringArrayT<T>::setitem_string_vector(PyObject *index, const StringArrayT<T> &data)
{
size_t start=0, end=0, slicelength=0;
Py_ssize_t step;
extract_slice_indices(index,start,end,step,slicelength);
// we have a valid range of indices
if (data.len() != slicelength) {
PyErr_SetString(PyExc_IndexError, "Dimensions of source do not match destination");
throw_error_already_set();
}
for (size_t i=0; i<slicelength; ++i) {
StringTableIndex di = _table.intern(data._table.lookup(data[i]));
(*this)[start+i*step] = di;
}
}
template<class T>
void
StringArrayT<T>::setitem_string_vector_mask(const FixedArray<int> &mask, const StringArrayT<T> &data)
{
size_t len = match_dimension(mask);
if (data.len() == len) {
for (size_t i=0; i<len; ++i) {
if (mask[i]) {
StringTableIndex di = _table.intern(data._table.lookup(data[i]));
(*this)[i] = di;
}
}
} else {
size_t count = 0;
for (size_t i=0; i<len; ++i) {
if (mask[i]) count += 1;
}
if (data.len() != count) {
PyErr_SetString(PyExc_IndexError, "Dimensions of source data do not match destination either masked or unmasked");
throw_error_already_set();
}
size_t dataIndex = 0;
for (size_t i=0; i<len; ++i) {
if (mask[i]) {
StringTableIndex di = _table.intern(data._table.lookup(data[dataIndex]));
(*this)[i] = di;
dataIndex += 1;
}
}
}
}
template<class T>
FixedArray<int> operator == (const StringArrayT<T> &a0, const StringArrayT<T> &a1) {
size_t len = a0.match_dimension(a1);
FixedArray<int> f(len);
const StringTableT<T> &t0 = a0.stringTable();
const StringTableT<T> &t1 = a1.stringTable();
for (size_t i=0;i<len;++i) {
f[i] = t0.lookup(a0[i])==t1.lookup(a1[i]);
}
return f;
}
template<class T>
FixedArray<int> operator == (const StringArrayT<T> &a0, const T &v1) {
size_t len = a0.len();
FixedArray<int> f(len);
const StringTableT<T> &t0 = a0.stringTable();
if (t0.hasString(v1)) {
StringTableIndex v1i = t0.lookup(v1);
for (size_t i=0;i<len;++i) {
f[i] = a0[i]==v1i;
}
} else {
for (size_t i=0;i<len;++i) {
f[i] = 0;
}
}
return f;
}
template<class T>
FixedArray<int> operator == (const T &v1,const StringArrayT<T> &a0) {
return a0 == v1;
}
template<class T>
FixedArray<int> operator != (const StringArrayT<T> &a0, const StringArrayT<T> &a1) {
size_t len = a0.match_dimension(a1);
FixedArray<int> f(len);
const StringTableT<T> &t0 = a0.stringTable();
const StringTableT<T> &t1 = a1.stringTable();
for (size_t i=0;i<len;++i) {
f[i] = t0.lookup(a0[i])!=t1.lookup(a1[i]);
}
return f;
}
template<class T>
FixedArray<int> operator != (const StringArrayT<T> &a0, const T &v1) {
size_t len = a0.len();
FixedArray<int> f(len);
const StringTableT<T> &t0 = a0.stringTable();
if (t0.hasString(v1)) {
StringTableIndex v1i = t0.lookup(v1);
for (size_t i=0;i<len;++i) {
f[i] = a0[i]!=v1i;
}
} else {
for (size_t i=0;i<len;++i) {
f[i] = 1;
}
}
return f;
}
template<class T>
FixedArray<int> operator != (const T &v1,const StringArrayT<T> &a0) {
return a0 != v1;
}
template<> PYIMATH_EXPORT StringTableIndex FixedArrayDefaultValue<StringTableIndex>::value() { return StringTableIndex(0); }
template<> PYIMATH_EXPORT const char* FixedArray<StringTableIndex>::name() { return "StringTableArray"; }
template class PYIMATH_EXPORT StringArrayT<std::string>;
template class PYIMATH_EXPORT StringArrayT<std::wstring>;
template FixedArray<int> operator == (const StringArray& a0, const StringArray& a1);
template FixedArray<int> operator == (const StringArray& a0, const std::string& v1);
template FixedArray<int> operator == (const std::string& a0, const StringArray& v1);
template FixedArray<int> operator != (const StringArray& a0, const StringArray& a1);
template FixedArray<int> operator != (const StringArray& a0, const std::string& v1);
template FixedArray<int> operator != (const std::string& a0, const StringArray& v1);
template FixedArray<int> operator == (const WstringArray& a0, const WstringArray& a1);
template FixedArray<int> operator == (const WstringArray& a0, const std::wstring& v1);
template FixedArray<int> operator == (const std::wstring& a0, const WstringArray& v1);
template FixedArray<int> operator != (const WstringArray& a0, const WstringArray& a1);
template FixedArray<int> operator != (const WstringArray& a0, const std::wstring& v1);
template FixedArray<int> operator != (const std::wstring& a0, const WstringArray& v1);
void register_StringArrays()
{
typedef StringArrayT<std::string> StringArray;
typedef StringArrayT<std::wstring> WstringArray;
class_<StringArray> string_array_class =
class_<StringArray>("StringArray",no_init);
string_array_class
.def("__init__", make_constructor(StringArray::createDefaultArray))
.def("__init__", make_constructor(StringArray::createUniformArray))
.def("__getitem__", &StringArray::getslice_string, return_value_policy<manage_new_object>())
.def("__getitem__", &StringArray::getitem_string)
.def("__setitem__", &StringArray::setitem_string_scalar)
.def("__setitem__", &StringArray::setitem_string_scalar_mask)
.def("__setitem__", &StringArray::setitem_string_vector)
.def("__setitem__", &StringArray::setitem_string_vector_mask)
.def("__len__",&StringArray::len)
.def(self == self)
.def(self == other<std::string>())
.def(other<std::string>() == self)
.def(self != self)
.def(self != other<std::string>())
.def(other<std::string>() != self)
;
class_<WstringArray> wstring_array_class =
class_<WstringArray>("WstringArray",no_init);
wstring_array_class
.def("__init__", make_constructor(WstringArray::createDefaultArray))
.def("__init__", make_constructor(WstringArray::createUniformArray))
.def("__getitem__", &WstringArray::getslice_string, return_value_policy<manage_new_object>())
.def("__getitem__", &WstringArray::getitem_string)
.def("__setitem__", &WstringArray::setitem_string_scalar)
.def("__setitem__", &WstringArray::setitem_string_scalar_mask)
.def("__setitem__", &WstringArray::setitem_string_vector)
.def("__setitem__", &WstringArray::setitem_string_vector_mask)
.def("__len__",&WstringArray::len)
.def(self == self)
.def(self == other<std::wstring>())
.def(other<std::wstring>() == self)
.def(self != self)
.def(self != other<std::wstring>())
.def(other<std::wstring>() != self)
;
}
} // namespace PyImath

View File

@ -0,0 +1,103 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2009-2012, 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathStringArray_h_
#define _PyImathStringArray_h_
#include <PyImathFixedArray.h>
#include <PyImathStringTable.h>
//
// A fixed lengy array class for string and wide string type in python.
// The implementation of StringArray is does not follow other FixeArray
// types. StringArray de-duplicate repeated strings using StringTable
// internally for compact memory usage.
//
namespace PyImath {
template <class T>
class StringArrayT : public FixedArray<StringTableIndex>
{
public:
typedef T BaseType;
typedef FixedArray<StringTableIndex> super;
static StringArrayT<T>* createDefaultArray(size_t length);
static StringArrayT<T>* createUniformArray(const T& initialValue, size_t length);
static StringArrayT<T>* createFromRawArray(const T* rawArray, size_t length);
StringArrayT(StringTableT<T> &table, StringTableIndex *ptr, size_t length, size_t stride = 1, boost::any tableHandle = boost::any());
StringArrayT(StringTableT<T> &table, StringTableIndex *ptr, size_t length, size_t stride, boost::any handle, boost::any tableHandle = boost::any()) ;
const StringTableT<T> & stringTable() const { return _table; }
T getitem_string(Py_ssize_t index) const {return _table.lookup(getitem(index)); }
StringArrayT* getslice_string(PyObject *index) const;
void setitem_string_scalar(PyObject *index, const T &data);
void setitem_string_scalar_mask(const FixedArray<int> &mask, const T &data);
void setitem_string_vector(PyObject *index, const StringArrayT<T> &data);
void setitem_string_vector_mask(const FixedArray<int> &mask, const StringArrayT<T> &data);
private:
typedef StringArrayT<T> this_type;
StringTableT<T> &_table;
// StringArray can borrow a string table from somewhere else or maintain
// its own string table. This handle optionally stores a shared pointer to
// a allocated StringTable class instance
boost::any _tableHandle;
};
template<class T>
FixedArray<int> operator == (const StringArrayT<T> &a0, const StringArrayT<T> &a1);
template<class T>
FixedArray<int> operator == (const StringArrayT<T> &a0, const T &v1);
template<class T>
FixedArray<int> operator == (const T &v1,const StringArrayT<T> &a0);
template<class T>
FixedArray<int> operator != (const StringArrayT<T> &a0, const StringArrayT<T> &a1);
template<class T>
FixedArray<int> operator != (const StringArrayT<T> &a0, const T &v1);
template<class T>
FixedArray<int> operator != (const T &v1,const StringArrayT<T> &a0);
typedef StringArrayT<std::string> StringArray;
typedef StringArrayT<std::wstring> WstringArray;
} // namespace PyImath
#endif

View File

@ -0,0 +1,46 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2009-2012, 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathStringArrayRegister_h_
#define _PyImathStringArrayRegister_h_
#include <PyImathExport.h>
namespace PyImath {
PYIMATH_EXPORT void register_StringArrays();
}
#endif

View File

@ -0,0 +1,126 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2009-2012, 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 <PyImathStringTable.h>
#include <Iex.h>
#include <limits>
#include <PyImathExport.h>
namespace PyImath {
template<class T>
StringTableIndex
StringTableT<T>::lookup(const T &s) const
{
typedef typename Table::template nth_index<1>::type StringSet;
const StringSet &strings = _table.template get<1>();
typename StringSet::const_iterator it = strings.find(s);
if (it == strings.end()) {
throw IEX_NAMESPACE::ArgExc("String table access out of bounds");
}
return it->i;
}
template<class T>
const T &
StringTableT<T>::lookup(StringTableIndex index) const
{
typedef typename Table::template nth_index<0>::type IndexSet;
const IndexSet &indices = _table.template get<0>();
typename IndexSet::const_iterator it = indices.find(index);
if (it == indices.end()) {
throw IEX_NAMESPACE::ArgExc("String table access out of bounds");
}
return it->s;
}
template<class T>
StringTableIndex
StringTableT<T>::intern(const T &s)
{
typedef typename Table::template nth_index<1>::type StringSet;
const StringSet &strings = _table.template get<1>();
typename StringSet::const_iterator it = strings.find(s);
if (it == strings.end()) {
size_t next_index = _table.size();
if (next_index > std::numeric_limits<StringTableIndex::index_type>::max()) {
throw IEX_NAMESPACE::ArgExc("Unable to intern string - string table would exceed maximum size");
}
StringTableIndex index = StringTableIndex(StringTableIndex::index_type(next_index));
_table.insert(StringTableEntry<T>(index,s));
return index;
}
return it->i;
}
template<class T>
size_t
StringTableT<T>::size() const
{
return _table.size();
}
template<class T>
bool
StringTableT<T>::hasString(const T &s) const
{
typedef typename Table::template nth_index<1>::type StringSet;
const StringSet &strings = _table.template get<1>();
return strings.find(s) != strings.end();
}
template<class T>
bool
StringTableT<T>::hasStringIndex(const StringTableIndex &s) const
{
typedef typename Table::template nth_index<0>::type IndexSet;
const IndexSet &indices = _table.template get<0>();
return indices.find(s) != indices.end();
}
namespace {
template class PYIMATH_EXPORT StringTableDetailT<std::string>;
template class PYIMATH_EXPORT StringTableDetailT<std::wstring>;
}
template class PYIMATH_EXPORT StringTableT<std::string>;
template class PYIMATH_EXPORT StringTableT<std::wstring>;
} // namespace PyImath

View File

@ -0,0 +1,170 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2009-2012, 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathStringTable_h_
#define _PyImathStringTable_h_
#include <string>
#include <stdint.h>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
namespace PyImath {
// define a separate index type so as not to have
// any confusion between ints and indices
struct StringTableIndex
{
public:
typedef uint32_t index_type;
// the default constructor was a private member before to prevent
// the empty instantiation. But, it became public now to resolve
// a linking error on windows platform. PyImathStringArray is
// exposed with PYIMATH_EXPORT, This causes to expose all the members
// of PyImathFixedArray<StringTableIndex> also.
StringTableIndex() : _index(0) {}
StringTableIndex (const StringTableIndex &si) : _index (si._index) {}
explicit StringTableIndex (index_type i) : _index (i) {}
const StringTableIndex & operator = (const StringTableIndex &si)
{
_index = si._index; return *this;
}
bool operator == (const StringTableIndex &si) const
{
return _index == si._index;
}
bool operator != (const StringTableIndex &si) const
{
return _index != si._index;
}
// operator less for sorting
bool operator < (const StringTableIndex &si) const
{
return _index < si._index;
}
index_type index() const { return _index; }
private:
index_type _index;
};
} // namespace PyImath
// Add a type trait for string indices to allow use in an AlignedArray
namespace boost {
template <> struct is_pod< ::PyImath::StringTableIndex>
{
BOOST_STATIC_CONSTANT(bool,value=true);
};
} // namespace boost
namespace PyImath {
//
// A string table entry containing a unique index and string
template<class T>
struct StringTableEntry
{
StringTableEntry(StringTableIndex ii,const T &ss) : i(ii), s(ss) {}
StringTableIndex i;
T s;
};
namespace {
using boost::multi_index_container;
using namespace boost::multi_index;
//
// A map data structure for string strings.
// It exposes two index types : StringTableIndex and string
//
template<class T>
class StringTableDetailT {
public:
typedef boost::multi_index_container<
StringTableEntry<T>,
indexed_by<
ordered_unique<member<StringTableEntry<T>,StringTableIndex,&StringTableEntry<T>::i> >,
ordered_unique<member<StringTableEntry<T>,T,&StringTableEntry<T>::s> >
>
> StringTableContainer;
};
} // namespace
typedef StringTableDetailT<std::string> StringTableDetail;
typedef StringTableDetailT<std::wstring> WStringTableDetail;
//
// Storage class for storing unique string elements.
//
//
template<class T>
class StringTableT
{
public:
// look up a string table entry either by value or index
StringTableIndex lookup(const T &s) const;
const T & lookup(StringTableIndex index) const;
// return the index to a string table entry, adding if not found
StringTableIndex intern(const T &i);
size_t size() const;
bool hasString(const T &s) const;
bool hasStringIndex(const StringTableIndex &s) const;
private:
typedef typename StringTableDetailT<T>::StringTableContainer Table;
Table _table;
};
typedef StringTableT<std::string> StringTable;
typedef StringTableT<std::wstring> WStringTable;
} // namespace PyImath
#endif

View File

@ -0,0 +1,72 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2010-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 <PyImathTask.h>
namespace PyImath {
static WorkerPool *_currentPool = 0;
WorkerPool *
WorkerPool::currentPool()
{
return _currentPool;
}
void
WorkerPool::setCurrentPool(WorkerPool *pool)
{
_currentPool = pool;
}
void
dispatchTask(Task &task,size_t length)
{
if (WorkerPool::currentPool() && !WorkerPool::currentPool()->inWorkerThread())
WorkerPool::currentPool()->dispatch(task,length);
else
task.execute(0,length,0);
}
size_t
workers()
{
if (WorkerPool::currentPool() && !WorkerPool::currentPool()->inWorkerThread())
return WorkerPool::currentPool()->workers();
else
return 1;
}
}

View File

@ -0,0 +1,66 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2010-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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathTask_h_
#define _PyImathTask_h_
#include <PyImathExport.h>
#include <unistd.h>
namespace PyImath {
struct PYIMATH_EXPORT Task
{
virtual ~Task() {}
virtual void execute(size_t start,size_t end) = 0;
virtual void execute(size_t start,size_t end, int tid) {execute(start,end);}
};
struct PYIMATH_EXPORT WorkerPool
{
virtual ~WorkerPool() {}
virtual size_t workers() const = 0;
virtual void dispatch(Task &task,size_t length) = 0;
virtual bool inWorkerThread() const = 0;
static WorkerPool *currentPool();
static void setCurrentPool(WorkerPool *pool);
};
PYIMATH_EXPORT void dispatchTask(Task &task,size_t length);
PYIMATH_EXPORT size_t workers();
}
#endif

View File

@ -0,0 +1,93 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2001-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 <PyImathUtil.h>
#include <Iex.h>
#include <boost/python.hpp>
#include <pystate.h>
namespace PyImath {
PyAcquireLock::PyAcquireLock()
{
_gstate = PyGILState_Ensure();
}
PyAcquireLock::~PyAcquireLock()
{
PyGILState_Release(_gstate);
}
#ifdef PLATFORM_LINUX
// On Windows, this extern is not needed and produces a symbol mismatch at link time.
// We should verify that it's still needed on Linux for Python 2.6.
extern "C" PyThreadState *_PyThreadState_Current;
#endif
static bool
pyHaveLock()
{
// This is very much dependent on the current Python
// implementation of this functionality. If we switch versions of
// Python and the implementation changes, we'll have to change
// this code as well and introduce a #define for the Python
// version.
if (!Py_IsInitialized())
throw IEX_NAMESPACE::LogicExc("PyReleaseLock called without the interpreter initialized");
PyThreadState *myThreadState = PyGILState_GetThisThreadState();
// If the interpreter is initialized the gil is held if the
// current thread's thread state is the current thread state
return myThreadState != 0 && myThreadState == _PyThreadState_Current;
}
PyReleaseLock::PyReleaseLock()
{
// only call PyEval_SaveThread if we have the interpreter lock held,
// otherwise PyReleaseLock is a no-op.
if (pyHaveLock())
_save = PyEval_SaveThread();
else
_save = 0;
}
PyReleaseLock::~PyReleaseLock()
{
if (_save != 0)
PyEval_RestoreThread(_save);
}
} // namespace PyImath

View File

@ -0,0 +1,166 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2001-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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_PYIMATHUTIL_H
#define INCLUDED_PYIMATHUTIL_H
//----------------------------------------------------------------------------
//
// PyImath.h -- miscellaneous classes, functions
// and macros that are useful for Python wrapping
// of C++ objects.
//
//----------------------------------------------------------------------------
#include <PyImathExport.h>
#include <Python.h>
namespace PyImath {
/**
* PyAcquireLock ensures that python is prepared for multi-threaded use and
* ensures that this thread has the global lock.
*
* This object must be instantiated (and continue to be in scope) during all
* threaded api calls. It assumes the python interpretter is instantiated and
* multithreading is enabled.
*
* Note: this is not compatible with additional interpreters (calls to
* Py_NewInterpreter());
*/
class PYIMATH_EXPORT PyAcquireLock
{
public:
PyAcquireLock();
~PyAcquireLock();
private:
PyGILState_STATE _gstate;
};
/**
* This object causes the python global lock to be released for the duration
* of it's existence.
*
* This object should be instantiated (and continue to be in scope) in thread-
* safe c++ functions called from python. This call is designed to be
* instantiated while an AcquireLock is in effect (nested).
*
*/
class PYIMATH_EXPORT PyReleaseLock
{
public:
PyReleaseLock();
~PyReleaseLock();
private:
PyThreadState *_save;
};
/**
* This object is safe object wrapper intended to use with boost python objects.
*
* This object correctly acquires the python lock for creation, copying and
* desctruction of the given object.
*
*/
template <class T>
class PySafeObject
{
public:
PySafeObject()
: _object(0)
{
PyAcquireLock pylock;
_object = new T();
}
PySafeObject(const T &value)
: _object(0)
{
PyAcquireLock pylock;
_object = new T(value);
}
~PySafeObject()
{
PyAcquireLock pylock;
delete _object;
_object = 0;
}
PySafeObject(const PySafeObject &other)
: _object(0)
{
PyAcquireLock pylock;
_object = new T(*other._object);
}
const PySafeObject &
operator = (const PySafeObject &other)
{
if (&other == this) return *this;
PyAcquireLock pylock;
*_object = *other._object;
return *this;
}
bool
operator == (const PySafeObject &other) const
{
if (&other == this) return true;
PyAcquireLock pylock;
return *_object == *other._object;
}
bool
operator != (const PySafeObject &other) const
{
if (&other == this) return false;
PyAcquireLock pylock;
return *_object != *other._object;
}
T & get() { return *_object; }
const T & get() const { return *_object; }
private:
T *_object;
};
} // namespace PyImath
#endif

View File

@ -0,0 +1,472 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathVec_h_
#define _PyImathVec_h_
#include <Python.h>
#include <boost/python.hpp>
#include <PyImath.h>
#include <ImathVec.h>
#include <PyImathFixedArray.h>
namespace PyImath {
template <class T> boost::python::class_<IMATH_NAMESPACE::Vec2<T> > register_Vec2();
template <class T> boost::python::class_<FixedArray<IMATH_NAMESPACE::Vec2<T> > > register_Vec2Array();
typedef FixedArray<IMATH_NAMESPACE::V2s> V2sArray;
typedef FixedArray<IMATH_NAMESPACE::V2i> V2iArray;
typedef FixedArray<IMATH_NAMESPACE::V2f> V2fArray;
typedef FixedArray<IMATH_NAMESPACE::V2d> V2dArray;
// TODO: template <class T> class Vec2Array : public FixedArray<IMATH_NAMESPACE::Vec2<T> >
}
// define vector*float array multiplication
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > operator * (const PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > &a0, T v1) {
PY_IMATH_LEAVE_PYTHON;
size_t len = a0.len(); PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > f(len); for (size_t i=0;i<len;++i) f[i]=a0[i]*v1; return f;
}
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > operator * (T v0, const PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > &a1) { return a1*v0; }
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > operator * (const PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > &a0, const PyImath::FixedArray<T> &a1) {
PY_IMATH_LEAVE_PYTHON;
size_t len = a0.match_dimension(a1); PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > f(len); for (size_t i=0;i<len;++i) f[i]=a0[i]*a1[i]; return f;
}
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > operator * (const PyImath::FixedArray<T> &a0, const PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > &a1) {
return a1*a0;
}
// define vector/float array division
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > operator / (const PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > &a0, T v1) {
PY_IMATH_LEAVE_PYTHON;
size_t len = a0.len(); PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > f(len); for (size_t i=0;i<len;++i) f[i]=a0[i]/v1; return f;
}
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > operator / (const PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > &a0, const PyImath::FixedArray<T> &a1) {
PY_IMATH_LEAVE_PYTHON;
size_t len = a0.match_dimension(a1); PyImath::FixedArray<IMATH_NAMESPACE::Vec2<T> > f(len); for (size_t i=0;i<len;++i) f[i]=a0[i]/a1[i]; return f;
}
namespace PyImath {
template <class T> boost::python::class_<IMATH_NAMESPACE::Vec3<T> > register_Vec3();
template <class T> boost::python::class_<FixedArray<IMATH_NAMESPACE::Vec3<T> > > register_Vec3Array();
typedef FixedArray<IMATH_NAMESPACE::Vec3<unsigned char> > V3cArray;
typedef FixedArray<IMATH_NAMESPACE::V3s> V3sArray;
typedef FixedArray<IMATH_NAMESPACE::V3i> V3iArray;
typedef FixedArray<IMATH_NAMESPACE::V3f> V3fArray;
typedef FixedArray<IMATH_NAMESPACE::V3d> V3dArray;
// TODO: template <class T> class Vec3Array : public FixedArray<IMATH_NAMESPACE::Vec3<T> >
}
// define vector*float array multiplication
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > operator * (const PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > &a0, T v1) {
PY_IMATH_LEAVE_PYTHON;
size_t len = a0.len(); PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > f(len); for (size_t i=0;i<len;++i) f[i]=a0[i]*v1; return f;
}
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > operator * (T v0, const PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > &a1) { return a1*v0; }
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > operator * (const PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > &a0, const PyImath::FixedArray<T> &a1) {
PY_IMATH_LEAVE_PYTHON;
size_t len = a0.match_dimension(a1); PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > f(len); for (size_t i=0;i<len;++i) f[i]=a0[i]*a1[i]; return f;
}
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > operator * (const PyImath::FixedArray<T> &a0, const PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > &a1) {
return a1*a0;
}
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > operator * (const PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > &va, const IMATH_NAMESPACE::M44f &m) {
PY_IMATH_LEAVE_PYTHON;
size_t len = va.len(); PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > f(len); for (size_t i = 0; i < len; ++i) f[i] = va[i] * m; return f;
}
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > operator * (const PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > &va, const IMATH_NAMESPACE::M44d &m) {
PY_IMATH_LEAVE_PYTHON;
size_t len = va.len(); PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > f(len); for (size_t i = 0; i < len; ++i) f[i] = va[i] * m; return f;
}
// define vector/float array division
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > operator / (const PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > &a0, T v1) {
PY_IMATH_LEAVE_PYTHON;
size_t len = a0.len(); PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > f(len); for (size_t i=0;i<len;++i) f[i]=a0[i]/v1; return f;
}
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > operator / (const PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > &a0, const PyImath::FixedArray<T> &a1) {
PY_IMATH_LEAVE_PYTHON;
size_t len = a0.match_dimension(a1); PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> > f(len); for (size_t i=0;i<len;++i) f[i]=a0[i]/a1[i]; return f;
}
namespace PyImath {
template <class T> boost::python::class_<IMATH_NAMESPACE::Vec4<T> > register_Vec4();
template <class T> boost::python::class_<PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > > register_Vec4Array();
typedef FixedArray<IMATH_NAMESPACE::Vec4<unsigned char> > V4cArray;
typedef FixedArray<IMATH_NAMESPACE::V4s> V4sArray;
typedef FixedArray<IMATH_NAMESPACE::V4i> V4iArray;
typedef FixedArray<IMATH_NAMESPACE::V4f> V4fArray;
typedef FixedArray<IMATH_NAMESPACE::V4d> V4dArray;
// TODO: template <class T> class Vec3Array : public FixedArray<IMATH_NAMESPACE::Vec3<T> >
}
// define vector*float array multiplication
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > operator * (const PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > &a0, T v1) {
PY_IMATH_LEAVE_PYTHON;
size_t len = a0.len(); PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > f(len); for (size_t i=0;i<len;++i) f[i]=a0[i]*v1; return f;
}
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > operator * (T v0, const PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > &a1) { return a1*v0; }
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > operator * (const PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > &a0, const PyImath::FixedArray<T> &a1) {
PY_IMATH_LEAVE_PYTHON;
size_t len = a0.match_dimension(a1); PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > f(len); for (size_t i=0;i<len;++i) f[i]=a0[i]*a1[i]; return f;
}
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > operator * (const PyImath::FixedArray<T> &a0, const PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > &a1) {
return a1*a0;
}
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > operator * (const PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > &va, const IMATH_NAMESPACE::M44f &m) {
PY_IMATH_LEAVE_PYTHON;
size_t len = va.len(); PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > f(len); for (size_t i = 0; i < len; ++i) f[i] = va[i] * m; return f;
}
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > operator * (const PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > &va, const IMATH_NAMESPACE::M44d &m) {
PY_IMATH_LEAVE_PYTHON;
size_t len = va.len(); PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > f(len); for (size_t i = 0; i < len; ++i) f[i] = va[i] * m; return f;
}
// define vector/float array division
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > operator / (const PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > &a0, T v1) {
PY_IMATH_LEAVE_PYTHON;
size_t len = a0.len(); PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > f(len); for (size_t i=0;i<len;++i) f[i]=a0[i]/v1; return f;
}
template <class T>
static PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > operator / (const PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > &a0, const PyImath::FixedArray<T> &a1) {
PY_IMATH_LEAVE_PYTHON;
size_t len = a0.match_dimension(a1); PyImath::FixedArray<IMATH_NAMESPACE::Vec4<T> > f(len); for (size_t i=0;i<len;++i) f[i]=a0[i]/a1[i]; return f;
}
//
namespace PyImath {
// Other code in the Zeno code base assumes the existance of a class with the
// same name as the Imath class, and with static functions wrap() and
// convert() to produce a PyImath object from an Imath object and vice-versa,
// respectively. The class Boost generates from the Imath class does not
// have these properties, so we define a companion class here.
// The template argument, T, is the element type for the vector (e.g., int,
// float, double).
template <class T>
class V2 {
public:
static PyObject * wrap (const IMATH_NAMESPACE::Vec2<T> &v);
static int convert (PyObject *p, IMATH_NAMESPACE::Vec2<T> *v);
};
template <class T>
class V3 {
public:
static PyObject * wrap (const IMATH_NAMESPACE::Vec3<T> &v);
static int convert (PyObject *p, IMATH_NAMESPACE::Vec3<T> *v);
};
template <class T>
class V4 {
public:
static PyObject * wrap (const IMATH_NAMESPACE::Vec4<T> &v);
static int convert (PyObject *p, IMATH_NAMESPACE::Vec4<T> *v);
};
template <class T>
PyObject *
V2<T>::wrap (const IMATH_NAMESPACE::Vec2<T> &v)
{
typename boost::python::return_by_value::apply < IMATH_NAMESPACE::Vec2<T> >::type converter;
PyObject *p = converter (v);
return p;
}
template <class T>
PyObject *
V3<T>::wrap (const IMATH_NAMESPACE::Vec3<T> &v)
{
typename boost::python::return_by_value::apply < IMATH_NAMESPACE::Vec3<T> >::type converter;
PyObject *p = converter (v);
return p;
}
template <class T>
PyObject *
V4<T>::wrap (const IMATH_NAMESPACE::Vec4<T> &v)
{
typename boost::python::return_by_value::apply < IMATH_NAMESPACE::Vec4<T> >::type converter;
PyObject *p = converter (v);
return p;
}
template <class T>
int
V2<T>::convert (PyObject *p, IMATH_NAMESPACE::Vec2<T> *v)
{
boost::python::extract <IMATH_NAMESPACE::V2i> extractorV2i (p);
if (extractorV2i.check())
{
IMATH_NAMESPACE::V2i v2i = extractorV2i();
v->setValue (T(v2i[0]), T(v2i[1]));
return 1;
}
boost::python::extract <IMATH_NAMESPACE::V2f> extractorV2f (p);
if (extractorV2f.check())
{
IMATH_NAMESPACE::V2f v2f = extractorV2f();
v->setValue (T(v2f[0]), T(v2f[1]));
return 1;
}
boost::python::extract <IMATH_NAMESPACE::V2d> extractorV2d (p);
if (extractorV2d.check())
{
IMATH_NAMESPACE::V2d v2d = extractorV2d();
v->setValue (T(v2d[0]), T(v2d[1]));
return 1;
}
boost::python::extract <boost::python::tuple> extractorTuple (p);
if (extractorTuple.check())
{
boost::python::tuple t = extractorTuple();
if (t.attr ("__len__") () == 2)
{
// Extracting the tuple elements as doubles and casting them to
// Ts in setValue() works better than extracting them as Ts from
// the start. Extracting them as Ts can fail in certain
// circumstances if T is int and the tuples elemnts are floats.
// In particular, this kind of failure occurs in PyImathBox.h,
// when Box2<int>::convert() is passed a tuple of two tuples of
// floats.
double a = boost::python::extract <double> (t[0]);
double b = boost::python::extract <double> (t[1]);
v->setValue (T(a), T(b));
return 1;
}
}
boost::python::extract <boost::python::list> extractorList (p);
if (extractorList.check())
{
boost::python::list l = extractorList();
if (l.attr ("__len__") () == 2)
{
boost::python::extract <double> extractor0 (l[0]);
boost::python::extract <double> extractor1 (l[1]);
if (extractor0.check() && extractor1.check())
{
v->setValue (T(extractor0()), T(extractor1()));
return 1;
}
}
}
return 0;
}
template <class T>
int
V3<T>::convert (PyObject *p, IMATH_NAMESPACE::Vec3<T> *v)
{
boost::python::extract <IMATH_NAMESPACE::V3i> extractorV3i (p);
if (extractorV3i.check())
{
IMATH_NAMESPACE::V3i v3i = extractorV3i();
v->setValue (T(v3i[0]), T(v3i[1]), T(v3i[2]));
return 1;
}
boost::python::extract <IMATH_NAMESPACE::V3f> extractorV3f (p);
if (extractorV3f.check())
{
IMATH_NAMESPACE::V3f v3f = extractorV3f();
v->setValue (T(v3f[0]), T(v3f[1]), T(v3f[2]));
return 1;
}
boost::python::extract <IMATH_NAMESPACE::V3d> extractorV3d (p);
if (extractorV3d.check())
{
IMATH_NAMESPACE::V3d v3d = extractorV3d();
v->setValue (T(v3d[0]), T(v3d[1]), T(v3d[2]));
return 1;
}
boost::python::extract <boost::python::tuple> extractorTuple (p);
if (extractorTuple.check())
{
boost::python::tuple t = extractorTuple();
if (t.attr ("__len__") () == 3)
{
// See the comment in V2<T>::convert().
double a = boost::python::extract <double> (t[0]);
double b = boost::python::extract <double> (t[1]);
double c = boost::python::extract <double> (t[2]);
v->setValue (T(a), T(b), T(c));
return 1;
}
}
boost::python::extract <boost::python::list> extractorList (p);
if (extractorList.check())
{
boost::python::list l = extractorList();
if (l.attr ("__len__") () == 3)
{
boost::python::extract <double> extractor0 (l[0]);
boost::python::extract <double> extractor1 (l[1]);
boost::python::extract <double> extractor2 (l[2]);
if (extractor0.check() && extractor1.check() &&
extractor2.check())
{
v->setValue (T(extractor0()), T(extractor1()),
T(extractor2()));
return 1;
}
}
}
return 0;
}
template <class T>
int
V4<T>::convert (PyObject *p, IMATH_NAMESPACE::Vec4<T> *v)
{
boost::python::extract <IMATH_NAMESPACE::V4i> extractorV4i (p);
if (extractorV4i.check())
{
IMATH_NAMESPACE::V4i v4i = extractorV4i();
*v = IMATH_NAMESPACE::Vec4<T>(v4i);
return 1;
}
boost::python::extract <IMATH_NAMESPACE::V4f> extractorV4f (p);
if (extractorV4f.check())
{
IMATH_NAMESPACE::V4f v4f = extractorV4f();
*v = IMATH_NAMESPACE::Vec4<T>(v4f);
return 1;
}
boost::python::extract <IMATH_NAMESPACE::V4d> extractorV4d (p);
if (extractorV4d.check())
{
IMATH_NAMESPACE::V4d v4d = extractorV4d();
*v = IMATH_NAMESPACE::Vec4<T>(v4d);
return 1;
}
boost::python::extract <boost::python::tuple> extractorTuple (p);
if (extractorTuple.check())
{
boost::python::tuple t = extractorTuple();
if (t.attr ("__len__") () == 4)
{
// See the comment in V2<T>::convert().
double a = boost::python::extract <double> (t[0]);
double b = boost::python::extract <double> (t[1]);
double c = boost::python::extract <double> (t[2]);
double d = boost::python::extract <double> (t[3]);
*v = IMATH_NAMESPACE::Vec4<T>(T(a), T(b), T(c), T(d));
return 1;
}
}
boost::python::extract <boost::python::list> extractorList (p);
if (extractorList.check())
{
boost::python::list l = extractorList();
if (l.attr ("__len__") () == 4)
{
boost::python::extract <double> extractor0 (l[0]);
boost::python::extract <double> extractor1 (l[1]);
boost::python::extract <double> extractor2 (l[2]);
boost::python::extract <double> extractor3 (l[3]);
if (extractor0.check() && extractor1.check() &&
extractor2.check() && extractor3.check())
{
*v = IMATH_NAMESPACE::Vec4<T>(T(extractor0()), T(extractor1()),
T(extractor2()), T(extractor3()));
return 1;
}
}
}
return 0;
}
typedef V2<int> V2i;
typedef V2<float> V2f;
typedef V2<double> V2d;
typedef V3<int> V3i;
typedef V3<float> V3f;
typedef V3<double> V3d;
typedef V4<int> V4i;
typedef V4<float> V4f;
typedef V4<double> V4d;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 "PyImathVec2Impl.h"
#include "PyImathExport.h"
namespace PyImath {
template <> const char *PyImath::V2fArray::name() { return "V2fArray"; }
template <> const char *PyImath::V2dArray::name() { return "V2dArray"; }
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template<> const char *Vec2Name<float>::value = "V2f";
template<> const char *Vec2Name<double>::value = "V2d";
// Specialization for float to full precision
template <>
std::string Vec2_repr(const Vec2<float> &v)
{
return (boost::format("%s(%.9g, %.9g)")
% Vec2Name<float>::value % v.x % v.y).str();
}
// Specialization for double to full precision
template <>
std::string Vec2_repr(const Vec2<double> &v)
{
return (boost::format("%s(%.17g, %.17g)")
% Vec2Name<double>::value % v.x % v.y).str();
}
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Vec2<float> > register_Vec2<float>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Vec2<double> > register_Vec2<double>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Vec2<float> > > register_Vec2Array<float>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Vec2<double> > > register_Vec2Array<double>();
template<> IMATH_NAMESPACE::Vec2<float> PYIMATH_EXPORT FixedArrayDefaultValue<IMATH_NAMESPACE::Vec2<float> >::value() { return IMATH_NAMESPACE::Vec2<float>(0,0); }
template<> IMATH_NAMESPACE::Vec2<double> PYIMATH_EXPORT FixedArrayDefaultValue<IMATH_NAMESPACE::Vec2<double> >::value() { return IMATH_NAMESPACE::Vec2<double>(0,0); }
}

View File

@ -0,0 +1,57 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 "PyImathVec2Impl.h"
#include "PyImathExport.h"
namespace PyImath {
template <> const char *PyImath::V2sArray::name() { return "V2sArray"; }
template <> const char *PyImath::V2iArray::name() { return "V2iArray"; }
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template<> const char *Vec2Name<short>::value = "V2s";
template<> const char *Vec2Name<int>::value = "V2i";
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Vec2<short> > register_Vec2<short>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Vec2<int> > register_Vec2<int>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Vec2<short> > > register_Vec2Array<short>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Vec2<int> > > register_Vec2Array<int>();
template<> IMATH_NAMESPACE::Vec2<short> PYIMATH_EXPORT FixedArrayDefaultValue<IMATH_NAMESPACE::Vec2<short> >::value() { return IMATH_NAMESPACE::Vec2<short>(0,0); }
template<> IMATH_NAMESPACE::Vec2<int> PYIMATH_EXPORT FixedArrayDefaultValue<IMATH_NAMESPACE::Vec2<int> >::value() { return IMATH_NAMESPACE::Vec2<int>(0,0); }
}

View File

@ -0,0 +1,187 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathVec3ArrayImpl_h_
#define _PyImathVec3ArrayImpl_h_
//
// This .C file was turned into a header file so that instantiations
// of the various V3* types can be spread across multiple files in
// order to work around MSVC limitations.
//
#include <PyImathVec.h>
#include "PyImathDecorators.h"
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/format.hpp>
#include <PyImath.h>
#include <PyImathBox.h>
#include <ImathVec.h>
#include <ImathVecAlgo.h>
#include <Iex.h>
#include <PyImathMathExc.h>
#include <PyImathOperators.h>
#include <PyImathVecOperators.h>
namespace PyImath {
using namespace boost::python;
using namespace IMATH_NAMESPACE;
// XXX fixme - template this
// really this should get generated automatically...
template <class T,int index>
static FixedArray<T>
Vec3Array_get(FixedArray<IMATH_NAMESPACE::Vec3<T> > &va)
{
return FixedArray<T>(&va[0][index],va.len(),3*va.stride(),va.handle());
}
template <class T>
static void
setItemTuple(FixedArray<IMATH_NAMESPACE::Vec3<T> > &va, Py_ssize_t index, const tuple &t)
{
if(t.attr("__len__")() == 3)
{
Vec3<T> v;
v.x = extract<T>(t[0]);
v.y = extract<T>(t[1]);
v.z = extract<T>(t[2]);
va[va.canonical_index(index)] = v;
}
else
THROW(IEX_NAMESPACE::LogicExc, "tuple of length 3 expected");
}
template <class T>
static IMATH_NAMESPACE::Vec3<T>
Vec3Array_min(const FixedArray<IMATH_NAMESPACE::Vec3<T> > &a)
{
Vec3<T> tmp(Vec3<T>(0));
size_t len = a.len();
if (len > 0)
tmp = a[0];
for (size_t i=1; i < len; ++i)
{
if (a[i].x < tmp.x)
tmp.x = a[i].x;
if (a[i].y < tmp.y)
tmp.y = a[i].y;
if (a[i].z < tmp.z)
tmp.z = a[i].z;
}
return tmp;
}
template <class T>
static IMATH_NAMESPACE::Vec3<T>
Vec3Array_max(const FixedArray<IMATH_NAMESPACE::Vec3<T> > &a)
{
Vec3<T> tmp(Vec3<T>(0));
size_t len = a.len();
if (len > 0)
tmp = a[0];
for (size_t i=1; i < len; ++i)
{
if (a[i].x > tmp.x)
tmp.x = a[i].x;
if (a[i].y > tmp.y)
tmp.y = a[i].y;
if (a[i].z > tmp.z)
tmp.z = a[i].z;
}
return tmp;
}
template <class T>
static IMATH_NAMESPACE::Box<IMATH_NAMESPACE::Vec3<T> >
Vec3Array_bounds(const FixedArray<IMATH_NAMESPACE::Vec3<T> > &a)
{
Box<Vec3<T> > tmp;
size_t len = a.len();
for (size_t i=0; i < len; ++i)
tmp.extendBy(a[i]);
return tmp;
}
template <class T>
class_<FixedArray<IMATH_NAMESPACE::Vec3<T> > >
register_Vec3Array()
{
using boost::mpl::true_;
using boost::mpl::false_;
class_<FixedArray<IMATH_NAMESPACE::Vec3<T> > > vec3Array_class = FixedArray<IMATH_NAMESPACE::Vec3<T> >::register_("Fixed length array of IMATH_NAMESPACE::Vec3");
vec3Array_class
.add_property("x",&Vec3Array_get<T,0>)
.add_property("y",&Vec3Array_get<T,1>)
.add_property("z",&Vec3Array_get<T,2>)
.def("__setitem__", &setItemTuple<T>)
.def("min", &Vec3Array_min<T>)
.def("max", &Vec3Array_max<T>)
.def("bounds", &Vec3Array_bounds<T>)
;
add_arithmetic_math_functions(vec3Array_class);
add_comparison_functions(vec3Array_class);
generate_member_bindings<op_vecLength<IMATH_NAMESPACE::Vec3<T> > >(vec3Array_class,"length","");
generate_member_bindings<op_vecLength2<IMATH_NAMESPACE::Vec3<T> > >(vec3Array_class,"length2","");
generate_member_bindings<op_vecNormalize<IMATH_NAMESPACE::Vec3<T> > >(vec3Array_class,"normalize","");
generate_member_bindings<op_vecNormalized<IMATH_NAMESPACE::Vec3<T> > >(vec3Array_class,"normalized","");
generate_member_bindings<op_vec3Cross<T>, true_>(vec3Array_class,"cross","return the cross product of (self,x)",boost::python::args("x"));
generate_member_bindings<op_vecDot<IMATH_NAMESPACE::Vec3<T> >,true_>(vec3Array_class,"dot","return the inner product of (self,x)",boost::python::args("x"));
generate_member_bindings<op_mul<IMATH_NAMESPACE::Vec3<T>,T>, true_>(vec3Array_class,"__mul__" ,"self*x", boost::python::args("x"));
generate_member_bindings<op_mul<IMATH_NAMESPACE::Vec3<T>,IMATH_NAMESPACE::M44f>,false_>(vec3Array_class,"__mul__" ,"self*x", boost::python::args("x"));
generate_member_bindings<op_mul<IMATH_NAMESPACE::Vec3<T>,IMATH_NAMESPACE::M44d>,false_>(vec3Array_class,"__mul__" ,"self*x", boost::python::args("x"));
generate_member_bindings<op_mul<IMATH_NAMESPACE::Vec3<T>,T>, true_>(vec3Array_class,"__rmul__","x*self", boost::python::args("x"));
generate_member_bindings<op_imul<IMATH_NAMESPACE::Vec3<T>,T>, true_>(vec3Array_class,"__imul__","self*=x",boost::python::args("x"));
generate_member_bindings<op_div<IMATH_NAMESPACE::Vec3<T>,T>, true_>(vec3Array_class,"__div__" ,"self/x", boost::python::args("x"));
generate_member_bindings<op_div<IMATH_NAMESPACE::Vec3<T>,T>, true_>(vec3Array_class,"__truediv__" ,"self/x", boost::python::args("x"));
generate_member_bindings<op_idiv<IMATH_NAMESPACE::Vec3<T>,T>, true_>(vec3Array_class,"__idiv__","self/=x",boost::python::args("x"));
generate_member_bindings<op_idiv<IMATH_NAMESPACE::Vec3<T>,T>, true_>(vec3Array_class,"__itruediv__","self/=x",boost::python::args("x"));
decoratecopy(vec3Array_class);
return vec3Array_class;
}
} // namespace PyImath
#endif // _PyImathVec3ArrayImpl_h_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 "PyImathVec3Impl.h"
#include "PyImathVec3ArrayImpl.h"
#include "PyImathExport.h"
namespace PyImath {
template <> const char *PyImath::V3fArray::name() { return "V3fArray"; }
template <> const char *PyImath::V3dArray::name() { return "V3dArray"; }
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template<> const char *Vec3Name<float>::value() { return "V3f"; }
template<> const char *Vec3Name<double>::value() { return "V3d"; }
// Specialization for float to full precision
template <>
std::string Vec3_repr(const Vec3<float> &v)
{
return (boost::format("%s(%.9g, %.9g, %.9g)")
% Vec3Name<float>::value() % v.x % v.y % v.z).str();
}
// Specialization for double to full precision
template <>
std::string Vec3_repr(const Vec3<double> &v)
{
return (boost::format("%s(%.17g, %.17g, %.17g)")
% Vec3Name<double>::value() % v.x % v.y % v.z).str();
}
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Vec3<float> > register_Vec3<float>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Vec3<double> > register_Vec3<double>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Vec3<float> > > register_Vec3Array<float>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Vec3<double> > > register_Vec3Array<double>();
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Vec3<float> PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Vec3<float> >::value() { return IMATH_NAMESPACE::Vec3<float>(0,0,0); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Vec3<double> PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Vec3<double> >::value() { return IMATH_NAMESPACE::Vec3<double>(0,0,0); }
}

View File

@ -0,0 +1,56 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 "PyImathVec3Impl.h"
#include "PyImathExport.h"
namespace PyImath {
template <> const char *PyImath::V3cArray::name() { return "V3cArray"; }
template <> const char *PyImath::V3sArray::name() { return "V3sArray"; }
template <> const char *PyImath::V3iArray::name() { return "V3iArray"; }
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template<> const char *Vec3Name<unsigned char>::value() { return "V3c"; }
template<> const char *Vec3Name<short>::value() { return "V3s"; }
template<> const char *Vec3Name<int>::value() { return "V3i"; }
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Vec3<unsigned char> > register_Vec3<unsigned char>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Vec3<short> > register_Vec3<short>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Vec3<int> > register_Vec3<int>();
}

View File

@ -0,0 +1,50 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 "PyImathVec3ArrayImpl.h"
#include "PyImathExport.h"
namespace PyImath {
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Vec3<unsigned char> > > register_Vec3Array<unsigned char>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Vec3<short> > > register_Vec3Array<short>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Vec3<int> > > register_Vec3Array<int>();
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Vec3<unsigned char> PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Vec3<unsigned char> >::value() { return IMATH_NAMESPACE::Vec3<unsigned char>(0,0,0); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Vec3<short> PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Vec3<short> >::value() { return IMATH_NAMESPACE::Vec3<short>(0,0,0); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Vec3<int> PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Vec3<int> >::value() { return IMATH_NAMESPACE::Vec3<int>(0,0,0); }
}

View File

@ -0,0 +1,175 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathVec4ArrayImpl_h_
#define _PyImathVec4ArrayImpl_h_
//
// This .C file was turned into a header file so that instantiations
// of the various V4* types can be spread across multiple files in
// order to work around MSVC limitations.
//
#include <PyImathVec.h>
#include "PyImathDecorators.h"
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/format.hpp>
#include <PyImath.h>
#include <ImathVec.h>
#include <ImathVecAlgo.h>
#include <Iex.h>
#include <PyImathMathExc.h>
#include <PyImathOperators.h>
#include <PyImathVecOperators.h>
namespace PyImath {
using namespace boost::python;
using namespace IMATH_NAMESPACE;
// XXX fixme - template this
// really this should get generated automatically...
template <class T,int index>
static FixedArray<T>
Vec4Array_get(FixedArray<IMATH_NAMESPACE::Vec4<T> > &va)
{
return FixedArray<T>(&va[0][index],va.len(),4*va.stride(),va.handle());
}
template <class T>
static void
setItemTuple(FixedArray<IMATH_NAMESPACE::Vec4<T> > &va, Py_ssize_t index, const tuple &t)
{
if(t.attr("__len__")() == 4)
{
Vec4<T> v;
v.x = extract<T>(t[0]);
v.y = extract<T>(t[1]);
v.z = extract<T>(t[2]);
v.w = extract<T>(t[3]);
va[va.canonical_index(index)] = v;
}
else
THROW(IEX_NAMESPACE::LogicExc, "tuple of length 4 expected");
}
template <class T>
static IMATH_NAMESPACE::Vec4<T>
Vec4Array_min(const FixedArray<IMATH_NAMESPACE::Vec4<T> > &a) {
Vec4<T> tmp(Vec4<T>(0));
size_t len = a.len();
if (len > 0)
tmp = a[0];
for (size_t i=1; i < len; ++i)
{
if (a[i].x < tmp.x)
tmp.x = a[i].x;
if (a[i].y < tmp.y)
tmp.y = a[i].y;
if (a[i].z < tmp.z)
tmp.z = a[i].z;
if (a[i].w < tmp.w)
tmp.w = a[i].w;
}
return tmp;
}
template <class T>
static IMATH_NAMESPACE::Vec4<T>
Vec4Array_max(const FixedArray<IMATH_NAMESPACE::Vec4<T> > &a)
{
Vec4<T> tmp(Vec4<T>(0));
size_t len = a.len();
if (len > 0)
tmp = a[0];
for (size_t i=1; i < len; ++i)
{
if (a[i].x > tmp.x)
tmp.x = a[i].x;
if (a[i].y > tmp.y)
tmp.y = a[i].y;
if (a[i].z > tmp.z)
tmp.z = a[i].z;
if (a[i].w > tmp.w)
tmp.w = a[i].w;
}
return tmp;
}
template <class T>
class_<FixedArray<IMATH_NAMESPACE::Vec4<T> > >
register_Vec4Array()
{
using boost::mpl::true_;
class_<FixedArray<IMATH_NAMESPACE::Vec4<T> > > vec4Array_class = FixedArray<IMATH_NAMESPACE::Vec4<T> >::register_("Fixed length array of IMATH_NAMESPACE::Vec4");
vec4Array_class
.add_property("x",&Vec4Array_get<T,0>)
.add_property("y",&Vec4Array_get<T,1>)
.add_property("z",&Vec4Array_get<T,2>)
.add_property("w",&Vec4Array_get<T,3>)
.def("__setitem__", &setItemTuple<T>)
.def("min", &Vec4Array_min<T>)
.def("max", &Vec4Array_max<T>)
;
add_arithmetic_math_functions(vec4Array_class);
add_comparison_functions(vec4Array_class);
generate_member_bindings<op_vecLength<IMATH_NAMESPACE::Vec4<T> > >(vec4Array_class,"length","");
generate_member_bindings<op_vecLength2<IMATH_NAMESPACE::Vec4<T> > >(vec4Array_class,"length2","");
generate_member_bindings<op_vecNormalize<IMATH_NAMESPACE::Vec4<T> > >(vec4Array_class,"normalize","");
generate_member_bindings<op_vecNormalized<IMATH_NAMESPACE::Vec4<T> > >(vec4Array_class,"normalized","");
generate_member_bindings<op_vecDot<IMATH_NAMESPACE::Vec4<T> >,true_>(vec4Array_class,"dot","return the inner product of (self,x)",boost::python::args("x"));
generate_member_bindings<op_mul<IMATH_NAMESPACE::Vec4<T>,T>, true_>(vec4Array_class,"__mul__" ,"self*x", boost::python::args("x"));
generate_member_bindings<op_mul<IMATH_NAMESPACE::Vec4<T>,T>, true_>(vec4Array_class,"__rmul__","x*self", boost::python::args("x"));
generate_member_bindings<op_imul<IMATH_NAMESPACE::Vec4<T>,T>, true_>(vec4Array_class,"__imul__","self*=x",boost::python::args("x"));
generate_member_bindings<op_div<IMATH_NAMESPACE::Vec4<T>,T>, true_>(vec4Array_class,"__div__" ,"self/x", boost::python::args("x"));
generate_member_bindings<op_div<IMATH_NAMESPACE::Vec4<T>,T>, true_>(vec4Array_class,"__truediv__" ,"self/x", boost::python::args("x"));
generate_member_bindings<op_idiv<IMATH_NAMESPACE::Vec4<T>,T>, true_>(vec4Array_class,"__idiv__","self/=x",boost::python::args("x"));
generate_member_bindings<op_idiv<IMATH_NAMESPACE::Vec4<T>,T>, true_>(vec4Array_class,"__itruediv__","self/=x",boost::python::args("x"));
decoratecopy(vec4Array_class);
return vec4Array_class;
}
} // namespace PyImath
#endif // _PyImathVec4ArrayImpl_h_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 "PyImathVec4Impl.h"
#include "PyImathVec4ArrayImpl.h"
#include "PyImathExport.h"
namespace PyImath {
template <> const char *PyImath::V4fArray::name() { return "V4fArray"; }
template <> const char *PyImath::V4dArray::name() { return "V4dArray"; }
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template<> const char *Vec4Name<float>::value() { return "V4f"; }
template<> const char *Vec4Name<double>::value() { return "V4d"; }
// Specialization for float to full precision
template <>
std::string Vec4_repr(const Vec4<float> &v)
{
return (boost::format("%s(%.9g, %.9g, %.9g, %.9g)")
% Vec4Name<float>::value() % v.x % v.y % v.z % v.w).str();
}
// Specialization for double to full precision
template <>
std::string Vec4_repr(const Vec4<double> &v)
{
return (boost::format("%s(%.17g, %.17g, %.17g, %.17g)")
% Vec4Name<double>::value() % v.x % v.y % v.z % v.w).str();
}
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Vec4<float> > register_Vec4<float>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Vec4<double> > register_Vec4<double>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Vec4<float> > > register_Vec4Array<float>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Vec4<double> > > register_Vec4Array<double>();
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Vec4<float> PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Vec4<float> >::value() { return IMATH_NAMESPACE::Vec4<float>(0,0,0,0); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Vec4<double> PyImath::FixedArrayDefaultValue<IMATH_NAMESPACE::Vec4<double> >::value() { return IMATH_NAMESPACE::Vec4<double>(0,0,0,0); }
}

View File

@ -0,0 +1,56 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 "PyImathVec4Impl.h"
#include "PyImathExport.h"
namespace PyImath {
template <> const char *PyImath::V4cArray::name() { return "V4cArray"; }
template <> const char *PyImath::V4sArray::name() { return "V4sArray"; }
template <> const char *PyImath::V4iArray::name() { return "V4iArray"; }
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template<> const char *Vec4Name<unsigned char>::value() { return "V4c"; }
template<> const char *Vec4Name<short>::value() { return "V4s"; }
template<> const char *Vec4Name<int>::value() { return "V4i"; }
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Vec4<unsigned char> > register_Vec4<unsigned char>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Vec4<short> > register_Vec4<short>();
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Vec4<int> > register_Vec4<int>();
}

View File

@ -0,0 +1,50 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 "PyImathVec4ArrayImpl.h"
#include "PyImathExport.h"
namespace PyImath {
using namespace boost::python;
using namespace IMATH_NAMESPACE;
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Vec4<unsigned char> > > register_Vec4Array<unsigned char>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Vec4<short> > > register_Vec4Array<short>();
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Vec4<int> > > register_Vec4Array<int>();
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Vec4<unsigned char> FixedArrayDefaultValue<IMATH_NAMESPACE::Vec4<unsigned char> >::value() { return IMATH_NAMESPACE::Vec4<unsigned char>(0,0,0,0); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Vec4<short> FixedArrayDefaultValue<IMATH_NAMESPACE::Vec4<short> >::value() { return IMATH_NAMESPACE::Vec4<short>(0,0,0,0); }
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Vec4<int> FixedArrayDefaultValue<IMATH_NAMESPACE::Vec4<int> >::value() { return IMATH_NAMESPACE::Vec4<int>(0,0,0,0); }
}

View File

@ -0,0 +1,77 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef _PyImathVecOperators_h_
#define _PyImathVecOperators_h_
namespace PyImath {
template <class T>
struct op_vecDot {
static inline typename T::BaseType apply(const T &a, const T &b) { return a.dot(b); }
};
template <class T>
struct op_vecLength {
static inline typename T::BaseType apply(const T &v) { return v.length(); }
};
template <class T>
struct op_vecLength2 {
static inline typename T::BaseType apply(const T &v) { return v.length2(); }
};
template <class T>
struct op_vecNormalize {
static inline void apply(T &v) { v.normalize(); }
};
template <class T>
struct op_vecNormalized {
static inline T apply(const T &v) { return v.normalized(); }
};
template <class T>
struct op_vec3Cross {
static inline IMATH_NAMESPACE::Vec3<T> apply(const IMATH_NAMESPACE::Vec3<T> &a, const IMATH_NAMESPACE::Vec3<T> &b) { return a.cross(b); }
};
template <class T>
struct op_vec2Cross {
static inline T apply(const IMATH_NAMESPACE::Vec2<T> &a, const IMATH_NAMESPACE::Vec2<T> &b) { return a.cross(b); }
};
} // namespace PyImath
#endif // _PyImathVecOperators_h_

View File

@ -0,0 +1,472 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 <Python.h>
#include <boost/python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/format.hpp>
#include <ImathVec.h>
#include <ImathQuat.h>
#include <ImathEuler.h>
#include <ImathFun.h>
#include <ImathMatrixAlgo.h>
#include <PyIexExport.h>
#include <PyImathFixedArray.h>
#include <PyImath.h>
#include <PyImathExport.h>
#include <PyImathBasicTypes.h>
#include <PyImathVec.h>
#include <PyImathMatrix.h>
#include <PyImathBox.h>
#include <PyImathFun.h>
#include <PyImathQuat.h>
#include <PyImathEuler.h>
#include <PyImathColor.h>
#include <PyImathFrustum.h>
#include <PyImathPlane.h>
#include <PyImathLine.h>
#include <PyImathRandom.h>
#include <PyImathShear.h>
#include <PyImathMathExc.h>
#include <PyImathAutovectorize.h>
#include <PyImathStringArrayRegister.h>
#include <PyIex.h>
using namespace boost::python;
using namespace PyImath;
namespace {
template <typename T>
IMATH_NAMESPACE::Box<IMATH_NAMESPACE::Vec3<T> >
computeBoundingBox(const PyImath::FixedArray<IMATH_NAMESPACE::Vec3<T> >& position)
{
IMATH_NAMESPACE::Box<IMATH_NAMESPACE::Vec3<T> > 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<IMATH_NAMESPACE::V3d> from; from.reserve (n);
std::vector<IMATH_NAMESPACE::V3d> to; to.reserve (n);
std::vector<double> 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<IMATH_NAMESPACE::V3d> (f));
to.push_back (boost::python::extract<IMATH_NAMESPACE::V3d> (t));
if (useWeights)
weights.push_back (boost::python::extract<double> (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<int> rangeX(int sizeX, int sizeY)
{
FixedArray2D<int> f(sizeX, sizeY);
for (int j=0; j<sizeY; j++)
for (int i=0; i<sizeX; i++)
f(i,j) = i;
return f;
}
FixedArray2D<int> rangeY(int sizeX, int sizeY)
{
FixedArray2D<int> f(sizeX, sizeY);
for (int j=0; j<sizeY; j++)
for (int i=0; i<sizeX; i++)
f(i,j) = j;
return f;
}
}
BOOST_PYTHON_MODULE(imath)
{
handle<> 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_<IntArray2D> 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<float>(iclass2D);
add_explicit_construction_from_type<double>(iclass2D);
class_<IntMatrix> imclass = IntMatrix::register_("IntMatrix","Fixed size matrix of ints");
add_arithmetic_math_functions(imclass);
class_<FloatArray2D> 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<int>(fclass2D);
add_explicit_construction_from_type<double>(fclass2D);
class_<FloatMatrix> fmclass = FloatMatrix::register_("FloatMatrix","Fixed size matrix of floats");
add_arithmetic_math_functions(fmclass);
add_pow_math_functions(fmclass);
class_<DoubleArray2D> 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<int>(dclass2D);
add_explicit_construction_from_type<float>(dclass2D);
class_<DoubleMatrix> 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<short>();
register_Vec2<int>();
register_Vec2<float>();
register_Vec2<double>();
class_<FixedArray<IMATH_NAMESPACE::V2s> > v2s_class = register_Vec2Array<short>();
class_<FixedArray<IMATH_NAMESPACE::V2i> > v2i_class = register_Vec2Array<int>();
class_<FixedArray<IMATH_NAMESPACE::V2f> > v2f_class = register_Vec2Array<float>();
class_<FixedArray<IMATH_NAMESPACE::V2d> > v2d_class = register_Vec2Array<double>();
add_explicit_construction_from_type<IMATH_NAMESPACE::V2f>(v2i_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::V2d>(v2i_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::V2i>(v2f_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::V2d>(v2f_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::V2i>(v2d_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::V2f>(v2d_class);
//
// Vec3
//
register_Vec3<unsigned char>();
register_Vec3<short>();
register_Vec3<int>();
register_Vec3<float>();
register_Vec3<double>();
class_<FixedArray<IMATH_NAMESPACE::V3s> > v3s_class = register_Vec3Array<short>();
class_<FixedArray<IMATH_NAMESPACE::V3i> > v3i_class = register_Vec3Array<int>();
class_<FixedArray<IMATH_NAMESPACE::V3f> > v3f_class = register_Vec3Array<float>();
class_<FixedArray<IMATH_NAMESPACE::V3d> > v3d_class = register_Vec3Array<double>();
add_explicit_construction_from_type<IMATH_NAMESPACE::V3f>(v3i_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::V3d>(v3i_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::V3i>(v3f_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::V3d>(v3f_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::V3i>(v3d_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::V3f>(v3d_class);
//
// Vec4
//
register_Vec4<unsigned char>();
register_Vec4<short>();
register_Vec4<int>();
register_Vec4<float>();
register_Vec4<double>();
class_<FixedArray<IMATH_NAMESPACE::V4s> > v4s_class = register_Vec4Array<short>();
class_<FixedArray<IMATH_NAMESPACE::V4i> > v4i_class = register_Vec4Array<int>();
class_<FixedArray<IMATH_NAMESPACE::V4f> > v4f_class = register_Vec4Array<float>();
class_<FixedArray<IMATH_NAMESPACE::V4d> > v4d_class = register_Vec4Array<double>();
add_explicit_construction_from_type<IMATH_NAMESPACE::V4f>(v4i_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::V4d>(v4i_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::V4i>(v4f_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::V4d>(v4f_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::V4i>(v4d_class);
//
// Quat
//
register_Quat<float>();
register_Quat<double>();
class_<FixedArray<IMATH_NAMESPACE::Quatf> > quatf_class = register_QuatArray<float>();
class_<FixedArray<IMATH_NAMESPACE::Quatd> > quatd_class = register_QuatArray<double>();
add_explicit_construction_from_type<IMATH_NAMESPACE::Quatd>(quatf_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::Quatf>(quatd_class);
//
// Euler
//
register_Euler<float>();
register_Euler<double>();
class_<FixedArray<IMATH_NAMESPACE::Eulerf> > eulerf_class = register_EulerArray<float>();
class_<FixedArray<IMATH_NAMESPACE::Eulerd> > eulerd_class = register_EulerArray<double>();
add_explicit_construction_from_type<IMATH_NAMESPACE::Eulerd>(eulerf_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::Eulerf>(eulerd_class);
//
// Box2
//
register_Box2<IMATH_NAMESPACE::V2s>();
register_Box2<IMATH_NAMESPACE::V2i>();
register_Box2<IMATH_NAMESPACE::V2f>();
register_Box2<IMATH_NAMESPACE::V2d>();
class_<FixedArray<IMATH_NAMESPACE::Box2s> > b2s_class = register_BoxArray<IMATH_NAMESPACE::V2s>();
class_<FixedArray<IMATH_NAMESPACE::Box2i> > b2i_class = register_BoxArray<IMATH_NAMESPACE::V2i>();
class_<FixedArray<IMATH_NAMESPACE::Box2f> > b2f_class = register_BoxArray<IMATH_NAMESPACE::V2f>();
class_<FixedArray<IMATH_NAMESPACE::Box2d> > b2d_class = register_BoxArray<IMATH_NAMESPACE::V2d>();
//
// Box3
//
register_Box3<IMATH_NAMESPACE::V3s>();
register_Box3<IMATH_NAMESPACE::V3i>();
register_Box3<IMATH_NAMESPACE::V3f>();
register_Box3<IMATH_NAMESPACE::V3d>();
class_<FixedArray<IMATH_NAMESPACE::Box3s> > b3s_class = register_BoxArray<IMATH_NAMESPACE::V3s>();
class_<FixedArray<IMATH_NAMESPACE::Box3i> > b3i_class = register_BoxArray<IMATH_NAMESPACE::V3i>();
class_<FixedArray<IMATH_NAMESPACE::Box3f> > b3f_class = register_BoxArray<IMATH_NAMESPACE::V3f>();
class_<FixedArray<IMATH_NAMESPACE::Box3d> > b3d_class = register_BoxArray<IMATH_NAMESPACE::V3d>();
//
// Matrix33/44
//
register_Matrix33<float>();
register_Matrix33<double>();
register_Matrix44<float>();
register_Matrix44<double>();
//
// M33/44Array
//
class_<FixedArray<IMATH_NAMESPACE::M44d> > m44d_class = register_M44Array<double>();
class_<FixedArray<IMATH_NAMESPACE::M44f> > m44f_class = register_M44Array<float>();
add_explicit_construction_from_type< IMATH_NAMESPACE::Matrix44<double> >(m44d_class);
add_explicit_construction_from_type< IMATH_NAMESPACE::Matrix44<float> > (m44f_class);
class_<FixedArray<IMATH_NAMESPACE::M33d> > m33d_class = register_M33Array<double>();
class_<FixedArray<IMATH_NAMESPACE::M33f> > m33f_class = register_M33Array<float>();
add_explicit_construction_from_type< IMATH_NAMESPACE::Matrix33<double> >(m33d_class);
add_explicit_construction_from_type< IMATH_NAMESPACE::Matrix33<float> > (m33f_class);
//
// String Array
//
register_StringArrays();
//
// Color3/4
//
register_Color3<unsigned char>();
register_Color3<float>();
register_Color4<unsigned char>();
register_Color4<float>();
//
// C3/4Array
//
class_<FixedArray<IMATH_NAMESPACE::Color3f> > c3f_class = register_Color3Array<float>();
class_<FixedArray<IMATH_NAMESPACE::Color3c> > c3c_class = register_Color3Array<unsigned char>();
add_explicit_construction_from_type<IMATH_NAMESPACE::V3f>(c3f_class);
add_explicit_construction_from_type<IMATH_NAMESPACE::V3d>(c3f_class);
class_<FixedArray<IMATH_NAMESPACE::Color4f> > c4f_class = register_Color4Array<float>();
class_<FixedArray<IMATH_NAMESPACE::Color4c> > c4c_class = register_Color4Array<unsigned char>();
//
// Color4Array
//
register_Color4Array2D<float>();
register_Color4Array2D<unsigned char>();
//
// Frustum
//
register_Frustum<float>();
register_Frustum<double>();
register_FrustumTest<float>();
register_FrustumTest<double>();
//
// Plane
//
register_Plane<float>();
register_Plane<double>();
//
// Line
//
register_Line<float>();
register_Line<double>();
//
// Shear
//
register_Shear<float>();
register_Shear<double>();
//
// 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<int>::min();
scope().attr("INT_MAX") = IMATH_NAMESPACE::limits<int>::max();
scope().attr("INT_SMALLEST") = IMATH_NAMESPACE::limits<int>::smallest();
scope().attr("INT_EPS") = IMATH_NAMESPACE::limits<int>::epsilon();
scope().attr("FLT_MIN") = IMATH_NAMESPACE::limits<float>::min();
scope().attr("FLT_MAX") = IMATH_NAMESPACE::limits<float>::max();
scope().attr("FLT_SMALLEST") = IMATH_NAMESPACE::limits<float>::smallest();
scope().attr("FLT_EPS") = IMATH_NAMESPACE::limits<float>::epsilon();
scope().attr("DBL_MIN") = IMATH_NAMESPACE::limits<double>::min();
scope().attr("DBL_MAX") = IMATH_NAMESPACE::limits<double>::max();
scope().attr("DBL_SMALLEST") = IMATH_NAMESPACE::limits<double>::smallest();
scope().attr("DBL_EPS") = IMATH_NAMESPACE::limits<double>::epsilon();
//
// Register Exceptions
//
PyIex::registerExc<IMATH_NAMESPACE::NullVecExc,IEX_NAMESPACE::MathExc>("NullVecExc","imath");
PyIex::registerExc<IMATH_NAMESPACE::NullQuatExc,IEX_NAMESPACE::MathExc>("NullQuatExc","imath");
PyIex::registerExc<IMATH_NAMESPACE::SingMatrixExc,IEX_NAMESPACE::MathExc>("SingMatrixExc","imath");
PyIex::registerExc<IMATH_NAMESPACE::ZeroScaleExc,IEX_NAMESPACE::MathExc>("ZeroScaleExc","imath");
PyIex::registerExc<IMATH_NAMESPACE::IntVecNormalizeExc,IEX_NAMESPACE::MathExc>("IntVecNormalizeExc","imath");
def("computeBoundingBox", &computeBoundingBox<float>,
"computeBoundingBox(position) -- computes the bounding box from the position array.");
def("computeBoundingBox", &computeBoundingBox<double>,
"computeBoundingBox(position) -- computes the bounding box from the position array.");
}

View File

@ -0,0 +1,144 @@
----------------------------------------------------------
Variable-length Fixed Array 'IntVArray' - Python Interface
----------------------------------------------------------
-----------
Terminology
-----------
Items - Similar to 'list items'. Can think of as the 'vertical'
dimension similar to the other FixedArray dimension. Each item
contains an array of varying length.
Elements - The 'variable-length' array members of each item. In this
case, each 'element' is an int. For a FloatVArray, the
elements would be floats.
------------
Construction
------------
v = IntVArray()
: Do not support; FixedArrays generally don't have empty construction.
v = IntVArray(10)
: Creates 10 items, each item has zero elements (i.e. empty).
v = IntVArray(int initialValue , 10, 5)
: Creates 10 items, each item has 5 elements that are initialized
to the initialValue.
v = IntVArray(IntArray initialValue, 10)
: Creates 10 items, each initialized with a copy of the elements of
the provided initialValue IntArray.
v = IntVArray([1, 2, 3], 10)
: Creates 10 items, each initialized with the elements of the provided
list. This would be similar to the previous constructor, but with
a different initialValue type. We probably don't want to support
this right away, but possibly at some point in the future.
v = IntVArray(int intialValue, IntArray() initialLengths)
: Creates initialLengths.len() items each with a number of elements
matching the values provided by the initialLengths array. The
initial value for all elements is 'initalValue'.
v = IntVArray(IntVArray clone)
: Created as a copy of 'clone'.
Usage (Accessing)
-----------------
int = v.len() (number of items)
IntArray = v[4] (reference of v's data)
IntArray = v[-1] (same as previous)
IntVArray = v[3:9] (reference of v's data; stride provides indexing)
IntVArray = v[:] (same as previous, stride probably not needed)
IntVArray = v[IntArray mask]
: Returns a reference of v's data; uses mask variable internally
IntVArray = v[BoolArray mask]
: Not currently supported, but would provide the same as previous.
This 'BoolArray' mask should be implemented sometime soon (for
this and all other FixedArrays).
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Question: Support v[5][2] semantics. This might work out-of-the-box since
v[5] would return an IntArray, which supports [] also. In this
case it would be fine and a single 'int' would be returned.
But for v[5][1:3], we would return another IntArray
instead of a regular int, so the levels of indirection
for original internal IntVArray data might get too complicated. Do
we support this semantic or not. The problem is that if we don't
want to support it, we'll have to specifically disable it somehow
since we'll get it by default (v[5] returns IntArray, which would
automatically support [1:3]).
Question: To avoid the previous issue, we'll probably want a special element
accessor method (probably called 'element'). That'll have to have
the ability to take in a 'slice' as an argument. Would that all
work?
In the continuing text, we'll assume we support an 'element' accessor
method and not the [5][6] double-box notation.
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
int = v[4].element(1) (returns a single integer)
int = v[4].element(-1) (same as previous)
IntArray = v[4].element(2:7) (return IntArray referencing original data)
IntArray = v[4].element(:) (same as previous; no 'stride' needed)
int = v[4].len() (would not work; int doesn't support 'len')
int = v[4].element(:).len() (the number of elements for item 4 ???)
IntArray = v[3:9].element(1) (All of the element-1 members for items 3 - 9)
IntArray = v.element(1) (All of the element-1 members for each item)
IntArray = v[3:9].element(-1) (same as previous, but returns last elements)
IntVArray = v[3:9].element(2:7) (subset of the original ?????)
IntVArray = v[3:9].element(:) (subset of the original v; only items 3 - 9)
int 6 = v[3:9].len()
IntArray = v[:].element(1) (List of all element-1s from all items ???)
IntArray = v[:].element(-1) (List of all last elements ???)
IntVArray = v[:].element(2:7) (subset of the original ????)
IntVArray = v[:].element(:) (basically a reference of the original)
int = v[:].len() (number of items in v)
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Question: We want to support easy indexing right into a 'X' V3fArray
or something similar. Lets say we want to add a V3f to all
coordinates of the entire system. We'd want to be able to
write expressions like:
x[ v[:].element(:) ] += imath.V3f(1,2,3)
x[ v[:].element(0) ] += imath.V3f(1,2,3) (the 'root' point)
x[ v[3].element(:) ] += ...
x[ v[1:10].element(:) ] += ...
x[ v[1:10].element(1:4) ] += ...
But in many cases, the expression returns another IntVArray.
Should/can we provide indexing into V3fArray from an IntVArray?
Do we currently support indexing into a V3fArray from IntArray?
What other ways can we make this convenient.
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Question: What about cases where not all items support the same number
of elements. What happens in these cases:
IntArray = v[:].element(7)
for cases where some or all of the items don't have an element-7.
Would the IntArray be a subset of v's items (i.e. if only 3 items
could return an element-7, the IntArray would be 3 long). Or
would the IntArray contain invalid/None/undefined integers within
it.
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Question: What other accessor/modification methods do we want to support.
append, remove, pop, push, etc?
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>