Introduce global placement calculations

This commit is contained in:
Stefan Tröger
2017-01-29 16:09:08 +01:00
committed by wmayer
parent d5022483c6
commit 61020c0b27
4 changed files with 59 additions and 0 deletions

View File

@@ -27,6 +27,7 @@
#endif
#include "GeoFeature.h"
#include "GeoFeatureGroupExtension.h"
#include <App/GeoFeaturePy.h>
using namespace App;
@@ -55,6 +56,16 @@ void GeoFeature::transformPlacement(const Base::Placement &transform)
this->Placement.setValue(plm);
}
Base::Placement GeoFeature::globalPlacement()
{
auto* group = GeoFeatureGroupExtension::getGroupOfObject(this);
if(group) {
auto ext = group->getExtensionByType<GeoFeatureGroupExtension>();
return ext->globalGroupPlacement() * Placement.getValue();
}
return Placement.getValue();
}
const PropertyComplexGeoData* GeoFeature::getPropertyOfGeometry() const
{
return nullptr;

View File

@@ -66,6 +66,20 @@ public:
* @return the Python binding object
*/
virtual PyObject* getPyObject(void);
/**
* @brief Calculates the placement in the global reference coordinate system
*
* In FreeCAD the GeoFeature placement describes the local placement of the object in its parent
* coordinate system. This is however not always the same as the global reference system. If the
* object is in a GeoFeatureGroup, hence in annother local coordinate system, the Placement
* property does only give the local transformation. This function can be used to calculate the
* placement of the object in the global reference coordinate system taking all stacked local
* system into account.
*
* @return Base::Placement The transformation from the global reference coordinate system
*/
Base::Placement globalPlacement();
};
} //namespace App

View File

@@ -160,6 +160,25 @@ DocumentObject* GeoFeatureGroupExtension::getGroupOfObject(const DocumentObject*
return 0;
}
Base::Placement GeoFeatureGroupExtension::globalGroupPlacement() {
return recursiveGroupPlacement(this);
}
Base::Placement GeoFeatureGroupExtension::recursiveGroupPlacement(GeoFeatureGroupExtension* group) {
auto inList = group->getExtendedObject()->getInList();
for(auto* link : inList) {
if(link->hasExtension(App::GeoFeatureGroupExtension::getExtensionClassTypeId()))
return recursiveGroupPlacement(link->getExtensionByType<GeoFeatureGroupExtension>()) * group->placement().getValue();
}
return group->placement().getValue();
}
// Python feature ---------------------------------------------------------
namespace App {

View File

@@ -70,12 +70,27 @@ public:
* default is true
*/
static DocumentObject* getGroupOfObject(const DocumentObject* obj, bool indirect=true);
/**
* @brief Calculates the global placement of this group
*
* The returned placement describes the transformation from the global reference coordinate
* system to the local coordinate system of this geo feature group. If this group has a no parent
* GeoFeatureGroup the returned placement is the one of this group. For multiple stacked
* GeoFeatureGroups the returned Placement is the combination of all parent placements including
* ths one of this group.
* @return Base::Placement The transformation from global reference system to the groups local system
*/
Base::Placement globalGroupPlacement();
/// Returns true if the given DocumentObject is DocumentObjectGroup but not GeoFeatureGroup
static bool isNonGeoGroup(const DocumentObject* obj) {
return obj->hasExtension(GroupExtension::getExtensionClassTypeId()) &&
!obj->hasExtension(GeoFeatureGroupExtension::getExtensionClassTypeId());
}
private:
Base::Placement recursiveGroupPlacement(GeoFeatureGroupExtension* group);
};
typedef ExtensionPythonT<GroupExtensionPythonT<GeoFeatureGroupExtension>> GeoFeatureGroupExtensionPython;