diff --git a/src/App/ComplexGeoDataPy.xml b/src/App/ComplexGeoDataPy.xml
index c341734a18..65e3422e9c 100644
--- a/src/App/ComplexGeoDataPy.xml
+++ b/src/App/ComplexGeoDataPy.xml
@@ -5,7 +5,7 @@
Name="ComplexGeoDataPy"
Twin="ComplexGeoData"
Include="App/ComplexGeoData.h"
- TwinPointer="ComplexGeoData"
+ TwinPointer="ComplexGeoData"
Namespace="Data"
FatherInclude="Base/PersistencePy.h"
FatherNamespace="Base"
@@ -14,34 +14,85 @@
Father of all complex geometric data types
+
+
+ Return a list of element types
+
+
+
+
+ Return the number of elements of a type
+
+
Return vertexes and faces from a sub-element
-
-
- Get the BoundBox of the object
-
-
-
-
-
- Get the current transformation of the object as placement
-
-
-
-
-
- Get the current transformation of the object as matrix
-
-
-
-
-
- Geometry Tag
-
-
-
+
+
+ Return vertexes and lines from a sub-element
+
+
+
+
+ Return a tuple of points and normals with a given accuracy
+
+
+
+
+ Return a tuple of points and lines with a given accuracy
+
+
+
+
+ Return a tuple of points and triangles with a given accuracy
+
+
+
+
+ Apply an additional translation to the placement
+
+
+
+
+ Apply an additional rotation to the placement
+
+
+
+
+ Apply a transformation to the underlying geometry
+
+
+
+
+ Get the BoundBox of the object
+
+
+
+
+
+ Get the center of gravity
+
+
+
+
+
+ Get the current transformation of the object as placement
+
+
+
+
+
+ Get the current transformation of the object as matrix
+
+
+
+
+
+ Geometry Tag
+
+
+
diff --git a/src/App/ComplexGeoDataPyImp.cpp b/src/App/ComplexGeoDataPyImp.cpp
index a89e02b29d..013035ef5b 100644
--- a/src/App/ComplexGeoDataPyImp.cpp
+++ b/src/App/ComplexGeoDataPyImp.cpp
@@ -22,6 +22,9 @@
#include "PreCompiled.h"
+#ifndef _PreComp_
+# include
+#endif
#include "ComplexGeoData.h"
@@ -43,24 +46,52 @@ std::string ComplexGeoDataPy::representation(void) const
return std::string("");
}
-PyObject* ComplexGeoDataPy::getFacesFromSubelement(PyObject *args)
+PyObject* ComplexGeoDataPy::getElementTypes(PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return nullptr;
+
+ std::vector types = getComplexGeoDataPtr()->getElementTypes();
+ Py::List list;
+ for (auto it : types) {
+ list.append(Py::String(it));
+ }
+ return Py::new_reference_to(list);
+}
+
+PyObject* ComplexGeoDataPy::countSubElements(PyObject *args)
+{
+ char *type;
+ if (!PyArg_ParseTuple(args, "s", &type))
+ return nullptr;
+
+ try {
+ unsigned long count = getComplexGeoDataPtr()->countSubElements(type);
+ return Py::new_reference_to(Py::Long(count));
+ }
+ catch (...) {
+ PyErr_SetString(PyExc_RuntimeError, "failed to count sub-elements from object");
+ return nullptr;
+ }
+}
+
+PyObject* ComplexGeoDataPy::getFacesFromSubelement(PyObject *args)
{
char *type;
int index;
if (!PyArg_ParseTuple(args, "si", &type, &index))
- return 0;
+ return nullptr;
std::vector points;
std::vector normals;
std::vector facets;
try {
- Data::Segment* segm = getComplexGeoDataPtr()->getSubElement(type, index);
- getComplexGeoDataPtr()->getFacesFromSubelement(segm, points, normals, facets);
- delete segm;
+ std::unique_ptr segm(getComplexGeoDataPtr()->getSubElement(type, index));
+ getComplexGeoDataPtr()->getFacesFromSubelement(segm.get(), points, normals, facets);
}
catch (...) {
PyErr_SetString(PyExc_RuntimeError, "failed to get sub-element from object");
- return 0;
+ return nullptr;
}
Py::Tuple tuple(2);
@@ -82,17 +113,214 @@ PyObject* ComplexGeoDataPy::getFacesFromSubelement(PyObject *args)
return Py::new_reference_to(tuple);
}
-Py::Object ComplexGeoDataPy::getBoundBox(void) const
+PyObject* ComplexGeoDataPy::getLinesFromSubelement(PyObject *args)
+{
+ char *type;
+ int index;
+ if (!PyArg_ParseTuple(args, "si", &type, &index))
+ return nullptr;
+
+ std::vector points;
+ std::vector lines;
+ try {
+ std::unique_ptr segm(getComplexGeoDataPtr()->getSubElement(type, index));
+ getComplexGeoDataPtr()->getLinesFromSubelement(segm.get(), points, lines);
+ }
+ catch (...) {
+ PyErr_SetString(PyExc_RuntimeError, "failed to get sub-element from object");
+ return nullptr;
+ }
+
+ Py::Tuple tuple(2);
+ Py::List vertex;
+ for (std::vector::const_iterator it = points.begin();
+ it != points.end(); ++it)
+ vertex.append(Py::asObject(new Base::VectorPy(*it)));
+ tuple.setItem(0, vertex);
+ Py::List line;
+ for (std::vector::const_iterator
+ it = lines.begin(); it != lines.end(); ++it) {
+ Py::Tuple l(2);
+ l.setItem(0,Py::Int((int)it->I1));
+ l.setItem(1,Py::Int((int)it->I2));
+ line.append(l);
+ }
+ tuple.setItem(1, line);
+ return Py::new_reference_to(tuple);
+}
+
+PyObject* ComplexGeoDataPy::getPoints(PyObject *args)
+{
+ double accuracy = 0.05;
+ if (!PyArg_ParseTuple(args, "d", &accuracy))
+ return nullptr;
+
+ std::vector points;
+ std::vector normals;
+ try {
+ getComplexGeoDataPtr()->getPoints(points, normals, accuracy);
+ }
+ catch (...) {
+ PyErr_SetString(PyExc_RuntimeError, "failed to get sub-element from object");
+ return nullptr;
+ }
+
+ Py::Tuple tuple(2);
+ Py::List vertex;
+ for (std::vector::const_iterator it = points.begin();
+ it != points.end(); ++it) {
+ vertex.append(Py::asObject(new Base::VectorPy(*it)));
+ }
+ tuple.setItem(0, vertex);
+
+ Py::List normal;
+ for (std::vector::const_iterator it = normals.begin();
+ it != normals.end(); ++it) {
+ vertex.append(Py::asObject(new Base::VectorPy(*it)));
+ }
+ tuple.setItem(1, normal);
+ return Py::new_reference_to(tuple);
+}
+
+PyObject* ComplexGeoDataPy::getLines(PyObject *args)
+{
+ double accuracy = 0.05;
+ if (!PyArg_ParseTuple(args, "d", &accuracy))
+ return nullptr;
+
+ std::vector points;
+ std::vector lines;
+ try {
+ getComplexGeoDataPtr()->getLines(points, lines, accuracy);
+ }
+ catch (...) {
+ PyErr_SetString(PyExc_RuntimeError, "failed to get sub-element from object");
+ return nullptr;
+ }
+
+ Py::Tuple tuple(2);
+ Py::List vertex;
+ for (std::vector::const_iterator it = points.begin();
+ it != points.end(); ++it)
+ vertex.append(Py::asObject(new Base::VectorPy(*it)));
+ tuple.setItem(0, vertex);
+ Py::List line;
+ for (std::vector::const_iterator
+ it = lines.begin(); it != lines.end(); ++it) {
+ Py::Tuple l(2);
+ l.setItem(0,Py::Int((int)it->I1));
+ l.setItem(1,Py::Int((int)it->I2));
+ line.append(l);
+ }
+ tuple.setItem(1, line);
+ return Py::new_reference_to(tuple);
+}
+
+PyObject* ComplexGeoDataPy::getFaces(PyObject *args)
+{
+ double accuracy = 0.05;
+ if (!PyArg_ParseTuple(args, "d", &accuracy))
+ return nullptr;
+
+ std::vector points;
+ std::vector facets;
+ try {
+ getComplexGeoDataPtr()->getFaces(points, facets, accuracy);
+ }
+ catch (...) {
+ PyErr_SetString(PyExc_RuntimeError, "failed to get sub-element from object");
+ return nullptr;
+ }
+
+ Py::Tuple tuple(2);
+ Py::List vertex;
+ for (std::vector::const_iterator it = points.begin();
+ it != points.end(); ++it)
+ vertex.append(Py::asObject(new Base::VectorPy(*it)));
+ tuple.setItem(0, vertex);
+ Py::List facet;
+ for (std::vector::const_iterator
+ it = facets.begin(); it != facets.end(); ++it) {
+ Py::Tuple f(3);
+ f.setItem(0,Py::Int((int)it->I1));
+ f.setItem(1,Py::Int((int)it->I2));
+ f.setItem(2,Py::Int((int)it->I3));
+ facet.append(f);
+ }
+ tuple.setItem(1, facet);
+ return Py::new_reference_to(tuple);
+}
+
+PyObject* ComplexGeoDataPy::applyTranslation(PyObject *args)
+{
+ PyObject *obj;
+ if (!PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type),&obj))
+ return nullptr;
+
+ try {
+ Base::Vector3d move = static_cast(obj)->value();
+ getComplexGeoDataPtr()->applyTranslation(move);
+ Py_Return;
+ }
+ catch (...) {
+ PyErr_SetString(PyExc_RuntimeError, "failed to apply rotation");
+ return nullptr;
+ }
+}
+
+PyObject* ComplexGeoDataPy::applyRotation(PyObject *args)
+{
+ PyObject *obj;
+ if (!PyArg_ParseTuple(args, "O!", &(Base::RotationPy::Type),&obj))
+ return nullptr;
+
+ try {
+ Base::Rotation rot = static_cast(obj)->value();
+ getComplexGeoDataPtr()->applyRotation(rot);
+ Py_Return;
+ }
+ catch (...) {
+ PyErr_SetString(PyExc_RuntimeError, "failed to apply rotation");
+ return nullptr;
+ }
+}
+
+PyObject* ComplexGeoDataPy::transformGeometry(PyObject *args)
+{
+ PyObject *obj;
+ if (!PyArg_ParseTuple(args, "O!", &(Base::MatrixPy::Type),&obj))
+ return nullptr;
+
+ try {
+ Base::Matrix4D mat = static_cast(obj)->value();
+ getComplexGeoDataPtr()->transformGeometry(mat);
+ Py_Return;
+ }
+ catch (...) {
+ PyErr_SetString(PyExc_RuntimeError, "failed to transform geometry");
+ return nullptr;
+ }
+}
+
+Py::Object ComplexGeoDataPy::getBoundBox() const
{
return Py::BoundingBox(getComplexGeoDataPtr()->getBoundBox());
}
+Py::Object ComplexGeoDataPy::getCenterOfGravity() const
+{
+ Base::Vector3d center;
+ if (getComplexGeoDataPtr()->getCenterOfGravity(center))
+ return Py::Vector(center);
+ throw Py::RuntimeError("Cannot get center of gravity");
+}
+
Py::Object ComplexGeoDataPy::getPlacement(void) const
{
return Py::Placement(getComplexGeoDataPtr()->getPlacement());
}
-void ComplexGeoDataPy::setPlacement(Py::Object arg)
+void ComplexGeoDataPy::setPlacement(Py::Object arg)
{
PyObject* p = arg.ptr();
if (PyObject_TypeCheck(p, &(Base::PlacementPy::Type))) {
@@ -112,7 +340,7 @@ Py::Object ComplexGeoDataPy::getMatrix(void) const
}
// FIXME would be better to call it setTransform() as in all other interfaces...
-void ComplexGeoDataPy::setMatrix(Py::Object arg)
+void ComplexGeoDataPy::setMatrix(Py::Object arg)
{
PyObject* p = arg.ptr();
if (PyObject_TypeCheck(p, &(Base::MatrixPy::Type))) {