More bug fixes for Body insertion/deletion of features
This commit is contained in:
parent
ee47c53339
commit
63f782d8f0
|
@ -50,25 +50,55 @@ Body::Body()
|
|||
ADD_PROPERTY(IsActive,(0));
|
||||
}
|
||||
|
||||
/*
|
||||
// Note: The following code will catch Python Document::removeObject() modifications. If the object removed is
|
||||
// a member of the Body::Model, then it will be automatically removed from the Model property which triggers the
|
||||
// following two methods
|
||||
// But since we require the Python user to call both Document::addObject() and Body::addFeature(), we should
|
||||
// also require calling both Document::removeObject and Body::removeFeature() in order to be consistent
|
||||
void Body::onBeforeChange(const App::Property *prop)
|
||||
{
|
||||
// Remember the feature before the current Tip. If the Tip is already at the first feature, remember the next feature
|
||||
if (prop == &Model) {
|
||||
std::vector<App::DocumentObject*> features = Model.getValues();
|
||||
if (features.empty()) {
|
||||
rememberTip = NULL;
|
||||
} else {
|
||||
std::vector<App::DocumentObject*>::iterator it = std::find(features.begin(), features.end(), Tip.getValue());
|
||||
if (it == features.begin()) {
|
||||
it++;
|
||||
if (it == features.end())
|
||||
rememberTip = NULL;
|
||||
else
|
||||
rememberTip = *it;
|
||||
} else {
|
||||
it--;
|
||||
rememberTip = *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Part::Feature::onBeforeChange(prop);
|
||||
}
|
||||
|
||||
void Body::onChanged(const App::Property *prop)
|
||||
{
|
||||
Base::Console().Error("Checking Body '%s' for sanity\n", getNameInDocument());
|
||||
App::DocumentObject* tip = Tip.getValue();
|
||||
Base::Console().Error(" Tip: %s\n", (tip == NULL) ? "None" : tip->getNameInDocument());
|
||||
std::vector<App::DocumentObject*> model = Model.getValues();
|
||||
Base::Console().Error(" Model:\n");
|
||||
for (std::vector<App::DocumentObject*>::const_iterator m = model.begin(); m != model.end(); m++) {
|
||||
Base::Console().Error(" %s", (*m)->getNameInDocument());
|
||||
if ((*m)->getTypeId().isDerivedFrom(PartDesign::SketchBased::getClassTypeId())) {
|
||||
App::DocumentObject* baseFeature = static_cast<PartDesign::SketchBased*>(*m)->BaseFeature.getValue();
|
||||
Base::Console().Error(", Base: %s\n", baseFeature == NULL ? "None" : baseFeature->getNameInDocument());
|
||||
if (prop == &Model) {
|
||||
std::vector<App::DocumentObject*> features = Model.getValues();
|
||||
if (features.empty()) {
|
||||
Tip.setValue(NULL);
|
||||
} else {
|
||||
Base::Console().Error("\n");
|
||||
std::vector<App::DocumentObject*>::iterator it = std::find(features.begin(), features.end(), Tip.getValue());
|
||||
if (it == features.end()) {
|
||||
// Tip feature was deleted
|
||||
Tip.setValue(rememberTip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Part::Feature::onChanged(prop);
|
||||
}
|
||||
*/
|
||||
|
||||
short Body::mustExecute() const
|
||||
{
|
||||
|
@ -189,7 +219,7 @@ Body* Body::findBodyOf(const App::DocumentObject* f)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void Body::insertFeature(App::DocumentObject *feature)
|
||||
void Body::addFeature(App::DocumentObject *feature)
|
||||
{
|
||||
// Set the BaseFeature property
|
||||
// Note: This is not strictly necessary for Datum features
|
||||
|
@ -236,6 +266,8 @@ void Body::insertFeature(App::DocumentObject *feature)
|
|||
|
||||
void Body::removeFeature(App::DocumentObject* feature)
|
||||
{
|
||||
// This method must be called BEFORE the feature is removed from the Document!
|
||||
|
||||
if (isSolidFeature(feature)) {
|
||||
// This is a solid feature
|
||||
// If the next feature is solid, reroute its BaseFeature property to the previous solid feature
|
||||
|
@ -250,10 +282,11 @@ void Body::removeFeature(App::DocumentObject* feature)
|
|||
}
|
||||
}
|
||||
|
||||
// Adjust Tip feature if it is pointing to the deleted object
|
||||
App::DocumentObject* tipFeature = Tip.getValue();
|
||||
std::vector<App::DocumentObject*> model = Model.getValues();
|
||||
std::vector<App::DocumentObject*>::iterator it = std::find(model.begin(), model.end(), feature);
|
||||
|
||||
// Adjust Tip feature if it is pointing to the deleted object
|
||||
App::DocumentObject* tipFeature = Tip.getValue();
|
||||
if (tipFeature == feature) {
|
||||
// Set the Tip to the previous feature if possible, otherwise to the next feature
|
||||
std::vector<App::DocumentObject*>::const_iterator prev = it, next = it;
|
||||
|
@ -270,7 +303,11 @@ void Body::removeFeature(App::DocumentObject* feature)
|
|||
Tip.setValue(NULL);
|
||||
}
|
||||
} else {
|
||||
Tip.setValue(NULL);
|
||||
next++;
|
||||
if (next != model.end())
|
||||
Tip.setValue(*next);
|
||||
else
|
||||
Tip.setValue(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,6 +318,22 @@ void Body::removeFeature(App::DocumentObject* feature)
|
|||
|
||||
App::DocumentObjectExecReturn *Body::execute(void)
|
||||
{
|
||||
Base::Console().Error("Checking Body '%s' for sanity\n", getNameInDocument());
|
||||
App::DocumentObject* tip = Tip.getValue();
|
||||
Base::Console().Error(" Tip: %s\n", (tip == NULL) ? "None" : tip->getNameInDocument());
|
||||
std::vector<App::DocumentObject*> model = Model.getValues();
|
||||
Base::Console().Error(" Model:\n");
|
||||
for (std::vector<App::DocumentObject*>::const_iterator m = model.begin(); m != model.end(); m++) {
|
||||
if (*m == NULL) continue;
|
||||
Base::Console().Error(" %s", (*m)->getNameInDocument());
|
||||
if ((*m)->getTypeId().isDerivedFrom(PartDesign::SketchBased::getClassTypeId())) {
|
||||
App::DocumentObject* baseFeature = static_cast<PartDesign::SketchBased*>(*m)->BaseFeature.getValue();
|
||||
Base::Console().Error(", Base: %s\n", baseFeature == NULL ? "None" : baseFeature->getNameInDocument());
|
||||
} else {
|
||||
Base::Console().Error("\n");
|
||||
}
|
||||
}
|
||||
|
||||
const Part::TopoShape& TipShape = getTipShape();
|
||||
|
||||
if (TipShape._Shape.IsNull())
|
||||
|
|
|
@ -48,9 +48,7 @@ public:
|
|||
//@{
|
||||
/// recalculate the feature
|
||||
App::DocumentObjectExecReturn *execute(void);
|
||||
short mustExecute() const;
|
||||
/// Just for debugging, remove when Body functionality is stable
|
||||
void onChanged(const App::Property* prop);
|
||||
short mustExecute() const;
|
||||
/// returns the type name of the view provider
|
||||
const char* getViewProviderName(void) const {
|
||||
return "PartDesignGui::ViewProviderBody";
|
||||
|
@ -83,8 +81,8 @@ public:
|
|||
/// Return true if the feature is located after the current Tip feature
|
||||
const bool isAfterTip(const App::DocumentObject *f);
|
||||
|
||||
/// Insert the feature into the body at the current insert point (Tip feature)
|
||||
void insertFeature(App::DocumentObject* feature);
|
||||
/// Add the feature into the body at the current insert point (Tip feature)
|
||||
void addFeature(App::DocumentObject* feature);
|
||||
|
||||
/// Remove the feature from the body
|
||||
void removeFeature(App::DocumentObject* feature);
|
||||
|
@ -102,7 +100,8 @@ public:
|
|||
|
||||
PyObject *getPyObject(void);
|
||||
|
||||
|
||||
private:
|
||||
App::DocumentObject* rememberTip;
|
||||
};
|
||||
|
||||
} //namespace PartDesign
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
<Author Licence="LGPL" Name="Juergen Riegel" EMail="FreeCAD@juergen-riegel.net" />
|
||||
<UserDocu>PartDesign body class</UserDocu>
|
||||
</Documentation>
|
||||
<Methode Name="insertFeature">
|
||||
<Methode Name="addFeature">
|
||||
<Documentation>
|
||||
<UserDocu>insertFeature(feat) - Insert the given feature after the current Tip feature</UserDocu>
|
||||
<UserDocu>addFeature(feat) - Add the given feature after the current Tip feature</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="removeFeature">
|
||||
|
|
|
@ -29,7 +29,7 @@ int BodyPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
|||
return 0;
|
||||
}
|
||||
|
||||
PyObject* BodyPy::insertFeature(PyObject *args)
|
||||
PyObject* BodyPy::addFeature(PyObject *args)
|
||||
{
|
||||
PyObject* featurePy;
|
||||
if (!PyArg_ParseTuple(args, "O!", &(Part::PartFeaturePy::Type), &featurePy))
|
||||
|
@ -45,7 +45,7 @@ PyObject* BodyPy::insertFeature(PyObject *args)
|
|||
Body* body = this->getBodyPtr();
|
||||
|
||||
try {
|
||||
body->insertFeature(feature);
|
||||
body->addFeature(feature);
|
||||
} catch (Base::Exception& e) {
|
||||
PyErr_SetString(PyExc_SystemError, e.what());
|
||||
return 0;
|
||||
|
|
|
@ -280,7 +280,7 @@ void CmdPartDesignNewSketch::activated(int iMsg)
|
|||
openCommand("Create a Sketch on Face");
|
||||
doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str());
|
||||
doCommand(Doc,"App.activeDocument().%s.Support = %s",FeatName.c_str(),supportString.c_str());
|
||||
doCommand(Doc,"App.activeDocument().%s.insertFeature(App.activeDocument().%s)",
|
||||
doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)",
|
||||
pcActiveBody->getNameInDocument(), FeatName.c_str());
|
||||
doCommand(Gui,"App.activeDocument().recompute()"); // recompute the sketch placement based on its support
|
||||
//doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str());
|
||||
|
@ -354,7 +354,7 @@ void CmdPartDesignNewSketch::activated(int iMsg)
|
|||
doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str());
|
||||
doCommand(Doc,"App.activeDocument().%s.Support = %s",FeatName.c_str(),supportString.c_str());
|
||||
doCommand(Doc,"App.activeDocument().%s.Placement = App.Placement(App.Vector(%f,%f,%f),App.Rotation(%f,%f,%f,%f))",FeatName.c_str(),p.x,p.y,p.z,r[0],r[1],r[2],r[3]);
|
||||
doCommand(Doc,"App.activeDocument().%s.insertFeature(App.activeDocument().%s)",
|
||||
doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)",
|
||||
pcActiveBody->getNameInDocument(), FeatName.c_str());
|
||||
//doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str());
|
||||
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
|
||||
|
@ -478,7 +478,7 @@ void prepareSketchBased(Gui::Command* cmd, const std::string& which, Part::Part2
|
|||
which.c_str(), FeatName.c_str());
|
||||
cmd->doCommand(cmd->Doc,"App.activeDocument().%s.Sketch = App.activeDocument().%s",
|
||||
FeatName.c_str(), sketch->getNameInDocument());
|
||||
cmd->doCommand(cmd->Doc,"App.activeDocument().%s.insertFeature(App.activeDocument().%s)",
|
||||
cmd->doCommand(cmd->Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)",
|
||||
pcActiveBody->getNameInDocument(), FeatName.c_str());
|
||||
}
|
||||
|
||||
|
|
|
@ -331,15 +331,22 @@ bool TaskDlgGrooveParameters::reject()
|
|||
// get the support and Sketch
|
||||
PartDesign::Groove* pcGroove = static_cast<PartDesign::Groove*>(GrooveView->getObject());
|
||||
Sketcher::SketchObject *pcSketch = 0;
|
||||
App::DocumentObject *pcSupport = 0;
|
||||
if (pcGroove->Sketch.getValue()) {
|
||||
pcSketch = static_cast<Sketcher::SketchObject*>(pcGroove->Sketch.getValue());
|
||||
pcSupport = pcSketch->Support.getValue();
|
||||
}
|
||||
|
||||
// role back the done things
|
||||
Gui::Command::abortCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
|
||||
|
||||
// if abort command deleted the object the support is visible again
|
||||
if (!Gui::Application::Instance->getViewProvider(pcGroove)) {
|
||||
if (pcSketch && Gui::Application::Instance->getViewProvider(pcSketch))
|
||||
Gui::Application::Instance->getViewProvider(pcSketch)->show();
|
||||
}
|
||||
|
||||
// Body housekeeping
|
||||
if (ActivePartObject != NULL) {
|
||||
ActivePartObject->removeFeature(pcGroove);
|
||||
// Make the new Tip and the previous solid feature visible again
|
||||
App::DocumentObject* tip = ActivePartObject->Tip.getValue();
|
||||
App::DocumentObject* prev = ActivePartObject->getPrevSolidFeature();
|
||||
|
@ -350,21 +357,6 @@ bool TaskDlgGrooveParameters::reject()
|
|||
}
|
||||
}
|
||||
|
||||
// role back the done things
|
||||
Gui::Command::abortCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
|
||||
|
||||
// if abort command deleted the object the support is visible again
|
||||
if (!Gui::Application::Instance->getViewProvider(pcGroove)) {
|
||||
if (pcSketch && Gui::Application::Instance->getViewProvider(pcSketch))
|
||||
Gui::Application::Instance->getViewProvider(pcSketch)->show();
|
||||
if (pcSupport && Gui::Application::Instance->getViewProvider(pcSupport))
|
||||
Gui::Application::Instance->getViewProvider(pcSupport)->show();
|
||||
}
|
||||
|
||||
//Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
|
||||
//Gui::Command::commitCommand();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -553,20 +553,7 @@ bool TaskDlgPadParameters::reject()
|
|||
Sketcher::SketchObject *pcSketch = 0;
|
||||
if (pcPad->Sketch.getValue()) {
|
||||
pcSketch = static_cast<Sketcher::SketchObject*>(pcPad->Sketch.getValue());
|
||||
}
|
||||
|
||||
// Body housekeeping
|
||||
if (ActivePartObject != NULL) {
|
||||
ActivePartObject->removeFeature(pcPad);
|
||||
// Make the new Tip and the previous solid feature visible again
|
||||
App::DocumentObject* tip = ActivePartObject->Tip.getValue();
|
||||
App::DocumentObject* prev = ActivePartObject->getPrevSolidFeature();
|
||||
if (tip != NULL) {
|
||||
Gui::Application::Instance->getViewProvider(tip)->show();
|
||||
if ((tip != prev) && (prev != NULL))
|
||||
Gui::Application::Instance->getViewProvider(prev)->show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// roll back the done things
|
||||
Gui::Command::abortCommand();
|
||||
|
@ -578,6 +565,18 @@ bool TaskDlgPadParameters::reject()
|
|||
Gui::Application::Instance->getViewProvider(pcSketch)->show();
|
||||
}
|
||||
|
||||
// Body housekeeping
|
||||
if (ActivePartObject != NULL) {
|
||||
// Make the new Tip and the previous solid feature visible again
|
||||
App::DocumentObject* tip = ActivePartObject->Tip.getValue();
|
||||
App::DocumentObject* prev = ActivePartObject->getPrevSolidFeature();
|
||||
if (tip != NULL) {
|
||||
Gui::Application::Instance->getViewProvider(tip)->show();
|
||||
if ((tip != prev) && (prev != NULL))
|
||||
Gui::Application::Instance->getViewProvider(prev)->show();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -495,15 +495,22 @@ bool TaskDlgPocketParameters::reject()
|
|||
// get the support and Sketch
|
||||
PartDesign::Pocket* pcPocket = static_cast<PartDesign::Pocket*>(PocketView->getObject());
|
||||
Sketcher::SketchObject *pcSketch = 0;
|
||||
App::DocumentObject *pcSupport = 0;
|
||||
if (pcPocket->Sketch.getValue()) {
|
||||
pcSketch = static_cast<Sketcher::SketchObject*>(pcPocket->Sketch.getValue());
|
||||
pcSupport = pcSketch->Support.getValue();
|
||||
pcSketch = static_cast<Sketcher::SketchObject*>(pcPocket->Sketch.getValue());
|
||||
}
|
||||
|
||||
// roll back the done things
|
||||
Gui::Command::abortCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
|
||||
|
||||
// if abort command deleted the object the sketch is visible again
|
||||
if (!Gui::Application::Instance->getViewProvider(pcPocket)) {
|
||||
if (pcSketch && Gui::Application::Instance->getViewProvider(pcSketch))
|
||||
Gui::Application::Instance->getViewProvider(pcSketch)->show();
|
||||
}
|
||||
|
||||
// Body housekeeping
|
||||
if (ActivePartObject != NULL) {
|
||||
ActivePartObject->removeFeature(pcPocket);
|
||||
// Make the new Tip and the previous solid feature visible again
|
||||
App::DocumentObject* tip = ActivePartObject->Tip.getValue();
|
||||
App::DocumentObject* prev = ActivePartObject->getPrevSolidFeature();
|
||||
|
@ -514,21 +521,6 @@ bool TaskDlgPocketParameters::reject()
|
|||
}
|
||||
}
|
||||
|
||||
// roll back the done things
|
||||
Gui::Command::abortCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
|
||||
|
||||
// if abort command deleted the object the support is visible again
|
||||
if (!Gui::Application::Instance->getViewProvider(pcPocket)) {
|
||||
if (pcSketch && Gui::Application::Instance->getViewProvider(pcSketch))
|
||||
Gui::Application::Instance->getViewProvider(pcSketch)->show();
|
||||
if (pcSupport && Gui::Application::Instance->getViewProvider(pcSupport))
|
||||
Gui::Application::Instance->getViewProvider(pcSupport)->show();
|
||||
}
|
||||
|
||||
//Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
|
||||
//Gui::Command::commitCommand();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -332,23 +332,8 @@ bool TaskDlgRevolutionParameters::reject()
|
|||
// get the support and Sketch
|
||||
PartDesign::Revolution* pcRevolution = static_cast<PartDesign::Revolution*>(RevolutionView->getObject());
|
||||
Sketcher::SketchObject *pcSketch = 0;
|
||||
App::DocumentObject *pcSupport = 0;
|
||||
if (pcRevolution->Sketch.getValue()) {
|
||||
pcSketch = static_cast<Sketcher::SketchObject*>(pcRevolution->Sketch.getValue());
|
||||
pcSupport = pcSketch->Support.getValue();
|
||||
}
|
||||
|
||||
// Body housekeeping
|
||||
if (ActivePartObject != NULL) {
|
||||
ActivePartObject->removeFeature(pcRevolution);
|
||||
// Make the new Tip and the previous solid feature visible again
|
||||
App::DocumentObject* tip = ActivePartObject->Tip.getValue();
|
||||
App::DocumentObject* prev = ActivePartObject->getPrevSolidFeature();
|
||||
if (tip != NULL) {
|
||||
Gui::Application::Instance->getViewProvider(tip)->show();
|
||||
if ((tip != prev) && (prev != NULL))
|
||||
Gui::Application::Instance->getViewProvider(prev)->show();
|
||||
}
|
||||
}
|
||||
|
||||
// role back the done things
|
||||
|
@ -359,12 +344,19 @@ bool TaskDlgRevolutionParameters::reject()
|
|||
if (!Gui::Application::Instance->getViewProvider(pcRevolution)) {
|
||||
if (pcSketch && Gui::Application::Instance->getViewProvider(pcSketch))
|
||||
Gui::Application::Instance->getViewProvider(pcSketch)->show();
|
||||
if (pcSupport && Gui::Application::Instance->getViewProvider(pcSupport))
|
||||
Gui::Application::Instance->getViewProvider(pcSupport)->show();
|
||||
}
|
||||
|
||||
//Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
|
||||
//Gui::Command::commitCommand();
|
||||
// Body housekeeping
|
||||
if (ActivePartObject != NULL) {
|
||||
// Make the new Tip and the previous solid feature visible again
|
||||
App::DocumentObject* tip = ActivePartObject->Tip.getValue();
|
||||
App::DocumentObject* prev = ActivePartObject->getPrevSolidFeature();
|
||||
if (tip != NULL) {
|
||||
Gui::Application::Instance->getViewProvider(tip)->show();
|
||||
if ((tip != prev) && (prev != NULL))
|
||||
Gui::Application::Instance->getViewProvider(prev)->show();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user