From 4da2c910d3e697123cdaafd80d9a43db05cfb900 Mon Sep 17 00:00:00 2001 From: mpv Date: Wed, 7 Sep 2016 11:19:01 +0300 Subject: [PATCH] Fix for the issue #1710 : don't allow to select already modified shapes (but appeared due to Recovery). Also change the context to the newest shape to avoid Naming crashes. --- src/Model/Model_AttributeSelection.cpp | 61 ++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 1de8bcb7e..f38510369 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -56,7 +57,8 @@ #include #include #include -#include +#include +#include using namespace std; //#define DEB_NAMING 1 @@ -596,7 +598,6 @@ bool Model_AttributeSelection::update() return setInvalidIfFalse(aSelLab, false); // unknown case } - void Model_AttributeSelection::selectBody( const ResultPtr& theContext, const std::shared_ptr& theSubShape) { @@ -617,13 +618,65 @@ void Model_AttributeSelection::selectBody( return; } } - TopoDS_Shape aNewShape = theSubShape ? theSubShape->impl() : aContext; + + // with "recover" feature the selected context may be not up to date (issue 1710) + Handle(TNaming_NamedShape) aResult; + TDF_Label aSelLab = selectionLabel(); + TopoDS_Shape aNewContext = aContext; + bool isUpdated = true; + while(!aNewContext.IsNull() && isUpdated) { // searching for the very last shape that was produced from this one + isUpdated = false; + if (!TNaming_Tool::HasLabel(aSelLab, aNewContext)) // to avoid crash of TNaming_SameShapeIterator if pure shape does not exists + break; + for(TNaming_SameShapeIterator anIter(aNewContext, aSelLab); anIter.More(); anIter.Next()) { + TDF_Label aNSLab = anIter.Label(); + if (!scope().Contains(aNSLab)) + continue; + Handle(TNaming_NamedShape) aNS; + if (aNSLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) { + for(TNaming_Iterator aShapesIter(aNS); aShapesIter.More(); aShapesIter.Next()) { + if (aShapesIter.Evolution() == TNaming_SELECTED) + continue; // don't use the selection evolution + if (!aShapesIter.OldShape().IsNull() && aShapesIter.OldShape().IsSame(aNewContext)) { + // found the original shape + aNewContext = aShapesIter.NewShape(); // go to the newer shape + isUpdated = true; + break; + } + } + } + } + } + if (aNewContext.IsNull()) { // a context is already deleted + setInvalidIfFalse(aSelLab, false); + Events_InfoMessage("Model_AttributeSelection", "Failed to select shape already deleted").send(); + return; + } + + TopoDS_Shape aNewSub = theSubShape ? theSubShape->impl() : aContext; + if (!aNewSub.IsEqual(aContext)) { // searching for subshape in the new context + bool isFound = false; + TopExp_Explorer anExp(aNewContext, aNewSub.ShapeType()); + for(; anExp.More(); anExp.Next()) { + if (anExp.Current().IsEqual(aNewSub)) { + isFound = true; + break; + } + } + if (!isFound) { // sub-shape is not found in the up-to-date instance of the context shape + setInvalidIfFalse(aSelLab, false); + Events_InfoMessage("Model_AttributeSelection", "Failed to select sub-shape already modified").send(); + return; + } + } + + /// fix for issue 411: result modified shapes must not participate in this selection mechanism FeaturePtr aFeatureOwner = std::dynamic_pointer_cast(owner()); if (aFeatureOwner.get()) aFeatureOwner->eraseResults(); if (!aContext.IsNull()) { - aSel.Select(aNewShape, aContext); + aSel.Select(aNewSub, aNewContext); } } -- 2.39.2