Browse Source

python: expose Color3 and Color4.

Mainly for RGB -> RGBA shortcuts. Need to invent some nice decoding from
a string.
pull/1/head
Vladimír Vondruš 7 years ago
parent
commit
998c428355
  1. 1
      src/python/magnum/__init__.py
  2. 71
      src/python/magnum/math.vector.h
  3. 8
      src/python/magnum/math.vectorfloat.cpp
  4. 75
      src/python/magnum/test/test_math.py

1
src/python/magnum/__init__.py

@ -41,6 +41,7 @@ __all__ = [
'Vector2d', 'Vector3d', 'Vector4d',
'Vector2i', 'Vector3i', 'Vector4i',
'Vector2ui', 'Vector3ui', 'Vector4ui',
'Color3', 'Color4',
'Matrix2x2', 'Matrix2x3', 'Matrix2x4',
'Matrix3x2', 'Matrix3x3', 'Matrix3x4',

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

@ -26,6 +26,7 @@
*/
#include <pybind11/operators.h>
#include <Magnum/Math/Color.h>
#include <Magnum/Math/Vector4.h>
#include "magnum/math.h"
@ -260,6 +261,76 @@ template<class T> void vector4(py::class_<Math::Vector4<T>>& c) {
"XY part of the vector");
}
template<class T, class Base> void color(py::class_<T, Base>& c) {
c
.def_static("zero_init", []() {
return T{Math::ZeroInit};
}, "Construct a zero color")
.def(py::init(), "Default constructor");
}
template<class T> void color3(py::class_<Math::Color3<T>, Math::Vector3<T>>& c) {
py::implicitly_convertible<const std::tuple<T, T, T>&, Math::Color3<T>>();
c
/* Constructors */
.def(py::init<T, T, T>(), "Constructor")
.def(py::init<T>(), "Construct with one value for all components")
.def(py::init<Math::Vector3<T>>(), "Construct from a vector")
.def(py::init([](const std::tuple<T, T, T>& value) {
return Math::Color3<T>{std::get<0>(value), std::get<1>(value), std::get<2>(value)};
}), "Construct from a tuple")
.def_static("from_hsv", [](Degd hue, typename Math::Color3<T>::FloatingPointType saturation, typename Math::Color3<T>::FloatingPointType value) {
return Math::Color3<T>::fromHsv({Math::Deg<T>(hue), saturation, value});
}, "Create RGB color from HSV representation", py::arg("hue"), py::arg("saturation"), py::arg("value"))
/* Accessors */
.def("to_hsv", [](Math::Color3<T>& self) {
auto hsv = self.toHsv();
return std::make_tuple(Degd(hsv.hue), hsv.saturation, hsv.value);
}, "Convert to HSV representation")
.def("hue", [](Math::Color3<T>& self) {
return Degd(self.hue());
}, "Hue")
.def("saturation", &Math::Color3<T>::saturation, "Saturation")
.def("value", &Math::Color3<T>::value, "Value");
}
template<class T> void color4(py::class_<Math::Color4<T>, Math::Vector4<T>>& c) {
py::implicitly_convertible<const std::tuple<T, T, T>&, Math::Color4<T>>();
py::implicitly_convertible<const std::tuple<T, T, T, T>&, Math::Color4<T>>();
py::implicitly_convertible<const Math::Color3<T>&, Math::Color4<T>>();
c
/* Constructors */
.def(py::init<T, T, T, T>(), "Constructor", py::arg("r"), py::arg("g"), py::arg("b"), py::arg("a") = Math::Implementation::fullChannel<T>())
.def(py::init<T, T>(), "Construct with one value for all components", py::arg("rgb"), py::arg("alpha") = Math::Implementation::fullChannel<T>())
.def(py::init<Math::Color3<T>, T>(), "Construct from a vector", py::arg("rgb"), py::arg("alpha") = Math::Implementation::fullChannel<T>())
.def(py::init<Math::Vector4<T>>(), "Construct from a vector")
.def(py::init([](const std::tuple<T, T, T>& value) {
return Math::Color4<T>{std::get<0>(value), std::get<1>(value), std::get<2>(value)};
}), "Construct from a RGB tuple")
.def(py::init([](const std::tuple<T, T, T, T>& value) {
return Math::Color4<T>{std::get<0>(value), std::get<1>(value), std::get<2>(value), std::get<3>(value)};
}), "Construct from a RGBA tuple")
.def_static("from_hsv", [](Degd hue, typename Math::Color4<T>::FloatingPointType saturation, typename Math::Color4<T>::FloatingPointType value, T alpha) {
return Math::Color4<T>::fromHsv({Math::Deg<T>(hue), saturation, value}, alpha);
}, "Create RGB color from HSV representation", py::arg("hue"), py::arg("saturation"), py::arg("value"), py::arg("alpha") = Math::Implementation::fullChannel<T>())
/* Accessors */
.def("to_hsv", [](Math::Color4<T>& self) {
auto hsv = self.toHsv();
return std::make_tuple(Degd(hsv.hue), hsv.saturation, hsv.value);
}, "Convert to HSV representation")
.def("hue", [](Math::Color4<T>& self) {
return Degd(self.hue());
}, "Hue")
.def("saturation", &Math::Color4<T>::saturation, "Saturation")
.def("value", &Math::Color4<T>::value, "Value");
}
}
#endif

