From 99156a76997fecc483c2f845d3e712805530cd64 Mon Sep 17 00:00:00 2001 From: nds Date: Fri, 15 Jan 2016 11:21:00 +0300 Subject: [PATCH] Issue #1199 - Fatal error when edit parameter: do not visualize operation prs when result has no a shape. --- src/PartSet/PartSet_CustomPrs.cpp | 49 ++++++++----------------- src/PartSet/PartSet_CustomPrs.h | 6 +--- src/PartSet/PartSet_OperationPrs.cpp | 51 +++++++++++--------------- src/PartSet/PartSet_OperationPrs.h | 8 ----- src/XGUI/XGUI_WorkshopListener.cpp | 54 ++++++++++++++++------------ src/XGUI/XGUI_WorkshopListener.h | 6 +++- 6 files changed, 74 insertions(+), 100 deletions(-) diff --git a/src/PartSet/PartSet_CustomPrs.cpp b/src/PartSet/PartSet_CustomPrs.cpp index ed43e19bd..e43ccc980 100755 --- a/src/PartSet/PartSet_CustomPrs.cpp +++ b/src/PartSet/PartSet_CustomPrs.cpp @@ -49,13 +49,11 @@ bool PartSet_CustomPrs::activate(const FeaturePtr& theFeature, const bool theUpd bool isModified = false; Handle(PartSet_OperationPrs) anOperationPrs = getPresentation(); - if (anOperationPrs->canActivate(theFeature)) { - myIsActive = true; - anOperationPrs->setFeature(theFeature); - if (theFeature.get()) { - displayPresentation(theUpdateViewer); - isModified = true; - } + myIsActive = true; + anOperationPrs->setFeature(theFeature); + if (theFeature.get()) { + displayPresentation(theUpdateViewer); + isModified = true; } return isModified; } @@ -77,10 +75,11 @@ bool PartSet_CustomPrs::deactivate(const bool theUpdateViewer) return isModified; } - -void PartSet_CustomPrs::displayPresentation(const bool theUpdateViewer) +bool PartSet_CustomPrs::displayPresentation(const bool theUpdateViewer) { + bool isModified = false; Handle(PartSet_OperationPrs) anOperationPrs = getPresentation(); + anOperationPrs->updateShapes(); Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); if (!aContext.IsNull() && !aContext->IsDisplayed(anOperationPrs)) { @@ -89,17 +88,22 @@ void PartSet_CustomPrs::displayPresentation(const bool theUpdateViewer) XGUI_Workshop* aWorkshop = workshop(); aWorkshop->displayer()->displayAIS(myOperationPrs, false/*load object in selection*/, theUpdateViewer); aContext->SetZLayer(anOperationPrs, aModule->getVisualLayerId()); + isModified = true; } } else { - if (!anOperationPrs->hasShapes()) + if (!anOperationPrs->hasShapes()) { erasePresentation(theUpdateViewer); + isModified = true; + } else { anOperationPrs->Redisplay(); + isModified = true; if (theUpdateViewer) workshop()->displayer()->updateViewer(); } } + return isModified; } void PartSet_CustomPrs::erasePresentation(const bool theUpdateViewer) @@ -123,30 +127,7 @@ bool PartSet_CustomPrs::redisplay(const ObjectPtr& theObject, #ifdef DO_NOT_VISUALIZE_CUSTOM_PRESENTATION return false; #endif - - bool isModified = false; - // the presentation should be recomputed if the previous AIS depend on the result - // [it should be hiddend] or the new AIS depend on it [it should be visualized] - Handle(PartSet_OperationPrs) anOperationPrs = getPresentation(); - Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); - if (!aContext.IsNull()) { - if (aContext->IsDisplayed(anOperationPrs)) { - // if there are performance poblems, to improve them, the necessity of redisplay can be checked - //bool aChanged = anOperationPrs->dependOn(theObject); - anOperationPrs->updateShapes(); - //aChanged = aChanged || anOperationPrs->dependOn(theObject); - //if (aChanged) - anOperationPrs->Redisplay(); - isModified = true; - if (theUpdateViewer) - workshop()->displayer()->updateViewer(); - } - else { - anOperationPrs->updateShapes(); - displayPresentation(theUpdateViewer); - } - } - return isModified; + return displayPresentation(theUpdateViewer); } void PartSet_CustomPrs::clearPrs() diff --git a/src/PartSet/PartSet_CustomPrs.h b/src/PartSet/PartSet_CustomPrs.h index 1d12d6802..ab82997a7 100755 --- a/src/PartSet/PartSet_CustomPrs.h +++ b/src/PartSet/PartSet_CustomPrs.h @@ -74,16 +74,12 @@ private: /// Displays the internal presentation in the viewer of workshop /// \param theUpdateViewer the parameter whether the viewer should be update immediatelly - void displayPresentation(const bool theUpdateViewer); + bool displayPresentation(const bool theUpdateViewer); /// Erases the internal presentation from the viewer of workshop /// \param theUpdateViewer the parameter whether the viewer should be update immediatelly void erasePresentation(const bool theUpdateViewer); - /// Sets color, point size and width of the presentation - /// \param theUpdateViewer the parameter whether the viewer should be update immediatelly - void customizePresentation(const bool theUpdateViewer); - private: bool myIsActive; ModuleBase_IWorkshop* myWorkshop; /// current workshop diff --git a/src/PartSet/PartSet_OperationPrs.cpp b/src/PartSet/PartSet_OperationPrs.cpp index cbf29b38b..af1f3ae4b 100755 --- a/src/PartSet/PartSet_OperationPrs.cpp +++ b/src/PartSet/PartSet_OperationPrs.cpp @@ -43,29 +43,11 @@ PartSet_OperationPrs::PartSet_OperationPrs(ModuleBase_IWorkshop* theWorkshop) myResultColor = ModuleBase_Tools::color("Visualization", "construction_plane_color", "0,1,0"); } -bool PartSet_OperationPrs::canActivate(const FeaturePtr& theFeature) -{ - bool aHasSelectionAttribute = false; - - std::list anAttributes = theFeature->data()->attributes(""); - std::list::const_iterator anIt = anAttributes.begin(), aLast = anAttributes.end(); - for (; anIt != aLast && !aHasSelectionAttribute; anIt++) - aHasSelectionAttribute = isSelectionAttribute(*anIt); - - return aHasSelectionAttribute; -} - void PartSet_OperationPrs::setFeature(const FeaturePtr& theFeature) { myFeature = theFeature; - updateShapes(); } -/*bool PartSet_OperationPrs::dependOn(const ObjectPtr& theResult) -{ - return myFeatureShapes.contains(theResult); -}*/ - void PartSet_OperationPrs::updateShapes() { myFeatureShapes.clear(); @@ -78,7 +60,27 @@ void PartSet_OperationPrs::updateShapes() bool PartSet_OperationPrs::hasShapes() { - return !myFeatureShapes.empty() || !myFeatureResults.empty(); + bool aHasShapes = !myFeatureShapes.empty(); + + // find a result which contains a shape + if (!aHasShapes && !myFeatureResults.empty()) { + std::list::const_iterator aRIt = myFeatureResults.begin(), + aRLast = myFeatureResults.end(); + XGUI_Displayer* aDisplayer = workshop()->displayer(); + for (; aRIt != aRLast; aRIt++) { + ResultPtr aResult = *aRIt; + if (!isVisible(aDisplayer, aResult)) + continue; + GeomShapePtr aGeomShape = aResult->shape(); + if (!aGeomShape.get()) + continue; + TopoDS_Shape aShape = aGeomShape->impl(); + if (!aShape.IsNull()) + aHasShapes = true; + } + } + + return aHasShapes; } void PartSet_OperationPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, @@ -326,17 +328,6 @@ bool PartSet_OperationPrs::isSelectionAttribute(const AttributePtr& theAttribute { std::string anAttrType = theAttribute->attributeType(); - /// workaround: start - /// this is a TEMPORARY correction in order to avoid crash by parameter edit - /// which is reproduced only on Linux Debian. - /// The possible reason is an empty AIS presentation visualized in the viewer. - /// The best solution is to analize whether the feature has shapes/results and only - /// in this case visualize custom presentation and hide it as soon as they disappear. - bool isAttributeArgument = theAttribute->isArgument(); - if (!isAttributeArgument) - return false; - /// workaround: end - return anAttrType == ModelAPI_AttributeSelectionList::typeId() || anAttrType == ModelAPI_AttributeRefList::typeId() || anAttrType == ModelAPI_AttributeRefAttr::typeId() || diff --git a/src/PartSet/PartSet_OperationPrs.h b/src/PartSet/PartSet_OperationPrs.h index 64d92151a..8bb9d36c8 100755 --- a/src/PartSet/PartSet_OperationPrs.h +++ b/src/PartSet/PartSet_OperationPrs.h @@ -47,18 +47,10 @@ public: /// Constructor Standard_EXPORT PartSet_OperationPrs(ModuleBase_IWorkshop* theWorkshop); - /// Returns true if the feature contains attributes, which has references to other features - /// \param theFeature a feature - /// \return boolean result - bool canActivate(const FeaturePtr& theFeature); - /// Sets the operation feature. It is used in Compute method to group the feature parameter shapes /// theFeature a feature void setFeature(const FeaturePtr& theFeature); - /// Returns true if the presentation - //bool dependOn(const ObjectPtr& theObject); - // Recompute internal list of shaped dependent on the current feature void updateShapes(); diff --git a/src/XGUI/XGUI_WorkshopListener.cpp b/src/XGUI/XGUI_WorkshopListener.cpp index 457d41216..f9c006199 100755 --- a/src/XGUI/XGUI_WorkshopListener.cpp +++ b/src/XGUI/XGUI_WorkshopListener.cpp @@ -194,7 +194,7 @@ void XGUI_WorkshopListener::processEvent(const std::shared_ptr& } else if (theMessage->eventID() == Events_Loop::eventByName(EVENT_OBJECT_ERROR_CHANGED)) { std::shared_ptr aUpdMsg = std::dynamic_pointer_cast(theMessage); - std::set aObjects = aUpdMsg->objects(); + std::set anObjects = aUpdMsg->objects(); ModuleBase_OperationFeature* aFOperation = dynamic_cast (workshop()->operationMgr()->currentOperation()); @@ -203,7 +203,7 @@ void XGUI_WorkshopListener::processEvent(const std::shared_ptr& FeaturePtr aFeature = aFOperation->feature(); if (aFeature.get()) { std::set::const_iterator aIt; - for (aIt = aObjects.begin(); aIt != aObjects.end() && !aFeatureChanged; ++aIt) { + for (aIt = anObjects.begin(); aIt != anObjects.end() && !aFeatureChanged; ++aIt) { aFeatureChanged = ModelAPI_Feature::feature(*aIt) == aFeature; } } @@ -231,14 +231,14 @@ void XGUI_WorkshopListener::onFeatureUpdatedMsg( const std::shared_ptr& theMsg) { #ifdef DEBUG_FEATURE_UPDATED - std::set aObjects = theMsg->objects(); + std::set anObjects = theMsg->objects(); std::set::const_iterator aIt; QStringList anInfo; - for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) { + for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) { anInfo.append(ModuleBase_Tools::objectInfo((*aIt))); } QString anInfoStr = anInfo.join(";\t"); - qDebug(QString("onFeatureUpdatedMsg: %1, %2").arg(aObjects.size()).arg(anInfoStr).toStdString().c_str()); + qDebug(QString("onFeatureUpdatedMsg: %1, %2").arg(anObjects.size()).arg(anInfoStr).toStdString().c_str()); #endif std::set aFeatures = theMsg->objects(); XGUI_OperationMgr* anOperationMgr = workshop()->operationMgr(); @@ -266,16 +266,16 @@ void XGUI_WorkshopListener::onFeatureUpdatedMsg( //****************************************************** void XGUI_WorkshopListener::onFeatureRedisplayMsg(const std::shared_ptr& theMsg) { - std::set aObjects = theMsg->objects(); + std::set anObjects = theMsg->objects(); std::set::const_iterator aIt; #ifdef DEBUG_FEATURE_REDISPLAY QStringList anInfo; - for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) { + for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) { anInfo.append(ModuleBase_Tools::objectInfo((*aIt))); } QString anInfoStr = anInfo.join(";\t"); - qDebug(QString("onFeatureRedisplayMsg: %1, %2").arg(aObjects.size()).arg(anInfoStr).toStdString().c_str()); + qDebug(QString("onFeatureRedisplayMsg: %1, %2").arg(anObjects.size()).arg(anInfoStr).toStdString().c_str()); #endif XGUI_Workshop* aWorkshop = workshop(); @@ -283,7 +283,7 @@ void XGUI_WorkshopListener::onFeatureRedisplayMsg(const std::shared_ptrviewer()->fitAll(); @@ -367,22 +367,22 @@ void XGUI_WorkshopListener::onFeatureRedisplayMsg(const std::shared_ptr& theMsg) { - std::set aObjects = theMsg->objects(); + std::set anObjects = theMsg->objects(); std::set::const_iterator aIt; #ifdef DEBUG_FEATURE_CREATED QStringList anInfo; - for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) { + for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) { anInfo.append(ModuleBase_Tools::objectInfo((*aIt))); } QString anInfoStr = anInfo.join(";\t"); - qDebug(QString("onFeatureCreatedMsg: %1, %2").arg(aObjects.size()).arg(anInfoStr).toStdString().c_str()); + qDebug(QString("onFeatureCreatedMsg: %1, %2").arg(anObjects.size()).arg(anInfoStr).toStdString().c_str()); #endif bool aFirstVisualizedBody = false; //bool aHasPart = false; bool aDisplayed = false; - for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) { + for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) { ObjectPtr anObject = *aIt; #ifdef DEBUG_RESULT_COMPSOLID @@ -418,10 +418,11 @@ void XGUI_WorkshopListener::onFeatureCreatedMsg(const std::shared_ptrprocessEvent(theMsg); if (aDisplayed) { - customizeCurrentObject(); //VSV FitAll updated viewer by it self if (aFirstVisualizedBody) myWorkshop->viewer()->fitAll(); @@ -561,20 +562,29 @@ bool XGUI_WorkshopListener::displayObject(ObjectPtr theObj, bool& theFirstVisual return aDisplayed; } -bool XGUI_WorkshopListener::customizeCurrentObject() +bool XGUI_WorkshopListener::customizeCurrentObject(const std::set& theObjects, + bool theForceRedisplay) { - bool aCustomized = false; XGUI_OperationMgr* anOperationMgr = workshop()->operationMgr(); + FeaturePtr aCurrentFeature; if (anOperationMgr->hasOperation()) { ModuleBase_OperationFeature* aFOperation = dynamic_cast (anOperationMgr->currentOperation()); if (aFOperation) { - FeaturePtr aCurrentFeature = aFOperation->feature(); - if (aCurrentFeature.get()) - aCustomized = myWorkshop->module()->customizeObject(aCurrentFeature, - ModuleBase_IModule::CustomizeAllObjects, false); + aCurrentFeature = aFOperation->feature(); } } + + bool aCustomized = false; + if (aCurrentFeature.get()) { + // the customize presentation should be redisplayed if force redislayed is true or + // if a list of message objects contains the operation feature for case when + // the feature is hidden, but arguments of the feature are modified + // e.g. extrusion is hidden(h=0) but sketch is chosen + if (theForceRedisplay || theObjects.find(aCurrentFeature) != theObjects.end()) + aCustomized = myWorkshop->module()->customizeObject(aCurrentFeature, + ModuleBase_IModule::CustomizeAllObjects, false); + } return aCustomized; } diff --git a/src/XGUI/XGUI_WorkshopListener.h b/src/XGUI/XGUI_WorkshopListener.h index cf611cb26..49199f225 100755 --- a/src/XGUI/XGUI_WorkshopListener.h +++ b/src/XGUI/XGUI_WorkshopListener.h @@ -68,8 +68,12 @@ protected: bool displayObject(ObjectPtr theObj, bool& theFirstVisualizedBody); /// Calls the module method of cusomize object for the feature of the current operation + /// Perform cusomize if the force redisplay flag is true or the list of objects contains the + /// current operation feature + /// \param theObjects a list of objects to find current operation feature if forced redisplay is false + /// \param theForceRedisplay a flag to customize object even always /// \return true if the object is modified - bool customizeCurrentObject(); + bool customizeCurrentObject(const std::set& theObjects, bool theForceRedisplay); /// Returns the workshop XGUI_Workshop* workshop() const; -- 2.39.2