X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FXGUI%2FXGUI_Displayer.cpp;h=24e7b9eb6f740d8dce04b28d42172ace6b21faea;hb=9baaa9343a9d1c026a6467ec2a864c2c317ab91b;hp=2c24b774aac73afaf0a3bd47a1ae06e540e3084c;hpb=ed4a3feb663344c4a785133c5f025a2687192c6d;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 2c24b774a..24e7b9eb6 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -25,11 +25,15 @@ #include #include #include +#include +#include #include #include #include +#include + #include #include #include @@ -41,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -71,6 +76,11 @@ const int MOUSE_SENSITIVITY_IN_PIXEL = 10; ///< defines the local context mouse //#define DEBUG_COMPOSILID_DISPLAY // Workaround for bug #25637 + +//#define DEBUG_OCCT_SHAPE_SELECTION + +//#define WORKAROUND_UNTIL_27523_IS_FIXED + void displayedObjects(const Handle(AIS_InteractiveContext)& theAIS, AIS_ListOfInteractive& theList) { // Get from null point @@ -103,11 +113,10 @@ QString qIntListInfo(const QIntList& theValues, const QString& theSeparator = QS } XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop) - : myWorkshop(theWorkshop), myEnableUpdateViewer(true), myNeedUpdate(false), - myIsTrihedronActive(false) + : myWorkshop(theWorkshop), myNeedUpdate(false), + myIsTrihedronActive(true), myViewerBlockedRecursiveCount(0) { - enableUpdateViewer(true); - myCustomPrs = std::shared_ptr(new XGUI_CustomPrs()); + myCustomPrs = std::shared_ptr(new XGUI_CustomPrs(theWorkshop)); } XGUI_Displayer::~XGUI_Displayer() @@ -143,6 +152,18 @@ bool XGUI_Displayer::display(ObjectPtr theObject, bool theUpdateViewer) bool isShading = false; if (aPrs.get() != NULL) { anAIS = aPrs->getAISObject(anAIS); + if (anAIS.get()) { + // correct deviation coefficient for + /*Handle(AIS_InteractiveObject) anAISPrs = anAIS->impl(); + if (!anAISPrs.IsNull()) { + Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(anAISPrs); + if (!aShapePrs.IsNull()) { + TopoDS_Shape aShape = aShapePrs->Shape(); + if (!aShape.IsNull()) + //ModuleBase_Tools::setDefaultDeviationCoefficient(aShape, anAISPrs->Attributes()); + } + }*/ + } } else { ResultPtr aResult = std::dynamic_pointer_cast(theObject); if (aResult.get() != NULL) { @@ -162,7 +183,15 @@ bool XGUI_Displayer::display(ObjectPtr theObject, bool theUpdateViewer) 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); + else { + Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(anAISPrs); + if (!aShapePrs.IsNull()) + ModuleBase_Tools::setPointBallHighlighting((AIS_Shape*) aShapePrs.Access()); + } + anAIS->setImpl(new Handle(AIS_InteractiveObject)(anAISPrs)); //anAIS->createShape(aShapePtr); isShading = true; } @@ -177,7 +206,7 @@ bool XGUI_Displayer::display(ObjectPtr theObject, bool 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()) { @@ -189,10 +218,7 @@ bool canBeShaded(Handle(AIS_InteractiveObject) theAIS) 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; @@ -222,15 +248,6 @@ bool XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS, 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); - } - } } if (theUpdateViewer) updateViewer(); @@ -253,7 +270,8 @@ bool XGUI_Displayer::erase(ObjectPtr theObject, const bool theUpdateViewer) Handle(AIS_InteractiveObject) anAIS = anObject->impl(); if (!anAIS.IsNull()) { emit beforeObjectErase(theObject, anObject); - aContext->Remove(anAIS, theUpdateViewer); + aContext->Remove(anAIS, false/*update viewer*/); + ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::erase -- Remove"); aErased = true; } } @@ -265,6 +283,10 @@ bool XGUI_Displayer::erase(ObjectPtr theObject, const bool theUpdateViewer) qDebug(QString("erase object: %1").arg(aPtrStr.str().c_str()).toStdString().c_str()); qDebug(getResult2AISObjectMapInfo().c_str()); #endif + + if (theUpdateViewer) + updateViewer(); + return aErased; } @@ -319,7 +341,28 @@ bool XGUI_Displayer::redisplay(ObjectPtr theObject, bool theUpdateViewer) 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(); + +#ifdef WORKAROUND_UNTIL_27523_IS_FIXED + if (!myActiveSelectionModes.contains(0)) + aContext->Activate(aAISIO, 0); +#endif + aContext->Redisplay(aAISIO, false); + +#ifdef WORKAROUND_UNTIL_27523_IS_FIXED + if (!myActiveSelectionModes.contains(0)) + aContext->Deactivate(aAISIO, 0); +#endif + + ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::redisplay -- Redisplay"); + + if (aNeedToRestoreSelection) + myWorkshop->module()->restoreSelection(); + aRedisplayed = true; #ifdef DEBUG_FEATURE_REDISPLAY qDebug(" Redisplay happens"); @@ -361,6 +404,7 @@ void XGUI_Displayer::deactivate(ObjectPtr theObject, const bool theUpdateViewer) deactivateAIS(anAIS); // the selection from the previous activation modes should be cleared manually (#26172) aContext->LocalContext()->ClearOutdatedSelection(anAIS, true); + ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::deactivate -- ClearOutdatedSelection"); if (theUpdateViewer) updateViewer(); } @@ -403,10 +447,79 @@ void XGUI_Displayer::getModesOfActivation(ObjectPtr theObject, QIntList& theMode int XGUI_Displayer::getSelectionMode(int theShapeType) { - return (theShapeType >= TopAbs_SHAPE)? theShapeType : - AIS_Shape::SelectionMode((TopAbs_ShapeEnum)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; + } + } + } + // it is possible that feature is presentable and has results, so we should check visibility + // of results if presentation is not shown (e.g. Sketch Circle/Arc features) + if (!aVisible) { + // check if all results of the feature are visible + FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); + std::list aResults; + ModelAPI_Tools::allResults(aFeature, aResults); + std::list::const_iterator aIt; + aVisible = !aResults.empty(); + for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { + aVisible = aVisible && theDisplayer->isVisible(*aIt); + } + } + return aVisible; +} + +#ifdef DEBUG_ACTIVATE_OBJECTS +QString getModeInfo(const int theMode) +{ + QString anInfo = "Undefined"; + switch(theMode) { + case 0: anInfo = "SHAPE(0)"; break; + case 1: anInfo = "VERTEX(1)"; break; + case 2: anInfo = "EDGE(2)"; break; + case 3: anInfo = "WIRE(3)"; break; + case 4: anInfo = "FACE(4)"; break; + case 5: anInfo = "SHELL(5)"; break; + case 6: anInfo = "SOLID(6)"; break; + case 7: anInfo = "COMPSOLID(7)"; break; + case 8: anInfo = "COMPOUND(8)"; break; + case 100: anInfo = "Sel_Mode_First(100)"; break; //SketcherPrs_Tools + case 101: anInfo = "Sel_Constraint(101)"; break; + case 102: anInfo = "Sel_Dimension_All(102)"; break; + case 103: anInfo = "Sel_Dimension_Line(103)"; break; + case 104: anInfo = "Sel_Dimension_Text(104)"; break; + default: break; + } + return anInfo; +} + +QString getModesInfo(const QIntList& theModes) +{ + QStringList aModesInfo; + for (int i = 0, aSize = theModes.size(); i < aSize; i++) + aModesInfo.append(getModeInfo(theModes[i])); + return QString("[%1] = %2").arg(aModesInfo.size()).arg(aModesInfo.join(", ")); +} +#endif + void XGUI_Displayer::activateObjects(const QIntList& theModes, const QObjectPtrList& theObjList, const bool theUpdateViewer) { @@ -424,9 +537,10 @@ void XGUI_Displayer::activateObjects(const QIntList& theModes, const QObjectPtrL } 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)). + qDebug(QString("activateObjects: new modes%1, active modes%2, objects[%3] = %4"). + arg(getModesInfo(aModes)). + arg(getModesInfo(myActiveSelectionModes)). + arg(theObjList.size()). arg(anInfoStr). toStdString().c_str()); #endif @@ -473,13 +587,6 @@ void XGUI_Displayer::activateObjects(const QIntList& theModes, const QObjectPtrL 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 @@ -495,20 +602,38 @@ bool XGUI_Displayer::isActive(ObjectPtr theObject) const aContext->ActivatedModes(anAIS, aModes); return aModes.Extent() > 0; } -void XGUI_Displayer::setSelected(const QList& theValues, bool theUpdateViewer) + + +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 (ModuleBase_ViewerPrs aPrs, theValues) { - const TopoDS_Shape& aShape = aPrs.shape(); - if (!aShape.IsNull()) { + aContext->UnhilightSelected(false); + aContext->ClearSelected(false); + NCollection_DataMap> aShapesToBeSelected; + + foreach (ModuleBase_ViewerPrsPtr aPrs, theValues) { + const GeomShapePtr& aGeomShape = aPrs->shape(); + if (aGeomShape.get() && !aGeomShape->isNull()) { + const TopoDS_Shape& aShape = aGeomShape->impl(); +#ifdef DEBUG_OCCT_SHAPE_SELECTION + // problem 1: performance + // problem 2: IO is not specified, so the first found owner is selected, as a result + // it might belong to another result aContext->AddOrRemoveSelected(aShape, false); +#else + NCollection_Map aPresentations; + if (aShapesToBeSelected.IsBound(aShape)) + aPresentations = aShapesToBeSelected.Find(aShape); + ObjectPtr anObject = aPrs->object(); + getPresentations(anObject, aPresentations); + + aShapesToBeSelected.Bind(aShape, aPresentations); +#endif } else { - ObjectPtr anObject = aPrs.object(); + ObjectPtr anObject = aPrs->object(); ResultPtr aResult = std::dynamic_pointer_cast(anObject); if (aResult.get() && isVisible(aResult)) { AISObjectPtr anObj = myResult2AISObjectMap[aResult]; @@ -524,11 +649,13 @@ void XGUI_Displayer::setSelected(const QList& theValues, } } } - } else { - aContext->UnhilightCurrents(); - aContext->ClearCurrents(); - foreach (ModuleBase_ViewerPrs aPrs, theValues) { - ObjectPtr anObject = aPrs.object(); + if (!aShapesToBeSelected.IsEmpty()) + XGUI_Displayer::AddOrRemoveSelectedShapes(aContext, aShapesToBeSelected); + } else { // it seems the next code is obsolete as the context is always opened in SHAPER + 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]; @@ -538,16 +665,17 @@ void XGUI_Displayer::setSelected(const QList& theValues, } } } + ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::setSelected -- AddOrRemoveSelected/UnhilightCurrents(no local context)"); if (theUpdateViewer) updateViewer(); } -void XGUI_Displayer::clearSelected() +void XGUI_Displayer::clearSelected(const bool theUpdateViewer) { Handle(AIS_InteractiveContext) aContext = AISContext(); if (!aContext.IsNull()) { aContext->UnhilightCurrents(false); - aContext->ClearSelected(); + aContext->ClearSelected(theUpdateViewer); } } @@ -562,13 +690,14 @@ bool XGUI_Displayer::eraseAll(const bool theUpdateViewer) 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 (theUpdateViewer) updateViewer(); } + ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::eraseAll -- Remove"); myResult2AISObjectMap.clear(); #ifdef DEBUG_DISPLAY qDebug("eraseAll"); @@ -583,6 +712,7 @@ void deactivateObject(Handle(AIS_InteractiveContext) theContext, { if (!theObject.IsNull()) { theContext->Deactivate(theObject); + ModuleBase_Tools::selectionInfo(theContext, "XGUI_Displayer::deactivateObject -- Deactivate"); //if (theClear) { //theObject->ClearSelected(); // theContext->LocalContext()->ClearOutdatedSelection(theObject, true); @@ -744,20 +874,28 @@ ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) bool XGUI_Displayer::enableUpdateViewer(const bool isEnabled) { - bool aWasEnabled = myEnableUpdateViewer; + bool aWasEnabled = isUpdateEnabled(); + if (isEnabled) + myViewerBlockedRecursiveCount--; + else + myViewerBlockedRecursiveCount++; - myEnableUpdateViewer = isEnabled; - if (myNeedUpdate && myEnableUpdateViewer) { + if (myNeedUpdate && isUpdateEnabled()) { updateViewer(); myNeedUpdate = false; } return aWasEnabled; } +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 { @@ -769,14 +907,37 @@ void XGUI_Displayer::activateAIS(const Handle(AIS_InteractiveObject)& theIO, const int theMode, const bool theUpdateViewer) const { Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); + if (!theIO.IsNull() && theIO == getTrihedron()) { + if (theMode != AIS_Shape::SelectionType(TopAbs_EDGE) && + theMode != AIS_Shape::SelectionType(TopAbs_VERTEX)) + return; + } if (!aContext.IsNull()) { - aContext->Activate(theIO, theMode, theUpdateViewer); + if (myWorkshop->module()) { + int aMode = (theMode > 8)? theMode : AIS_Shape::SelectionType(theMode); + aContext->Activate(theIO, theMode, false); + } else + aContext->Activate(theIO, theMode, false); + + // the fix from VPA for more suitable selection of sketcher lines + if (theIO->Width() > 1) { + double aPrecision = theIO->Width() + 2; + if (theMode == getSelectionMode(TopAbs_VERTEX)) + aPrecision = ModuleBase_Preferences::resourceMgr()->doubleValue("Viewer", "point-selection-sensitivity", 20); + else if ((theMode == getSelectionMode(TopAbs_EDGE)) || (theMode == getSelectionMode(TopAbs_WIRE))) + aPrecision = theIO->Width() + + ModuleBase_Preferences::resourceMgr()->doubleValue("Viewer", "edge-selection-sensitivity", 2); + aContext->SetSelectionSensitivity(theIO, theMode, aPrecision); + } + ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::activateAIS -- Activate"); #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(); } } @@ -786,9 +947,10 @@ void XGUI_Displayer::deactivateAIS(const Handle(AIS_InteractiveObject)& theIO, c if (!aContext.IsNull()) { if (theMode == -1) aContext->Deactivate(theIO); - else + else aContext->Deactivate(theIO, theMode); - + ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::deactivateAIS -- Deactivate"); + #ifdef DEBUG_DEACTIVATE_AIS ObjectPtr anObject = getObject(theIO); anInfo.append(ModuleBase_Tools::objectInfo((*anIt))); @@ -827,7 +989,7 @@ bool XGUI_Displayer::displayAIS(AISObjectPtr theAIS, const bool toActivateInSele Handle(AIS_InteractiveContext) aContext = AISContext(); Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); if (!aContext.IsNull() && !anAISIO.IsNull()) { - aContext->Display(anAISIO, 0/*wireframe*/, 0, theUpdateViewer, true, AIS_DS_Displayed); + aContext->Display(anAISIO, 0/*wireframe*/, 0, false/*update viewer*/, true, AIS_DS_Displayed); aDisplayed = true; aContext->Deactivate(anAISIO); aContext->Load(anAISIO); @@ -842,6 +1004,8 @@ bool XGUI_Displayer::displayAIS(AISObjectPtr theAIS, const bool toActivateInSele } } } + if (theUpdateViewer) + updateViewer(); } return aDisplayed; } @@ -853,10 +1017,13 @@ bool XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool theUpdateViewer) if (!aContext.IsNull()) { Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); if (!anAISIO.IsNull() && aContext->IsDisplayed(anAISIO)) { - aContext->Remove(anAISIO, theUpdateViewer); + aContext->Remove(anAISIO, false/*update viewer*/); + ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::eraseAIS -- Remove"); aErased = true; } } + if (aErased && theUpdateViewer) + updateViewer(); return aErased; } @@ -1005,7 +1172,7 @@ bool XGUI_Displayer::canBeShaded(ObjectPtr theObject) const return false; Handle(AIS_InteractiveObject) anAIS = aAISObj->impl(); - return ::canBeShaded(anAIS); + return ::canBeShaded(anAIS, myWorkshop->module()); } bool XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO, @@ -1033,6 +1200,7 @@ bool XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO, bool isDeactivated = false; for (; itr.More(); itr.Next() ) { Standard_Integer aMode = itr.Value(); + int aShapeMode = (aMode > 8)? aMode : AIS_Shape::SelectionType(aMode); if (!theModes.contains(aMode)) { deactivateAIS(theIO, aMode); isDeactivated = true; @@ -1045,6 +1213,7 @@ bool XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO, // the selection from the previous activation modes should be cleared manually (#26172) theIO->ClearSelected(); aContext->LocalContext()->ClearOutdatedSelection(theIO, true); + ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::activate -- ClearSelected/ClearOutdatedSelection"); // For performance issues //if (theUpdateViewer) // updateViewer(); @@ -1145,6 +1314,42 @@ std::string XGUI_Displayer::getResult2AISObjectMapInfo() const arg(aContent.join("\n")).toStdString().c_str(); } +void XGUI_Displayer::getPresentations(const ObjectPtr& theObject, + NCollection_Map& thePresentations) +{ + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + if (aResult.get()) { + AISObjectPtr aAISObj = getAISObject(aResult); + if (aAISObj.get() != NULL) { + Handle(AIS_InteractiveObject) anAIS = aAISObj->impl(); + if (!anAIS.IsNull() && !thePresentations.Contains(anAIS)) + thePresentations.Add(anAIS); + } + } + else { + FeaturePtr aFeature = std::dynamic_pointer_cast(theObject); + // find presentation of the feature + AISObjectPtr aAISObj = getAISObject(aFeature); + if (aAISObj.get() != NULL) { + Handle(AIS_InteractiveObject) anAIS = aAISObj->impl(); + if (!anAIS.IsNull() && !thePresentations.Contains(anAIS)) + thePresentations.Add(anAIS); + } + // find presentations of the feature results + std::list aResults; + ModelAPI_Tools::allResults(aFeature, aResults); + std::list::const_iterator anIt = aResults.begin(), aLast = aResults.end(); + for (; anIt != aLast; ++anIt) { + AISObjectPtr aAISObj = getAISObject(*anIt); + if (aAISObj.get() != NULL) { + Handle(AIS_InteractiveObject) anAIS = aAISObj->impl(); + if (!anAIS.IsNull() && !thePresentations.Contains(anAIS)) + thePresentations.Add(anAIS); + } + } + } +} + void XGUI_Displayer::activateTrihedron(bool theIsActive) { myIsTrihedronActive = theIsActive; @@ -1184,3 +1389,56 @@ void XGUI_Displayer::displayTrihedron(bool theToDisplay) const 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; +} + +void XGUI_Displayer::AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) theContext, + const NCollection_DataMap>& theShapesToBeSelected) +{ + Handle(AIS_LocalContext) aLContext = theContext->LocalContext(); + TCollection_AsciiString aSelectionName = aLContext->SelectionName(); + aLContext->UnhilightPicked(Standard_False); + + NCollection_List anActiveOwners; + aLContext->MainSelector()->ActiveOwners(anActiveOwners); + NCollection_List::Iterator anOwnersIt (anActiveOwners); + Handle(SelectMgr_EntityOwner) anOwner; + + /// It is very important to check that the owner is processed only once and has a map of + /// processed owners because SetSelected works as a switch. + /// If count of calls setSelectec is even, the object stays in the previous state + /// (selected, deselected) + /// OCCT: to write about the problem that active owners method returns one owner several times + QList aSelectedIds; // Remember of selected address in order to avoid duplicates + for (; anOwnersIt.More(); anOwnersIt.Next()) { + anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value()); + if (aSelectedIds.contains((long)anOwner.Access())) + continue; + aSelectedIds.append((long)anOwner.Access()); + + Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(anOwner); + if (!BROwnr.IsNull() && BROwnr->HasShape()) { + const TopoDS_Shape& aShape = BROwnr->Shape(); + if (!aShape.IsNull() && theShapesToBeSelected.IsBound(aShape)) { + Handle(AIS_InteractiveObject) anOwnerPresentation = + Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable()); + NCollection_Map aPresentations = + theShapesToBeSelected.Find(aShape); + if (aPresentations.Contains(anOwnerPresentation)) { + AIS_Selection::Selection(aSelectionName.ToCString())->Select(anOwner); + anOwner->SetSelected (Standard_True); + } + } + } + } + aLContext->HilightPicked(Standard_False); +}