X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_AttributeSelection.cpp;h=92be8663dbc26432cf9469ff69e52055c14d0e7e;hb=c4eab94a20a0d93100549a210582d46409fec1cc;hp=ba7ebae63a9b39fa71f65155e46476d6daca9821;hpb=e74c1257a2a5f86000dd272cf4db90f18143e6c1;p=modules%2Fshaper.git diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index ba7ebae63..92be8663d 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2019 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -12,10 +12,9 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "Model_AttributeSelection.h" @@ -1086,9 +1085,10 @@ void Model_AttributeSelection::computeValues( if (aWasWholeContext) { theValShape = theOldContext->shape()->impl(); } + TopAbs_ShapeEnum aValType = theValShape.ShapeType(); TopoDS_Shape aNewContShape = theNewContext->shape()->impl(); // if a new value is unchanged in the new context, do nothing: value is correct - TopExp_Explorer aSubExp(aNewContShape, theValShape.ShapeType()); + TopExp_Explorer aSubExp(aNewContShape, aValType); for(; aSubExp.More(); aSubExp.Next()) { if (aSubExp.Current().IsSame(theValShape)) { theShapes.Append(theValShape); @@ -1133,17 +1133,15 @@ void Model_AttributeSelection::computeValues( return; } // don't add edges generated from faces - if (aPairIter.NewShape().ShapeType() <= theValShape.ShapeType()) + if (aPairIter.NewShape().ShapeType() <= aValType) theShapes.Append(aPairIter.NewShape()); } } else if (!aPairIter.OldShape().IsNull()) { // search shape that contains this sub - TopExp_Explorer anExp(aPairIter.OldShape(), theValShape.ShapeType()); + TopExp_Explorer anExp(aPairIter.OldShape(), aValType); for(; anExp.More(); anExp.Next()) { if (anExp.Current().IsSame(theValShape)) { // found a new container - if (aPairIter.NewShape().IsNull()) {// value was removed - theShapes.Clear(); - return; - } + if (aPairIter.NewShape().IsNull()) // skip removed high-level shape + continue; aNewToOld.Bind(aPairIter.NewShape(), aPairIter.OldShape()); anOlds.Add(aPairIter.OldShape()); break; @@ -1160,7 +1158,7 @@ void Model_AttributeSelection::computeValues( NCollection_Map aNewTypes; // types of shapes to iterate TopTools_DataMapOfShapeShape::Iterator aNewTypeIter(aNewToOld); for(; aNewTypeIter.More(); aNewTypeIter.Next()) { - if (aNewTypeIter.Key().ShapeType() != theValShape.ShapeType()) + if (aNewTypeIter.Key().ShapeType() != aValType) aNewTypes.Add(aNewTypeIter.Key().ShapeType()); } NCollection_Map::Iterator aTypeIter(aNewTypes); @@ -1169,7 +1167,7 @@ void Model_AttributeSelection::computeValues( TopoDS_Shape anOld = anExp.Current(); if (aNewToOld.IsBound(anOld) || anOlds.Contains(anOld)) // this was modified continue; - TopExp_Explorer aValExp(anOld, theValShape.ShapeType()); + TopExp_Explorer aValExp(anOld, aValType); for(; aValExp.More(); aValExp.Next()) { const TopoDS_Shape& anUnchanged = aValExp.Current(); if (anUnchanged.IsSame(theValShape)) { @@ -1185,7 +1183,7 @@ void Model_AttributeSelection::computeValues( NCollection_DataMap aSubs; TopTools_DataMapOfShapeShape::Iterator aContIter(aNewToOld); for(; aContIter.More(); aContIter.Next()) { - TopExp_Explorer aSubExp(aContIter.Key(), theValShape.ShapeType()); + TopExp_Explorer aSubExp(aContIter.Key(), aValType); for(; aSubExp.More(); aSubExp.Next()) { if (!aSubs.IsBound(aSubExp.Current())) { aSubs.Bind(aSubExp.Current(), TopTools_MapOfShape()); @@ -1216,13 +1214,35 @@ void Model_AttributeSelection::computeValues( if (aWasWholeContext) theShapes.Append(TopoDS_Shape()); else { // if theValShape exists in new context, add it without changes, otherwise - nothing - for (TopExp_Explorer aNew(aNewContShape, theValShape.ShapeType()); aNew.More(); aNew.Next()){ + for (TopExp_Explorer aNew(aNewContShape, aValType); aNew.More(); aNew.Next()){ if (aNew.Current().IsSame(theValShape)) { theShapes.Append(theValShape); break; } } } + } else if (theShapes.Size() > 1) { + // check it is possible to remove extra sub-shapes: + // keep only shapes with the same number of containers if possible + TopAbs_ShapeEnum anAncType = TopAbs_FACE; + if (aValType == TopAbs_VERTEX) + anAncType = TopAbs_EDGE; + TopoDS_Shape anOldContext = theOldContext->shape()->impl(); + TopTools_IndexedDataMapOfShapeListOfShape anOldMap; + TopExp::MapShapesAndUniqueAncestors(anOldContext, aValType, anAncType, anOldMap); + if (anOldMap.Contains(theValShape)) { + int aNumInOld = anOldMap.FindFromKey(theValShape).Extent(); + TopTools_IndexedDataMapOfShapeListOfShape aNewMap; + TopExp::MapShapesAndUniqueAncestors(aNewContShape, aValType, anAncType, aNewMap); + TopTools_ListOfShape aNewResults; + for(TopTools_ListOfShape::Iterator aNewSubs(theShapes); aNewSubs.More(); aNewSubs.Next()) { + TopoDS_Shape aCand = aNewSubs.Value(); + if (aNewMap.Contains(aCand) && aNewMap.FindFromKey(aCand).Extent() == aNumInOld) + aNewResults.Append(aCand); + } + if (!aNewResults.IsEmpty() && aNewResults.Size() < theShapes.Size()) + theShapes = aNewResults; + } } } @@ -1287,8 +1307,46 @@ bool Model_AttributeSelection::searchNewContext(std::shared_ptr } else aResIter++; } - if (aResults.empty()) + if (aResults.empty()) { + // check the context become concealed by operation which is earlier than this selection + std::list allRes; + ResultPtr aRoot = ModelAPI_Tools::bodyOwner(theContext, true); + if (!aRoot.get()) + aRoot = theContext; + ResultBodyPtr aRootBody = std::dynamic_pointer_cast(aRoot); + if (aRootBody.get()) { + ModelAPI_Tools::allSubs(aRootBody, allRes); + allRes.push_back(aRootBody); + } else + allRes.push_back(aRoot); + + FeaturePtr aThisFeature = std::dynamic_pointer_cast(owner()); + for (std::list::iterator aSub = allRes.begin(); aSub != allRes.end(); aSub++) { + ResultPtr aResCont = *aSub; + const std::set& aRefs = aResCont->data()->refsToMe(); + std::set::const_iterator aRef = aRefs.begin(); + for (; aRef != aRefs.end(); aRef++) { + if (!aRef->get() || !(*aRef)->owner().get()) + continue; + // concealed attribute only + FeaturePtr aRefFeat = std::dynamic_pointer_cast((*aRef)->owner()); + if (aRefFeat == aThisFeature) + continue; + if (!ModelAPI_Session::get()->validators()->isConcealed( + aRefFeat->getKind(), (*aRef)->id())) + continue; + if (theDoc->isLaterByDep(aThisFeature, aRefFeat)) { + // for extrusion cut in python script the nested sketch reference may be concealed before + // it is nested, so, check this composite feature is valid + static ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators(); + // need to be validated to update the "Apply" state if not previewed + if (aFactory->validate(aRefFeat)) + return true; // feature conceals result, return true, so the context will be removed + } + } + } return false; // no modifications found, must stay the same + } // iterate all results to find further modifications std::set::iterator aResIter = aResults.begin(); for(; aResIter != aResults.end(); aResIter++) { @@ -1325,7 +1383,7 @@ bool Model_AttributeSelection::searchNewContext(std::shared_ptr return true; // theResults must be empty: everything is deleted } -void Model_AttributeSelection::updateInHistory() +void Model_AttributeSelection::updateInHistory(bool& theRemove) { ResultPtr aContext = std::dynamic_pointer_cast(myRef.value()); // only bodies and parts may be modified later in the history, don't do anything otherwise @@ -1359,7 +1417,7 @@ void Model_AttributeSelection::updateInHistory() continue; FeaturePtr aRefFeat = std::dynamic_pointer_cast((*aRef)->owner()); - if (aRefFeat.get() && aRefFeat != owner()) { + if (aRefFeat.get() && aRefFeat != owner() && aRefFeat->firstResult().get()) { FeaturePtr aThisFeature = std::dynamic_pointer_cast(owner()); if (!aDoc->isLaterByDep(aRefFeat, aThisFeature)) { // found better feature aFoundNewContext = true; @@ -1414,9 +1472,12 @@ void Model_AttributeSelection::updateInHistory() GeomAPI_Shape::ShapeType aListShapeType = GeomAPI_Shape::SHAPE; if (myParent) { - if (myParent->selectionType() == "VERTEX") aListShapeType = GeomAPI_Shape::VERTEX; - else if (myParent->selectionType() == "EDGE") aListShapeType = GeomAPI_Shape::EDGE; - else if (myParent->selectionType() == "FACE") aListShapeType = GeomAPI_Shape::FACE; + if (myParent->selectionType() == "VERTEX" || myParent->selectionType() == "Vertices") + aListShapeType = GeomAPI_Shape::VERTEX; + else if (myParent->selectionType() == "EDGE" || myParent->selectionType() == "Edges") + aListShapeType = GeomAPI_Shape::EDGE; + else if (myParent->selectionType() == "FACE" || myParent->selectionType() == "Faces") + aListShapeType = GeomAPI_Shape::FACE; } std::list::iterator aNewCont = aNewContexts.begin(); @@ -1451,10 +1512,14 @@ void Model_AttributeSelection::updateInHistory() } } if (aFirst) { // nothing was added, all results were deleted - ResultPtr anEmptyContext; - std::shared_ptr anEmptyShape; - setValue(anEmptyContext, anEmptyShape); // nullify the selection - return; + if (myParent) { + theRemove = true; + } else { + ResultPtr anEmptyContext; + std::shared_ptr anEmptyShape; + setValue(anEmptyContext, anEmptyShape); // nullify the selection + return; + } } } }