From: nds Date: Fri, 15 Apr 2016 08:54:28 +0000 (+0300) Subject: Issue #1404 Random crash with Shaper. REDISPLAY is not flushed in deleteFeature.... X-Git-Tag: V_2.3.0~217 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=388af8d735d040dd4861b8b2e6e0e7980b9feaa9;p=modules%2Fshaper.git Issue #1404 Random crash with Shaper. REDISPLAY is not flushed in deleteFeature. It improves the application performance. Problem case is "Delete" in Sketch: create a rectangle, a lenght, select a line, after a lenght(or with rectangle so, that the line is the first), call Delete action. Result: warning message(in Debug mode) about empty AIS(it's caused a crash). Additionaly performance of fillet, mirror, rotation are improved by this modification. --- diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 312472a8d..f76c3cf27 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -90,6 +90,8 @@ class Model_Document : public ModelAPI_Document const bool isSendError = true); //! Removes the feature from the document (with result) + //! It is necessary to flush REDISPLAY signal manually after this method because + //! the method sends it, but for the performance purpose does not flush it //! \param theFeature a removed feature MODEL_EXPORT virtual void removeFeature(FeaturePtr theFeature); diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index e2eeeea2e..fa6991582 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -263,8 +263,6 @@ void Model_Objects::removeFeature(FeaturePtr theFeature) RemoveFromRefArray(featuresLabel(), aFeatureLabel); // event: feature is deleted ModelAPI_EventCreator::get()->sendDeleted(theFeature->document(), ModelAPI_Feature::group()); - // the redisplay signal should be flushed in order to erase the feature presentation in the viewer - Events_Loop::loop()->flush(EVENT_DISP); updateHistory(ModelAPI_Feature::group()); } } diff --git a/src/Model/Model_Update.cpp b/src/Model/Model_Update.cpp index d49990aa5..c8ca55d4b 100644 --- a/src/Model/Model_Update.cpp +++ b/src/Model/Model_Update.cpp @@ -253,7 +253,7 @@ void Model_Update::processEvent(const std::shared_ptr& theMessag myProcessOnFinish.clear(); // processed features must be only on finish, so clear anyway (to avoid reimport on load) if (!(theMessage->eventID() == kOpStartEvent)) { - processFeatures(); + processFeatures(false); } // remove all macros before clearing all created std::set::iterator anUpdatedIter = myWaitForFinish.begin(); @@ -275,13 +275,18 @@ void Model_Update::processEvent(const std::shared_ptr& theMessag anUpdatedIter++; } } + // the redisplay signal should be flushed in order to erase the feature presentation in the viewer + // if should be done after removeFeature() of document, + // by this reason, upper processFeatures() do not perform this flush + Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY)); + // in the end of transaction everything is updated, so clear the old objects myIsParamUpdated = false; myWaitForFinish.clear(); } } -void Model_Update::processFeatures() +void Model_Update::processFeatures(const bool theFlushRedisplay) { // perform update of everything if it is not performed right now or any preview is blocked if (!myIsProcessed && !myIsPreviewBlocked) { @@ -303,8 +308,10 @@ void Model_Update::processFeatures() aLoop->flush(kUpdatedEvent); // flush to update display - static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); - aLoop->flush(EVENT_DISP); + if (theFlushRedisplay) { + static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); + aLoop->flush(EVENT_DISP); + } #ifdef DEB_UPDATE std::cout<<"****** End processing"< #include #include +#include #include #include @@ -767,6 +768,11 @@ bool PartSet_Module::deleteObjects() anOpMgr->startOperation(anOpAction); + // WORKAROUND, should be done to avoid viewer highlight update after deletetion of objects + // the problem is in AIS Dimensions recompute if a line and the dim are removed, line is the first + // it causes the AIS recompute, where the base line is null, the result is empty AIS in the viewer + XGUI_Tools::workshop(myWorkshop)->selector()->clearSelection(); + // 4. delete features // sketch feature should be skipped, only sub-features can be removed // when sketch operation is active diff --git a/src/PartSetPlugin/PartSetPlugin_Part.cpp b/src/PartSetPlugin/PartSetPlugin_Part.cpp index 31759862f..c40a0eadf 100644 --- a/src/PartSetPlugin/PartSetPlugin_Part.cpp +++ b/src/PartSetPlugin/PartSetPlugin_Part.cpp @@ -108,10 +108,4 @@ bool PartSetPlugin_Part::isSub(ObjectPtr theObject) const void PartSetPlugin_Part::removeFeature(std::shared_ptr theFeature) { - ResultPartPtr aResult = std::dynamic_pointer_cast(firstResult()); - if (aResult.get()) { - DocumentPtr aDoc = aResult->partDoc(); - if (aDoc.get() && aDoc->isOpened()) - aDoc->removeFeature(theFeature); - } } diff --git a/src/PartSetPlugin/PartSetPlugin_Remove.cpp b/src/PartSetPlugin/PartSetPlugin_Remove.cpp index d74666a65..a1c7bcfda 100644 --- a/src/PartSetPlugin/PartSetPlugin_Remove.cpp +++ b/src/PartSetPlugin/PartSetPlugin_Remove.cpp @@ -6,6 +6,7 @@ #include "PartSetPlugin_Remove.h" #include "PartSetPlugin_Part.h" + #include #include #include @@ -13,6 +14,9 @@ #include #include #include +#include + +#include void PartSetPlugin_Remove::execute() { @@ -27,8 +31,12 @@ void PartSetPlugin_Remove::execute() aPart->data()->document(ModelAPI_ResultPart::DOC_REF())->value()->close(); std::set > aRefFeatures; aRoot->refsToFeature(aFeature, aRefFeatures); - if (aRefFeatures.empty()) + if (aRefFeatures.empty()) { aRoot->removeFeature(aFeature); + // the redisplay signal should be flushed in order to erase the feature presentation in the viewer + // after removeFeature from the document + Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY)); + } } } } diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 1b601779c..4949ecd94 100755 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -1386,7 +1386,7 @@ void XGUI_Workshop::cleanHistory() mySelector->clearSelection(); std::set anIgnoredFeatures; - if (removeFeatures(anUnusedObjects, anIgnoredFeatures, anActionId)) { + if (removeFeatures(anUnusedObjects, anIgnoredFeatures, anActionId, true)) { operationMgr()->commitOperation(); } else { @@ -1565,6 +1565,7 @@ bool XGUI_Workshop::deleteFeaturesInternal(const QObjectPtrList& theList, const std::set& theIgnoredFeatures, const bool doDeleteReferences) { + bool isDone = false; if (doDeleteReferences) { std::set aFeaturesToDelete = aDirectRefFeatures; aFeaturesToDelete.insert(aIndirectRefFeatures.begin(), aIndirectRefFeatures.end()); @@ -1577,7 +1578,9 @@ bool XGUI_Workshop::deleteFeaturesInternal(const QObjectPtrList& theList, FeaturePtr aFeature = (*anIt); DocumentPtr aDoc = aFeature->document(); if (theIgnoredFeatures.find(aFeature) == theIgnoredFeatures.end()) { + // flush REDISPLAY signal after remove feature aDoc->removeFeature(aFeature); + isDone = true; #ifdef DEBUG_DELETE anInfo.append(ModuleBase_Tools::objectInfo(aFeature).toStdString().c_str()); #endif @@ -1590,13 +1593,21 @@ bool XGUI_Workshop::deleteFeaturesInternal(const QObjectPtrList& theList, } QString anActionId = "DELETE_CMD"; - return removeFeatures(theList, theIgnoredFeatures, anActionId); + isDone = removeFeatures(theList, theIgnoredFeatures, anActionId, false) || isDone; + + if (isDone) { + // the redisplay signal should be flushed in order to erase the feature presentation in the viewer + // if should be done after removeFeature() of document + Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY)); + } + return isDone; } //************************************************************** bool XGUI_Workshop::removeFeatures(const QObjectPtrList& theList, const std::set& theIgnoredFeatures, - const QString& theActionId) + const QString& theActionId, + const bool theFlushRedisplay) { bool isDone = false; @@ -1624,11 +1635,18 @@ bool XGUI_Workshop::removeFeatures(const QObjectPtrList& theList, anInfo.append(anInfoStr); qDebug(QString("remove feature :%1").arg(anInfoStr).toStdString().c_str()); #endif + // flush REDISPLAY signal after remove feature aDoc->removeFeature(aFeature); isDone = true; } } } + if (isDone && theFlushRedisplay) { + // the redisplay signal should be flushed in order to erase the feature presentation in the viewer + // if should be done after removeFeature() of document + Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY)); + } + #ifdef DEBUG_DELETE qDebug(QString("remove features:%1").arg(anInfo.join("; ")).toStdString().c_str()); #endif diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index 0c09e0873..6cbc1429c 100755 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -504,9 +504,11 @@ private: //! \param theList an objects to be deleted //! \param theIgnoredFeatures a list of features to be ignored during delete //! \param theActionId an action command key to find context menu object types enabled for remove + //! \param theFlushRedisplay a boolean value if the redisplay signal should be flushed bool removeFeatures(const QObjectPtrList& theList, const std::set& theIgnoredFeatures, - const QString& theActionId); + const QString& theActionId, + const bool theFlushRedisplay); //! Creates list of actions (commands) by given history list from session QList processHistoryList(const std::list&) const;