8
src/python/magnum/math.vectorfloat.cpp

@ -85,6 +85,14 @@ void mathVectorFloat(py::module& root, py::module& m) {
py::class_<Vector4d> vector4d{root, "Vector4d", "Four-component double vector"};
vectorsFloat<Float>(m, vector2, vector3, vector4);
vectorsFloat<Double>(m, vector2d, vector3d, vector4d);
py::class_<Color3, Vector3> color3_{root, "Color3", "Color in linear RGB color space"};
color(color3_);
color3(color3_);
py::class_<Color4, Vector4> color4_{root, "Color4", "Color in linear RGBA color space"};
color(color4_);
color4(color4_);
}
}

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

@ -259,6 +259,81 @@ class Vector(unittest.TestCase):
def test_repr(self):
self.assertEqual(repr(Vector3(1.0, 3.14, -13.37)), 'Vector(1, 3.14, -13.37)')
class Color3_(unittest.TestCase):
def test_init(self):
a1 = Color3()
a2 = Color3.zero_init()
self.assertEqual(a1, Color3(0.0, 0.0, 0.0))
self.assertEqual(a2, Color3(0.0, 0.0, 0.0))
b = Color3(0.5)
self.assertEqual(b, Color3(0.5, 0.5, 0.5))
c1 = Color3(0.5, 0.75, 1.0)
c2 = Color3((0.5, 0.75, 1.0))
c3 = Color3(Vector3(0.5, 0.75, 1.0))
self.assertEqual(c1, Color3(0.5, 0.75, 1.0))
self.assertEqual(c2, Color3(0.5, 0.75, 1.0))
self.assertEqual(c3, Color3(0.5, 0.75, 1.0))
def test_hsv(self):
a = Color3.from_hsv(Deg(230.0), 0.749, 0.427)
self.assertEqual(a, Color3(0.107177, 0.160481, 0.427))
self.assertEqual(a.hue(), Deg(230.0))
self.assertAlmostEqual(a.saturation(), 0.749)
self.assertAlmostEqual(a.value(), 0.427)
self.assertEqual(a.to_hsv()[0], Deg(230.0))
self.assertAlmostEqual(a.to_hsv()[1], 0.749)
self.assertAlmostEqual(a.to_hsv()[2], 0.427)
class Color4_(unittest.TestCase):
def test_init(self):
a1 = Color4()
a2 = Color4.zero_init()
self.assertEqual(a1, Color4(0.0, 0.0, 0.0, 0.0))
self.assertEqual(a2, Color4(0.0, 0.0, 0.0, 0.0))
b = Color4(0.5)
self.assertEqual(b, Color4(0.5, 0.5, 0.5, 1.0))
c = Color4(0.5, 0.75)
self.assertEqual(c, Color4(0.5, 0.5, 0.5, 0.75))
d1 = Color4(0.5, 0.75, 0.875)
d2 = Color4((0.5, 0.75, 0.875))
d3 = Color4(Vector3(0.5, 0.75, 0.875))
self.assertEqual(d1, Color4(0.5, 0.75, 0.875, 1.0))
self.assertEqual(d2, Color4(0.5, 0.75, 0.875, 1.0))
self.assertEqual(d3, Color4(0.5, 0.75, 0.875, 1.0))
e1 = Color4(0.5, 0.75, 0.875, 0.9)
e2 = Color4((0.5, 0.75, 0.875), 0.9)
e3 = Color4((0.5, 0.75, 0.875, 0.9))
e4 = Color4(Vector3(0.5, 0.75, 0.875), 0.9)
e5 = Color4(Vector4(0.5, 0.75, 0.875, 0.9))
self.assertEqual(e1, Color4(0.5, 0.75, 0.875, 0.9))
self.assertEqual(e2, Color4(0.5, 0.75, 0.875, 0.9))
self.assertEqual(e3, Color4(0.5, 0.75, 0.875, 0.9))
self.assertEqual(e4, Color4(0.5, 0.75, 0.875, 0.9))
self.assertEqual(e5, Color4(0.5, 0.75, 0.875, 0.9))
def test_hsv(self):
a = Color4.from_hsv(Deg(230.0), 0.749, 0.427, 0.95)
self.assertEqual(a, Color4(0.107177, 0.160481, 0.427, 0.95))
self.assertEqual(a.hue(), Deg(230.0))
self.assertAlmostEqual(a.saturation(), 0.749)
self.assertAlmostEqual(a.value(), 0.427)
self.assertEqual(a.to_hsv()[0], Deg(230.0))
self.assertAlmostEqual(a.to_hsv()[1], 0.749)
self.assertAlmostEqual(a.to_hsv()[2], 0.427)
b = Color4.from_hsv(Deg(230.0), 0.749, 0.427)
self.assertEqual(b, Color4(0.107177, 0.160481, 0.427, 1.0))
class Matrix(unittest.TestCase):
def test_init(self):
a = Matrix3x2()

Loading…
Cancel
Save