X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_Displayer.cpp;h=fd4fae9d704fb2c1ff00116a3f0ea9642a3c995d;hb=c6745a6b1ad00c0285fab5aeac2cb0d57afef5cc;hp=15d4e4b7891f863ff07a9a97da33f5ec1ce5baa8;hpb=1ba63bcfd84d023788fb707b7bf638b95a0174ef;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 15d4e4b78..fd4fae9d7 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -1,15 +1,30 @@ -// 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_FacesPanel.h" #include "XGUI_Selection.h" -#include "XGUI_CustomPrs.h" +#include "XGUI_SelectionActivate.h" +#include "XGUI_SelectionMgr.h" +#include "XGUI_ViewerProxy.h" +#include "XGUI_Workshop.h" #ifndef HAVE_SALOME #include @@ -20,91 +35,77 @@ #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 #include #include #include -#ifdef VINSPECTOR -#include +#ifdef TINSPECTOR +#include #endif #include #include +#include #include /// defines the local context mouse selection sensitivity const int MOUSE_SENSITIVITY_IN_PIXEL = 10; -//#define DEBUG_ACTIVATE_OBJECTS -//#define DEBUG_DEACTIVATE -//#define DEBUG_ACTIVATE_AIS -//#define DEBUG_DEACTIVATE_AIS - //#define DEBUG_DISPLAY //#define DEBUG_FEATURE_REDISPLAY //#define DEBUG_SELECTION_FILTERS -//#define DEBUG_COMPOSILID_DISPLAY -// Workaround for bug #25637 - //#define DEBUG_OCCT_SHAPE_SELECTION -//#define WORKAROUND_UNTIL_27523_IS_FIXED +#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(", ")) @@ -117,106 +118,53 @@ QString qIntListInfo(const QIntList& theValues, const QString& theSeparator = QS return anInfo.join(theSeparator); } +//************************************************************** XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop) - : myWorkshop(theWorkshop), myNeedUpdate(false), - myIsTrihedronActive(true), myViewerBlockedRecursiveCount(0) +: myWorkshop(theWorkshop), myNeedUpdate(false), + myViewerBlockedRecursiveCount(0), myContextId(0) { - #ifdef VINSPECTOR - myContextCallBack = 0; - #endif - myCustomPrs = std::shared_ptr(new XGUI_CustomPrs(theWorkshop)); } +//************************************************************** XGUI_Displayer::~XGUI_Displayer() { } +//************************************************************** bool XGUI_Displayer::isVisible(ObjectPtr theObject) const { return myResult2AISObjectMap.contains(theObject); } +//************************************************************** bool XGUI_Displayer::display(ObjectPtr theObject, bool theUpdateViewer) { bool aDisplayed = false; if (isVisible(theObject)) { -#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) { - 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()); - } - }*/ + 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) { -#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()); - 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; - } -#ifdef DEBUG_COMPOSILID_DISPLAY - } // close else -#endif - } + anAIS = myWorkshop->module()->createPresentation(theObject); + isShading = true; } - if (anAIS) + if (anAIS.get()) aDisplayed = display(theObject, anAIS, isShading, theUpdateViewer); } return aDisplayed; } + +//************************************************************** bool canBeShaded(Handle(AIS_InteractiveObject) theAIS, ModuleBase_IModule* theModule) { Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(theAIS); @@ -235,6 +183,7 @@ bool canBeShaded(Handle(AIS_InteractiveObject) theAIS, ModuleBase_IModule* theMo return false; } +//************************************************************** bool XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS, bool isShading, bool theUpdateViewer) { @@ -248,20 +197,20 @@ bool XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS, if (!anAISIO.IsNull()) { appendResultObject(theObject, theAIS); - bool isCustomized = customizeObject(theObject); + //bool isCustomized = customizeObject(theObject); 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 VINSPECTOR - if (myContextCallBack) myContextCallBack->Display(anAISIO); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Display(anAISIO); #endif aDisplayed = true; emit objectDisplayed(theObject, theAIS); - activate(anAISIO, myActiveSelectionModes, theUpdateViewer); + selectionActivate()->activate(anAISIO, theUpdateViewer); } if (theUpdateViewer) updateViewer(); @@ -269,6 +218,7 @@ bool XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS, return aDisplayed; } +//************************************************************** bool XGUI_Displayer::erase(ObjectPtr theObject, const bool theUpdateViewer) { bool aErased = false; @@ -279,16 +229,15 @@ bool XGUI_Displayer::erase(ObjectPtr theObject, const bool theUpdateViewer) if (aContext.IsNull()) return aErased; - AISObjectPtr anObject = myResult2AISObjectMap[theObject]; + AISObjectPtr anObject = myResult2AISObjectMap.value(theObject); if (anObject) { Handle(AIS_InteractiveObject) anAIS = anObject->impl(); if (!anAIS.IsNull()) { emit beforeObjectErase(theObject, anObject); aContext->Remove(anAIS, false/*update viewer*/); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->Remove(anAIS); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Remove(anAIS); #endif - ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::erase -- Remove"); aErased = true; } } @@ -307,30 +256,43 @@ bool XGUI_Displayer::erase(ObjectPtr theObject, const bool theUpdateViewer) return aErased; } +//************************************************************** bool XGUI_Displayer::redisplay(ObjectPtr theObject, bool theUpdateViewer) { bool aRedisplayed = false; + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull()) + return aRedisplayed; + if (!isVisible(theObject)) return aRedisplayed; AISObjectPtr aAISObj = getAISObject(theObject); - Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl(); + Handle(AIS_InteractiveObject) aAISIO; 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) { aRedisplayed = erase(theObject, theUpdateViewer); return aRedisplayed; } if (aAIS_Obj != aAISObj) { + erase(theObject, theUpdateViewer); appendResultObject(theObject, aAIS_Obj); } aAISIO = aAIS_Obj->impl(); } + else { + aAISIO = aAISObj->impl(); + } - Handle(AIS_InteractiveContext) aContext = AISContext(); - if (!aContext.IsNull() && !aAISIO.IsNull()) { + if (!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 @@ -338,103 +300,80 @@ bool XGUI_Displayer::redisplay(ObjectPtr theObject, bool theUpdateViewer) // before and after the values modification. // Moreother, this check avoids customize and redisplay presentation if the presentable // parameter is changed. - bool isEqualShapes = false; - ResultPtr aResult = std::dynamic_pointer_cast(theObject); - if (aResult.get() != NULL) { - Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(aAISIO); - if (!aShapePrs.IsNull()) { - std::shared_ptr aShapePtr = ModelAPI_Tools::shape(aResult); - if (aShapePtr.get()) { - const TopoDS_Shape& aOldShape = aShapePrs->Shape(); - if (!aOldShape.IsNull()) - isEqualShapes = aOldShape.IsEqual(aShapePtr->impl()); - } - } - } + //bool isEqualShapes = false; + //ResultPtr aResult = std::dynamic_pointer_cast(theObject); + //if (aResult.get() != NULL) { + // Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(aAISIO); + // if (!aShapePrs.IsNull()) { + // std::shared_ptr aShapePtr = ModelAPI_Tools::shape(aResult); + // if (aShapePtr.get()) { + // const TopoDS_Shape& aOldShape = aShapePrs->Shape(); + // if (!aOldShape.IsNull()) + // isEqualShapes = aOldShape.IsEqual(aShapePtr->impl()); + // } + // } + //} // Customization of presentation - bool isCustomized = customizeObject(theObject); + //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"). + arg(!isEqualShapes/* || isCustomized*/).arg(isEqualShapes) + .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 + //if (!isEqualShapes/* || isCustomized*/) { + // /// if shapes are equal and presentation are customized, selection should be restored + // bool aNeedToRestoreSelection = isEqualShapes/* && isCustomized*/; + // if (aNeedToRestoreSelection) + if (aAISObj.get() && myWorkshop->facesPanel()) + myWorkshop->facesPanel()->customizeObject(theObject, aAISObj); - aContext->Redisplay(aAISIO, false); + myWorkshop->module()->storeSelection(); -#ifdef WORKAROUND_UNTIL_27523_IS_FIXED - if (!myActiveSelectionModes.contains(0)) - aContext->Deactivate(aAISIO, 0); +#ifdef CLEAR_OUTDATED_SELECTION_BEFORE_REDISPLAY + myWorkshop->selector()->deselectPresentation(aAISIO); #endif - - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->Redisplay(aAISIO); + if (aContext->IsDisplayed(aAISIO)) + aContext->Redisplay(aAISIO, false); + else { + aContext->Display(aAISIO, false); + } + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Redisplay(aAISIO); #endif - ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::redisplay -- Redisplay"); - if (aNeedToRestoreSelection) - myWorkshop->module()->restoreSelection(); + //if (aNeedToRestoreSelection) + myWorkshop->module()->restoreSelection(); - aRedisplayed = true; - #ifdef DEBUG_FEATURE_REDISPLAY - qDebug(" Redisplay happens"); - #endif - if (theUpdateViewer) - updateViewer(); - } + aRedisplayed = true; + #ifdef DEBUG_FEATURE_REDISPLAY + qDebug(" Redisplay happens"); + #endif + if (theUpdateViewer) + updateViewer(); } return aRedisplayed; } +//************************************************************** void XGUI_Displayer::redisplayObjects() { // 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 aDisplayed = 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::deactivate(ObjectPtr theObject, const bool theUpdateViewer) -{ -#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 - Handle(AIS_InteractiveContext) aContext = AISContext(); - if (!aContext.IsNull() && isVisible(theObject)) { - AISObjectPtr anObj = myResult2AISObjectMap[theObject]; - Handle(AIS_InteractiveObject) anAIS = anObj->impl(); - - deactivateAIS(anAIS); - // the selection from the previous activation modes should be cleared manually (#26172) - aContext->LocalContext()->ClearOutdatedSelection(anAIS, true); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->ClearOutdatedSelection(anAIS); - #endif - ModuleBase_Tools::selectionInfo(aContext, - "XGUI_Displayer::deactivate -- ClearOutdatedSelection"); - if (theUpdateViewer) - updateViewer(); + XGUI_ViewerProxy* aViewer = myWorkshop->viewer(); + if (aViewer->isColorScaleVisible()) { + aViewer->setupColorScale(); + aViewer->setColorScaleShown(true); } + Events_Loop::loop()->flush(EVENT_DISP); } +//************************************************************** void XGUI_Displayer::deactivateObjects(const QObjectPtrList& theObjList, const bool theUpdateViewer) { @@ -444,38 +383,14 @@ void XGUI_Displayer::deactivateObjects(const QObjectPtrList& theObjList, QObjectPtrList::const_iterator anIt = theObjList.begin(), aLast = theObjList.end(); for (; anIt != aLast; anIt++) { - deactivate(*anIt, false); + selectionActivate()->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() || !isVisible(theObject)) - return; - - AISObjectPtr aAISObj = getAISObject(theObject); - - if (aAISObj.get() != NULL) { - Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl(); - TColStd_ListOfInteger aTColModes; - aContext->ActivatedModes(anAISIO, aTColModes); - TColStd_ListIteratorOfListOfInteger itr( aTColModes ); - for (; itr.More(); itr.Next() ) { - theModes.append(itr.Value()); - } - } -} - -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; @@ -486,12 +401,12 @@ bool XGUI_Displayer::isVisible(XGUI_Displayer* theDisplayer, const ObjectPtr& th // 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 (!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 - bool anAllSubsVisible = aCompsolidResult->numberOfSubs() > 0; - for(int i = 0; i < aCompsolidResult->numberOfSubs() && anAllSubsVisible; i++) { + int aNumberOfSubs = aCompsolidResult->numberOfSubs(); + bool anAllSubsVisible = aNumberOfSubs > 0; + for(int i = 0; i < aNumberOfSubs && anAllSubsVisible; i++) { anAllSubsVisible = theDisplayer->isVisible(aCompsolidResult->subResult(i)); } aVisible = anAllSubsVisible; @@ -514,231 +429,102 @@ bool XGUI_Displayer::isVisible(XGUI_Displayer* theDisplayer, const ObjectPtr& th 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) -{ - // 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: new modes%1, active modes%2, objects[%3] = %4"). - arg(getModesInfo(aModes)). - arg(getModesInfo(myActiveSelectionModes)). - arg(theObjList.size()). - arg(anInfoStr). - toStdString().c_str()); -#endif - // In order to avoid doblications of selection modes - QIntList aNewModes; - foreach (int aMode, aModes) { - if (!aNewModes.contains(aMode)) - aNewModes.append(aMode); - } - myActiveSelectionModes = aNewModes; - Handle(AIS_InteractiveContext) aContext = AISContext(); - // Open local context if there is no one - if (aContext.IsNull() || !aContext->HasOpenedContext()) - return; - - //aContext->UseDisplayedObjects(); - //myUseExternalObjects = true; - - Handle(AIS_InteractiveObject) anAISIO; - AIS_ListOfInteractive aPrsList; - //if (aObjList.isEmpty()) - // return; - //else { - foreach(ObjectPtr aObj, theObjList) { - if (myResult2AISObjectMap.contains(aObj)) - aPrsList.Append(myResult2AISObjectMap[aObj]->impl()); - } - //} - - // 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; - - AIS_ListIteratorOfListOfInteractive aLIt(aPrsList); - bool isActivationChanged = false; - for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()){ - anAISIO = aLIt.Value(); - if (activate(anAISIO, myActiveSelectionModes, false)) - isActivationChanged = true; - } -} - -bool XGUI_Displayer::isActive(ObjectPtr theObject) const -{ - Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull() || !isVisible(theObject)) - return false; - - AISObjectPtr anObj = myResult2AISObjectMap[theObject]; - Handle(AIS_InteractiveObject) anAIS = anObj->impl(); - - TColStd_ListOfInteger aModes; - aContext->ActivatedModes(anAIS, aModes); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->ActivatedModes(anAIS, aModes); - #endif - - return aModes.Extent() > 0; -} - - +//************************************************************** void XGUI_Displayer::setSelected(const QList& theValues, bool theUpdateViewer) { Handle(AIS_InteractiveContext) aContext = AISContext(); if (aContext.IsNull()) return; - if (aContext->HasOpenedContext()) { - aContext->UnhilightSelected(false); - aContext->ClearSelected(false); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->ClearSelected(); - #endif - NCollection_DataMap> - aShapesToBeSelected; + 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(); + 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 VINSPECTOR - if (myContextCallBack) myContextCallBack->AddOrRemoveSelected(aShape); - #endif + // 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); + NCollection_Map aPresentations; + if (aShapesToBeSelected.IsBound(aShape)) + aPresentations = aShapesToBeSelected.Find(aShape); + ObjectPtr anObject = aPrs->object(); + getPresentations(anObject, aPresentations); - aShapesToBeSelected.Bind(aShape, 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[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); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->AddOrRemoveSelected(anAIS); - #endif - } - } - } - } - 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) { + } else { ObjectPtr anObject = aPrs->object(); ResultPtr aResult = std::dynamic_pointer_cast(anObject); if (aResult.get() && isVisible(aResult)) { - AISObjectPtr anObj = myResult2AISObjectMap[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 + } } } } - ModuleBase_Tools::selectionInfo(aContext, - "XGUI_Displayer::setSelected -- AddOrRemoveSelected/UnhilightCurrents(no local context)"); + if (!aShapesToBeSelected.IsEmpty()) + XGUI_Displayer::AddOrRemoveSelectedShapes(aContext, aShapesToBeSelected); + if (theUpdateViewer) updateViewer(); } +//************************************************************** void XGUI_Displayer::clearSelected(const bool theUpdateViewer) { Handle(AIS_InteractiveContext) aContext = AISContext(); if (!aContext.IsNull()) { - aContext->UnhilightCurrents(false); + aContext->UnhilightSelected(false);//UnhilightCurrents(false); aContext->ClearSelected(theUpdateViewer); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->ClearSelected(); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->ClearSelected(); #endif } } +//************************************************************** 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/*update viewer*/); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->Remove(anIO); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Remove(anIO); #endif aErased = true; } @@ -746,7 +532,6 @@ bool XGUI_Displayer::eraseAll(const bool theUpdateViewer) if (theUpdateViewer) updateViewer(); } - ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::eraseAll -- Remove"); myResult2AISObjectMap.clear(); #ifdef DEBUG_DISPLAY qDebug("eraseAll"); @@ -755,200 +540,44 @@ bool XGUI_Displayer::eraseAll(const bool theUpdateViewer) return aErased; } -void deactivateObject(Handle(AIS_InteractiveContext) theContext, - Handle(AIS_InteractiveObject) theObject, -#ifdef VINSPECTOR - VInspectorAPI_CallBack* theCallBack, -#endif - const bool theClear = true) -{ - if (!theObject.IsNull()) { - theContext->Deactivate(theObject); - #ifdef VINSPECTOR - if (theCallBack) theCallBack->Deactivate(theObject); - #endif - ModuleBase_Tools::selectionInfo(theContext, "XGUI_Displayer::deactivateObject -- Deactivate"); - //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 - #ifdef VINSPECTOR - , myContextCallBack - #endif - ); - - /// #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() - #ifdef VINSPECTOR - , myContextCallBack - #endif - ); - deactivateObject(aContext, aTrie->YAxis() - #ifdef VINSPECTOR - , myContextCallBack - #endif - ); - deactivateObject(aContext, aTrie->Axis() - #ifdef VINSPECTOR - , myContextCallBack - #endif - ); - deactivateObject(aContext, aTrie->Position() - #ifdef VINSPECTOR - , myContextCallBack - #endif - ); - - deactivateObject(aContext, aTrie->XYPlane() - #ifdef VINSPECTOR - , myContextCallBack - #endif - ); - deactivateObject(aContext, aTrie->XZPlane() - #ifdef VINSPECTOR - , myContextCallBack - #endif - ); - deactivateObject(aContext, aTrie->YZPlane() - #ifdef VINSPECTOR - , myContextCallBack - #endif - ); - - if (theUpdateViewer) - updateViewer(); - } -} - -Handle(AIS_InteractiveObject) XGUI_Displayer::getTrihedron() const -{ - return myWorkshop->viewer()->trihedron(); -} - -void XGUI_Displayer::openLocalContext() -{ - Handle(AIS_InteractiveContext) aContext = AISContext(); - // Open local context if there is no one - if (!aContext.IsNull() && !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(); - //deactivateTrihedron(); - //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 theUpdateViewer) -{ - 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); - - // 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; - 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 (theUpdateViewer) - 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 { +#ifdef OPTIMIZE_PRS + ObjectPtr anObject = myResult2AISObjectMap.value(theIO); +#else ObjectPtr anObject; - foreach (ObjectPtr anObj, myResult2AISObjectMap.keys()) { - AISObjectPtr aAIS = myResult2AISObjectMap[anObj]; + 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) - anObject = anObj; + anObject = aMapIter.key(); if (anObject.get()) break; } +#endif if (!anObject.get()) { std::shared_ptr anAISObj = AISObjectPtr(new GeomAPI_AISObject()); if (!theIO.IsNull()) { @@ -959,6 +588,7 @@ ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) return anObject; } +//************************************************************** bool XGUI_Displayer::enableUpdateViewer(const bool isEnabled) { bool aWasEnabled = isUpdateEnabled(); @@ -967,6 +597,10 @@ bool XGUI_Displayer::enableUpdateViewer(const bool isEnabled) else myViewerBlockedRecursiveCount++; +#ifdef DEBUG_VIEWER_BLOCKED_COUNT + std::cout << "myViewerBlockedRecursiveCount = " << myViewerBlockedRecursiveCount << std::endl; +#endif + if (myNeedUpdate && isUpdateEnabled()) { updateViewer(); myNeedUpdate = false; @@ -974,109 +608,86 @@ bool XGUI_Displayer::enableUpdateViewer(const bool isEnabled) return aWasEnabled; } -bool XGUI_Displayer::isUpdateEnabled() const -{ - return myViewerBlockedRecursiveCount == 0; -} - +//************************************************************** void XGUI_Displayer::updateViewer() const { Handle(AIS_InteractiveContext) aContext = AISContext(); + +#ifdef DEBUG_VIEWER_BLOCKED_COUNT + std::cout << "updateViewer: " << (myViewerBlockedRecursiveCount == 0 ? " done" : " later") + << std::endl; +#endif + if (!aContext.IsNull() && isUpdateEnabled()) { - myWorkshop->viewer()->Zfitall(); + //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) XGUI_Displayer::AISContext() 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()) { - if (myWorkshop->module()) { - int aMode = (theMode > 8)? theMode : AIS_Shape::SelectionType(theMode); - aContext->Activate(theIO, theMode, false); - } else - aContext->Activate(theIO, theMode, false); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->Activate(theIO, theMode); - #endif - - // 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", - 12); - 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"); + if (!aContext.IsNull() && (myContextId != aContext.get())) { + myContextId = aContext.get(); + if (!myWorkshop->selectionActivate()->isTrihedronActive()) + selectionActivate()->deactivateTrihedron(true); + aContext->DefaultDrawer()->VIsoAspect()->SetNumber(0); + aContext->DefaultDrawer()->UIsoAspect()->SetNumber(0); -#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(); + //Handle(AIS_Trihedron) aTrihedron = myWorkshop->viewer()->trihedron(); + //aTrihedron->getHighlightPointAspect()->SetScale(2.0); + //aTrihedron->getHighlightPointAspect()->SetTypeOfMarker(Aspect_TOM_O_STAR); + + // Commented out according to discussion in bug #2825 + //ModuleBase_IViewer::DefaultHighlightDrawer = aContext->HighlightStyle(); + //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; } -void XGUI_Displayer::deactivateAIS(const Handle(AIS_InteractiveObject)& theIO, - const int theMode) const +//************************************************************** +void XGUI_Displayer::setSelectionColor(const std::vector& theColor) { Handle(AIS_InteractiveContext) aContext = AISContext(); if (!aContext.IsNull()) { - if (theMode == -1) { - aContext->Deactivate(theIO); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->Deactivate(theIO); - #endif - } - else { - aContext->Deactivate(theIO, theMode); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->Deactivate(theIO, theMode); - #endif - } - ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::deactivateAIS -- Deactivate"); - -#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 + Quantity_Color aQColor(theColor[0] / 255., + theColor[1] / 255., + theColor[2] / 255., Quantity_TOC_RGB); + aContext->SelectionStyle()->SetColor(aQColor); + aContext->SelectionStyle()->PointAspect()->SetColor(aQColor); + aContext->SelectionStyle()->LineAspect()->SetColor(aQColor); + aContext->HighlightStyle(Prs3d_TypeOfHighlight_LocalSelected)->SetColor(aQColor); } } -Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const + +//************************************************************** +std::vector XGUI_Displayer::selectionColor() const { - Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); - if (!aContext.IsNull() && !aContext->HasOpenedContext()) { - aContext->OpenLocalContext(); - if (!isTrihedronActive()) - deactivateTrihedron(true); - aContext->DefaultDrawer()->VIsoAspect()->SetNumber(0); - aContext->DefaultDrawer()->UIsoAspect()->SetNumber(0); + std::vector aColor; + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (!aContext.IsNull()) { + Quantity_Color aQColor = aContext->SelectionStyle()->Color(); + aColor.push_back((int)(aQColor.Red() * 255)); + aColor.push_back((int)(aQColor.Green() * 255)); + aColor.push_back((int)(aQColor.Blue() * 255)); } - return aContext; + return aColor; } + +//************************************************************** Handle(SelectMgr_AndFilter) XGUI_Displayer::GetFilter() { Handle(AIS_InteractiveContext) aContext = AISContext(); @@ -1087,43 +698,37 @@ Handle(SelectMgr_AndFilter) XGUI_Displayer::GetFilter() return myAndFilter; } +//************************************************************** bool XGUI_Displayer::displayAIS(AISObjectPtr theAIS, const bool toActivateInSelectionModes, - bool theUpdateViewer) + const Standard_Integer theDisplayMode, bool theUpdateViewer) { bool aDisplayed = false; Handle(AIS_InteractiveContext) aContext = AISContext(); Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); if (!aContext.IsNull() && !anAISIO.IsNull()) { - aContext->Display(anAISIO, 0/*wireframe*/, 0, false/*update viewer*/, true, AIS_DS_Displayed); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->Display(anAISIO); + 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 VINSPECTOR - if (myContextCallBack) myContextCallBack->Deactivate(anAISIO); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Deactivate(anAISIO); #endif aContext->Load(anAISIO); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->Load(anAISIO); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Load(anAISIO); #endif - if (toActivateInSelectionModes) { - if (aContext->HasOpenedContext()) { - if (myActiveSelectionModes.size() == 0) - activateAIS(anAISIO, 0, theUpdateViewer); - else { - foreach(int aMode, myActiveSelectionModes) { - activateAIS(anAISIO, aMode, theUpdateViewer); - } - } - } - } + if (toActivateInSelectionModes) + myWorkshop->selectionActivate()->activateOnDisplay(anAISIO, theUpdateViewer); + if (theUpdateViewer) updateViewer(); } return aDisplayed; } +//************************************************************** bool XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool theUpdateViewer) { bool aErased = false; @@ -1132,10 +737,9 @@ bool XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool theUpdateViewer) Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); if (!anAISIO.IsNull() && aContext->IsDisplayed(anAISIO)) { aContext->Remove(anAISIO, false/*update viewer*/); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->Remove(anAISIO); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Remove(anAISIO); #endif - ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::eraseAIS -- Remove"); aErased = true; } } @@ -1144,7 +748,7 @@ bool XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool theUpdateViewer) return aErased; } - +//************************************************************** void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bool theUpdateViewer) { if (theMode == NoMode) @@ -1165,6 +769,7 @@ void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bo updateViewer(); } +//************************************************************** XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) const { Handle(AIS_InteractiveContext) aContext = AISContext(); @@ -1179,7 +784,8 @@ XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) con return (XGUI_Displayer::DisplayMode) aAISIO->DisplayMode(); } -void XGUI_Displayer::deactivateSelectionFilters() +//************************************************************** +void XGUI_Displayer::deactivateSelectionFilters(const bool theAddFilterOnly) { Handle(AIS_InteractiveContext) aContext = AISContext(); if (!myAndFilter.IsNull()) { @@ -1198,6 +804,7 @@ void XGUI_Displayer::deactivateSelectionFilters() } } +//************************************************************** void XGUI_Displayer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) { Handle(AIS_InteractiveContext) aContext = AISContext(); @@ -1214,6 +821,7 @@ void XGUI_Displayer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilte } } +//************************************************************** void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) { Handle(AIS_InteractiveContext) aContext = AISContext(); @@ -1231,6 +839,7 @@ void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFi } } +//************************************************************** bool XGUI_Displayer::hasSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) { bool aFilterFound = false; @@ -1241,20 +850,21 @@ bool XGUI_Displayer::hasSelectionFilter(const Handle(SelectMgr_Filter)& theFilte const SelectMgr_ListOfFilter& aFilters = aContext->Filters(); SelectMgr_ListIteratorOfListOfFilter aIt(aFilters); for (; aIt.More() && !aFilterFound; aIt.Next()) { - if (theFilter.Access() == aIt.Value().Access()) + 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.Access() == aIt.Value().Access()) + if (theFilter.get() == aIt.Value().get()) aFilterFound = true; } } return aFilterFound; } +//************************************************************** void XGUI_Displayer::removeFilters() { Handle(AIS_InteractiveContext) aContext = AISContext(); @@ -1266,9 +876,14 @@ void XGUI_Displayer::removeFilters() 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); @@ -1280,6 +895,7 @@ void XGUI_Displayer::showOnly(const QObjectPtrList& theList) updateViewer(); } +//************************************************************** bool XGUI_Displayer::canBeShaded(ObjectPtr theObject) const { if (!isVisible(theObject)) @@ -1293,117 +909,40 @@ bool XGUI_Displayer::canBeShaded(ObjectPtr theObject) const return ::canBeShaded(anAIS, myWorkshop->module()); } -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 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. - // 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); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->ActivatedModes(theIO, aTColModes); - #endif - TColStd_ListIteratorOfListOfInteger itr( aTColModes ); - QIntList aModesActivatedForIO; - 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; - } - else { - aModesActivatedForIO.append(aMode); - } - } - if (isDeactivated) { - // the selection from the previous activation modes should be cleared manually (#26172) - theIO->ClearSelected(); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->ClearSelected(theIO); - #endif - aContext->LocalContext()->ClearOutdatedSelection(theIO, true); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->ClearOutdatedSelection(theIO); - #endif - ModuleBase_Tools::selectionInfo(aContext, - "XGUI_Displayer::activate -- ClearSelected/ClearOutdatedSelection"); - // For performance issues - //if (theUpdateViewer) - // updateViewer(); - isActivationChanged = true; - } - - // loading the interactive object allowing the decomposition - if (aTColModes.IsEmpty()) { - aContext->Load(theIO, -1, true); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->Load(theIO); - #endif - } - - // 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()) { - // In order to clear active modes list - if (theModes.size() == 0) { - activateAIS(theIO, 0, theUpdateViewer); - } else { - foreach(int aMode, theModes) { - if (!aModesActivatedForIO.contains(aMode)) { - activateAIS(theIO, aMode, theUpdateViewer); - isActivationChanged = true; - } - } - } - } - return isActivationChanged; -} - -bool XGUI_Displayer::customizeObject(ObjectPtr theObject) -{ - AISObjectPtr anAISObj = getAISObject(theObject); - // correct the result's color it it has the attribute - ResultPtr aResult = std::dynamic_pointer_cast(theObject); - - // Customization of presentation - GeomCustomPrsPtr aCustomPrs; - FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); - if (aFeature.get() != NULL) { - GeomCustomPrsPtr aCustPrs = std::dynamic_pointer_cast(aFeature); - if (aCustPrs.get() != NULL) - aCustomPrs = aCustPrs; - } - if (aCustomPrs.get() == NULL) { - GeomPresentablePtr aPrs = std::dynamic_pointer_cast(theObject); - // we ignore presentable not customized objects - if (aPrs.get() == NULL) - aCustomPrs = myCustomPrs; - } - bool isCustomized = aCustomPrs.get() && - aCustomPrs->customisePresentation(aResult, anAISObj, myCustomPrs); - return isCustomized; -} - - +//************************************************************** +//bool XGUI_Displayer::customizeObject(ObjectPtr theObject) +//{ +// AISObjectPtr anAISObj = getAISObject(theObject); +// // correct the result's color it it has the attribute +// ResultPtr aResult = std::dynamic_pointer_cast(theObject); +// +// // Customization of presentation +// GeomCustomPrsPtr aCustomPrs; +// FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); +// if (aFeature.get() != NULL) { +// GeomCustomPrsPtr aCustPrs = std::dynamic_pointer_cast(aFeature); +// if (aCustPrs.get() != NULL) +// aCustomPrs = aCustPrs; +// } +// if (aCustomPrs.get() == NULL) { +// GeomPresentablePtr aPrs = std::dynamic_pointer_cast(theObject); +// // we ignore presentable not customized objects +// if (aPrs.get() == NULL) +// aCustomPrs = 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 theUpdateViewer) @@ -1420,9 +959,14 @@ QColor XGUI_Displayer::setObjectColor(ObjectPtr theObject, 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; @@ -1432,11 +976,18 @@ void XGUI_Displayer::appendResultObject(ObjectPtr theObject, AISObjectPtr theAIS #endif } +#ifdef _DEBUG +//************************************************************** std::string XGUI_Displayer::getResult2AISObjectMapInfo() const { QStringList aContent; - 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 std::ostringstream aPtrStr; aPtrStr << "aObj = " << aObj.get() << ":"; aPtrStr << "anAIS = " << aAISObj.get() << ":"; @@ -1447,13 +998,23 @@ std::string XGUI_Displayer::getResult2AISObjectMapInfo() const 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)) @@ -1484,14 +1045,7 @@ void XGUI_Displayer::getPresentations(const ObjectPtr& theObject, } } -void XGUI_Displayer::activateTrihedron(bool theIsActive) -{ - myIsTrihedronActive = theIsActive; - if (!myIsTrihedronActive) { - deactivateTrihedron(true); - } -} - +//************************************************************** void XGUI_Displayer::displayTrihedron(bool theToDisplay) const { Handle(AIS_InteractiveContext) aContext = AISContext(); @@ -1500,6 +1054,7 @@ void XGUI_Displayer::displayTrihedron(bool theToDisplay) const Handle(AIS_Trihedron) aTrihedron = myWorkshop->viewer()->trihedron(); + XGUI_SelectionActivate* aSelectionActive = selectionActivate(); if (theToDisplay) { if (!aContext->IsDisplayed(aTrihedron)) aContext->Display(aTrihedron, @@ -1508,60 +1063,34 @@ void XGUI_Displayer::displayTrihedron(bool theToDisplay) const Standard_True /* update viewer*/, Standard_False /* allow decomposition */, AIS_DS_Displayed /* xdisplay status */); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->Display(aTrihedron); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Display(aTrihedron); #endif - if (!isTrihedronActive()) - deactivateTrihedron(false); + if (!aSelectionActive->isTrihedronActive()) + aSelectionActive->deactivateTrihedron(false); else - activate(aTrihedron, myActiveSelectionModes, false); + aSelectionActive->activate(aTrihedron, false); } else { - deactivateTrihedron(false); - //aContext->LocalContext()->ClearOutdatedSelection(aTrihedron, true); - // the selection from the previous activation modes should be cleared manually (#26172) + aSelectionActive->deactivateTrihedron(false); - aContext->Erase(aTrihedron); - #ifdef VINSPECTOR - if (myContextCallBack) myContextCallBack->Remove(aTrihedron); + aContext->Erase(aTrihedron, Standard_True); + #ifdef TINSPECTOR + if (getCallBack()) getCallBack()->Remove(aTrihedron); #endif } - - 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; -} - -#ifdef VINSPECTOR -void XGUI_Displayer::setCallBack(VInspectorAPI_CallBack* theCallBack) -{ - myContextCallBack = theCallBack; -} - -VInspectorAPI_CallBack* XGUI_Displayer::getCallBack() const -{ - return myContextCallBack; } -#endif +//************************************************************** 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_Map aCompsolidPresentations; + NCollection_Map aSelectedPresentations; NCollection_List anActiveOwners; - aLContext->MainSelector()->ActiveOwners(anActiveOwners); + theContext->MainSelector()->ActiveOwners(anActiveOwners); NCollection_List::Iterator anOwnersIt (anActiveOwners); Handle(SelectMgr_EntityOwner) anOwner; @@ -1570,27 +1099,112 @@ void XGUI_Displayer::AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) th /// 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 + 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())) + if (aSelectedIds.contains((size_t)anOwner.get())) continue; - aSelectedIds.append((long)anOwner.Access()); + 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() && 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); + 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); } } } } - aLContext->HilightPicked(Standard_False); + // 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; }