diff --git a/src/Mod/PartDesign/App/Body.cpp b/src/Mod/PartDesign/App/Body.cpp index 8f7740750..b09b95158 100644 --- a/src/Mod/PartDesign/App/Body.cpp +++ b/src/Mod/PartDesign/App/Body.cpp @@ -130,6 +130,8 @@ App::DocumentObject* Body::getPrevSolidFeature(App::DocumentObject *start, const std::vector features = Model.getValues(); if (features.empty()) return NULL; App::DocumentObject* st = (start == NULL ? Tip.getValue() : start); + if (st == NULL) + return st; // Tip is NULL if (inclusive && isSolidFeature(st)) return st; @@ -156,7 +158,11 @@ App::DocumentObject* Body::getNextSolidFeature(App::DocumentObject *start, const if (inclusive && isSolidFeature(st)) return st; - std::vector::iterator it = std::find(features.begin(), features.end(), st); + std::vector::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 // 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) { + App::DocumentObject* tipFeature = Tip.getValue(); + if (tipFeature == NULL) + return true; + std::vector features = Model.getValues(); std::vector::const_iterator it = std::find(features.begin(), features.end(), f); - std::vector::const_iterator tip = std::find(features.begin(), features.end(), Tip.getValue()); + std::vector::const_iterator tip = std::find(features.begin(), features.end(), tipFeature); return (it > tip); } @@ -226,7 +236,8 @@ void Body::addFeature(App::DocumentObject *feature) // First feature in the body model.push_back(feature); 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 { // Insert after Tip std::vector::iterator it = std::find(model.begin(), model.end(), tipFeature); @@ -334,13 +345,15 @@ Base::BoundBox3d Body::getBoundBox() Part::Feature* tipSolid = static_cast(getPrevSolidFeature()); if (tipSolid != NULL) { - TopoDS_Shape sh = tipSolid->Shape.getValue(); - if (sh.IsNull()) + if (tipSolid->Shape.getValue().IsNull()) // This can happen when a new feature is added without having its Shape property set yet tipSolid = static_cast(getPrevSolidFeature(NULL, false)); if (tipSolid != NULL) { - result = tipSolid->Shape.getShape().getBoundBox(); + if (tipSolid->Shape.getValue().IsNull()) + tipSolid = NULL; + else + result = tipSolid->Shape.getShape().getBoundBox(); } } if (tipSolid == NULL) diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index f8145dfab..d2971b833 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -178,7 +178,10 @@ void CmdPartDesignMoveTip::activated(int iMsg) if (features.empty()) return; 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 pcActiveBody = static_cast(Part::BodyBase::findBodyOf(selFeature)); if (pcActiveBody != NULL) @@ -188,21 +191,27 @@ void CmdPartDesignMoveTip::activated(int iMsg) 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"); - 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 - doCommand(Gui,"Gui.activeDocument().show(\"%s\")", selFeature->getNameInDocument()); - prevSolidFeature = pcActiveBody->getPrevSolidFeature(); - if ((prevSolidFeature != NULL) && !PartDesign::Body::isSolidFeature(selFeature)) - doCommand(Gui,"Gui.activeDocument().show(\"%s\")", prevSolidFeature->getNameInDocument()); + if (selFeature == NULL) { + doCommand(Doc,"App.activeDocument().%s.Tip = None", pcActiveBody->getNameInDocument()); + } else { + doCommand(Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",pcActiveBody->getNameInDocument(), selFeature->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 // others, so we would have to remember their state somehow diff --git a/src/Mod/PartDesign/Gui/Workbench.cpp b/src/Mod/PartDesign/Gui/Workbench.cpp index a4dc29293..665cda863 100644 --- a/src/Mod/PartDesign/Gui/Workbench.cpp +++ b/src/Mod/PartDesign/Gui/Workbench.cpp @@ -276,7 +276,8 @@ void Workbench::setupContextMenu(const char* recipient, Gui::MenuItem* item) con { 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::Part2DObject::getClassTypeId()) > 0 ) *item << "PartDesign_MoveTip";