diff --git a/src/Decimater.hh b/src/Decimater.hh index 4206f3231083ea39a2d4e5d9abc2d0a24f05e145..ae7fd17180b9aabb067a0af08d037ec32d2e36f8 100644 --- a/src/Decimater.hh +++ b/src/Decimater.hh @@ -40,6 +40,62 @@ py::list infolist(Module& _self) { return res; } +template <class Mesh> +void copy_locked_vertex_prop(Mesh& _mesh, const std::string& _name) { + if (!_mesh.template py_has_property<OM::VertexHandle>(_name)) { + const std::string msg = "Vertex property \"" + _name + "\" does not exist."; + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + throw py::error_already_set(); + } + for (auto vh : _mesh.vertices()) { + const auto val = _mesh.template py_property<OM::VertexHandle, typename Mesh::VPropHandle>(_name, vh); + // BaseDecimaterT ctor requests vertex status + _mesh.status(vh).set_locked(py::cast<bool>(val)); + } +} + +template <class Mesh> +void copy_feature_vertex_prop(Mesh& _mesh, const std::string& _name) { + if (!_mesh.template py_has_property<OM::VertexHandle>(_name)) { + const std::string msg = "Vertex property \"" + _name + "\" does not exist."; + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + throw py::error_already_set(); + } + for (auto vh : _mesh.vertices()) { + const auto val = _mesh.template py_property<OM::VertexHandle, typename Mesh::VPropHandle>(_name, vh); + // BaseDecimaterT ctor requests vertex status + _mesh.status(vh).set_feature(py::cast<bool>(val)); + } +} + +template <class Mesh> +void copy_feature_edge_prop(Mesh& _mesh, const std::string& _name) { + if (!_mesh.template py_has_property<OM::EdgeHandle>(_name)) { + const std::string msg = "Edge property \"" + _name + "\" does not exist."; + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + throw py::error_already_set(); + } + for (auto eh : _mesh.edges()) { + const auto val = _mesh.template py_property<OM::EdgeHandle, typename Mesh::EPropHandle>(_name, eh); + // BaseDecimaterT ctor requests edge status + _mesh.status(eh).set_feature(py::cast<bool>(val)); + } +} + +template <class Mesh> +void copy_status_props(Mesh& _mesh, + py::object _locked_vertex_propname, + py::object _feature_vertex_propname, + py::object _feature_edge_propname) +{ + if (!_locked_vertex_propname.is_none()) + copy_locked_vertex_prop(_mesh, py::cast<std::string>(_locked_vertex_propname)); + if (!_feature_vertex_propname.is_none()) + copy_feature_vertex_prop(_mesh, py::cast<std::string>(_feature_vertex_propname)); + if (!_feature_edge_propname.is_none()) + copy_feature_edge_prop(_mesh, py::cast<std::string>(_feature_edge_propname)); +} + template <class Mesh> void expose_decimater(py::module& m, const char *_name) { @@ -64,11 +120,8 @@ void expose_decimater(py::module& m, const char *_name) { typedef OM::Decimater::ModHandleT<ModQuadric> ModQuadricHandle; typedef OM::Decimater::ModHandleT<ModRoundness> ModRoundnessHandle; - typedef OM::Decimater::BaseDecimaterT<Mesh> BaseDecimater; typedef OM::Decimater::DecimaterT<Mesh> Decimater; - typedef typename ModProgMesh::Info Info; - typedef std::vector<Info> InfoList; // Decimater // ---------------------------------------- @@ -78,10 +131,53 @@ void expose_decimater(py::module& m, const char *_name) { py::class_<Decimater>(m, buffer) .def(py::init<Mesh&>(), py::keep_alive<1,2>()) - .def("decimate", &Decimater::decimate, py::arg("n_collapses")=0) - .def("decimate_to", &Decimater::decimate_to) - .def("decimate_to_faces", &Decimater::decimate_to_faces, - py::arg("n_vertices")=0, py::arg("n_faces")=0) + + .def("decimate", [](Decimater& _self, + size_t _n_collapses, + py::object _locked_vertex_propname, + py::object _feature_vertex_propname, + py::object _feature_edge_propname) + { + copy_status_props(_self.mesh(), _locked_vertex_propname, + _feature_vertex_propname, _feature_edge_propname); + _self.decimate(_n_collapses); + }, + py::arg("n_collapses")=0, + py::arg("locked_vertex_propname")=py::none(), + py::arg("feature_vertex_propname")=py::none(), + py::arg("feature_edge_propname")=py::none()) + + .def("decimate_to", [](Decimater& _self, + size_t _n_vertices, + py::object _locked_vertex_propname, + py::object _feature_vertex_propname, + py::object _feature_edge_propname) + { + copy_status_props(_self.mesh(), _locked_vertex_propname, + _feature_vertex_propname, _feature_edge_propname); + _self.decimate_to(_n_vertices); + }, + py::arg("n_vertices"), + py::arg("locked_vertex_propname")=py::none(), + py::arg("feature_vertex_propname")=py::none(), + py::arg("feature_edge_propname")=py::none()) + + .def("decimate_to_faces", [](Decimater& _self, + size_t _n_vertices, + size_t _n_faces, + py::object _locked_vertex_propname, + py::object _feature_vertex_propname, + py::object _feature_edge_propname) + { + copy_status_props(_self.mesh(), _locked_vertex_propname, + _feature_vertex_propname, _feature_edge_propname); + _self.decimate_to_faces(_n_vertices, _n_faces); + }, + py::arg("n_vertices")=0, + py::arg("n_faces")=0, + py::arg("locked_vertex_propname")=py::none(), + py::arg("feature_vertex_propname")=py::none(), + py::arg("feature_edge_propname")=py::none()) .def("initialize", [](Decimater& _self) { return _self.initialize(); }) .def("is_initialized", [](Decimater& _self) { return _self.is_initialized(); })