From 6c73ac750a59ccc9048038c94e04a168cd82ca48 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 2 Jul 2016 18:10:23 +0200 Subject: [PATCH] compute minimum volume oriented box --- src/Mod/Mesh/App/AppMeshPy.cpp | 68 +++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/src/Mod/Mesh/App/AppMeshPy.cpp b/src/Mod/Mesh/App/AppMeshPy.cpp index 5621aa465..018a9b230 100644 --- a/src/Mod/Mesh/App/AppMeshPy.cpp +++ b/src/Mod/Mesh/App/AppMeshPy.cpp @@ -37,6 +37,7 @@ #include #include +#include #include #include "Core/MeshKernel.h" @@ -45,9 +46,11 @@ #include "Core/Iterator.h" #include "Core/Approximation.h" -#include "MeshPy.h" +#include "WildMagic4/Wm4ContBox3.h" + #include "Mesh.h" #include "FeatureMeshImport.h" +#include using namespace Mesh; using namespace MeshCore; @@ -105,6 +108,10 @@ public: add_varargs_method("polynomialFit",&Module::polynomialFit, "polynomialFit(seq(Base.Vector)) -- Calculates a polynomial fit." ); + add_varargs_method("minimumVolumeOrientedBox",&Module::minimumVolumeOrientedBox, + "minimumVolumeOrientedBox(seq(Base.Vector)) -- Calculates the minimum volume oriented box containing all points.\n" + "The return value is a tuple of seven items: center, u, v, w directions and the lengths of the three vectors." + ); initialize("The functions in this module allow working with mesh objects.\n" "A set of functions are provided that allow to read in registered mesh file formats\n" "to either an newly created or already exising document.\n" @@ -545,6 +552,65 @@ private: return dict; } + Py::Object minimumVolumeOrientedBox(const Py::Tuple& args) { + PyObject *input; + + if (!PyArg_ParseTuple(args.ptr(), "O",&input)) + throw Py::Exception(); + + if (!PySequence_Check(input)) { + throw Py::TypeError("Input has to be a sequence of Base.Vector()"); + } + + Py::Sequence list(input); + std::vector points; + points.reserve(list.size()); + for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { + PyObject* value = (*it).ptr(); + if (PyObject_TypeCheck(value, &(Base::VectorPy::Type))) { + Base::VectorPy *pcObject = static_cast(value); + Base::Vector3d* val = pcObject->getVectorPtr(); + Wm4::Vector3d pt; + pt[0] = val->x; + pt[1] = val->y; + pt[2] = val->z; + points.push_back(pt); + } + } + + if (points.size() < 4) + throw Py::RuntimeError("Too few points"); + + Wm4::Box3d mobox = Wm4::ContMinBox(points.size(), &(points[0]), 0.001, Wm4::Query::QT_REAL); + Py::Tuple result(7); + Base::Vector3d v; + + v.x = mobox.Center[0]; + v.y = mobox.Center[1]; + v.z = mobox.Center[2]; + result.setItem(0, Py::Vector(v)); + + v.x = mobox.Axis[0][0]; + v.y = mobox.Axis[0][1]; + v.z = mobox.Axis[0][2]; + result.setItem(1, Py::Vector(v)); + + v.x = mobox.Axis[1][0]; + v.y = mobox.Axis[1][1]; + v.z = mobox.Axis[1][2]; + result.setItem(2, Py::Vector(v)); + + v.x = mobox.Axis[2][0]; + v.y = mobox.Axis[2][1]; + v.z = mobox.Axis[2][2]; + result.setItem(3, Py::Vector(v)); + + result.setItem(4, Py::Float(mobox.Extent[0])); + result.setItem(5, Py::Float(mobox.Extent[1])); + result.setItem(6, Py::Float(mobox.Extent[2])); + + return result; + } }; PyObject* initModule()