Browse Source

python: adapt to std::pair cleanup in Magnum.

Also expand the math function tests to explicitly test both the integer
and float variants. Yes, I should have exposed Containers::Pair directly
instead of doing this. No time.
next
Vladimír Vondruš 3 years ago
parent
commit
ecb6351497
  1. 6
      src/python/magnum/gl.cpp
  2. 24
      src/python/magnum/math.cpp
  3. 6
      src/python/magnum/math.range.cpp
  4. 5
      src/python/magnum/math.vector.h
  5. 20
      src/python/magnum/test/test_math.py

6
src/python/magnum/gl.cpp

@ -28,6 +28,7 @@
#include <Corrade/Containers/ArrayView.h>
#include <Corrade/Containers/StringIterable.h>
#include <Corrade/Containers/StringStl.h>
#include <Corrade/Containers/PairStl.h> /** @todo drop once Containers::Pair is exposed directly */
#include <Magnum/Image.h>
#include <Magnum/ImageView.h>
#include <Magnum/GL/AbstractShaderProgram.h>
@ -300,7 +301,10 @@ void gl(py::module_& m) {
;
m
.def("version", static_cast<GL::Version(*)(Int, Int)>(GL::version), "Enum value from major and minor version number", py::arg("major"), py::arg("minor"))
.def("version", static_cast<std::pair<Int, Int>(*)(GL::Version)>(GL::version), "Major and minor version number from enum value", py::arg("version"))
.def("version", [](GL::Version version) {
/** @todo bind Containers::Pair directly */
return std::pair<Int, Int>(GL::version(version));
}, "Major and minor version number from enum value", py::arg("version"))
.def("is_version_es", GL::isVersionES, "Whether given version is OpenGL ES or WebGL");
/* Context */

24
src/python/magnum/math.cpp

@ -26,6 +26,7 @@
#include <sstream>
#include <pybind11/pybind11.h>
#include <pybind11/operators.h>
#include <Corrade/Containers/PairStl.h> /** @todo drop once Containers::Pair is exposed directly */
#include <Magnum/Magnum.h>
#include <Magnum/Math/Angle.h>
#include <Magnum/Math/BitVector.h>
@ -160,7 +161,10 @@ template<class T> void angle(py::module_& m, py::class_<T>& c) {
.def("isnan", static_cast<bool(*)(T)>(Math::isNan), "If given number is a NaN")
.def("min", static_cast<T(*)(T, T)>(Math::min), "Minimum", py::arg("value"), py::arg("min"))
.def("max", static_cast<T(*)(T, T)>(Math::max), "Maximum", py::arg("value"), py::arg("min"))
.def("minmax", static_cast<std::pair<T, T>(*)(T, T)>(Math::minmax), "Minimum and maximum of two values")
.def("minmax", [](T a, T b) {
/** @todo bind Containers::Pair directly */
return std::pair<T, T>(Math::minmax(a, b));
}, "Minimum and maximum of two values")
.def("clamp", static_cast<T(*)(T, T, T)>(Math::clamp), "Clamp value", py::arg("value"), py::arg("min"), py::arg("max"))
.def("sign", Math::sign<T>, "Sign")
.def("abs", static_cast<T(*)(T)>(Math::abs), "Absolute value")
@ -472,7 +476,10 @@ void math(py::module_& root, py::module_& m) {
/* Functions */
m
.def("div", [](Long x, Long y) { return Math::div(x, y); }, "Integer division with remainder", py::arg("x"), py::arg("y"))
.def("div", [](Long x, Long y) {
/** @todo bind Containers::Pair directly */
return std::pair<Long, Long>(Math::div(x, y));
}, "Integer division with remainder", py::arg("x"), py::arg("y"))
/** @todo binomialCoefficient(), asserts are hard to replicate (have an
internal variant returning an Optional?) */
.def("popcount", static_cast<UnsignedInt(*)(UnsignedLong)>(Math::popcount), "Count of bits set in a number")
@ -481,7 +488,8 @@ void math(py::module_& root, py::module_& m) {
.def("sin", [](Radd angle) { return Math::sin(angle); }, "Sine")
.def("cos", [](Radd angle) { return Math::cos(angle); }, "Cosine")
.def("sincos", [](Radd angle) {
return Math::sincos(angle);
/** @todo bind Containers::Pair directly */
return std::pair<Double, Double>(Math::sincos(angle));
}, "Sine and cosine")
.def("tan", [](Radd angle) { return Math::tan(angle); }, "Tangent")
.def("asin", [](Double angle) { return Math::asin(angle); }, "Arc sine")
@ -496,8 +504,14 @@ void math(py::module_& root, py::module_& m) {
.def("min", static_cast<Double(*)(Double, Double)>(Math::min), "Minimum", py::arg("value"), py::arg("min"))
.def("max", static_cast<Long(*)(Long, Long)>(Math::max), "Maximum", py::arg("value"), py::arg("min"))
.def("max", static_cast<Double(*)(Double, Double)>(Math::max), "Maximum", py::arg("value"), py::arg("min"))
.def("minmax", static_cast<std::pair<Long, Long>(*)(Long, Long)>(Math::minmax), "Minimum and maximum of two values")
.def("minmax", static_cast<std::pair<Double, Double>(*)(Double, Double)>(Math::minmax), "Minimum and maximum of two values")
.def("minmax", [](Long a, Long b) {
/** @todo bind Containers::Pair directly */
return std::pair<Long, Long>(Math::minmax(a, b));
}, "Minimum and maximum of two values")
.def("minmax", [](Double a, Double b) {
/** @todo bind Containers::Pair directly */
return std::pair<Double, Double>(Math::minmax(a, b));
}, "Minimum and maximum of two values")
.def("clamp", static_cast<Long(*)(Long, Long, Long)>(Math::clamp), "Clamp value", py::arg("value"), py::arg("min"), py::arg("max"))
.def("clamp", static_cast<Double(*)(Double, Double, Double)>(Math::clamp), "Clamp value", py::arg("value"), py::arg("min"), py::arg("max"))
.def("sign", Math::sign<Long>, "Sign")

6
src/python/magnum/math.range.cpp

@ -25,6 +25,7 @@
#include <pybind11/pybind11.h>
#include <pybind11/operators.h>
#include <Corrade/Containers/PairStl.h>
#include <Magnum/Magnum.h>
#include <Magnum/Math/Range.h>
@ -53,7 +54,10 @@ template<class T> void range(py::module_& m, py::class_<T>& c) {
}, "Construct a zero range")
.def(py::init(), "Default constructor")
.def(py::init<typename T::VectorType, typename T::VectorType>(), "Construct a range from minimal and maximal coordinates")
.def(py::init<std::pair<typename T::VectorType, typename T::VectorType>>(), "Construct a range from minimal and maximal coordinates")
.def(py::init([](const std::pair<typename T::VectorType, typename T::VectorType>& minmax) {
/** @todo bind Containers::Pair directly */
return T{minmax};
}), "Construct a range from minimal and maximal coordinates")
/* Comparison */
.def(py::self == py::self, "Equality comparison")

5
src/python/magnum/math.vector.h

@ -26,6 +26,7 @@
*/
#include <pybind11/operators.h>
#include <Corrade/Containers/PairStl.h> /** @todo drop once Containers::Pair is exposed directly */
#include <Corrade/Containers/ScopeGuard.h>
#include <Magnum/Math/Color.h>
#include <Magnum/Math/Vector4.h>
@ -212,7 +213,9 @@ template<class T> void vector(py::module_& m, py::class_<T>& c) {
return T{Math::max(value, max)};
}, "Maximum", py::arg("value"), py::arg("max"))
.def("minmax", [](const T& a, const T& b) {
return std::pair<T, T>{Math::minmax(a, b)};
/** @todo clean up the cast once minmax() properly returns the
input type; bind Containers::Pair directly */
return std::pair<T, T>{Containers::Pair<T, T>{Math::minmax(a, b)}};
}, "Minimum and maximum of two values")
.def("clamp", [](const T& a, const T& min, const T& max) {
return T{Math::clamp(a, min, max)};

20
src/python/magnum/test/test_math.py

@ -121,7 +121,22 @@ class Functions(unittest.TestCase):
self.assertAlmostEqual(sincos[0], 1.0)
self.assertAlmostEqual(sincos[1], 0.0)
def test_scalar(self):
def test_scalar_integer(self):
self.assertEqual(math.min(15, 3), 3)
self.assertEqual(math.max(15, 3), 15)
self.assertEqual(math.minmax(15, 3), (3, 15))
self.assertEqual(math.clamp(7, -1, 5), 5)
self.assertEqual(math.sign(-15), -1)
self.assertEqual(math.abs(-15), 15)
self.assertEqual(math.lerp(2, 5, 0.5), 3)
self.assertEqual(math.lerp(2, 5, True), 5)
self.assertEqual(math.select(2, 5, 1.0), 5)
self.assertEqual(math.fma(2.0, 3.0, 0.75), 6.75)
def test_scalar_float(self):
self.assertFalse(math.isinf(math.nan))
self.assertFalse(math.isnan(math.inf))
self.assertTrue(math.isinf(math.inf))
@ -143,11 +158,8 @@ class Functions(unittest.TestCase):
self.assertEqual(math.lerp(2.0, 5.0, 0.5), 3.5)
self.assertEqual(math.lerp(2.0, 5.0, False), 2.0)
self.assertEqual(math.lerp(2, 5, 0.5), 3)
self.assertEqual(math.lerp(2, 5, True), 5)
self.assertEqual(math.lerp_inverted(2.0, 5.0, 3.5), 0.5)
self.assertEqual(math.select(2.0, 5.0, 0.6), 2.0)
self.assertEqual(math.select(2, 5, 1.0), 5)
self.assertEqual(math.fma(2.0, 3.0, 0.75), 6.75)

Loading…
Cancel
Save