X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_Displayer.cpp;h=bfb5ce29fc8303efdb18c09f4adacdd43b7dbd63;hb=2469ecd08c3b16def494626928ff81e575bdfe3d;hp=9914826eff9967d9bdc3e3fad27e9955d47ed790;hpb=0c46f6519b30378dd74a1337697f774060adb4c1;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 9914826ef..bfb5ce29f 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -11,15 +11,20 @@ #include "XGUI_Selection.h" #include "XGUI_CustomPrs.h" +#ifndef HAVE_SALOME #include +#endif #include #include #include #include #include +#include #include +#include +#include #include #include @@ -32,20 +37,39 @@ #include #include #include +#include +#include +#include +#include #include #include #include +#include +#include +#include + +#include #include #include +#include +#include + #include const int MOUSE_SENSITIVITY_IN_PIXEL = 10; ///< defines the local context mouse selection sensitivity +//#define DEBUG_ACTIVATE_OBJECTS +//#define DEBUG_DEACTIVATE +//#define DEBUG_ACTIVATE_AIS +//#define DEBUG_DEACTIVATE_AIS + //#define DEBUG_DISPLAY -//#define DEBUG_ACTIVATE +//#define DEBUG_FEATURE_REDISPLAY +//#define DEBUG_SELECTION_FILTERS +//#define DEBUG_COMPOSILID_DISPLAY // Workaround for bug #25637 void displayedObjects(const Handle(AIS_InteractiveContext)& theAIS, AIS_ListOfInteractive& theList) { @@ -68,12 +92,21 @@ void displayedObjects(const Handle(AIS_InteractiveContext)& theAIS, AIS_ListOfIn } } +QString qIntListInfo(const QIntList& theValues, const QString& theSeparator = QString(", ")) +{ + QStringList anInfo; + QIntList::const_iterator anIt = theValues.begin(), aLast = theValues.end(); + for (; anIt != aLast; anIt++) { + anInfo.append(QString::number(*anIt)); + } + return anInfo.join(theSeparator); +} XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop) - : myWorkshop(theWorkshop) + : myWorkshop(theWorkshop), myNeedUpdate(false), + myIsTrihedronActive(false), myViewerBlockedRecursiveCount(0) { - enableUpdateViewer(true); - myCustomPrs = std::shared_ptr(new XGUI_CustomPrs()); + myCustomPrs = std::shared_ptr(new XGUI_CustomPrs(theWorkshop)); } XGUI_Displayer::~XGUI_Displayer() @@ -85,21 +118,26 @@ bool XGUI_Displayer::isVisible(ObjectPtr theObject) const return myResult2AISObjectMap.contains(theObject); } -void XGUI_Displayer::display(ObjectPtr theObject, bool isUpdateViewer) +bool XGUI_Displayer::display(ObjectPtr theObject, bool theUpdateViewer) { + bool aDisplayed = false; 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()); +#ifdef DEBUG_COMPOSILID_DISPLAY + ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast(theObject); + if (aCompsolidResult.get()) { + for(int i = 0; i < aCompsolidResult->numberOfSubs(); i++) { + ResultPtr aSubResult = aCompsolidResult->subResult(i); + if (aSubResult.get()) + redisplay(aSubResult, false); + } + if (theUpdateViewer) + updateViewer(); } + else #endif + aDisplayed = redisplay(theObject, theUpdateViewer); + } else { AISObjectPtr anAIS; - GeomPresentablePtr aPrs = std::dynamic_pointer_cast(theObject); bool isShading = false; if (aPrs.get() != NULL) { @@ -107,101 +145,137 @@ void XGUI_Displayer::display(ObjectPtr theObject, bool isUpdateViewer) } else { ResultPtr aResult = std::dynamic_pointer_cast(theObject); if (aResult.get() != NULL) { +#ifdef DEBUG_COMPOSILID_DISPLAY + ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast(theObject); + if (aCompsolidResult.get()) { + for(int i = 0; i < aCompsolidResult->numberOfSubs(); i++) { + ResultPtr aSubResult = aCompsolidResult->subResult(i); + if (aSubResult.get()) + display(aSubResult, false); + } + if (theUpdateViewer) + updateViewer(); + } + else { +#endif std::shared_ptr aShapePtr = ModelAPI_Tools::shape(aResult); if (aShapePtr.get() != NULL) { anAIS = AISObjectPtr(new GeomAPI_AISObject()); - anAIS->setImpl(new Handle(AIS_InteractiveObject)(new ModuleBase_ResultPrs(aResult))); + Handle(AIS_InteractiveObject) anAISPrs = myWorkshop->module()->createPresentation(aResult); + if (anAISPrs.IsNull()) + anAISPrs = new ModuleBase_ResultPrs(aResult); + anAIS->setImpl(new Handle(AIS_InteractiveObject)(anAISPrs)); //anAIS->createShape(aShapePtr); isShading = true; } +#ifdef DEBUG_COMPOSILID_DISPLAY + } // close else +#endif } } if (anAIS) - display(theObject, anAIS, isShading, isUpdateViewer); + aDisplayed = display(theObject, anAIS, isShading, theUpdateViewer); } + return aDisplayed; } -bool canBeShaded(Handle(AIS_InteractiveObject) theAIS) +bool canBeShaded(Handle(AIS_InteractiveObject) theAIS, ModuleBase_IModule* theModule) { Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(theAIS); if (!aShapePrs.IsNull()) { TopoDS_Shape aShape = aShapePrs->Shape(); + if (aShape.IsNull()) + return false; TopAbs_ShapeEnum aType = aShape.ShapeType(); if ((aType == TopAbs_VERTEX) || (aType == TopAbs_EDGE) || (aType == TopAbs_WIRE)) return false; 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 theModule->canBeShaded(theAIS); } } return false; } -void XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS, - bool isShading, bool isUpdateViewer) +bool XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS, + bool isShading, bool theUpdateViewer) { + bool aDisplayed = false; + Handle(AIS_InteractiveContext) aContext = AISContext(); if (aContext.IsNull()) - return; + return aDisplayed; Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); if (!anAISIO.IsNull()) { - myResult2AISObjectMap[theObject] = theAIS; - bool aCanBeShaded = ::canBeShaded(anAISIO); - // In order to avoid extra closing/opening context - SelectMgr_IndexedMapOfOwner aSelectedOwners; - if (aCanBeShaded) { - myWorkshop->selector()->selection()->selectedOwners(aSelectedOwners); - closeLocalContexts(false); - } - aContext->Display(anAISIO, false); - aContext->SetDisplayMode(anAISIO, isShading? Shading : Wireframe, false); - if (isShading) - anAISIO->Attributes()->SetFaceBoundaryDraw( Standard_True ); - emit objectDisplayed(theObject, theAIS); + appendResultObject(theObject, theAIS); bool isCustomized = customizeObject(theObject); - if (isCustomized) - aContext->Redisplay(anAISIO, false); - if (aCanBeShaded) { - openLocalContext(); - activateObjects(myActiveSelectionModes); - myWorkshop->selector()->setSelectedOwners(aSelectedOwners, false); + int aDispMode = isShading? Shading : Wireframe; + if (isShading) + anAISIO->Attributes()->SetFaceBoundaryDraw( Standard_True ); + anAISIO->SetDisplayMode(aDispMode); + aContext->Display(anAISIO, aDispMode, 0, false, true, AIS_DS_Displayed); + aDisplayed = true; + + emit objectDisplayed(theObject, theAIS); + activate(anAISIO, myActiveSelectionModes, theUpdateViewer); + // the fix from VPA for more suitable selection of sketcher lines + if(anAISIO->Width() > 1) { + for(int aModeIdx = 0; aModeIdx < myActiveSelectionModes.length(); ++aModeIdx) { + int aMode = myActiveSelectionModes.value(aModeIdx); + double aPrecision = (aMode == getSelectionMode(TopAbs_VERTEX))? 20 : + (anAISIO->Width() + 2); + aContext->SetSelectionSensitivity(anAISIO, aMode, aPrecision); + } } - else - activate(anAISIO, myActiveSelectionModes); - } - if (isUpdateViewer) + } + if (theUpdateViewer) updateViewer(); + + return aDisplayed; } -void XGUI_Displayer::erase(ObjectPtr theObject, const bool isUpdateViewer) +bool XGUI_Displayer::erase(ObjectPtr theObject, const bool theUpdateViewer) { + bool aErased = false; if (!isVisible(theObject)) - return; + return aErased; Handle(AIS_InteractiveContext) aContext = AISContext(); if (aContext.IsNull()) - return; + return aErased; + AISObjectPtr anObject = myResult2AISObjectMap[theObject]; if (anObject) { Handle(AIS_InteractiveObject) anAIS = anObject->impl(); if (!anAIS.IsNull()) { emit beforeObjectErase(theObject, anObject); - aContext->Remove(anAIS, isUpdateViewer); + aContext->Remove(anAIS, false/*update viewer*/); + aErased = true; } } myResult2AISObjectMap.remove(theObject); + +#ifdef DEBUG_DISPLAY + std::ostringstream aPtrStr; + aPtrStr << theObject.get(); + qDebug(QString("erase object: %1").arg(aPtrStr.str().c_str()).toStdString().c_str()); + qDebug(getResult2AISObjectMapInfo().c_str()); +#endif + + if (theUpdateViewer) + updateViewer(); + + return aErased; } -void XGUI_Displayer::redisplay(ObjectPtr theObject, bool isUpdateViewer) +bool XGUI_Displayer::redisplay(ObjectPtr theObject, bool theUpdateViewer) { + bool aRedisplayed = false; if (!isVisible(theObject)) - return; + return aRedisplayed; AISObjectPtr aAISObj = getAISObject(theObject); Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl(); @@ -210,23 +284,20 @@ void XGUI_Displayer::redisplay(ObjectPtr theObject, bool isUpdateViewer) if (aPrs) { AISObjectPtr aAIS_Obj = aPrs->getAISObject(aAISObj); if (!aAIS_Obj) { - erase(theObject, isUpdateViewer); - return; + aRedisplayed = erase(theObject, theUpdateViewer); + return aRedisplayed; } if (aAIS_Obj != aAISObj) { - myResult2AISObjectMap[theObject] = aAIS_Obj; + appendResultObject(theObject, aAIS_Obj); } aAISIO = aAIS_Obj->impl(); } - if (!aAISIO.IsNull()) { - Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull()) - return; + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (!aContext.IsNull() && !aAISIO.IsNull()) { // 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 @@ -238,79 +309,95 @@ void XGUI_Displayer::redisplay(ObjectPtr theObject, bool isUpdateViewer) 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); + const TopoDS_Shape& aOldShape = aShapePrs->Shape(); + if (!aOldShape.IsNull()) + isEqualShapes = aOldShape.IsEqual(aShapePtr->impl()); } } } // Customization of presentation bool isCustomized = customizeObject(theObject); + #ifdef DEBUG_FEATURE_REDISPLAY + qDebug(QString("Redisplay: %1, isEqualShapes=%2, isCustomized=%3"). + arg(!isEqualShapes || isCustomized).arg(isEqualShapes).arg(isCustomized).toStdString().c_str()); + #endif if (!isEqualShapes || isCustomized) { + /// if shapes are equal and presentation are customized, selection should be restored + bool aNeedToRestoreSelection = isEqualShapes && isCustomized; + if (aNeedToRestoreSelection) + myWorkshop->module()->storeSelection(); + aContext->Redisplay(aAISIO, false); - if (isUpdateViewer) + + if (aNeedToRestoreSelection) + myWorkshop->module()->restoreSelection(); + + aRedisplayed = true; + #ifdef DEBUG_FEATURE_REDISPLAY + qDebug(" Redisplay happens"); + #endif + if (theUpdateViewer) updateViewer(); } } + return aRedisplayed; } -void XGUI_Displayer::deactivate(ObjectPtr theObject) +void XGUI_Displayer::redisplayObjects() { - if (isVisible(theObject)) { - Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull()) - return; - - AISObjectPtr anObj = myResult2AISObjectMap[theObject]; - Handle(AIS_InteractiveObject) anAIS = anObj->impl(); - aContext->Deactivate(anAIS); + // redisplay objects visualized in the viewer + static Events_ID EVENT_DISP = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY); + static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get(); + QObjectPtrList aDisplayed = myWorkshop->displayer()->displayedObjects(); + QObjectPtrList::const_iterator anIt = aDisplayed.begin(), aLast = aDisplayed.end(); + for (; anIt != aLast; anIt++) { + aECreator->sendUpdated(*anIt, EVENT_DISP); } + Events_Loop::loop()->flush(EVENT_DISP); } -/*void XGUI_Displayer::activate(ObjectPtr theFeature) -{ - activate(theFeature, myActiveSelectionModes); -} - -void XGUI_Displayer::activate(ObjectPtr theObject, const QIntList& theModes) +void XGUI_Displayer::deactivate(ObjectPtr theObject, const bool theUpdateViewer) { -#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()); - } +#ifdef DEBUG_DEACTIVATE + QString anInfoStr = ModuleBase_Tools::objectInfo(theObject); + qDebug(QString("deactivate: myActiveSelectionModes[%1]: %2, objects = "). + arg(myActiveSelectionModes.size()).arg(qIntListInfo(myActiveSelectionModes)). + arg(anInfoStr). + toStdString().c_str()); #endif - - if (isVisible(theObject)) { - Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull()) - return; - + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (!aContext.IsNull() && isVisible(theObject)) { AISObjectPtr anObj = myResult2AISObjectMap[theObject]; Handle(AIS_InteractiveObject) anAIS = anObj->impl(); - activate(anAIS, theModes); + deactivateAIS(anAIS); + // the selection from the previous activation modes should be cleared manually (#26172) + aContext->LocalContext()->ClearOutdatedSelection(anAIS, true); + if (theUpdateViewer) + updateViewer(); } -}*/ +} -void XGUI_Displayer::getModesOfActivation(ObjectPtr theObject, QIntList& theModes) +void XGUI_Displayer::deactivateObjects(const QObjectPtrList& theObjList, + const bool theUpdateViewer) { - if (!isVisible(theObject)) - return; + //Handle(AIS_InteractiveObject) aTrihedron = getTrihedron(); + //if (!aTrihedron.IsNull()) + // deactivateAIS(aTrihedron); + QObjectPtrList::const_iterator anIt = theObjList.begin(), aLast = theObjList.end(); + for (; anIt != aLast; anIt++) { + deactivate(*anIt, false); + } + //VSV It seems that there is no necessity to update viewer on deactivation + //if (theUpdateViewer) + // updateViewer(); +} + +void XGUI_Displayer::getModesOfActivation(ObjectPtr theObject, QIntList& theModes) +{ Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull()) + if (aContext.IsNull() || !isVisible(theObject)) return; AISObjectPtr aAISObj = getAISObject(theObject); @@ -326,71 +413,125 @@ void XGUI_Displayer::getModesOfActivation(ObjectPtr theObject, QIntList& theMode } } -void XGUI_Displayer::activateObjects(const QIntList& theModes) +int XGUI_Displayer::getSelectionMode(int theShapeType) +{ + return (theShapeType >= TopAbs_SHAPE)? theShapeType : + AIS_Shape::SelectionMode((TopAbs_ShapeEnum)theShapeType); +} + +bool XGUI_Displayer::isVisible(XGUI_Displayer* theDisplayer, const ObjectPtr& theObject) +{ + bool aVisible = false; + GeomPresentablePtr aPrs = std::dynamic_pointer_cast(theObject); + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + if (aPrs.get() || aResult.get()) { + aVisible = theDisplayer->isVisible(theObject); + // compsolid is not visualized in the viewer, but should have presentation when all sub solids are + // visible. It is useful for highlight presentation where compsolid shape is selectable + if (!aVisible && aResult.get() && aResult->groupName() == ModelAPI_ResultCompSolid::group()) { + ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast(aResult); + if (aCompsolidResult.get() != NULL) { // change colors for all sub-solids + bool anAllSubsVisible = aCompsolidResult->numberOfSubs() > 0; + for(int i = 0; i < aCompsolidResult->numberOfSubs() && anAllSubsVisible; i++) { + anAllSubsVisible = theDisplayer->isVisible(aCompsolidResult->subResult(i)); + } + aVisible = anAllSubsVisible; + } + } + } + else { + // check if all results of the feature are visible + FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); + std::list aResults = aFeature->results(); + std::list::const_iterator aIt; + aVisible = !aResults.empty(); + for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { + aVisible = aVisible && theDisplayer->isVisible(*aIt); + } + } + return aVisible; +} + + +void XGUI_Displayer::activateObjects(const QIntList& theModes, const QObjectPtrList& theObjList, + const bool theUpdateViewer) { -#ifdef DEBUG_ACTIVATE - qDebug(QString("activate all features: theModes: %2, myActiveSelectionModes: %3"). - arg(theModes.size()). - arg(myActiveSelectionModes.size()). + // Convert shape types to selection types + QIntList aModes; + foreach(int aType, theModes) { + aModes.append(getSelectionMode(aType)); + } + +#ifdef DEBUG_ACTIVATE_OBJECTS + QStringList anInfo; + QObjectPtrList::const_iterator anIt = theObjList.begin(), aLast = theObjList.end(); + for (; anIt != aLast; ++anIt) { + anInfo.append(ModuleBase_Tools::objectInfo((*anIt))); + } + QString anInfoStr = anInfo.join(", "); + + qDebug(QString("activateObjects: aModes[%1] = %2, myActiveSelectionModes[%3] = %4, objects = %5"). + arg(aModes.size()).arg(qIntListInfo(aModes)). + arg(myActiveSelectionModes.size()).arg(qIntListInfo(myActiveSelectionModes)). + arg(anInfoStr). toStdString().c_str()); #endif // In order to avoid doblications of selection modes QIntList aNewModes; - foreach (int aMode, theModes) { + foreach (int aMode, aModes) { if (!aNewModes.contains(aMode)) aNewModes.append(aMode); } myActiveSelectionModes = aNewModes; Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull()) - return; // Open local context if there is no one - if (!aContext->HasOpenedContext()) + if (aContext.IsNull() || !aContext->HasOpenedContext()) return; //aContext->UseDisplayedObjects(); //myUseExternalObjects = true; - AIS_ListOfInteractive 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(); - activate(anAISIO, myActiveSelectionModes); + AIS_ListOfInteractive aPrsList; + //if (aObjList.isEmpty()) + // return; + //else { + foreach(ObjectPtr aObj, theObjList) { + if (myResult2AISObjectMap.contains(aObj)) + aPrsList.Append(myResult2AISObjectMap[aObj]->impl()); } -} - - -void XGUI_Displayer::deactivateObjects() -{ - myActiveSelectionModes.clear(); - Handle(AIS_InteractiveContext) aContext = AISContext(); - // Open local context if there is no one - if (!aContext->HasOpenedContext()) + //} + + // Add trihedron because it has to partisipate in selection + Handle(AIS_InteractiveObject) aTrihedron; + if (isTrihedronActive()) { + aTrihedron = getTrihedron(); + if (!aTrihedron.IsNull() && aContext->IsDisplayed(aTrihedron)) + aPrsList.Append(aTrihedron); + } + if (aPrsList.Extent() == 0) return; - //aContext->NotUseDisplayedObjects(); - AIS_ListOfInteractive aPrsList; - ::displayedObjects(aContext, aPrsList); - - AIS_ListIteratorOfListOfInteractive aLIt; - //Handle(AIS_Trihedron) aTrihedron; - Handle(AIS_InteractiveObject) anAISIO; + AIS_ListIteratorOfListOfInteractive aLIt(aPrsList); + bool isActivationChanged = false; for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()){ anAISIO = aLIt.Value(); - aContext->Deactivate(anAISIO); + if (activate(anAISIO, myActiveSelectionModes, false)) + isActivationChanged = true; + } + if (!aTrihedron.IsNull()) { + foreach(int aMode, myActiveSelectionModes) + aContext->SetSelectionSensitivity(aTrihedron, aMode, 20); } + // VSV It seems that there is no necessity to update viewer on activation + //if (theUpdateViewer && isActivationChanged) + // updateViewer(); } bool XGUI_Displayer::isActive(ObjectPtr theObject) const { Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull()) - return false; - if (!isVisible(theObject)) + if (aContext.IsNull() || !isVisible(theObject)) return false; AISObjectPtr anObj = myResult2AISObjectMap[theObject]; @@ -400,28 +541,43 @@ bool XGUI_Displayer::isActive(ObjectPtr theObject) const aContext->ActivatedModes(anAIS, aModes); return aModes.Extent() > 0; } - -void XGUI_Displayer::setSelected(const QObjectPtrList& theResults, const bool isUpdateViewer) +void XGUI_Displayer::setSelected(const QList& theValues, bool theUpdateViewer) { Handle(AIS_InteractiveContext) aContext = AISContext(); if (aContext.IsNull()) return; if (aContext->HasOpenedContext()) { - aContext->UnhilightSelected(); - aContext->ClearSelected(); - foreach(ObjectPtr aResult, theResults) { - if (isVisible(aResult)) { - AISObjectPtr anObj = myResult2AISObjectMap[aResult]; - Handle(AIS_InteractiveObject) anAIS = anObj->impl(); - if (!anAIS.IsNull()) - aContext->SetSelected(anAIS, false); + aContext->UnhilightSelected(false); + aContext->ClearSelected(false); + foreach (ModuleBase_ViewerPrsPtr aPrs, theValues) { + const GeomShapePtr& aGeomShape = aPrs->shape(); + if (aGeomShape.get() && !aGeomShape->isNull()) { + const TopoDS_Shape& aShape = aGeomShape->impl(); + aContext->AddOrRemoveSelected(aShape, false); + } else { + ObjectPtr anObject = aPrs->object(); + ResultPtr aResult = std::dynamic_pointer_cast(anObject); + if (aResult.get() && isVisible(aResult)) { + AISObjectPtr anObj = myResult2AISObjectMap[aResult]; + Handle(AIS_InteractiveObject) anAIS = anObj->impl(); + if (!anAIS.IsNull()) { + // The methods are replaced in order to provide multi-selection, e.g. restore selection + // by activating multi selector widget. It also gives an advantage that the multi + // selection in OB gives multi-selection in the viewer + //aContext->SetSelected(anAIS, false); + // The selection in the context was cleared, so the method sets the objects are selected + aContext->AddOrRemoveSelected(anAIS, false); + } + } } } } else { - aContext->UnhilightCurrents(); - aContext->ClearCurrents(); - foreach(ObjectPtr aResult, theResults) { - if (isVisible(aResult)) { + aContext->UnhilightCurrents(false); + aContext->ClearCurrents(false); + foreach (ModuleBase_ViewerPrsPtr aPrs, theValues) { + ObjectPtr anObject = aPrs->object(); + ResultPtr aResult = std::dynamic_pointer_cast(anObject); + if (aResult.get() && isVisible(aResult)) { AISObjectPtr anObj = myResult2AISObjectMap[aResult]; Handle(AIS_InteractiveObject) anAIS = anObj->impl(); if (!anAIS.IsNull()) @@ -429,22 +585,22 @@ void XGUI_Displayer::setSelected(const QObjectPtrList& theResults, const bool is } } } - if (isUpdateViewer) + if (theUpdateViewer) updateViewer(); } - void XGUI_Displayer::clearSelected() { Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext) { + if (!aContext.IsNull()) { aContext->UnhilightCurrents(false); aContext->ClearSelected(); } } -void XGUI_Displayer::eraseAll(const bool isUpdateViewer) +bool XGUI_Displayer::eraseAll(const bool theUpdateViewer) { + bool aErased = false; Handle(AIS_InteractiveContext) aContext = AISContext(); if (!aContext.IsNull()) { foreach (ObjectPtr aObj, myResult2AISObjectMap.keys()) { @@ -453,22 +609,69 @@ void XGUI_Displayer::eraseAll(const bool isUpdateViewer) Handle(AIS_InteractiveObject) anIO = aAISObj->impl(); if (!anIO.IsNull()) { emit beforeObjectErase(aObj, aAISObj); - aContext->Remove(anIO, false); + aContext->Remove(anIO, false/*update viewer*/); + aErased = true; } } - if (isUpdateViewer) + if (theUpdateViewer) updateViewer(); } myResult2AISObjectMap.clear(); +#ifdef DEBUG_DISPLAY + qDebug("eraseAll"); + qDebug(getResult2AISObjectMapInfo().c_str()); +#endif + return aErased; +} + +void deactivateObject(Handle(AIS_InteractiveContext) theContext, + Handle(AIS_InteractiveObject) theObject, + const bool theClear = true) +{ + if (!theObject.IsNull()) { + theContext->Deactivate(theObject); + //if (theClear) { + //theObject->ClearSelected(); + // theContext->LocalContext()->ClearOutdatedSelection(theObject, true); + //} + } +} + +void XGUI_Displayer::deactivateTrihedron(const bool theUpdateViewer) const +{ + Handle(AIS_InteractiveObject) aTrihedron = getTrihedron(); + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (!aTrihedron.IsNull() && aContext->IsDisplayed(aTrihedron)) { + Handle(AIS_Trihedron) aTrie = Handle(AIS_Trihedron)::DownCast(aTrihedron); + deactivateObject(aContext, aTrie); + + /// #1136 hidden axis are selected in sketch + /// workaround for Cascade: there is a crash in AIS_LocalContext::ClearOutdatedSelection + /// for Position AIS object in SelectionModes. + deactivateObject(aContext, aTrie->XAxis()); + deactivateObject(aContext, aTrie->YAxis()); + deactivateObject(aContext, aTrie->Axis()); + deactivateObject(aContext, aTrie->Position()); + + deactivateObject(aContext, aTrie->XYPlane()); + deactivateObject(aContext, aTrie->XZPlane()); + deactivateObject(aContext, aTrie->YZPlane()); + + if (theUpdateViewer) + updateViewer(); + } +} + +Handle(AIS_InteractiveObject) XGUI_Displayer::getTrihedron() const +{ + return myWorkshop->viewer()->trihedron(); } void XGUI_Displayer::openLocalContext() { - Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); - if (aContext.IsNull()) - return; + Handle(AIS_InteractiveContext) aContext = AISContext(); // Open local context if there is no one - if (!aContext->HasOpenedContext()) { + if (!aContext.IsNull() && !aContext->HasOpenedContext()) { // Preserve selected objects //AIS_ListOfInteractive aAisList; //for (aContext->InitCurrent(); aContext->MoreCurrent(); aContext->NextCurrent()) @@ -484,6 +687,7 @@ void XGUI_Displayer::openLocalContext() //aContext->ClearCurrents(); aContext->OpenLocalContext(); + //deactivateTrihedron(); //aContext->NotUseDisplayedObjects(); //myUseExternalObjects = false; @@ -500,10 +704,10 @@ void XGUI_Displayer::openLocalContext() } } -void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer) +void XGUI_Displayer::closeLocalContexts(const bool theUpdateViewer) { Handle(AIS_InteractiveContext) aContext = AISContext(); - if ( (!aContext.IsNull()) && (aContext->HasOpenedContext()) ) { + if (!aContext.IsNull() && aContext->HasOpenedContext()) { // Preserve selected objects //AIS_ListOfInteractive aAisList; //for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) @@ -517,15 +721,18 @@ void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer) //aContext->ClearSelected(); aContext->CloseAllContexts(false); + // From the moment when the AIS_DS_Displayed flag is used in the Display of AIS object, + // this code is obsolete. It is temporaty commented and should be removed after + // the test campaign. // Redisplay all object if they were displayed in localContext - Handle(AIS_InteractiveObject) aAISIO; + /*Handle(AIS_InteractiveObject) aAISIO; foreach (AISObjectPtr aAIS, myResult2AISObjectMap) { aAISIO = aAIS->impl(); if (aContext->DisplayStatus(aAISIO) != AIS_DS_Displayed) { aContext->Display(aAISIO, false); aContext->SetDisplayMode(aAISIO, Shading, false); } - } + }*/ // Append the filters from the local selection in the global selection context SelectMgr_ListIteratorOfListOfFilter aIt(aFilters); @@ -534,7 +741,7 @@ void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer) aContext->AddFilter(aFilter); } - if (isUpdateViewer) + if (theUpdateViewer) updateViewer(); //myUseExternalObjects = false; @@ -563,37 +770,99 @@ ObjectPtr XGUI_Displayer::getObject(const AISObjectPtr& theIO) const ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) const { - ObjectPtr aFeature; + ObjectPtr anObject; foreach (ObjectPtr anObj, myResult2AISObjectMap.keys()) { AISObjectPtr aAIS = myResult2AISObjectMap[anObj]; Handle(AIS_InteractiveObject) anAIS = aAIS->impl(); if (anAIS == theIO) - return anObj; + anObject = anObj; + if (anObject.get()) + break; } - return aFeature; + if (!anObject.get()) { + std::shared_ptr anAISObj = AISObjectPtr(new GeomAPI_AISObject()); + if (!theIO.IsNull()) { + anAISObj->setImpl(new Handle(AIS_InteractiveObject)(theIO)); + } + anObject = myWorkshop->module()->findPresentedObject(anAISObj); + } + return anObject; } bool XGUI_Displayer::enableUpdateViewer(const bool isEnabled) { - bool aWasEnabled = myEnableUpdateViewer; - - myEnableUpdateViewer = isEnabled; + bool aWasEnabled = isUpdateEnabled(); + if (isEnabled) + myViewerBlockedRecursiveCount--; + else + myViewerBlockedRecursiveCount++; + if (myNeedUpdate && isUpdateEnabled()) { + updateViewer(); + myNeedUpdate = false; + } return aWasEnabled; } -void XGUI_Displayer::updateViewer() +bool XGUI_Displayer::isUpdateEnabled() const +{ + return myViewerBlockedRecursiveCount == 0; +} + +void XGUI_Displayer::updateViewer() const { Handle(AIS_InteractiveContext) aContext = AISContext(); - if (!aContext.IsNull() && myEnableUpdateViewer) + if (!aContext.IsNull() && isUpdateEnabled()) { + myWorkshop->viewer()->Zfitall(); aContext->UpdateCurrentViewer(); + } else { + myNeedUpdate = true; + } +} + +void XGUI_Displayer::activateAIS(const Handle(AIS_InteractiveObject)& theIO, + const int theMode, const bool theUpdateViewer) const +{ + Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); + if (!aContext.IsNull()) { + aContext->Activate(theIO, theMode, false); + +#ifdef DEBUG_ACTIVATE_AIS + ObjectPtr anObject = getObject(theIO); + anInfo.append(ModuleBase_Tools::objectInfo((*anIt))); + qDebug(QString("activateAIS: theMode = %1, object = %2").arg(theMode).arg(anInfo).toStdString().c_str()); +#endif + if (theUpdateViewer) + updateViewer(); + } +} + +void XGUI_Displayer::deactivateAIS(const Handle(AIS_InteractiveObject)& theIO, const int theMode) const +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (!aContext.IsNull()) { + if (theMode == -1) + aContext->Deactivate(theIO); + else + aContext->Deactivate(theIO, theMode); + +#ifdef DEBUG_DEACTIVATE_AIS + ObjectPtr anObject = getObject(theIO); + anInfo.append(ModuleBase_Tools::objectInfo((*anIt))); + qDebug(QString("deactivateAIS: theMode = %1, object = %2").arg(theMode).arg(anInfo).toStdString().c_str()); +#endif + } } Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const { Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); - if ((!aContext.IsNull()) && (!aContext->HasOpenedContext())) { + if (!aContext.IsNull() && !aContext->HasOpenedContext()) { aContext->OpenLocalContext(); + if (!isTrihedronActive()) + deactivateTrihedron(true); + aContext->DefaultDrawer()->VIsoAspect()->SetNumber(0); + aContext->DefaultDrawer()->UIsoAspect()->SetNumber(0); } return aContext; } @@ -601,48 +870,59 @@ Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const Handle(SelectMgr_AndFilter) XGUI_Displayer::GetFilter() { Handle(AIS_InteractiveContext) aContext = AISContext(); - if (myAndFilter.IsNull() && !aContext.IsNull()) { + if (!aContext.IsNull() && myAndFilter.IsNull()) { myAndFilter = new SelectMgr_AndFilter(); aContext->AddFilter(myAndFilter); } return myAndFilter; } -void XGUI_Displayer::displayAIS(AISObjectPtr theAIS, bool isUpdate) +bool XGUI_Displayer::displayAIS(AISObjectPtr theAIS, const bool toActivateInSelectionModes, + bool theUpdateViewer) { + bool aDisplayed = false; Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull()) - return; Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); - if (!anAISIO.IsNull()) { - aContext->Display(anAISIO, isUpdate); - if (aContext->HasOpenedContext()) { - //if (myUseExternalObjects) { + if (!aContext.IsNull() && !anAISIO.IsNull()) { + aContext->Display(anAISIO, 0/*wireframe*/, 0, false/*update viewer*/, true, AIS_DS_Displayed); + aDisplayed = true; + aContext->Deactivate(anAISIO); + aContext->Load(anAISIO); + if (toActivateInSelectionModes) { + if (aContext->HasOpenedContext()) { if (myActiveSelectionModes.size() == 0) - aContext->Activate(anAISIO); + activateAIS(anAISIO, 0, theUpdateViewer); else { foreach(int aMode, myActiveSelectionModes) { - aContext->Activate(anAISIO, aMode); + activateAIS(anAISIO, aMode, theUpdateViewer); } } - //} + } } + if (theUpdateViewer) + updateViewer(); } + return aDisplayed; } -void XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool isUpdate) +bool XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool theUpdateViewer) { + bool aErased = false; Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull()) - return; - Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); - if (!anAISIO.IsNull()) { - aContext->Remove(anAISIO, isUpdate); + if (!aContext.IsNull()) { + Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); + if (!anAISIO.IsNull() && aContext->IsDisplayed(anAISIO)) { + aContext->Remove(anAISIO, false/*update viewer*/); + aErased = true; + } } + if (aErased && theUpdateViewer) + updateViewer(); + return aErased; } -void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bool toUpdate) +void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bool theUpdateViewer) { if (theMode == NoMode) return; @@ -656,20 +936,9 @@ void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bo return; Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl(); - 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) + // Redisplay in order to update new mode because it could be not computed before + if (theUpdateViewer) updateViewer(); } @@ -687,18 +956,39 @@ XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) con return (XGUI_Displayer::DisplayMode) aAISIO->DisplayMode(); } +void XGUI_Displayer::deactivateSelectionFilters() +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (!myAndFilter.IsNull()) { + bool aFound = false; + if (!aContext.IsNull()) { + const SelectMgr_ListOfFilter& aFilters = aContext->Filters(); + SelectMgr_ListIteratorOfListOfFilter anIt(aFilters); + for (; anIt.More() && !aFound; anIt.Next()) { + Handle(SelectMgr_Filter) aFilter = anIt.Value(); + aFound = aFilter == myAndFilter; + } + if (aFound) + aContext->RemoveFilter(myAndFilter); + } + myAndFilter.Nullify(); + } +} + void XGUI_Displayer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) { Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull()) + if (aContext.IsNull() || hasSelectionFilter(theFilter)) return; - const SelectMgr_ListOfFilter& aFilters = aContext->Filters(); - SelectMgr_ListIteratorOfListOfFilter aIt(aFilters); - for (; aIt.More(); aIt.Next()) { - if (theFilter.Access() == aIt.Value().Access()) - return; + + Handle(SelectMgr_CompositionFilter) aCompositeFilter = GetFilter(); + if (!aCompositeFilter.IsNull()) { + aCompositeFilter->Add(theFilter); +#ifdef DEBUG_SELECTION_FILTERS + int aCount = aCompositeFilter->StoredFilters().Extent(); + qDebug(QString("addSelectionFilter: filters.count() = %1").arg(aCount).toStdString().c_str()); +#endif } - GetFilter()->Add(theFilter); } void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) @@ -706,9 +996,39 @@ void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFi Handle(AIS_InteractiveContext) aContext = AISContext(); if (aContext.IsNull()) return; + Handle(SelectMgr_AndFilter) aCompositeFilter = GetFilter(); - if (aCompositeFilter->IsIn(theFilter)) + if (!aCompositeFilter.IsNull() && aCompositeFilter->IsIn(theFilter)) { aCompositeFilter->Remove(theFilter); +#ifdef DEBUG_SELECTION_FILTERS + int aCount = aCompositeFilter->StoredFilters().Extent(); + qDebug(QString("removeSelectionFilter: filters.count() = %1").arg(aCount).toStdString().c_str()); +#endif + } +} + +bool XGUI_Displayer::hasSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) +{ + bool aFilterFound = false; + + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull()) + return aFilterFound; + const SelectMgr_ListOfFilter& aFilters = aContext->Filters(); + SelectMgr_ListIteratorOfListOfFilter aIt(aFilters); + for (; aIt.More() && !aFilterFound; aIt.Next()) { + if (theFilter.Access() == aIt.Value().Access()) + aFilterFound = true; + } + Handle(SelectMgr_CompositionFilter) aCompositeFilter = GetFilter(); + if (!aCompositeFilter.IsNull()) { + const SelectMgr_ListOfFilter& aStoredFilters = aCompositeFilter->StoredFilters(); + for (aIt.Initialize(aStoredFilters); aIt.More() && !aFilterFound; aIt.Next()) { + if (theFilter.Access() == aIt.Value().Access()) + aFilterFound = true; + } + } + return aFilterFound; } void XGUI_Displayer::removeFilters() @@ -716,7 +1036,10 @@ void XGUI_Displayer::removeFilters() Handle(AIS_InteractiveContext) aContext = AISContext(); if (aContext.IsNull()) return; - GetFilter()->Clear(); + + Handle(SelectMgr_CompositionFilter) aCompositeFilter = GetFilter(); + if (!aCompositeFilter.IsNull()) + aCompositeFilter->Clear(); } void XGUI_Displayer::showOnly(const QObjectPtrList& theList) @@ -743,16 +1066,18 @@ bool XGUI_Displayer::canBeShaded(ObjectPtr theObject) const return false; Handle(AIS_InteractiveObject) anAIS = aAISObj->impl(); - return ::canBeShaded(anAIS); + return ::canBeShaded(anAIS, myWorkshop->module()); } -void XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO, - const QIntList& theModes) const +bool XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO, + const QIntList& theModes, + const bool theUpdateViewer) const { Handle(AIS_InteractiveContext) aContext = AISContext(); if (aContext.IsNull() || theIO.IsNull()) - return; - + return false; + + bool isActivationChanged = false; // deactivate object in all modes, which are not in the list of activation // It seems that after the IO deactivation the selected state of the IO's owners // is modified in OCC(version: 6.8.0) and the selection of the object later is lost. @@ -766,48 +1091,51 @@ void XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO, aContext->ActivatedModes(theIO, aTColModes); TColStd_ListIteratorOfListOfInteger itr( aTColModes ); QIntList aModesActivatedForIO; + bool isDeactivated = false; 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); + deactivateAIS(theIO, aMode); + isDeactivated = true; } else { aModesActivatedForIO.append(aMode); -#ifdef DEBUG_ACTIVATE - qDebug(QString(" active: %1").arg(aMode).toStdString().c_str()); -#endif } } + if (isDeactivated) { + // the selection from the previous activation modes should be cleared manually (#26172) + theIO->ClearSelected(); + aContext->LocalContext()->ClearOutdatedSelection(theIO, true); + // For performance issues + //if (theUpdateViewer) + // updateViewer(); + isActivationChanged = true; + } + // loading the interactive object allowing the decomposition - if (aTColModes.IsEmpty()) + 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 + // trihedron AIS check should be after the AIS loading. + // If it is not loaded, it is steel selectable in the viewer. + Handle(AIS_Trihedron) aTrihedron; + if (!isTrihedronActive()) + aTrihedron = Handle(AIS_Trihedron)::DownCast(theIO); if (aTrihedron.IsNull()) { - //aContext->Load(anAISIO, -1, true); - // In order to clear active modes list + // 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 + activateAIS(theIO, 0, theUpdateViewer); } 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 + activateAIS(theIO, aMode, theUpdateViewer); + isActivationChanged = true; } } } } + return isActivationChanged; } bool XGUI_Displayer::customizeObject(ObjectPtr theObject) @@ -825,17 +1153,18 @@ bool XGUI_Displayer::customizeObject(ObjectPtr theObject) 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; + // we ignore presentable not customized objects + if (aPrs.get() == NULL) + aCustomPrs = myCustomPrs; } - return aCustomPrs->customisePresentation(aResult, anAISObj, myCustomPrs); + bool isCustomized = aCustomPrs.get() && + aCustomPrs->customisePresentation(aResult, anAISObj, myCustomPrs); + return isCustomized; } -QColor XGUI_Displayer::setObjectColor(ObjectPtr theObject, const QColor& theColor, bool toUpdate) +QColor XGUI_Displayer::setObjectColor(ObjectPtr theObject, const QColor& theColor, bool theUpdateViewer) { if (!isVisible(theObject)) return Qt::black; @@ -844,7 +1173,85 @@ QColor XGUI_Displayer::setObjectColor(ObjectPtr theObject, const QColor& theColo int aR, aG, aB; anAISObj->getColor(aR, aG, aB); anAISObj->setColor(theColor.red(), theColor.green(), theColor.blue()); - if (toUpdate) + if (theUpdateViewer) updateViewer(); return QColor(aR, aG, aB); } + +void XGUI_Displayer::appendResultObject(ObjectPtr theObject, AISObjectPtr theAIS) +{ + myResult2AISObjectMap[theObject] = theAIS; + +#ifdef DEBUG_DISPLAY + std::ostringstream aPtrStr; + aPtrStr << theObject.get(); + qDebug(QString("display object: %1").arg(aPtrStr.str().c_str()).toStdString().c_str()); + qDebug(getResult2AISObjectMapInfo().c_str()); +#endif +} + +std::string XGUI_Displayer::getResult2AISObjectMapInfo() const +{ + QStringList aContent; + foreach (ObjectPtr aObj, myResult2AISObjectMap.keys()) { + AISObjectPtr aAISObj = myResult2AISObjectMap[aObj]; + std::ostringstream aPtrStr; + aPtrStr << "aObj = " << aObj.get() << ":"; + aPtrStr << "anAIS = " << aAISObj.get() << ":"; + aPtrStr << "[" << ModuleBase_Tools::objectInfo(aObj).toStdString().c_str() << "]"; + + aContent.append(aPtrStr.str().c_str()); + } + return QString("myResult2AISObjectMap: size = %1\n%2\n").arg(myResult2AISObjectMap.size()). + arg(aContent.join("\n")).toStdString().c_str(); +} + +void XGUI_Displayer::activateTrihedron(bool theIsActive) +{ + myIsTrihedronActive = theIsActive; + if (!myIsTrihedronActive) { + deactivateTrihedron(true); + } +} + +void XGUI_Displayer::displayTrihedron(bool theToDisplay) const +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull()) + return; + + Handle(AIS_Trihedron) aTrihedron = myWorkshop->viewer()->trihedron(); + + if (theToDisplay) { + if (!aContext->IsDisplayed(aTrihedron)) + aContext->Display(aTrihedron, + 0 /*wireframe*/, + -1 /* selection mode */, + Standard_True /* update viewer*/, + Standard_False /* allow decomposition */, + AIS_DS_Displayed /* xdisplay status */); + + if (!isTrihedronActive()) + deactivateTrihedron(false); + else + activate(aTrihedron, myActiveSelectionModes, false); + } else { + deactivateTrihedron(false); + //aContext->LocalContext()->ClearOutdatedSelection(aTrihedron, true); + // the selection from the previous activation modes should be cleared manually (#26172) + + aContext->Erase(aTrihedron); + } + + updateViewer(); +} + +QIntList XGUI_Displayer::activeSelectionModes() const +{ + QIntList aModes; + foreach (int aMode, myActiveSelectionModes) { + // aMode < 9 is a Shape Enum values + aModes << ((aMode < 9)? AIS_Shape::SelectionType(aMode) : aMode); + } + return aModes; +}