X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_Displayer.cpp;h=368dbb57469080e6f02d66e23a37690cb3388df4;hb=998909e881f6117ac083d0f4ae607602fce7fc55;hp=09bc3494f32fff71799e3cb536fcdd108b87348a;hpb=2265bb69d407b8f7020330fb4ca68e7f6aa2fdd0;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 09bc3494f..368dbb574 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -7,6 +7,9 @@ #include "XGUI_Displayer.h" #include "XGUI_Workshop.h" #include "XGUI_ViewerProxy.h" +#include "XGUI_SelectionMgr.h" +#include "XGUI_Selection.h" +#include "XGUI_CustomPrs.h" #include @@ -14,6 +17,7 @@ #include #include #include +#include #include @@ -39,6 +43,8 @@ const int MOUSE_SENSITIVITY_IN_PIXEL = 10; ///< defines the local context mouse selection sensitivity +//#define DEBUG_DISPLAY +//#define DEBUG_ACTIVATE // Workaround for bug #25637 void displayedObjects(const Handle(AIS_InteractiveContext)& theAIS, AIS_ListOfInteractive& theList) @@ -66,6 +72,8 @@ void displayedObjects(const Handle(AIS_InteractiveContext)& theAIS, AIS_ListOfIn XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop) : myWorkshop(theWorkshop) { + enableUpdateViewer(true); + myCustomPrs = std::shared_ptr(new XGUI_CustomPrs()); } XGUI_Displayer::~XGUI_Displayer() @@ -82,12 +90,20 @@ void XGUI_Displayer::display(ObjectPtr theObject, bool isUpdateViewer) if (isVisible(theObject)) { redisplay(theObject, isUpdateViewer); } else { +#ifdef DEBUG_DISPLAY + FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); + if (aFeature.get() != NULL) { + qDebug(QString("display feature: %1, displayed: %2"). + arg(aFeature->data()->name().c_str()). + arg(displayedObjects().size()).toStdString().c_str()); + } +#endif AISObjectPtr anAIS; GeomPresentablePtr aPrs = std::dynamic_pointer_cast(theObject); bool isShading = false; if (aPrs.get() != NULL) { - anAIS = aPrs->getAISObject(AISObjectPtr()); + anAIS = aPrs->getAISObject(anAIS); } else { ResultPtr aResult = std::dynamic_pointer_cast(theObject); if (aResult.get() != NULL) { @@ -113,8 +129,13 @@ bool canBeShaded(Handle(AIS_InteractiveObject) theAIS) TopAbs_ShapeEnum aType = aShape.ShapeType(); if ((aType == TopAbs_VERTEX) || (aType == TopAbs_EDGE) || (aType == TopAbs_WIRE)) return false; - else + else { + // Check that the presentation is not a sketch + Handle(ModuleBase_ResultPrs) aPrs = Handle(ModuleBase_ResultPrs)::DownCast(theAIS); + if (!aPrs.IsNull()) + return !aPrs->isSketchMode(); return true; + } } return false; } @@ -129,26 +150,31 @@ void XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS, Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); if (!anAISIO.IsNull()) { myResult2AISObjectMap[theObject] = theAIS; - bool aCanBeShaded = canBeShaded(anAISIO); + bool aCanBeShaded = ::canBeShaded(anAISIO); // In order to avoid extra closing/opening context - if (aCanBeShaded) + SelectMgr_IndexedMapOfOwner aSelectedOwners; + if (aCanBeShaded) { + myWorkshop->selector()->selection()->selectedOwners(aSelectedOwners); closeLocalContexts(false); + } aContext->Display(anAISIO, false); - qDebug("### Display %i", (long)anAISIO.Access()); - aContext->SetDisplayMode(anAISIO, isShading? Shading : Wireframe, false); - // Customization of presentation - FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); - if (aFeature.get() != NULL) { - GeomCustomPrsPtr aCustPrs = std::dynamic_pointer_cast(aFeature); - if (aCustPrs.get() != NULL) - aCustPrs->customisePresentation(theAIS); - } + if (isShading) + anAISIO->Attributes()->SetFaceBoundaryDraw( Standard_True ); + emit objectDisplayed(theObject, theAIS); + + bool isCustomized = customizeObject(theObject); + if (isCustomized) + aContext->Redisplay(anAISIO, false); + if (aCanBeShaded) { openLocalContext(); activateObjects(myActiveSelectionModes); + myWorkshop->selector()->setSelectedOwners(aSelectedOwners, false); } - } + else + activate(anAISIO, myActiveSelectionModes); + } if (isUpdateViewer) updateViewer(); } @@ -165,6 +191,7 @@ void XGUI_Displayer::erase(ObjectPtr theObject, const bool isUpdateViewer) if (anObject) { Handle(AIS_InteractiveObject) anAIS = anObject->impl(); if (!anAIS.IsNull()) { + emit beforeObjectErase(theObject, anObject); aContext->Remove(anAIS, isUpdateViewer); } } @@ -196,7 +223,36 @@ void XGUI_Displayer::redisplay(ObjectPtr theObject, bool isUpdateViewer) Handle(AIS_InteractiveContext) aContext = AISContext(); if (aContext.IsNull()) return; - aContext->Redisplay(aAISIO, isUpdateViewer); + // Check that the visualized shape is the same and the redisplay is not necessary + // Redisplay of AIS object leads to this object selection compute and the selection + // in the browser is lost + + // this check is not necessary anymore because the selection store/restore is realized + // before and after the values modification. + // Moreother, this check avoids customize and redisplay presentation if the presentable + // parameter is changed. + bool isEqualShapes = false; + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + if (aResult.get() != NULL) { + Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(aAISIO); + if (!aShapePrs.IsNull()) { + std::shared_ptr aShapePtr = ModelAPI_Tools::shape(aResult); + if (aShapePtr.get()) { + const TopoDS_Shape& aShape = aShapePrs->Shape(); + std::shared_ptr anAISShapePtr(new GeomAPI_Shape()); + anAISShapePtr->setImpl(new TopoDS_Shape(aShape)); + + isEqualShapes = aShapePtr->isEqual(anAISShapePtr); + } + } + } + // Customization of presentation + bool isCustomized = customizeObject(theObject); + if (!isEqualShapes || isCustomized) { + aContext->Redisplay(aAISIO, false); + if (isUpdateViewer) + updateViewer(); + } } } @@ -210,17 +266,32 @@ void XGUI_Displayer::deactivate(ObjectPtr theObject) AISObjectPtr anObj = myResult2AISObjectMap[theObject]; Handle(AIS_InteractiveObject) anAIS = anObj->impl(); aContext->Deactivate(anAIS); - qDebug("### Deactivate obj %i", (long)anAIS.Access()); } } -void XGUI_Displayer::activate(ObjectPtr theFeature) +/*void XGUI_Displayer::activate(ObjectPtr theFeature) { activate(theFeature, myActiveSelectionModes); } void XGUI_Displayer::activate(ObjectPtr theObject, const QIntList& theModes) { +#ifdef DEBUG_ACTIVATE + FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); + + if (aFeature.get() != NULL) { + QIntList aModes; + getModesOfActivation(theObject, aModes); + + + qDebug(QString("activate feature: %1, theModes: %2, myActiveSelectionModes: %3, getModesOf: %4"). + arg(aFeature->data()->name().c_str()). + arg(theModes.size()). + arg(myActiveSelectionModes.size()). + arg(aModes.size()).toStdString().c_str()); + } +#endif + if (isVisible(theObject)) { Handle(AIS_InteractiveContext) aContext = AISContext(); if (aContext.IsNull()) @@ -228,25 +299,41 @@ void XGUI_Displayer::activate(ObjectPtr theObject, const QIntList& theModes) AISObjectPtr anObj = myResult2AISObjectMap[theObject]; Handle(AIS_InteractiveObject) anAIS = anObj->impl(); - aContext->Deactivate(anAIS); - aContext->Load(anAIS, -1, true); - // In order to clear active modes list - if (theModes.size() > 0) { - foreach(int aMode, theModes) { - //aContext->Load(anAIS, aMode, true); - aContext->Activate(anAIS, aMode); - qDebug("### 1. Activate obj %i, %i", (long)anAIS.Access(), aMode); - } - } else { - //aContext->Load(anAIS, 0, true); - aContext->Activate(anAIS); - qDebug("### 2. Activate obj %i", (long)anAIS.Access()); + + activate(anAIS, theModes); + } +}*/ + +void XGUI_Displayer::getModesOfActivation(ObjectPtr theObject, QIntList& theModes) +{ + if (!isVisible(theObject)) + return; + + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull()) + return; + + AISObjectPtr aAISObj = getAISObject(theObject); + + if (aAISObj.get() != NULL) { + Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl(); + TColStd_ListOfInteger aTColModes; + aContext->ActivatedModes(anAISIO, aTColModes); + TColStd_ListIteratorOfListOfInteger itr( aTColModes ); + for (; itr.More(); itr.Next() ) { + theModes.append(itr.Value()); } } } void XGUI_Displayer::activateObjects(const QIntList& theModes) { +#ifdef DEBUG_ACTIVATE + qDebug(QString("activate all features: theModes: %2, myActiveSelectionModes: %3"). + arg(theModes.size()). + arg(myActiveSelectionModes.size()). + toStdString().c_str()); +#endif // In order to avoid doblications of selection modes QIntList aNewModes; foreach (int aMode, theModes) { @@ -255,6 +342,8 @@ void XGUI_Displayer::activateObjects(const QIntList& theModes) } myActiveSelectionModes = aNewModes; Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull()) + return; // Open local context if there is no one if (!aContext->HasOpenedContext()) return; @@ -263,32 +352,14 @@ void XGUI_Displayer::activateObjects(const QIntList& theModes) //myUseExternalObjects = true; AIS_ListOfInteractive aPrsList; - displayedObjects(aContext, aPrsList); + ::displayedObjects(aContext, aPrsList); Handle(AIS_Trihedron) aTrihedron; AIS_ListIteratorOfListOfInteractive aLIt(aPrsList); Handle(AIS_InteractiveObject) anAISIO; for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()){ anAISIO = aLIt.Value(); - aContext->Load(anAISIO, -1, true); - aContext->Deactivate(anAISIO); - aTrihedron = Handle(AIS_Trihedron)::DownCast(anAISIO); - //Deactivate trihedron which can be activated in local selector - if (aTrihedron.IsNull()) { - //aContext->Load(anAISIO, -1, true); - // In order to clear active modes list - if (myActiveSelectionModes.size() == 0) { - //aContext->Load(anAISIO, 0, true); - aContext->Activate(anAISIO); - qDebug("### 2. Activate all %i", (long)anAISIO.Access()); - } else { - foreach(int aMode, myActiveSelectionModes) { - //aContext->Load(anAISIO, aMode, true); - aContext->Activate(anAISIO, aMode); - qDebug("### 1. Activate all %i, %i", (long)anAISIO.Access(), aMode); - } - } - } + activate(anAISIO, myActiveSelectionModes); } } @@ -303,7 +374,7 @@ void XGUI_Displayer::deactivateObjects() //aContext->NotUseDisplayedObjects(); AIS_ListOfInteractive aPrsList; - displayedObjects(aContext, aPrsList); + ::displayedObjects(aContext, aPrsList); AIS_ListIteratorOfListOfInteractive aLIt; //Handle(AIS_Trihedron) aTrihedron; @@ -311,11 +382,6 @@ void XGUI_Displayer::deactivateObjects() for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()){ anAISIO = aLIt.Value(); aContext->Deactivate(anAISIO); - //aTrihedron = Handle(AIS_Trihedron)::DownCast(anAISIO); - //if (aTrihedron.IsNull()) { - // qDebug("### Deactivate all %i", (long)anAISIO.Access()); - // //aContext->Activate(anAISIO); - //} } } @@ -380,23 +446,25 @@ void XGUI_Displayer::clearSelected() void XGUI_Displayer::eraseAll(const bool isUpdateViewer) { Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull()) - return; - - foreach (AISObjectPtr aAISObj, myResult2AISObjectMap) { - // erase an object - Handle(AIS_InteractiveObject) anIO = aAISObj->impl(); - if (!anIO.IsNull()) - aContext->Remove(anIO, false); - } - myResult2AISObjectMap.clear(); - if (isUpdateViewer) - updateViewer(); - } + if (!aContext.IsNull()) { + foreach (ObjectPtr aObj, myResult2AISObjectMap.keys()) { + AISObjectPtr aAISObj = myResult2AISObjectMap[aObj]; + // erase an object + Handle(AIS_InteractiveObject) anIO = aAISObj->impl(); + if (!anIO.IsNull()) { + emit beforeObjectErase(aObj, aAISObj); + aContext->Remove(anIO, false); + } + } + if (isUpdateViewer) + updateViewer(); + } + myResult2AISObjectMap.clear(); +} void XGUI_Displayer::openLocalContext() { - Handle(AIS_InteractiveContext) aContext = AISContext(); + Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); if (aContext.IsNull()) return; // Open local context if there is no one @@ -416,7 +484,6 @@ void XGUI_Displayer::openLocalContext() //aContext->ClearCurrents(); aContext->OpenLocalContext(); - qDebug("### Open context"); //aContext->NotUseDisplayedObjects(); //myUseExternalObjects = false; @@ -449,7 +516,6 @@ void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer) //aContext->ClearSelected(); aContext->CloseAllContexts(false); - qDebug("### Close context"); // Redisplay all object if they were displayed in localContext Handle(AIS_InteractiveObject) aAISIO; @@ -507,10 +573,19 @@ ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) return aFeature; } +bool XGUI_Displayer::enableUpdateViewer(const bool isEnabled) +{ + bool aWasEnabled = myEnableUpdateViewer; + + myEnableUpdateViewer = isEnabled; + + return aWasEnabled; +} + void XGUI_Displayer::updateViewer() { Handle(AIS_InteractiveContext) aContext = AISContext(); - if (!aContext.IsNull()) + if (!aContext.IsNull() && myEnableUpdateViewer) aContext->UpdateCurrentViewer(); } @@ -519,7 +594,6 @@ Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); if ((!aContext.IsNull()) && (!aContext->HasOpenedContext())) { aContext->OpenLocalContext(); - qDebug("### Open context"); } return aContext; } @@ -537,6 +611,8 @@ Handle(SelectMgr_AndFilter) XGUI_Displayer::GetFilter() void XGUI_Displayer::displayAIS(AISObjectPtr theAIS, bool isUpdate) { Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull()) + return; Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); if (!anAISIO.IsNull()) { aContext->Display(anAISIO, isUpdate); @@ -557,6 +633,8 @@ void XGUI_Displayer::displayAIS(AISObjectPtr theAIS, bool isUpdate) void XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool isUpdate) { Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull()) + return; Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); if (!anAISIO.IsNull()) { aContext->Remove(anAISIO, isUpdate); @@ -578,7 +656,21 @@ void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bo return; Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl(); - aContext->SetDisplayMode(aAISIO, theMode, toUpdate); + bool aCanBeShaded = ::canBeShaded(aAISIO); + // In order to avoid extra closing/opening context + SelectMgr_IndexedMapOfOwner aSelectedOwners; + if (aCanBeShaded) { + myWorkshop->selector()->selection()->selectedOwners(aSelectedOwners); + closeLocalContexts(false); + } + aContext->SetDisplayMode(aAISIO, theMode, false); + if (aCanBeShaded) { + openLocalContext(); + activateObjects(myActiveSelectionModes); + myWorkshop->selector()->setSelectedOwners(aSelectedOwners, false); + } + if (toUpdate) + updateViewer(); } XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) const @@ -614,7 +706,9 @@ void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFi Handle(AIS_InteractiveContext) aContext = AISContext(); if (aContext.IsNull()) return; - GetFilter()->Remove(theFilter); + Handle(SelectMgr_AndFilter) aCompositeFilter = GetFilter(); + if (aCompositeFilter->IsIn(theFilter)) + aCompositeFilter->Remove(theFilter); } void XGUI_Displayer::removeFilters() @@ -638,3 +732,111 @@ void XGUI_Displayer::showOnly(const QObjectPtrList& theList) } updateViewer(); } + +bool XGUI_Displayer::canBeShaded(ObjectPtr theObject) const +{ + if (!isVisible(theObject)) + return false; + + AISObjectPtr aAISObj = getAISObject(theObject); + if (aAISObj.get() == NULL) + return false; + + Handle(AIS_InteractiveObject) anAIS = aAISObj->impl(); + return ::canBeShaded(anAIS); +} + +void XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO, + const QIntList& theModes) const +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull() || theIO.IsNull()) + return; + + // deactivate object in all modes, which are not in the list of activation + TColStd_ListOfInteger aTColModes; + aContext->ActivatedModes(theIO, aTColModes); + TColStd_ListIteratorOfListOfInteger itr( aTColModes ); + QIntList aModesActivatedForIO; + for (; itr.More(); itr.Next() ) { + Standard_Integer aMode = itr.Value(); + if (!theModes.contains(aMode)) { +#ifdef DEBUG_ACTIVATE + qDebug(QString("deactivate: %1").arg(aMode).toStdString().c_str()); +#endif + aContext->Deactivate(theIO, aMode); + } + else { + aModesActivatedForIO.append(aMode); +#ifdef DEBUG_ACTIVATE + qDebug(QString(" active: %1").arg(aMode).toStdString().c_str()); +#endif + } + } + // loading the interactive object allowing the decomposition + if (aTColModes.IsEmpty()) + aContext->Load(theIO, -1, true); + + Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast(theIO); + //Deactivate trihedron which can be activated in local selector + if (aTrihedron.IsNull()) { + //aContext->Load(anAISIO, -1, true); + // In order to clear active modes list + if (theModes.size() == 0) { + //aContext->Load(anAISIO, 0, true); + aContext->Activate(theIO); +#ifdef DEBUG_ACTIVATE + qDebug("activate in all modes"); +#endif + } else { + foreach(int aMode, theModes) { + //aContext->Load(anAISIO, aMode, true); + if (!aModesActivatedForIO.contains(aMode)) { + aContext->Activate(theIO, aMode); +#ifdef DEBUG_ACTIVATE + qDebug(QString("activate: %1").arg(aMode).toStdString().c_str()); +#endif + } + } + } + } +} + +bool XGUI_Displayer::customizeObject(ObjectPtr theObject) +{ + AISObjectPtr anAISObj = getAISObject(theObject); + // correct the result's color it it has the attribute + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + + // Customization of presentation + GeomCustomPrsPtr aCustomPrs; + FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); + if (aFeature.get() != NULL) { + GeomCustomPrsPtr aCustPrs = std::dynamic_pointer_cast(aFeature); + if (aCustPrs.get() != NULL) + aCustomPrs = aCustPrs; + } + if (aCustomPrs.get() == NULL) { + // we ignore presentable not customized objects + GeomPresentablePtr aPrs = std::dynamic_pointer_cast(theObject); + if (aPrs.get() != NULL) + return false; + aCustomPrs = myCustomPrs; + } + return aCustomPrs->customisePresentation(aResult, anAISObj, myCustomPrs); +} + + +QColor XGUI_Displayer::setObjectColor(ObjectPtr theObject, const QColor& theColor, bool toUpdate) +{ + if (!isVisible(theObject)) + return Qt::black; + + AISObjectPtr anAISObj = getAISObject(theObject); + int aR, aG, aB; + anAISObj->getColor(aR, aG, aB); + anAISObj->setColor(theColor.red(), theColor.green(), theColor.blue()); + if (toUpdate) + updateViewer(); + return QColor(aR, aG, aB); +}