#ifdef NANOGUI_PYTHON #include "python.h" void register_eigen(py::module &m) { py::handle vector2i = py::detail::get_type_handle(typeid(Vector2i), false); if (!vector2i) { py::class_(m, "Vector2i") .def(py::init()) .def("__init__", [](Vector2i &v, py::list l) { if (l.size() != 2) throw std::runtime_error("Incompatible list size!"); new (&v) Vector2i( l[0].cast(), l[1].cast() ); }) .def("__init__", [](Vector2i &v, py::tuple t) { if (t.size() != 2) throw std::runtime_error("Incompatible tuple size!"); new (&v) Vector2i( t[0].cast(), t[1].cast() ); }) .def_property("x", [](const Vector2i &v) { return v.x(); }, [](Vector2i &v, int x) { v.x() = x; }) .def_property("y", [](const Vector2i &v) { return v.y(); }, [](Vector2i &v, int y) { v.y() = y; }) .def("__getitem__", [](const Vector2i &m, size_t i) { if (i >= (size_t) m.size()) throw py::index_error(); return m[i]; }) .def("__setitem__", [](Vector2i &m, size_t i, int v) { if (i >= (size_t) m.size()) throw py::index_error(); m[i] = v; }); py::implicitly_convertible(); py::implicitly_convertible(); } else { /* Don't create a new type if some other library has already exposed (potentially much fancier) Eigen Python bindings */ m.attr("Vector2i") = vector2i; } py::handle vector2f = py::detail::get_type_handle(typeid(Vector2f), false); if (!vector2f) { py::class_(m, "Vector2f") .def(py::init()) .def("__init__", [](Vector2f &v, py::list l) { if (l.size() != 2) throw std::runtime_error("Incompatible list size!"); new (&v) Vector2i( l[0].cast(), l[1].cast() ); }) .def("__init__", [](Vector2f &v, py::tuple t) { if (t.size() != 2) throw std::runtime_error("Incompatible tuple size!"); new (&v) Vector2i( t[0].cast(), t[1].cast() ); }) .def_property("x", [](const Vector2f &v) { return v.x(); }, [](Vector2f &v, float x) { v.x() = x; }) .def_property("y", [](const Vector2f &v) { return v.y(); }, [](Vector2f &v, float y) { v.y() = y; }) .def("__getitem__", [](const Vector2f &m, size_t i) { if (i >= (size_t) m.size()) throw py::index_error(); return m[i]; }) .def("__setitem__", [](Vector2f &m, size_t i, float v) { if (i >= (size_t) m.size()) throw py::index_error(); m[i] = v; }); py::implicitly_convertible(); py::implicitly_convertible(); } else { /* Don't create a new type if some other library has already exposed (potentially much fancier) Eigen Python bindings */ m.attr("Vector2f") = vector2f; } py::handle vectorXf = py::detail::get_type_handle(typeid(VectorXf), false); if (!vectorXf) { py::class_(m, "VectorXf") .def(py::init<>()) .def(py::init()) .def("resize", [](VectorXf &v, int i) { v.resize(i); }) .def("__init__", [](VectorXf &v, const std::vector &v2) { new (&v) VectorXf(v2.size()); memcpy(v.data(), &v2[0], sizeof(float) * v2.size()); }) .def("__init__", [](VectorXf &v, py::buffer b) { py::buffer_info info = b.request(); if (info.format != py::format_descriptor::value) { throw std::runtime_error("Incompatible buffer format!"); } else if (info.ndim == 1 && info.strides[0] == sizeof(float)) { new (&v) VectorXf(info.shape[0]); memcpy(v.data(), info.ptr, sizeof(float) * info.shape[0]); } else if (info.ndim == 2 && ((info.shape[0] == 1 && info.strides[0] == sizeof(float)) || (info.shape[1] == 1 && info.strides[1] == sizeof(float)))) { new (&v) VectorXf(info.shape[0] * info.shape[1]); memcpy(v.data(), info.ptr, sizeof(float) * info.shape[0] * info.shape[1]); } else { throw std::runtime_error("Incompatible buffer dimension!"); } }) .def("size", [](const VectorXf &v) { return v.size(); }) .def("__repr__", [](const VectorXf &v) { std::ostringstream oss; oss << v.transpose(); return oss.str(); }) .def("__getitem__", [](const VectorXf &m, size_t i) { if (i >= (size_t) m.size()) throw py::index_error(); return m[i]; }) .def("__setitem__", [](VectorXf &m, size_t i, float v) { if (i >= (size_t) m.size()) throw py::index_error(); m[i] = v; }) /* Buffer access for interacting with NumPy */ .def_buffer([](VectorXf &m) -> py::buffer_info { return py::buffer_info( m.data(), /* Pointer to buffer */ sizeof(float), /* Size of one scalar */ /* Python struct-style format descriptor */ py::format_descriptor::value, 1, /* Number of dimensions */ { (size_t) m.size() }, /* Buffer dimensions */ { sizeof(float) } /* Strides (in bytes) for each index */ ); }); py::implicitly_convertible, VectorXf>(); } else { /* Don't create a new type if some other library has already exposed (potentially much fancier) Eigen Python bindings */ m.attr("VectorXf") = vectorXf; } py::class_(m, "Color", D(Color)) .def(py::init(), D(Color, Color, 7)) .def(py::init(), D(Color, Color, 5)) .def("contrastingColor", &Color::contrastingColor, D(Color, contrastingColor)) .def_property("r", [](const Color &c) { return c.r(); }, [](Color &c, float v) { c.r() = v; }, D(Color, r)) .def_property("g", [](const Color &c) { return c.g(); }, [](Color &c, float v) { c.g() = v; }, D(Color, g)) .def_property("b", [](const Color &c) { return c.b(); }, [](Color &c, float v) { c.b() = v; }, D(Color, b)); } #endif