| 15 | namespace py = pybind11; |
| 16 | |
| 17 | void BindSim3(py::module& m) { |
| 18 | using Rotation3dWrapper = pycolmap::Rotation3dWrapper; |
| 19 | py::classh_ext<Sim3d> PySim3d(m, "Sim3d"); |
| 20 | PySim3d.def(py::init<>()) |
| 21 | .def( |
| 22 | py::init<double, const Eigen::Quaterniond&, const Eigen::Vector3d&>(), |
| 23 | "scale"_a, |
| 24 | "rotation"_a, |
| 25 | "translation"_a) |
| 26 | .def(py::init(&Sim3d::FromMatrix), |
| 27 | "matrix"_a, |
| 28 | "3x4 transformation matrix.") |
| 29 | .def_property( |
| 30 | "params", |
| 31 | [](Sim3d& self) -> Eigen::Vector8d& { return self.params; }, |
| 32 | [](Sim3d& self, const Eigen::Vector8d& params) { |
| 33 | self.params = params; |
| 34 | }) |
| 35 | .def_property( |
| 36 | "scale", |
| 37 | [](py::object self) { |
| 38 | Sim3d& sim3 = self.cast<Sim3d&>(); |
| 39 | return py::array_t<double>({}, {}, sim3.params.data() + 7, self); |
| 40 | }, |
| 41 | [](Sim3d& self, const py::object& value) { |
| 42 | if (py::isinstance<py::array>(value)) { |
| 43 | auto arr = value.cast<py::array_t<double>>(); |
| 44 | THROW_CHECK_EQ(arr.size(), 1); |
| 45 | self.scale() = arr.at(0); |
| 46 | } else { |
| 47 | self.scale() = value.cast<double>(); |
| 48 | } |
| 49 | }) |
| 50 | .def_property( |
| 51 | "rotation", |
| 52 | [](py::object self) { |
| 53 | Sim3d& sim3 = self.cast<Sim3d&>(); |
| 54 | py::array_t<double> arr( |
| 55 | {4}, {sizeof(double)}, sim3.params.data(), self); |
| 56 | return Rotation3dWrapper(std::move(arr)); |
| 57 | }, |
| 58 | [](Sim3d& self, const Eigen::Quaterniond& q) { self.rotation() = q; }) |
| 59 | .def_property( |
| 60 | "translation", |
| 61 | [](py::object self) { |
| 62 | Sim3d& sim3 = self.cast<Sim3d&>(); |
| 63 | return py::array_t<double>( |
| 64 | {3}, {sizeof(double)}, sim3.params.data() + 4, self); |
| 65 | }, |
| 66 | [](Sim3d& self, const Eigen::Vector3d& t) { self.translation() = t; }) |
| 67 | .def("matrix", &Sim3d::ToMatrix) |
| 68 | .def(py::self * Sim3d()) |
| 69 | .def(py::self * Eigen::Vector3d()) |
| 70 | .def("__mul__", |
| 71 | [](const Sim3d& t, |
| 72 | const py::EigenDRef<const Eigen::MatrixX3d>& points) |
| 73 | -> Eigen::MatrixX3d { |
| 74 | return (t.scale() * |
no test coverage detected