PartDesign/Body: add methodes to insert features into specific place

Add a Body::insertFeature() methodes as well as python API for it.
This commit is contained in:
Alexander Golubev 2015-06-28 04:01:26 +03:00 committed by Stefan Tröger
parent ec2bbc4c34
commit 7c2413b0aa
4 changed files with 119 additions and 35 deletions

View File

@ -230,51 +230,64 @@ const bool Body::isAllowed(const App::DocumentObject* f)
);
}
void Body::addFeature(App::DocumentObject *feature)
{
// Set the BaseFeature property
if (feature->getTypeId().isDerivedFrom(PartDesign::Feature::getClassTypeId())) {
App::DocumentObject* prevSolidFeature = getPrevSolidFeature(NULL, true);
if (prevSolidFeature != NULL)
// Set BaseFeature property to previous feature (this might be the Tip feature)
static_cast<PartDesign::Feature*>(feature)->BaseFeature.setValue(prevSolidFeature);
insertFeature (feature, Tip.getValue(), /*after = */ true);
// Move the Tip
Tip.setValue (feature);
}
void Body::insertFeature(App::DocumentObject* feature, App::DocumentObject* target, bool after)
{
// Check if the after feature belongs to the body
if (target && !hasFeature (target)) {
throw Base::Exception("Body: the feature we should insert relative to is not part of that body");
}
std::vector<App::DocumentObject*> model = Model.getValues();
std::vector<App::DocumentObject*>::iterator insertInto;
// Find out the position there to insert the feature
if (!target) {
if (after) {
insertInto = model.begin();
} else {
insertInto = model.end();
}
} else {
std::vector<App::DocumentObject*>::iterator targetIt = std::find (model.begin(), model.end(), target);
assert (targetIt != model.end());
if (after) {
insertInto = targetIt + 1;
} else {
insertInto = targetIt;
}
}
// Insert the new feature after the given
model.insert (insertInto, feature);
Model.setValues (model);
// Set the BaseFeature property
if (Body::isSolidFeature(feature)) {
// Set BaseFeature property to previous feature (this might be the Tip feature)
App::DocumentObject* prevSolidFeature = getPrevSolidFeature(feature, false);
if (prevSolidFeature)
static_cast<PartDesign::Feature*>(feature)->BaseFeature.setValue(prevSolidFeature);
// Reroute the next solid feature's BaseFeature property to this feature
App::DocumentObject* nextSolidFeature = getNextSolidFeature(NULL, false);
if (nextSolidFeature != NULL)
App::DocumentObject* nextSolidFeature = getNextSolidFeature(feature, false);
if (nextSolidFeature)
static_cast<PartDesign::Feature*>(nextSolidFeature)->BaseFeature.setValue(feature);
}
// Insert the new feature after the current Tip feature
App::DocumentObject* tipFeature = Tip.getValue();
std::vector<App::DocumentObject*> model = Model.getValues();
if (tipFeature == NULL) {
if (model.empty())
// First feature in the body
model.push_back(feature);
else
// Insert feature as before all other features in the body
model.insert(model.begin(), feature);
} else {
// Insert after Tip
std::vector<App::DocumentObject*>::iterator it = std::find(model.begin(), model.end(), tipFeature);
if (it == model.end())
throw Base::Exception("Body: Tip is not contained in model");
it++;
if (it == model.end())
model.push_back(feature);
else
model.insert(it, feature);
}
Model.setValues(model);
// Move the Tip
Tip.setValue(feature);
}
void Body::removeFeature(App::DocumentObject* feature)
{
// This method must be called BEFORE the feature is removed from the Document!
@ -328,6 +341,7 @@ void Body::removeFeature(App::DocumentObject* feature)
}
App::DocumentObjectExecReturn *Body::execute(void)
{
/*

View File

@ -81,9 +81,22 @@ public:
/// Add the feature into the body at the current insert point (Tip feature)
void addFeature(App::DocumentObject* feature);
/**
* Insert the feature into the body after the given feature.
*
* @param feature The feature to insert into the body
* @param target The feature relative which one should be inserted the given.
* If target is NULL than insert into the end if where is InsertBefore
* and into the begin if where is InsertAfter.
* @param after if true insert the feature after the target. Default is false.
*
* @note the methode doesn't modifies the Tip unlike addFeature()
*/
void insertFeature(App::DocumentObject* feature, App::DocumentObject* target, bool after=false);
/// Remove the feature from the body
void removeFeature(App::DocumentObject* feature);
/// Checks if the given document object is a feaure of this body
bool isFeature(App::DocumentObject* feature);

View File

@ -23,5 +23,20 @@
<UserDocu>removeFeature(feat) - Remove the given feature from the Body</UserDocu>
</Documentation>
</Methode>
<Methode Name="insertFeature">
<Documentation>
<UserDocu>insertFeatureAfter(feature, target, after=False)
Insert the feature into the body after the given feature.
@param feature The feature to insert into the body
@param target The feature relative which one should be inserted the given.
If target is NULL than insert into the end if where is InsertBefore
and into the begin if where is InsertAfter.
@param after if true insert the feature after the target. Default is false.
@note the methode doesn't modifies the Tip unlike addFeature()
</UserDocu>
</Documentation>
</Methode>
</PythonExport>
</GenerateModel>

View File

@ -1,6 +1,8 @@
#include "PreCompiled.h"
#include <cstring>
#include "Mod/Part/App/Part2DObject.h"
#include "Mod/PartDesign/App/Body.h"
@ -40,6 +42,7 @@ PyObject* BodyPy::addFeature(PyObject *args)
PyErr_SetString(PyExc_SystemError, "Only PartDesign features, datum features and sketches can be inserted into a Body");
return 0;
}
Body* body = this->getBodyPtr();
try {
@ -52,6 +55,45 @@ PyObject* BodyPy::addFeature(PyObject *args)
Py_Return;
}
PyObject* BodyPy::insertFeature(PyObject *args)
{
PyObject* featurePy;
PyObject* targetPy;
PyObject* afterPy = 0;
if (!PyArg_ParseTuple(args, "O!O|O", &(App::DocumentObjectPy::Type), &featurePy, &targetPy, &afterPy)) {
return 0;
}
App::DocumentObject* feature = static_cast<App::DocumentObjectPy*>(featurePy)->getDocumentObjectPtr();
App::DocumentObject* target = static_cast<App::DocumentObjectPy*>(targetPy)->getDocumentObjectPtr();
int after = 0;
if (!Body::isAllowed(feature)) {
PyErr_SetString(PyExc_SystemError, "Only PartDesign features, datum features and sketches can be inserted into a Body");
return 0;
}
if (afterPy) {
after = PyObject_IsTrue(afterPy);
if ( after == -1) {
// Note: shouldn't happen
PyErr_SetString(PyExc_ValueError, "The after parameter should be of boolean type");
return 0;
}
}
Body* body = this->getBodyPtr();
try {
body->insertFeature(feature, target, after);
} catch (Base::Exception& e) {
PyErr_SetString(PyExc_SystemError, e.what());
return 0;
}
Py_Return;
}
PyObject* BodyPy::removeFeature(PyObject *args)
{
PyObject* featurePy;