X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_Update.cpp;h=052468c7845d62c84ebfaae62300e2ae508063fd;hb=4635fa2d17f7d9cca2892169b7372ffa37cd2180;hp=c4cbbc94247dce88769565cb91b5397c193826f5;hpb=f39d4f0ba6a24326c08dc70fbbd44b9322104973;p=modules%2Fshaper.git diff --git a/src/Model/Model_Update.cpp b/src/Model/Model_Update.cpp old mode 100755 new mode 100644 index c4cbbc942..052468c78 --- a/src/Model/Model_Update.cpp +++ b/src/Model/Model_Update.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2020 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 @@ -43,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -300,16 +300,19 @@ void Model_Update::processEvent(const std::shared_ptr& theMessag std::dynamic_pointer_cast(theMessage); const std::set& anObjs = aMsg->objects(); std::set::const_iterator anObjIter = anObjs.cbegin(); + std::list aFeatures, aResults; for(; anObjIter != anObjs.cend(); anObjIter++) { if (std::dynamic_pointer_cast((*anObjIter)->document())->executeFeatures()) { if ((*anObjIter)->groupName() == ModelAPI_Feature::group()) { // results creation means enabling, not update - ModelAPI_EventCreator::get()->sendUpdated(*anObjIter, kUpdatedEvent); + aFeatures.push_back(*anObjIter); } else { - ModelAPI_EventCreator::get()->sendUpdated(*anObjIter, kRedisplayEvent); + aResults.push_back(*anObjIter); } } } + ModelAPI_EventCreator::get()->sendUpdated(aFeatures, kUpdatedEvent); + ModelAPI_EventCreator::get()->sendUpdated(aResults, kRedisplayEvent); return; } if (theMessage->eventID() == kUpdatedEvent) { @@ -438,7 +441,7 @@ void Model_Update::processEvent(const std::shared_ptr& theMessag Events_Loop::loop()->flush(kRedisplayEvent); // in the end of transaction everything is updated, so clear the old objects - myIsParamUpdated = false; + //myIsParamUpdated = false; // to avoid problems in sprocket.py parameter update myWaitForFinish.clear(); } else if (theMessage->eventID() == kReorderEvent) { std::shared_ptr aMsg = @@ -532,9 +535,21 @@ bool Model_Update::processFeature(FeaturePtr theFeature) return false; } + // check this feature is not yet checked or processed + bool aIsModified = myModified.find(theFeature) != myModified.end(); + if (!aIsModified && myIsFinish) { // get info about the modification for features without preview + if (theFeature->data()->execState() == ModelAPI_StateMustBeUpdated) { + aIsModified = true; + std::set > aNewSet; + // contains itself, so, we don't know which was the reason and the reason is any + aNewSet.insert(theFeature); + myModified[theFeature] = aNewSet; + } + } + if (myProcessed.find(theFeature) == myProcessed.end()) { myProcessed[theFeature] = 0; - } else { + } else if (aIsModified) { int aCount = myProcessed[theFeature]; if (aCount > 100) { // too many repetition of processing (in VS it may crash on 330 with stack overflow) @@ -547,54 +562,52 @@ bool Model_Update::processFeature(FeaturePtr theFeature) myProcessed[theFeature] = aCount + 1; } - // check this feature is not yet checked or processed - bool aIsModified = myModified.find(theFeature) != myModified.end(); - if (!aIsModified && myIsFinish) { // get info about the modification for features without preview - if (theFeature->data()->execState() == ModelAPI_StateMustBeUpdated) { - aIsModified = true; - std::set > aNewSet; - // contains itself, so, we don't know which was the reason and the reason is any - aNewSet.insert(theFeature); - myModified[theFeature] = aNewSet; - } - } - #ifdef DEB_UPDATE std::cout<<"* Process feature "<name()<getKind() == "Sketch") { + if (aIsModified && theFeature->getKind() == "Sketch") { #ifdef DEB_UPDATE - std::cout<<"****** Update sketch args "<name()<name() << std::endl; #endif - AttributeSelectionPtr anExtSel = theFeature->selection("External"); - if (anExtSel.get()) { - ResultPtr aContext = anExtSel->context(); - if (aContext.get() && aContext->document().get()) { - FeaturePtr anExtBase = aContext->document()->feature(aContext); - if (anExtBase.get()) { - processFeature(anExtBase); + AttributeSelectionPtr anExtSel = theFeature->selection("External"); + if (anExtSel.get()) { + ResultPtr aContext = anExtSel->context(); + if (aContext.get() && aContext->document().get()) { + FeaturePtr anExtBase = aContext->document()->feature(aContext); + if (anExtBase.get()) { + processFeature(anExtBase); + } + std::shared_ptr anOrigin = + std::dynamic_pointer_cast(theFeature->attribute("Origin")); + double anOX = anOrigin->x(), anOY = anOrigin->y(), anOZ = anOrigin->z(); + std::shared_ptr aDir = + std::dynamic_pointer_cast(theFeature->attribute("DirX")); + double aDX = aDir->x(), aDY = aDir->y(), aDZ = aDir->z(); + std::shared_ptr aNorm = + std::dynamic_pointer_cast(theFeature->attribute("Norm")); + double aNX = aNorm->x(), aNY = aNorm->y(), aNZ = aNorm->z(); + // update sketch plane + updateArguments(theFeature); + theFeature->attributeChanged("External"); // to recompute origin, direction and normal + // check it is updated, so all must be changed + if (anOrigin->x() != anOX || anOrigin->y() != anOY || anOrigin->z() != anOZ || + aDir->x() != aDX || aDir->y() != aDY || aDir->z() != aDZ || + aNorm->x() != aNX || aNorm->y() != aNY || aNorm->z() != aNZ) + { + std::set aWholeR; + allReasons(theFeature, aWholeR); + std::set::iterator aRIter = aWholeR.begin(); + for (; aRIter != aWholeR.end(); aRIter++) { + if ((*aRIter)->data()->selection("External").get()) + (*aRIter)->attributeChanged("External"); + } + } } } } - std::shared_ptr aShapeBefore = anExtSel->value(); - if (!aShapeBefore.get() && anExtSel->context()) aShapeBefore = anExtSel->context()->shape(); - updateArguments(theFeature); - std::shared_ptr aShapeAfter = anExtSel->value(); - if (!aShapeAfter.get() && anExtSel->context()) aShapeAfter = anExtSel->context()->shape(); - // if selected plane is changed, try to re-take external references of all subs of the sketch - if (aShapeBefore.get() && !aShapeBefore->isEqual(aShapeAfter)) { - std::set aWholeR; - allReasons(theFeature, aWholeR); - std::set::iterator aRIter = aWholeR.begin(); - for(; aRIter != aWholeR.end(); aRIter++) { - if ((*aRIter)->data()->selection("External")) - (*aRIter)->attributeChanged("External"); - } - } - } if (!aIsModified) { // no modification is needed return false; @@ -634,7 +647,12 @@ bool Model_Update::processFeature(FeaturePtr theFeature) } // searching for the next not used reason aProcessedReasons.insert(aReason); - aReasons.erase(aReason); + // check theFeature is still in the list of modified, because it may be removed sometimes + // while updating SketchPlugin_Ellipse + if (myModified.find(theFeature) != myModified.end()) + aReasons.erase(aReason); + else + break; } // restore the modified reasons: they will be used in the update of arguments if (allSubsUsed) { // restore theFeature in this set @@ -709,10 +727,8 @@ bool Model_Update::processFeature(FeaturePtr theFeature) if (myUpdateBlocked) { if (!theFeature->isStable()) { aDoExecute = true; - } else if (theFeature->results().size()) { // execute only not-results features - aDoExecute = !(theFeature->firstResult()->groupName() == ModelAPI_ResultBody::group() || - theFeature->firstResult()->groupName() == ModelAPI_ResultPart::group() || - theFeature->getKind() == "Sketch"); + } else if (theFeature->results().size()) { // execute only not persistent results features + aDoExecute = !theFeature->isPersistentResult(); } else { aDoExecute = aState != ModelAPI_StateInvalidArgument; } @@ -901,7 +917,7 @@ void Model_Update::updateArguments(FeaturePtr theFeature) { if (aSelAttr) { ObjectPtr aContext = aSelAttr->context(); // update argument only if the referenced object is ready to use - if (aContext.get() && !aContext->isDisabled() && !aSelAttr->isInvalid()) { + if (aContext.get() && !aContext->isDisabled()) { if (isReason(theFeature, aContext)) { if (!aSelAttr->update()) { bool isObligatory = !aFactory->isNotObligatory( @@ -911,7 +927,7 @@ void Model_Update::updateArguments(FeaturePtr theFeature) { aState = ModelAPI_StateInvalidArgument; } } - } else if (aContext.get() || aSelAttr->isInvalid()) { + } else if (aContext.get()) { // here it may be not obligatory, but if the reference is wrong, it should not be correct bool isObligatory = aFactory->isCase(theFeature, theFeature->data()->id(aSel)); if (isObligatory) @@ -1055,19 +1071,27 @@ void Model_Update::updateSelection(const std::set aSel = std::dynamic_pointer_cast(*aRefsIter); - aSel->updateInHistory(); + bool aRemove = false; + aSel->updateInHistory(aRemove); } // update the selection list attributes if any aRefs = (*anObj)->data()->attributes(ModelAPI_AttributeSelectionList::typeId()); for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) { + std::set aRemoveSet; std::shared_ptr aSel = std::dynamic_pointer_cast(*aRefsIter); for(int a = aSel->size() - 1; a >= 0; a--) { std::shared_ptr aSelAttr = std::dynamic_pointer_cast(aSel->value(a)); - if (aSelAttr.get()) - aSelAttr->updateInHistory(); + if (aSelAttr.get()) { + bool theRemove = false; + aSelAttr->updateInHistory(theRemove); + if (theRemove) { + aRemoveSet.insert(a); + } + } } + aSel->remove(aRemoveSet); } } }