X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_Displayer.cpp;h=ccad93e0e2325f4d0a776c4c8a9044ebb5b3af85;hb=8d04b5f4360b23cf376beff9c5e7c12d0e6a5f1e;hp=c30e93d56f11d84742e596fcf9566716b6674fa2;hpb=a90ab0e7171b2dfab838fbc066c2f20217c49c03;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index c30e93d56..ccad93e0e 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -1,234 +1,313 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> - -// File: XGUI_Displayer.cpp -// Created: 20 Apr 2014 -// Author: Natalia ERMOLAEVA +// Copyright (C) 2014-2019 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #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 "XGUI_FacesPanel.h" +#include "XGUI_Selection.h" +#include "XGUI_SelectionActivate.h" +#include "XGUI_SelectionMgr.h" +#include "XGUI_ViewerProxy.h" +#include "XGUI_Workshop.h" +#ifndef HAVE_SALOME #include +#endif #include #include #include #include #include +#include +#include +#include +#include +#include #include +#include +#include +#include #include #include #include +#include +#include + +#include #include -#include #include #include #include #include #include -#include +#include +#ifdef BEFORE_TRIHEDRON_PATCH +#include +#include +#include +#endif +#include +#include +#include #include #include +#include +#include + +#include #include #include +#ifdef TINSPECTOR +#include +#endif + +#include +#include +#include + #include -const int MOUSE_SENSITIVITY_IN_PIXEL = 10; ///< defines the local context mouse selection sensitivity +/// defines the local context mouse selection sensitivity +const int MOUSE_SENSITIVITY_IN_PIXEL = 10; //#define DEBUG_DISPLAY -//#define DEBUG_ACTIVATE //#define DEBUG_FEATURE_REDISPLAY //#define DEBUG_SELECTION_FILTERS -// Workaround for bug #25637 +//#define DEBUG_OCCT_SHAPE_SELECTION + +#define CLEAR_OUTDATED_SELECTION_BEFORE_REDISPLAY + +//#define DEBUG_VIEWER_BLOCKED_COUNT + +//************************************************************** void displayedObjects(const Handle(AIS_InteractiveContext)& theAIS, AIS_ListOfInteractive& theList) { // Get from null point theAIS->DisplayedObjects(theList, true); - if (theAIS->HasOpenedContext()) { - // get from local context - const Handle(AIS_LocalContext)& aLC = theAIS->LocalContext(); - TColStd_MapOfTransient aMap; - int NbDisp = aLC->DisplayedObjects(aMap); - TColStd_MapIteratorOfMapOfTransient aIt(aMap); - - Handle(AIS_InteractiveObject) curIO; - Handle(Standard_Transient) Tr; - for(; aIt.More(); aIt.Next()){ - Tr = aIt.Key(); - curIO = *((Handle(AIS_InteractiveObject)*) &Tr); - theList.Append(curIO); - } - } } +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), + myViewerBlockedRecursiveCount(0), myIsFirstAISContextUse(true) { - enableUpdateViewer(true); - myCustomPrs = std::shared_ptr(new XGUI_CustomPrs()); + myCustomPrs = std::shared_ptr(new XGUI_CustomPrs(theWorkshop)); } +//************************************************************** XGUI_Displayer::~XGUI_Displayer() { } +//************************************************************** 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); + aDisplayed = redisplay(theObject, theUpdateViewer); } 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) { + GeomScreenParamsPtr aScreen = std::dynamic_pointer_cast(theObject); + if (aScreen.get()) { + aScreen->setScreenPlane(getScreenPlane()); + aScreen->setViewScale(getViewScale()); + } anAIS = aPrs->getAISObject(anAIS); } else { - ResultPtr aResult = std::dynamic_pointer_cast(theObject); - if (aResult.get() != NULL) { - 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))); - //anAIS->createShape(aShapePtr); - isShading = true; + Handle(AIS_InteractiveObject) anAISPrs = + myWorkshop->module()->createPresentation(theObject); + if (anAISPrs.IsNull()) { + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + if (aResult.get() != NULL) { + std::shared_ptr aShapePtr = ModelAPI_Tools::shape(aResult); + if (aShapePtr.get() != NULL) { + anAISPrs = new ModuleBase_ResultPrs(aResult); + } } } + Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(anAISPrs); + if (!aShapePrs.IsNull()) + ModuleBase_Tools::setPointBallHighlighting((AIS_Shape*)aShapePrs.get()); + anAIS = AISObjectPtr(new GeomAPI_AISObject()); + anAIS->setImpl(new Handle(AIS_InteractiveObject)(anAISPrs)); + isShading = true; } 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); - } - else - activate(anAISIO, myActiveSelectionModes); - } - if (isUpdateViewer) + 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); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Display(anAISIO); + #endif + aDisplayed = true; + + emit objectDisplayed(theObject, theAIS); + selectionActivate()->activate(anAISIO, theUpdateViewer); + } + 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; - AISObjectPtr anObject = myResult2AISObjectMap[theObject]; + return aErased; + + AISObjectPtr anObject = myResult2AISObjectMap.value(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*/); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Remove(anAIS); + #endif + 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(); GeomPresentablePtr aPrs = std::dynamic_pointer_cast(theObject); if (aPrs) { + GeomScreenParamsPtr aScreen = std::dynamic_pointer_cast(theObject); + if (aScreen.get()) { + aScreen->setScreenPlane(getScreenPlane()); + aScreen->setViewScale(getViewScale()); + } 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; + erase(theObject, theUpdateViewer); + 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 + // 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 @@ -240,417 +319,413 @@ 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()); + qDebug(QString("Redisplay: %1, isEqualShapes=%2, isCustomized=%3"). + arg(!isEqualShapes || isCustomized).arg(isEqualShapes) + .arg(isCustomized).toStdString().c_str()); #endif if (!isEqualShapes || isCustomized) { - aContext->Redisplay(aAISIO, false); - #ifdef DEBUG_FEATURE_REDISPLAY - //qDebug(" Redisplay happens"); - #endif - if (isUpdateViewer) - updateViewer(); - } - } -} - -void XGUI_Displayer::deactivate(ObjectPtr theObject) -{ - 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); - } -} + /// if shapes are equal and presentation are customized, selection should be restored + bool aNeedToRestoreSelection = isEqualShapes && isCustomized; + if (aNeedToRestoreSelection) + myWorkshop->module()->storeSelection(); -/*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()); - } +#ifdef CLEAR_OUTDATED_SELECTION_BEFORE_REDISPLAY + myWorkshop->selector()->deselectPresentation(aAISIO); #endif + if (aContext->IsDisplayed(aAISIO)) + aContext->Redisplay(aAISIO, false); + else + aContext->Display(aAISIO, false); - if (isVisible(theObject)) { - Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull()) - return; - - AISObjectPtr anObj = myResult2AISObjectMap[theObject]; - Handle(AIS_InteractiveObject) anAIS = anObj->impl(); - - activate(anAIS, theModes); - } -}*/ - -void XGUI_Displayer::getModesOfActivation(ObjectPtr theObject, QIntList& theModes) -{ - if (!isVisible(theObject)) - return; - - Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull()) - return; + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Redisplay(aAISIO); + #endif - AISObjectPtr aAISObj = getAISObject(theObject); + if (aNeedToRestoreSelection) + myWorkshop->module()->restoreSelection(); - 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()); + aRedisplayed = true; + #ifdef DEBUG_FEATURE_REDISPLAY + qDebug(" Redisplay happens"); + #endif + if (theUpdateViewer) + updateViewer(); } } + return aRedisplayed; } -void XGUI_Displayer::activateObjects(const QIntList& theModes) +//************************************************************** +void XGUI_Displayer::redisplayObjects() { -#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) { - if (!aNewModes.contains(aMode)) - aNewModes.append(aMode); + // 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 = displayedObjects(); + QObjectPtrList::const_iterator anIt = aDisplayed.begin(), aLast = aDisplayed.end(); + for (; anIt != aLast; anIt++) { + aECreator->sendUpdated(*anIt, EVENT_DISP); } - myActiveSelectionModes = aNewModes; - Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull()) - return; - // Open local context if there is no one - if (!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); + XGUI_ViewerProxy* aViewer = myWorkshop->viewer(); + if (aViewer->isColorScaleVisible()) { + aViewer->setupColorScale(); + aViewer->setColorScaleShown(true); } + Events_Loop::loop()->flush(EVENT_DISP); } - -void XGUI_Displayer::deactivateObjects() +//************************************************************** +void XGUI_Displayer::deactivateObjects(const QObjectPtrList& theObjList, + const bool theUpdateViewer) { - myActiveSelectionModes.clear(); - Handle(AIS_InteractiveContext) aContext = AISContext(); - // Open local context if there is no one - if (!aContext->HasOpenedContext()) - return; - - //aContext->NotUseDisplayedObjects(); - AIS_ListOfInteractive aPrsList; - ::displayedObjects(aContext, aPrsList); + //Handle(AIS_InteractiveObject) aTrihedron = getTrihedron(); + //if (!aTrihedron.IsNull()) + // deactivateAIS(aTrihedron); - AIS_ListIteratorOfListOfInteractive aLIt; - //Handle(AIS_Trihedron) aTrihedron; - Handle(AIS_InteractiveObject) anAISIO; - for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()){ - anAISIO = aLIt.Value(); - aContext->Deactivate(anAISIO); + QObjectPtrList::const_iterator anIt = theObjList.begin(), aLast = theObjList.end(); + for (; anIt != aLast; anIt++) { + selectionActivate()->deactivate(*anIt, false); } + //VSV It seems that there is no necessity to update viewer on deactivation + //if (theUpdateViewer) + // updateViewer(); } -bool XGUI_Displayer::isActive(ObjectPtr theObject) const +//************************************************************** +bool XGUI_Displayer::isVisible(XGUI_Displayer* theDisplayer, const ObjectPtr& theObject) { - Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull()) - return false; - if (!isVisible(theObject)) - return false; - - AISObjectPtr anObj = myResult2AISObjectMap[theObject]; - Handle(AIS_InteractiveObject) anAIS = anObj->impl(); - - TColStd_ListOfInteger aModes; - aContext->ActivatedModes(anAIS, aModes); - return aModes.Extent() > 0; + 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_ResultBody::group()) { + ResultBodyPtr aCompsolidResult = std::dynamic_pointer_cast(aResult); + if (aCompsolidResult.get() != NULL) { // change colors for all sub-solids + int aNumberOfSubs = aCompsolidResult->numberOfSubs(); + bool anAllSubsVisible = aNumberOfSubs > 0; + for(int i = 0; i < aNumberOfSubs && 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; } -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); - } - } - } else { - aContext->UnhilightCurrents(); - aContext->ClearCurrents(); - foreach(ObjectPtr aResult, theResults) { - if (isVisible(aResult)) { - AISObjectPtr anObj = myResult2AISObjectMap[aResult]; + aContext->UnhilightSelected(false); + aContext->ClearSelected(false); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->ClearSelected(); + #endif + 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); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->AddOrRemoveSelected(aShape); + #endif +#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(); + ResultPtr aResult = std::dynamic_pointer_cast(anObject); + if (aResult.get() && isVisible(aResult)) { + AISObjectPtr anObj = myResult2AISObjectMap.value(aResult); Handle(AIS_InteractiveObject) anAIS = anObj->impl(); - if (!anAIS.IsNull()) - aContext->SetCurrentObject(anAIS, false); + 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); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->AddOrRemoveSelected(anAIS); + #endif + } } } } - if (isUpdateViewer) + if (!aShapesToBeSelected.IsEmpty()) + XGUI_Displayer::AddOrRemoveSelectedShapes(aContext, aShapesToBeSelected); + + if (theUpdateViewer) updateViewer(); } - -void XGUI_Displayer::clearSelected() +//************************************************************** +void XGUI_Displayer::clearSelected(const bool theUpdateViewer) { Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext) { - aContext->UnhilightCurrents(false); - aContext->ClearSelected(); + if (!aContext.IsNull()) { + aContext->UnhilightSelected(false);//UnhilightCurrents(false); + aContext->ClearSelected(theUpdateViewer); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->ClearSelected(); + #endif } } -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()) { +#ifdef OPTIMIZE_PRS + foreach(ObjectPtr aObj, myResult2AISObjectMap.objects()) { + AISObjectPtr aAISObj = myResult2AISObjectMap.value(aObj); +#else + foreach(ObjectPtr aObj, myResult2AISObjectMap.keys()) { AISObjectPtr aAISObj = myResult2AISObjectMap[aObj]; +#endif // erase an object Handle(AIS_InteractiveObject) anIO = aAISObj->impl(); if (!anIO.IsNull()) { emit beforeObjectErase(aObj, aAISObj); - aContext->Remove(anIO, false); + aContext->Remove(anIO, false/*update viewer*/); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Remove(anIO); + #endif + aErased = true; } } - if (isUpdateViewer) + if (theUpdateViewer) updateViewer(); } myResult2AISObjectMap.clear(); +#ifdef DEBUG_DISPLAY + qDebug("eraseAll"); + qDebug(getResult2AISObjectMapInfo().c_str()); +#endif + return aErased; } -void XGUI_Displayer::openLocalContext() -{ - Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); - if (aContext.IsNull()) - return; - // Open local context if there is no one - if (!aContext->HasOpenedContext()) { - // Preserve selected objects - //AIS_ListOfInteractive aAisList; - //for (aContext->InitCurrent(); aContext->MoreCurrent(); aContext->NextCurrent()) - // aAisList.Append(aContext->Current()); - - // get the filters from the global context and append them to the local context - // a list of filters in the global context is not cleared and should be cleared here - SelectMgr_ListOfFilter aFilters; - aFilters.Assign(aContext->Filters()); - // it is important to remove the filters in the global context, because there is a code - // in the closeLocalContex, which restore the global context filters - aContext->RemoveFilters(); - - //aContext->ClearCurrents(); - aContext->OpenLocalContext(); - //aContext->NotUseDisplayedObjects(); - - //myUseExternalObjects = false; - - SelectMgr_ListIteratorOfListOfFilter aIt(aFilters); - for (;aIt.More(); aIt.Next()) { - aContext->AddFilter(aIt.Value()); - } - // Restore selection - //AIS_ListIteratorOfListOfInteractive aIt2(aAisList); - //for(; aIt2.More(); aIt2.Next()) { - // aContext->SetSelected(aIt2.Value(), false); - //} - } -} - -void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer) -{ - Handle(AIS_InteractiveContext) aContext = AISContext(); - if ( (!aContext.IsNull()) && (aContext->HasOpenedContext()) ) { - // Preserve selected objects - //AIS_ListOfInteractive aAisList; - //for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) - // aAisList.Append(aContext->SelectedInteractive()); - - // get the filters from the local context and append them to the global context - // a list of filters in the local context is cleared - SelectMgr_ListOfFilter aFilters; - aFilters.Assign(aContext->Filters()); - - //aContext->ClearSelected(); - aContext->CloseAllContexts(false); - - // Redisplay all object if they were displayed in localContext - 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); - for (;aIt.More(); aIt.Next()) { - Handle(SelectMgr_Filter) aFilter = aIt.Value(); - aContext->AddFilter(aFilter); - } - - if (isUpdateViewer) - updateViewer(); - //myUseExternalObjects = false; - - // Restore selection - //AIS_ListIteratorOfListOfInteractive aIt2(aAisList); - //for(; aIt2.More(); aIt2.Next()) { - // if (aContext->IsDisplayed(aIt2.Value())) - // aContext->SetCurrentObject(aIt2.Value(), false); - //} - } -} +//************************************************************** AISObjectPtr XGUI_Displayer::getAISObject(ObjectPtr theObject) const { +#ifdef OPTIMIZE_PRS + return myResult2AISObjectMap.value(theObject); +#else AISObjectPtr anIO; if (myResult2AISObjectMap.contains(theObject)) anIO = myResult2AISObjectMap[theObject]; return anIO; +#endif } +//************************************************************** ObjectPtr XGUI_Displayer::getObject(const AISObjectPtr& theIO) const { Handle(AIS_InteractiveObject) aRefAIS = theIO->impl(); return getObject(aRefAIS); } +//************************************************************** ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) const { - ObjectPtr aFeature; - foreach (ObjectPtr anObj, myResult2AISObjectMap.keys()) { - AISObjectPtr aAIS = myResult2AISObjectMap[anObj]; +#ifdef OPTIMIZE_PRS + ObjectPtr anObject = myResult2AISObjectMap.value(theIO); +#else + ObjectPtr anObject; + ResultToAISMap::const_iterator aMapIter = myResult2AISObjectMap.cbegin(); + for (; aMapIter != myResult2AISObjectMap.cend(); aMapIter++) { + const AISObjectPtr& aAIS = aMapIter.value(); Handle(AIS_InteractiveObject) anAIS = aAIS->impl(); if (anAIS == theIO) - return anObj; + anObject = aMapIter.key(); + if (anObject.get()) + break; } - return aFeature; +#endif + 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++; + +#ifdef DEBUG_VIEWER_BLOCKED_COUNT + std::cout << "myViewerBlockedRecursiveCount = " << myViewerBlockedRecursiveCount << std::endl; +#endif + if (myNeedUpdate && isUpdateEnabled()) { + updateViewer(); + myNeedUpdate = false; + } return aWasEnabled; } -void XGUI_Displayer::updateViewer() +//************************************************************** +void XGUI_Displayer::updateViewer() const { Handle(AIS_InteractiveContext) aContext = AISContext(); - if (!aContext.IsNull() && myEnableUpdateViewer) + +#ifdef DEBUG_VIEWER_BLOCKED_COUNT + std::cout << "updateViewer: " << (myViewerBlockedRecursiveCount == 0 ? " done" : " later") + << std::endl; +#endif + + if (!aContext.IsNull() && isUpdateEnabled()) { + //myWorkshop->viewer()->Zfitall(); aContext->UpdateCurrentViewer(); + } else { + myNeedUpdate = true; + } } +//************************************************************** Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const { Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); - if ((!aContext.IsNull()) && (!aContext->HasOpenedContext())) { - aContext->OpenLocalContext(); + if (!aContext.IsNull() && myIsFirstAISContextUse/*&& !aContext->HasOpenedContext()*/) { + XGUI_Displayer* aDisplayer = (XGUI_Displayer*)this; + aDisplayer->myIsFirstAISContextUse = false; + if (!myWorkshop->selectionActivate()->isTrihedronActive()) + selectionActivate()->deactivateTrihedron(true); + aContext->DefaultDrawer()->VIsoAspect()->SetNumber(0); + aContext->DefaultDrawer()->UIsoAspect()->SetNumber(0); + + ModuleBase_IViewer::DefaultHighlightDrawer = aContext->HighlightStyle(); + // Commented out according to discussion in bug #2825 + //Handle(Prs3d_Drawer) aSelStyle = aContext->SelectionStyle(); + //double aDeflection = + // QString(ModelAPI_ResultConstruction::DEFAULT_DEFLECTION().c_str()).toDouble(); + //try { + // aDeflection = Config_PropManager::real("Visualization", "construction_deflection"); + //} catch (...) {} + + //ModuleBase_IViewer::DefaultHighlightDrawer->SetDeviationCoefficient(aDeflection); + //aSelStyle->SetDeviationCoefficient(aDeflection); } return aContext; } +//************************************************************** 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, + const Standard_Integer theDisplayMode, 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 (myActiveSelectionModes.size() == 0) - aContext->Activate(anAISIO); - else { - foreach(int aMode, myActiveSelectionModes) { - aContext->Activate(anAISIO, aMode); - } - } - //} - } + if (!aContext.IsNull() && !anAISIO.IsNull()) { + aContext->Display(anAISIO, theDisplayMode, 0, false/*update viewer*/, true, AIS_DS_Displayed); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Display(anAISIO); + #endif + aDisplayed = true; + aContext->Deactivate(anAISIO); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Deactivate(anAISIO); + #endif + aContext->Load(anAISIO); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Load(anAISIO); + #endif + if (toActivateInSelectionModes) + myWorkshop->selectionActivate()->activateOnDisplay(anAISIO, 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*/); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Remove(anAISIO); + #endif + 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; @@ -664,23 +739,13 @@ 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(); } +//************************************************************** XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) const { Handle(AIS_InteractiveContext) aContext = AISContext(); @@ -695,55 +760,106 @@ XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) con return (XGUI_Displayer::DisplayMode) aAISIO->DisplayMode(); } +//************************************************************** +void XGUI_Displayer::deactivateSelectionFilters(const bool theAddFilterOnly) +{ + 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) aCompFilter = GetFilter(); - const SelectMgr_ListOfFilter& aStoredFilters = aCompFilter->StoredFilters(); - for (aIt.Initialize(aStoredFilters); aIt.More(); aIt.Next()) { - if (theFilter.Access() == aIt.Value().Access()) - return; - } - aCompFilter->Add(theFilter); + + Handle(SelectMgr_CompositionFilter) aCompositeFilter = GetFilter(); + if (!aCompositeFilter.IsNull()) { + aCompositeFilter->Add(theFilter); #ifdef DEBUG_SELECTION_FILTERS - int aCount = GetFilter()->StoredFilters().Extent(); - qDebug(QString("addSelectionFilter: filters.count() = %1").arg(aCount).toStdString().c_str()); + int aCount = aCompositeFilter->StoredFilters().Extent(); + qDebug(QString("addSelectionFilter: filters.count() = %1").arg(aCount).toStdString().c_str()); #endif + } } +//************************************************************** void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) { 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 = GetFilter()->StoredFilters().Extent(); - qDebug(QString("removeSelectionFilter: filters.count() = %1").arg(aCount).toStdString().c_str()); + 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.get() == aIt.Value().get()) + 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.get() == aIt.Value().get()) + aFilterFound = true; + } + } + return aFilterFound; +} + +//************************************************************** 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) { +#ifdef OPTIMIZE_PRS + QObjectPtrList aDispList = myResult2AISObjectMap.objects(); +#else QObjectPtrList aDispList = myResult2AISObjectMap.keys(); +#endif foreach(ObjectPtr aObj, aDispList) { if (!theList.contains(aObj)) erase(aObj, false); @@ -755,8 +871,9 @@ void XGUI_Displayer::showOnly(const QObjectPtrList& theList) updateViewer(); } +//************************************************************** bool XGUI_Displayer::canBeShaded(ObjectPtr theObject) const -{ +{ if (!isVisible(theObject)) return false; @@ -765,73 +882,10 @@ bool XGUI_Displayer::canBeShaded(ObjectPtr theObject) const 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 - // 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. - // By this reason, the number of the IO deactivate is decreased and the object is deactivated - // only if there is a difference in the current modes and the parameters modes. - // If the selection problem happens again, it is possible to write a test scenario and create - // a bug. The bug steps are the following: - // Create two IO, activate them in 5 modes, select the first IO, deactivate 3 modes for both, - // with clicked SHIFT select the second object. The result is the selection of the first IO is lost. - 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 - } - } - } - } + return ::canBeShaded(anAIS, myWorkshop->module()); } +//************************************************************** bool XGUI_Displayer::customizeObject(ObjectPtr theObject) { AISObjectPtr anAISObj = getAISObject(theObject); @@ -847,17 +901,27 @@ 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); + isCustomized = myWorkshop->module()->afterCustomisePresentation(aResult, anAISObj, myCustomPrs) + || isCustomized; + // update presentation state if faces panel is active + if (anAISObj.get() && myWorkshop->facesPanel()) + isCustomized = myWorkshop->facesPanel()->customizeObject(theObject, anAISObj) || isCustomized; + + 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; @@ -866,7 +930,257 @@ 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) +{ +#ifdef OPTIMIZE_PRS + myResult2AISObjectMap.add(theObject, theAIS); +#else + myResult2AISObjectMap[theObject] = theAIS; +#endif + +#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 +} + +#ifdef _DEBUG +//************************************************************** +std::string XGUI_Displayer::getResult2AISObjectMapInfo() const +{ + QStringList aContent; +#ifdef OPTIMIZE_PRS + foreach(ObjectPtr aObj, myResult2AISObjectMap.objects()) { + AISObjectPtr aAISObj = myResult2AISObjectMap.value(aObj); +#else + foreach(ObjectPtr aObj, myResult2AISObjectMap.keys()) { + AISObjectPtr aAISObj = myResult2AISObjectMap[aObj]; +#endif + 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(); +} +#endif + +//************************************************************** +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) { + // if result is a result of a composite feature, it is visualized by visualization of + // composite children, so we should get one of this presentations + ResultBodyPtr aCompSolid = std::dynamic_pointer_cast(aResult); + if (aCompSolid.get() && aCompSolid->numberOfSubs() > 0) { + aAISObj = getAISObject(aCompSolid->subResult(0)); + } + } + 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::displayTrihedron(bool theToDisplay) const +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull()) + return; + + Handle(AIS_Trihedron) aTrihedron = myWorkshop->viewer()->trihedron(); + + XGUI_SelectionActivate* aSelectionActive = selectionActivate(); + 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 */); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Display(aTrihedron); + #endif + + if (!aSelectionActive->isTrihedronActive()) + aSelectionActive->deactivateTrihedron(false); + else + aSelectionActive->activate(aTrihedron, false); + } else { + aSelectionActive->deactivateTrihedron(false); + + aContext->Erase(aTrihedron, Standard_True); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Remove(aTrihedron); + #endif + } +} + +//************************************************************** +void XGUI_Displayer::AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) theContext, + const NCollection_DataMap>& theShapesToBeSelected) +{ + NCollection_Map aCompsolidPresentations; + NCollection_Map aSelectedPresentations; + + NCollection_List anActiveOwners; + theContext->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((size_t)anOwner.get())) + continue; + aSelectedIds.append((size_t)anOwner.get()); + + Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(anOwner); + if (!BROwnr.IsNull() && BROwnr->HasShape()) { + const TopoDS_Shape& aShape = BROwnr->Shape(); + if (aShape.IsNull()) + continue; + + Handle(ModuleBase_BRepOwner) aCustomOwner = Handle(ModuleBase_BRepOwner)::DownCast(anOwner); + + NCollection_DataMap > + ::Iterator aShapeIt(theShapesToBeSelected); + for (; aShapeIt.More(); aShapeIt.Next()) { + const TopoDS_Shape& aParameterShape = aShapeIt.Key(); + // In case of compound we cannot rely on simple comparison method. + // If the compound is generated by Group feature then this compound is alwais new. + // So, we have to compare content of these compounds + + // isSame should be used here as it does not check orientation of shapes + // despite on isEqual of shapes or IsBound for shape in QMap. Orientation is + // different for Edges shapes in model shape and owner even if this is the same shape + if (ModuleBase_Tools::isSameShape(aParameterShape, aShape)) { + Handle(AIS_InteractiveObject) anOwnerPresentation = + Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable()); + NCollection_Map aPresentations = + theShapesToBeSelected.Find(aParameterShape); + if (aPresentations.Contains(anOwnerPresentation)) { + theContext->AddOrRemoveSelected(anOwner, Standard_False); + anOwner->SetSelected(Standard_True); + // collect selected presentations to do not select them if compsolid is selected + if (!aSelectedPresentations.Contains(anOwnerPresentation)) + aSelectedPresentations.Add(anOwnerPresentation); + } + } + else if (!aCustomOwner.IsNull()) { // CompSolid processing #2219 + // shape of owner is compound, but shape to be selected is compsolid, so + // we need to compare shape to AIS presentation of owner(rule of the owner creation) + Handle(AIS_Shape) anOwnerPresentation = + Handle(AIS_Shape)::DownCast(anOwner->Selectable()); + const TopoDS_Shape& aPresentationShape = anOwnerPresentation->Shape(); + if (aParameterShape.IsSame(anOwnerPresentation->Shape()) && + !aCompsolidPresentations.Contains(anOwnerPresentation)) + aCompsolidPresentations.Add(anOwnerPresentation); + } + } + } + } + // select CompSolid presentations if their owners was not selected yet + NCollection_Map::Iterator anIt (aCompsolidPresentations); + for (; anIt.More(); anIt.Next()) { + if (aSelectedPresentations.Contains(anIt.Value())) + continue; + theContext->AddOrRemoveSelected(anIt.Value(), Standard_False); + } +} + +//************************************************************** +XGUI_SelectionActivate* XGUI_Displayer::selectionActivate() const +{ + return myWorkshop->selectionActivate(); +} + +//************************************************************** +GeomPlanePtr XGUI_Displayer::getScreenPlane() const +{ + GeomPlanePtr aResult; + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (!aContext.IsNull()) { + Handle(V3d_Viewer) aViewer = aContext->CurrentViewer(); + Handle(V3d_View) aView; + for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews()) { + aView = aViewer->ActiveView(); + break; + } + if (!aView.IsNull()) { + double aEyeX, aEyeY, aEyeZ; + aView->Eye(aEyeX, aEyeY, aEyeZ); + + double aProjX, aProjY, aProjZ; + aView->Proj(aProjX, aProjY, aProjZ); + + GeomPointPtr aPnt = GeomPointPtr(new GeomAPI_Pnt(aEyeX, aEyeY, aEyeZ)); + GeomDirPtr aDir = GeomDirPtr(new GeomAPI_Dir(aProjX, aProjY, aProjZ)); + + aResult = GeomPlanePtr(new GeomAPI_Pln(aPnt, aDir)); + } + } + return aResult; +} + +double XGUI_Displayer::getViewScale() const +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (!aContext.IsNull()) { + Handle(V3d_Viewer) aViewer = aContext->CurrentViewer(); + Handle(V3d_View) aView; + for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews()) { + aView = aViewer->ActiveView(); + break; + } + return aView->Camera()->Scale(); + } + return 1; +}