Allow inserting at the beginning of a body

This commit is contained in:
jrheinlaender 2013-05-23 19:26:39 +04:30 committed by Stefan Tröger
parent 7983862b52
commit 999b1c028b
3 changed files with 44 additions and 21 deletions

View File

@ -130,6 +130,8 @@ App::DocumentObject* Body::getPrevSolidFeature(App::DocumentObject *start, const
std::vector<App::DocumentObject*> features = Model.getValues(); std::vector<App::DocumentObject*> features = Model.getValues();
if (features.empty()) return NULL; if (features.empty()) return NULL;
App::DocumentObject* st = (start == NULL ? Tip.getValue() : start); App::DocumentObject* st = (start == NULL ? Tip.getValue() : start);
if (st == NULL)
return st; // Tip is NULL
if (inclusive && isSolidFeature(st)) if (inclusive && isSolidFeature(st))
return st; return st;
@ -156,7 +158,11 @@ App::DocumentObject* Body::getNextSolidFeature(App::DocumentObject *start, const
if (inclusive && isSolidFeature(st)) if (inclusive && isSolidFeature(st))
return st; return st;
std::vector<App::DocumentObject*>::iterator it = std::find(features.begin(), features.end(), st); std::vector<App::DocumentObject*>::iterator it;
if (st == NULL)
it = features.begin(); // Tip is NULL
else
it = std::find(features.begin(), features.end(), st);
if (it == features.end()) return NULL; // Invalid start object if (it == features.end()) return NULL; // Invalid start object
// Skip sketches and datum features // Skip sketches and datum features
@ -170,9 +176,13 @@ App::DocumentObject* Body::getNextSolidFeature(App::DocumentObject *start, const
} }
const bool Body::isAfterTip(const App::DocumentObject *f) { const bool Body::isAfterTip(const App::DocumentObject *f) {
App::DocumentObject* tipFeature = Tip.getValue();
if (tipFeature == NULL)
return true;
std::vector<App::DocumentObject*> features = Model.getValues(); std::vector<App::DocumentObject*> features = Model.getValues();
std::vector<App::DocumentObject*>::const_iterator it = std::find(features.begin(), features.end(), f); std::vector<App::DocumentObject*>::const_iterator it = std::find(features.begin(), features.end(), f);
std::vector<App::DocumentObject*>::const_iterator tip = std::find(features.begin(), features.end(), Tip.getValue()); std::vector<App::DocumentObject*>::const_iterator tip = std::find(features.begin(), features.end(), tipFeature);
return (it > tip); return (it > tip);
} }
@ -226,7 +236,8 @@ void Body::addFeature(App::DocumentObject *feature)
// First feature in the body // First feature in the body
model.push_back(feature); model.push_back(feature);
else else
throw Base::Exception("Body has features, but Tip is not valid"); // Insert feature as before all other features in the body
model.insert(model.begin(), feature);
} else { } else {
// Insert after Tip // Insert after Tip
std::vector<App::DocumentObject*>::iterator it = std::find(model.begin(), model.end(), tipFeature); std::vector<App::DocumentObject*>::iterator it = std::find(model.begin(), model.end(), tipFeature);
@ -334,13 +345,15 @@ Base::BoundBox3d Body::getBoundBox()
Part::Feature* tipSolid = static_cast<Part::Feature*>(getPrevSolidFeature()); Part::Feature* tipSolid = static_cast<Part::Feature*>(getPrevSolidFeature());
if (tipSolid != NULL) { if (tipSolid != NULL) {
TopoDS_Shape sh = tipSolid->Shape.getValue(); if (tipSolid->Shape.getValue().IsNull())
if (sh.IsNull())
// This can happen when a new feature is added without having its Shape property set yet // This can happen when a new feature is added without having its Shape property set yet
tipSolid = static_cast<Part::Feature*>(getPrevSolidFeature(NULL, false)); tipSolid = static_cast<Part::Feature*>(getPrevSolidFeature(NULL, false));
if (tipSolid != NULL) { if (tipSolid != NULL) {
result = tipSolid->Shape.getShape().getBoundBox(); if (tipSolid->Shape.getValue().IsNull())
tipSolid = NULL;
else
result = tipSolid->Shape.getShape().getBoundBox();
} }
} }
if (tipSolid == NULL) if (tipSolid == NULL)

View File

@ -178,7 +178,10 @@ void CmdPartDesignMoveTip::activated(int iMsg)
if (features.empty()) return; if (features.empty()) return;
App::DocumentObject* selFeature = features.front(); App::DocumentObject* selFeature = features.front();
if (!pcActiveBody->hasFeature(selFeature)) { if (selFeature->getTypeId().isDerivedFrom(PartDesign::Body::getClassTypeId())) {
// Insert at the beginning of this body
selFeature = NULL;
} else if (!pcActiveBody->hasFeature(selFeature)) {
// Switch to other body // Switch to other body
pcActiveBody = static_cast<PartDesign::Body*>(Part::BodyBase::findBodyOf(selFeature)); pcActiveBody = static_cast<PartDesign::Body*>(Part::BodyBase::findBodyOf(selFeature));
if (pcActiveBody != NULL) if (pcActiveBody != NULL)
@ -188,21 +191,27 @@ void CmdPartDesignMoveTip::activated(int iMsg)
return; return;
} }
App::DocumentObject* oldTip = pcActiveBody->Tip.getValue();
if (!oldTip->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId()))
doCommand(Gui,"Gui.activeDocument().hide(\"%s\")", oldTip->getNameInDocument());
App::DocumentObject* prevSolidFeature = pcActiveBody->getPrevSolidFeature();
if (prevSolidFeature != NULL)
doCommand(Gui,"Gui.activeDocument().hide(\"%s\")", prevSolidFeature->getNameInDocument());
openCommand("Move insert point to selected feature"); openCommand("Move insert point to selected feature");
doCommand(Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",pcActiveBody->getNameInDocument(), selFeature->getNameInDocument()); App::DocumentObject* oldTip = pcActiveBody->Tip.getValue();
if (oldTip != NULL) {
if (!oldTip->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId()))
doCommand(Gui,"Gui.activeDocument().hide(\"%s\")", oldTip->getNameInDocument());
App::DocumentObject* prevSolidFeature = pcActiveBody->getPrevSolidFeature();
if (prevSolidFeature != NULL)
doCommand(Gui,"Gui.activeDocument().hide(\"%s\")", prevSolidFeature->getNameInDocument());
}
// Adjust visibility to show only the Tip feature and (if the Tip feature is not solid) the solid feature prior to the Tip if (selFeature == NULL) {
doCommand(Gui,"Gui.activeDocument().show(\"%s\")", selFeature->getNameInDocument()); doCommand(Doc,"App.activeDocument().%s.Tip = None", pcActiveBody->getNameInDocument());
prevSolidFeature = pcActiveBody->getPrevSolidFeature(); } else {
if ((prevSolidFeature != NULL) && !PartDesign::Body::isSolidFeature(selFeature)) doCommand(Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",pcActiveBody->getNameInDocument(), selFeature->getNameInDocument());
doCommand(Gui,"Gui.activeDocument().show(\"%s\")", prevSolidFeature->getNameInDocument());
// Adjust visibility to show only the Tip feature and (if the Tip feature is not solid) the solid feature prior to the Tip
doCommand(Gui,"Gui.activeDocument().show(\"%s\")", selFeature->getNameInDocument());
App::DocumentObject* prevSolidFeature = pcActiveBody->getPrevSolidFeature();
if ((prevSolidFeature != NULL) && !PartDesign::Body::isSolidFeature(selFeature))
doCommand(Gui,"Gui.activeDocument().show(\"%s\")", prevSolidFeature->getNameInDocument());
}
// TOOD: Hide all datum features after the Tip feature? But the user might have already hidden some and wants to see // TOOD: Hide all datum features after the Tip feature? But the user might have already hidden some and wants to see
// others, so we would have to remember their state somehow // others, so we would have to remember their state somehow

View File

@ -276,7 +276,8 @@ void Workbench::setupContextMenu(const char* recipient, Gui::MenuItem* item) con
{ {
if (strcmp(recipient,"Tree") == 0) if (strcmp(recipient,"Tree") == 0)
{ {
if (Gui::Selection().countObjectsOfType(PartDesign::Feature::getClassTypeId()) + if (Gui::Selection().countObjectsOfType(PartDesign::Body::getClassTypeId()) +
Gui::Selection().countObjectsOfType(PartDesign::Feature::getClassTypeId()) +
Gui::Selection().countObjectsOfType(Part::Datum::getClassTypeId()) + Gui::Selection().countObjectsOfType(Part::Datum::getClassTypeId()) +
Gui::Selection().countObjectsOfType(Part::Part2DObject::getClassTypeId()) > 0 ) Gui::Selection().countObjectsOfType(Part::Part2DObject::getClassTypeId()) > 0 )
*item << "PartDesign_MoveTip"; *item << "PartDesign_MoveTip";