Skip to content

Commit

Permalink
pybindtest
Browse files Browse the repository at this point in the history
Signed-off-by: Cary Phillips <[email protected]>
  • Loading branch information
cary-ilm committed Jan 23, 2025
1 parent e4fe355 commit 1f35395
Show file tree
Hide file tree
Showing 5 changed files with 10,957 additions and 96 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ endif()
#set(CTEST_DROP_SITE_CDASH TRUE)
include(CTest)
if(BUILD_TESTING AND NOT IMATH_IS_SUBPROJECT)
enable_testing()
add_subdirectory(src/ImathTest)
# enable_testing()
# add_subdirectory(src/ImathTest)
endif()

# Including this module will add a `clang-format` target to the build
Expand Down
5 changes: 5 additions & 0 deletions src/pybind11/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@ set(PYBINDIMATH_LIB_SUFFIX "-${IMATH_VERSION_API}" CACHE STRING "String added to
set(PYBINDIMATH_LIB_PYTHONVER_ROOT "_Python" CACHE STRING "String added as a root to the identifier of the python version in the libraries")

add_subdirectory(PyBindImath)
if(BUILD_TESTING)
enable_testing()
add_subdirectory( PyBindImathTest )
endif()

234 changes: 140 additions & 94 deletions src/pybind11/PyBindImath/PyBindImathVec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,121 +7,167 @@
#include <ImathVec.h>
#include <ImathVecAlgo.h>

namespace py = pybind11;

namespace PyBindImath {

template <class T>
void register_vec(pybind11::class_<T>& c)

template <class V>
void setValue2(V& v, typename V::BaseType x, typename V::BaseType y)
{
v.setValue(x, y);
}

template <class Vec>
py::class_<Vec> register_vec(py::class_<Vec>& c)
{
typedef typename Vec::BaseType T;

return c.def(py::self == py::self)
.def(py::self != py::self)
.def(py::self + py::self)
.def(py::self += py::self)
.def(py::self * py::self)
.def(py::self * int())
.def(py::self * float())
.def(py::self * double())
.def(py::self *= py::self)
.def(py::self *= int())
.def(py::self *= float())
.def(py::self *= double())
.def(py::self / py::self)
.def(py::self / int())
.def(py::self / float())
.def(py::self / double())
.def(py::self /= py::self)
.def(py::self /= int())
.def(py::self /= float())
.def(py::self /= double())
.def(py::self - py::self)
.def(py::self -= py::self)
.def(py::self ^ py::self)
.def(-py::self)
.def("__getitem__", [](const Vec &v, size_t i) {
return v[i]; // Read-only index operator
})
.def("__setitem__", [](Vec &v, size_t i, T value) {
v[i] = value; // Writable index operator
})
.def_static("baseTypeEpsilon", &Vec::baseTypeEpsilon,"baseTypeEpsilon() epsilon value of the base type of the vector")
.def_static("baseTypeMax", &Vec::baseTypeMax,"baseTypeMax() max value of the base type of the vector")
.def_static("baseTypeLowest", &Vec::baseTypeLowest,"baseTypeLowest() largest negative value of the base type of the vector")
.def_static("baseTypeSmallest", &Vec::baseTypeSmallest,"baseTypeSmallest() smallest value of the base type of the vector")
.def("dot", &Vec::dot, "v1.dot(v2) inner product of the two vectors")
.def("dimensions", &Vec::dimensions, "dimensions() number of dimensions in the vector")
.def("equalWithAbsError", &Vec::equalWithAbsError, "v1.equalWithAbsError(v2) true if the elements of v1 and v2 are the same with an absolute error of no more than e, i.e., abs(v1[i] - v2[i]) <= e")
.def("equalWithRelError", &Vec::equalWithRelError, "v1.equalWithRelError(v2) true if the elements of v1 and v2 are the same with a relative error of no more than e, i.e., abs(v1[i] - v2[i]) <= e * abs(v1[i])")

// things from ImathVecAlgo
.def("closestVertex", &IMATH_NAMESPACE::closestVertex<Vec>)
;
}

template <class Vec>
py::class_<Vec> register_vec_nonint(py::class_<Vec> c)
{
c.def(pybind11::self == pybind11::self)
.def(pybind11::self != pybind11::self)
.def(pybind11::self + pybind11::self)
.def(pybind11::self += pybind11::self)
.def(pybind11::self * pybind11::self)
.def(pybind11::self * int())
.def(pybind11::self * float())
.def(pybind11::self * double())
.def(pybind11::self *= pybind11::self)
.def(pybind11::self *= int())
.def(pybind11::self *= float())
.def(pybind11::self *= double())
.def(pybind11::self / pybind11::self)
.def(pybind11::self / int())
.def(pybind11::self / float())
.def(pybind11::self / double())
.def(pybind11::self /= pybind11::self)
.def(pybind11::self /= int())
.def(pybind11::self /= float())
.def(pybind11::self /= double())
.def(pybind11::self - pybind11::self)
.def(pybind11::self -= pybind11::self)
.def(pybind11::self ^ pybind11::self)
.def(-pybind11::self)
.def_static("baseTypeEpsilon", &T::baseTypeEpsilon,"baseTypeEpsilon() epsilon value of the base type of the vector")
.def_static("baseTypeMax", &T::baseTypeMax,"baseTypeMax() max value of the base type of the vector")
.def_static("baseTypeLowest", &T::baseTypeLowest,"baseTypeLowest() largest negative value of the base type of the vector")
.def_static("baseTypeSmallest", &T::baseTypeSmallest,"baseTypeSmallest() smallest value of the base type of the vector")
.def("dot", &T::dot, "v1.dot(v2) inner product of the two vectors")
.def("dimensions", &T::dimensions, "dimensions() number of dimensions in the vector")
.def("equalWithAbsError", &T::equalWithAbsError, "v1.equalWithAbsError(v2) true if the elements of v1 and v2 are the same with an absolute error of no more than e, i.e., abs(v1[i] - v2[i]) <= e")
.def("equalWithRelError", &T::equalWithRelError, "v1.equalWithRelError(v2) true if the elements of v1 and v2 are the same with a relative error of no more than e, i.e., abs(v1[i] - v2[i]) <= e * abs(v1[i])")
.def("length", &T::length, "length() magnitude of the vector")
.def("length2", &T::length2,"length2() square magnitude of the vector")
.def("negate", &T::negate)
.def("normalize", &T::normalize, "v.normalize() destructively normalizes v and returns a reference to it")
.def("normalizeExc", &T::normalizeExc, "v.normalizeExc() destructively normalizes V and returns a reference to it, throwing an exception if length() == 0")
.def("normalizeNonNull", &T::normalizeNonNull, "v.normalizeNonNull() destructively normalizes V and returns a reference to it, faster if length() != 0")
.def("normalized", &T::normalized, "v.normalized() returns a normalized copy of v")
.def("normalizedExc", &T::normalizedExc, "v.normalizedExc() returns a normalized copy of v, throwing an exception if length() == 0")
.def("normalizedNonNull", &T::normalizedNonNull, "v.normalizedNonNull() returns a normalized copy of v, faster if lngth() != 0")

// things from ImathVecAlgo
.def("closestVertex", &IMATH_NAMESPACE::closestVertex<T>)
.def("orthogonal", &IMATH_NAMESPACE::orthogonal<T>)
.def("project", &IMATH_NAMESPACE::project<T>)
.def("reflect", &IMATH_NAMESPACE::reflect<T>)
;
return c.def("length", &Vec::length, "length() magnitude of the vector")
.def("length2", &Vec::length2,"length2() square magnitude of the vector")
.def("negate", &Vec::negate)
.def("normalize", &Vec::normalize, "v.normalize() destructively normalizes v and returns a reference to it")
.def("normalizeExc", &Vec::normalizeExc, "v.normalizeExc() destructively normalizes V and returns a reference to it, throwing an exception if length() == 0")
.def("normalizeNonNull", &Vec::normalizeNonNull, "v.normalizeNonNull() destructively normalizes V and returns a reference to it, faster if length() != 0")
.def("normalized", &Vec::normalized, "v.normalized() returns a normalized copy of v")
.def("normalizedExc", &Vec::normalizedExc, "v.normalizedExc() returns a normalized copy of v, throwing an exception if length() == 0")
.def("normalizedNonNull", &Vec::normalizedNonNull, "v.normalizedNonNull() returns a normalized copy of v, faster if lngth() != 0")
.def("orthogonal", &IMATH_NAMESPACE::orthogonal<Vec>)
.def("project", &IMATH_NAMESPACE::project<Vec>)
.def("reflect", &IMATH_NAMESPACE::reflect<Vec>);
}

template <class T, class S>
void register_vec2(pybind11::module& m, const char * name)
template <class Vec>
py::class_<Vec> register_vec2(py::module& m, const char * name)
{
typedef typename Vec::BaseType T;

// no %=

pybind11::class_<T> c(m, name);
c.def(pybind11::init<>())
.def(pybind11::init<S>())
.def(pybind11::init<S, S>())
.def(pybind11::self % pybind11::self)
.def("cross", &T::cross, "v1.cross(v2) right handed cross product")
.def_readwrite("x", &T::x)
.def_readwrite("y", &T::y);
py::class_<Vec> c(m, name);
c.def(py::init<>())
.def(py::init<T>())
.def(py::init<T, T>())
.def(py::self % py::self)
.def("cross", &Vec::cross, "v1.cross(v2) right handed cross product")
.def_readwrite("x", &Vec::x)
.def_readwrite("y", &Vec::y)
.def("setValue",
[](Vec& self, T x, T y) {
setValue2(self, x, y);
},
py::arg("x"), py::arg("y"),
"set to the given x,y values");

register_vec<Vec>(c);

register_vec<T>(c);
return py::cast<py::class_<Vec>>(c);
}

template <class T, class S>
void register_vec3(pybind11::module& m, const char * name)
template <class Vec>
py::class_<Vec> register_vec3(py::module& m, const char * name)
{
pybind11::class_<T> c(m, name);
c.def(pybind11::init<>())
.def(pybind11::init<S>())
.def(pybind11::init<S, S, S>())
.def(pybind11::self % pybind11::self)
.def(pybind11::self %= pybind11::self)
.def("cross", &T::cross, "v1.cross(v2) right handed cross product")
.def_readwrite("x", &T::x)
.def_readwrite("y", &T::y)
.def_readwrite("z", &T::z);

register_vec<T>(c);
typedef typename Vec::BaseType T;

py::class_<Vec> c(m, name);
c.def(py::init<>())
.def(py::init<T>())
.def(py::init<T, T, T>())
.def(py::self % py::self)
.def(py::self %= py::self)
.def("cross", &Vec::cross, "v1.cross(v2) right handed cross product")
.def_readwrite("x", &Vec::x)
.def_readwrite("y", &Vec::y)
.def_readwrite("z", &Vec::z);

register_vec<Vec>(c);

return py::cast<py::class_<Vec>>(c);
}

template <class T, class S>
void register_vec4(pybind11::module& m, const char * name)
template <class Vec>
py::class_<Vec> register_vec4(py::module& m, const char * name)
{
typedef typename Vec::BaseType T;

// Does a cross product not exist for Vec4? if not then thats why there is no % %= cross
pybind11::class_<T> c(m, name);
c.def(pybind11::init<>())
.def(pybind11::init<S>())
.def(pybind11::init<S, S, S, S>())
.def_readwrite("x", &T::x)
.def_readwrite("y", &T::y)
.def_readwrite("z", &T::z)
.def_readwrite("w", &T::z);

register_vec<T>(c);
py::class_<Vec> c(m, name);
c.def(py::init<>())
.def(py::init<T>())
.def(py::init<T, T, T, T>())
.def_readwrite("x", &Vec::x)
.def_readwrite("y", &Vec::y)
.def_readwrite("z", &Vec::z)
.def_readwrite("w", &Vec::z);

register_vec<Vec>(c);

return py::cast<py::class_<Vec>>(c);
}

void register_imath_vec(pybind11::module& m)
void register_imath_vec(py::module& m)
{
register_vec2<IMATH_NAMESPACE::V2d, double>(m, "V2d");
register_vec2<IMATH_NAMESPACE::V2f, float>(m, "V2f");
register_vec2<IMATH_NAMESPACE::V2s>(m, "V2s");
register_vec2<IMATH_NAMESPACE::V2i>(m, "V2i");
register_vec_nonint(register_vec2<IMATH_NAMESPACE::V2f>(m, "V2f"));
register_vec_nonint(register_vec2<IMATH_NAMESPACE::V2d>(m, "V2d"));

register_vec3<IMATH_NAMESPACE::V3d, double>(m, "V3d");
register_vec3<IMATH_NAMESPACE::V3f, float>(m, "V3f");
register_vec3<IMATH_NAMESPACE::V3s>(m, "V3s");
register_vec3<IMATH_NAMESPACE::V3i>(m, "V3i");
register_vec_nonint(register_vec3<IMATH_NAMESPACE::V3f>(m, "V3f"));
register_vec_nonint(register_vec3<IMATH_NAMESPACE::V3d>(m, "V3d"));

register_vec4<IMATH_NAMESPACE::V4d, double>(m, "V4d");
register_vec4<IMATH_NAMESPACE::V4f, float>(m, "V4f");
register_vec4<IMATH_NAMESPACE::V4s>(m, "V4s");
register_vec4<IMATH_NAMESPACE::V4i>(m, "V4i");
register_vec_nonint(register_vec4<IMATH_NAMESPACE::V4f>(m, "V4f"));
register_vec_nonint(register_vec4<IMATH_NAMESPACE::V4d>(m, "V4d"));
}

}
10 changes: 10 additions & 0 deletions src/pybind11/PyBindImathTest/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.

find_package(Python COMPONENTS Interpreter REQUIRED)

add_test(PyBindImath
env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/../PyBindImath"
${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/pyImathTest.in)


Loading

0 comments on commit 1f35395

Please sign in to comment.