diff --git a/src/Python/Bindings.cc b/src/Python/Bindings.cc index 81ee4e68..61acd6f4 100644 --- a/src/Python/Bindings.cc +++ b/src/Python/Bindings.cc @@ -3,6 +3,7 @@ #include "Python/Mesh.hh" #include "Python/PropertyManager.hh" #include "Python/InputOutput.hh" +#include "Python/Decimater.hh" #include @@ -142,6 +143,9 @@ BOOST_PYTHON_MODULE(openmesh) { expose_property_manager, FaceHandle, FaceIterWrapper>("FPropertyManager"); expose_io(); + + expose_decimater("PolyMesh"); + expose_decimater("TriMesh"); } } // namespace Python diff --git a/src/Python/Decimater.hh b/src/Python/Decimater.hh new file mode 100644 index 00000000..5eb18e61 --- /dev/null +++ b/src/Python/Decimater.hh @@ -0,0 +1,295 @@ +#ifndef OPENMESH_PYTHON_DECIMATER_HH +#define OPENMESH_PYTHON_DECIMATER_HH + +#include "Python/Bindings.hh" +#include "OpenMesh/Tools/Decimater/ModBaseT.hh" +#include "OpenMesh/Tools/Decimater/ModAspectRatioT.hh" +#include "OpenMesh/Tools/Decimater/ModEdgeLengthT.hh" +#include "OpenMesh/Tools/Decimater/ModHausdorffT.hh" +#include "OpenMesh/Tools/Decimater/ModIndependentSetsT.hh" +#include "OpenMesh/Tools/Decimater/ModNormalDeviationT.hh" +#include "OpenMesh/Tools/Decimater/ModNormalFlippingT.hh" +#include "OpenMesh/Tools/Decimater/ModProgMeshT.hh" +#include "OpenMesh/Tools/Decimater/ModQuadricT.hh" +#include "OpenMesh/Tools/Decimater/ModRoundnessT.hh" +#include "OpenMesh/Tools/Decimater/DecimaterT.hh" + +#include + +namespace OpenMesh { +namespace Python { + +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(decimate_overloads, decimate, 0, 1) +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(decimate_to_faces_overloads, decimate_to_faces, 0, 2) +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(set_max_err_overloads, set_max_err, 1, 2) +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(set_min_roundness_overloads, set_min_roundness, 1, 2) + + +template +void expose_module_handle(const char *_name) { + class_(_name) + .def("is_valid", &Handle::is_valid) + ; +} + +template +list infolist(Module& _self) { + const typename Module::InfoList& infos = _self.infolist(); + list res; + for (size_t i = 0; i < infos.size(); ++i) { + res.append(infos[i]); + } + return res; +} + +template +void expose_decimater(const char *_name) { + + typedef Decimater::ModBaseT ModBase; + typedef Decimater::ModAspectRatioT ModAspectRatio; + typedef Decimater::ModEdgeLengthT ModEdgeLength; + typedef Decimater::ModHausdorffT ModHausdorff; + typedef Decimater::ModIndependentSetsT ModIndependentSets; + typedef Decimater::ModNormalDeviationT ModNormalDeviation; + typedef Decimater::ModNormalFlippingT ModNormalFlipping; + typedef Decimater::ModProgMeshT ModProgMesh; + typedef Decimater::ModQuadricT ModQuadric; + typedef Decimater::ModRoundnessT ModRoundness; + + typedef Decimater::ModHandleT ModAspectRatioHandle; + typedef Decimater::ModHandleT ModEdgeLengthHandle; + typedef Decimater::ModHandleT ModHausdorffHandle; + typedef Decimater::ModHandleT ModIndependentSetsHandle; + typedef Decimater::ModHandleT ModNormalDeviationHandle; + typedef Decimater::ModHandleT ModNormalFlippingHandle; + typedef Decimater::ModHandleT ModProgMeshHandle; + typedef Decimater::ModHandleT ModQuadricHandle; + typedef Decimater::ModHandleT ModRoundnessHandle; + + typedef Decimater::BaseDecimaterT BaseDecimater; + typedef Decimater::DecimaterT Decimater; + + typedef typename ModProgMesh::Info Info; + typedef std::vector InfoList; + + bool (BaseDecimater::*add1)(ModAspectRatioHandle&) = &Decimater::add; + bool (BaseDecimater::*add2)(ModEdgeLengthHandle&) = &Decimater::add; + bool (BaseDecimater::*add3)(ModHausdorffHandle&) = &Decimater::add; + bool (BaseDecimater::*add4)(ModIndependentSetsHandle&) = &Decimater::add; + bool (BaseDecimater::*add5)(ModNormalDeviationHandle&) = &Decimater::add; + bool (BaseDecimater::*add6)(ModNormalFlippingHandle&) = &Decimater::add; + bool (BaseDecimater::*add7)(ModProgMeshHandle&) = &Decimater::add; + bool (BaseDecimater::*add8)(ModQuadricHandle&) = &Decimater::add; + bool (BaseDecimater::*add9)(ModRoundnessHandle&) = &Decimater::add; + + bool (BaseDecimater::*remove1)(ModAspectRatioHandle&) = &Decimater::remove; + bool (BaseDecimater::*remove2)(ModEdgeLengthHandle&) = &Decimater::remove; + bool (BaseDecimater::*remove3)(ModHausdorffHandle&) = &Decimater::remove; + bool (BaseDecimater::*remove4)(ModIndependentSetsHandle&) = &Decimater::remove; + bool (BaseDecimater::*remove5)(ModNormalDeviationHandle&) = &Decimater::remove; + bool (BaseDecimater::*remove6)(ModNormalFlippingHandle&) = &Decimater::remove; + bool (BaseDecimater::*remove7)(ModProgMeshHandle&) = &Decimater::remove; + bool (BaseDecimater::*remove8)(ModQuadricHandle&) = &Decimater::remove; + bool (BaseDecimater::*remove9)(ModRoundnessHandle&) = &Decimater::remove; + + ModAspectRatio& (BaseDecimater::*module1)(ModAspectRatioHandle&) = &Decimater::module; + ModEdgeLength& (BaseDecimater::*module2)(ModEdgeLengthHandle&) = &Decimater::module; + ModHausdorff& (BaseDecimater::*module3)(ModHausdorffHandle&) = &Decimater::module; + ModIndependentSets& (BaseDecimater::*module4)(ModIndependentSetsHandle&) = &Decimater::module; + ModNormalDeviation& (BaseDecimater::*module5)(ModNormalDeviationHandle&) = &Decimater::module; + ModNormalFlipping& (BaseDecimater::*module6)(ModNormalFlippingHandle&) = &Decimater::module; + ModProgMesh& (BaseDecimater::*module7)(ModProgMeshHandle&) = &Decimater::module; + ModQuadric& (BaseDecimater::*module8)(ModQuadricHandle&) = &Decimater::module; + ModRoundness& (BaseDecimater::*module9)(ModRoundnessHandle&) = &Decimater::module; + + // Decimater + // ---------------------------------------- + + char buffer[64]; + snprintf(buffer, sizeof buffer, "%s%s", _name, "Decimater"); + + class_(buffer, init()) + .def("decimate", &Decimater::decimate, decimate_overloads()) + .def("decimate_to", &Decimater::decimate_to) + .def("decimate_to_faces", &Decimater::decimate_to_faces, decimate_to_faces_overloads()) + + .def("initialize", &Decimater::initialize) + .def("is_initialized", &Decimater::is_initialized) + + .def("add", add1) + .def("add", add2) + .def("add", add3) + .def("add", add4) + .def("add", add5) + .def("add", add6) + .def("add", add7) + .def("add", add8) + .def("add", add9) + + .def("remove", remove1) + .def("remove", remove2) + .def("remove", remove3) + .def("remove", remove4) + .def("remove", remove5) + .def("remove", remove6) + .def("remove", remove7) + .def("remove", remove8) + .def("remove", remove9) + + .def("module", module1, return_value_policy()) + .def("module", module2, return_value_policy()) + .def("module", module3, return_value_policy()) + .def("module", module4, return_value_policy()) + .def("module", module5, return_value_policy()) + .def("module", module6, return_value_policy()) + .def("module", module7, return_value_policy()) + .def("module", module8, return_value_policy()) + .def("module", module9, return_value_policy()) + ; + + // ModBase + // ---------------------------------------- + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModBase"); + + class_(buffer, no_init) + .def("name", &ModBase::name, OPENMESH_PYTHON_DEFAULT_POLICY) + .def("is_binary", &ModBase::is_binary) + .def("set_binary", &ModBase::set_binary) + .def("initialize", &ModBase::initialize) // TODO VIRTUAL + .def("collapse_priority", &ModBase::collapse_priority) // TODO VIRTUAL + .def("preprocess_collapse", &ModBase::preprocess_collapse) // TODO VIRTUAL + .def("postprocess_collapse", &ModBase::postprocess_collapse) // TODO VIRTUAL + .def("set_error_tolerance_factor", &ModBase::set_error_tolerance_factor) // TODO VIRTUAL + ; + + // ModAspectRatio + // ---------------------------------------- + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModAspectRatio"); + + class_, boost::noncopyable>(buffer, init()) + .def("aspect_ratio", &ModAspectRatio::aspect_ratio) + .def("set_aspect_ratio", &ModAspectRatio::set_aspect_ratio) + ; + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModAspectRatioHandle"); + expose_module_handle(buffer); + + // ModEdgeLength + // ---------------------------------------- + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModEdgeLength"); + + class_, boost::noncopyable>(buffer, init()) + .def("edge_length", &ModEdgeLength::edge_length) + .def("set_edge_length", &ModEdgeLength::set_edge_length) + ; + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModEdgeLengthHandle"); + expose_module_handle(buffer); + + // ModHausdorff + // ---------------------------------------- + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModHausdorff"); + + class_, boost::noncopyable>(buffer, init()) + .def("tolerance", &ModHausdorff::tolerance) + .def("set_tolerance", &ModHausdorff::set_tolerance) + ; + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModHausdorffHandle"); + expose_module_handle(buffer); + + // ModIndependentSets + // ---------------------------------------- + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModIndependentSets"); + + class_, boost::noncopyable>(buffer, init()); + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModIndependentSetsHandle"); + expose_module_handle(buffer); + + // ModNormalDeviation + // ---------------------------------------- + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModNormalDeviation"); + + class_, boost::noncopyable>(buffer, init()) + .def("normal_deviation", &ModNormalDeviation::normal_deviation) + .def("set_normal_deviation", &ModNormalDeviation::set_normal_deviation) + ; + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModNormalDeviationHandle"); + expose_module_handle(buffer); + + // ModNormalFlipping + // ---------------------------------------- + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModNormalFlipping"); + + class_, boost::noncopyable>(buffer, init()) + .def("max_normal_deviation", &ModNormalFlipping::max_normal_deviation) + .def("set_max_normal_deviation", &ModNormalFlipping::set_max_normal_deviation) + ; + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModNormalFlippingHandle"); + expose_module_handle(buffer); + + // ModProgMesh + // ---------------------------------------- + + class_("Info", no_init) + .def_readwrite("v0", &Info::v0) + .def_readwrite("v1", &Info::v1) + .def_readwrite("vl", &Info::vl) + .def_readwrite("vr", &Info::vr) + ; + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModProgMesh"); + + class_, boost::noncopyable>(buffer, init()) + .def("pmi", &infolist) + .def("infolist", &infolist) + .def("write", &ModProgMesh::write) + ; + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModProgMeshHandle"); + expose_module_handle(buffer); + + // ModQuadric + // ---------------------------------------- + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModQuadric"); + + class_, boost::noncopyable>(buffer, init()) + .def("set_max_err", &ModQuadric::set_max_err, set_max_err_overloads()) + .def("unset_max_err", &ModQuadric::unset_max_err) + .def("max_err", &ModQuadric::max_err) + ; + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModQuadricHandle"); + expose_module_handle(buffer); + + // ModRoundness + // ---------------------------------------- + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModRoundness"); + + class_, boost::noncopyable>(buffer, init()) + .def("set_min_angle", &ModRoundness::set_min_angle) + .def("set_min_roundness", &ModRoundness::set_min_roundness, set_min_roundness_overloads()) + .def("unset_min_roundness", &ModRoundness::unset_min_roundness) + .def("roundness", &ModRoundness::roundness) + ; + + snprintf(buffer, sizeof buffer, "%s%s", _name, "ModRoundnessHandle"); + expose_module_handle(buffer); +} + +} // namespace OpenMesh +} // namespace Python + +#endif