Salome HOME
Make highlight of points as a circle instead of +
[modules/shaper.git] / src / XGUI / XGUI_Displayer.cpp
index 6e006e9f7f10c86232b28703e609304774d0009e..091cd446cca37ed7bf98a69e2582d9049eb59b48 100644 (file)
 #include <ModuleBase_Tools.h>
 #include <ModuleBase_IModule.h>
 #include <ModuleBase_ViewerPrs.h>
+#include <ModuleBase_Preferences.h>
 
 #include <GeomAPI_Shape.h>
 #include <GeomAPI_IPresentable.h>
 #include <GeomAPI_ICustomPrs.h>
 
+#include <SUIT_ResourceMgr.h>
+
 #include <AIS_InteractiveContext.hxx>
 #include <AIS_LocalContext.hxx>
 #include <AIS_ListOfInteractive.hxx>
@@ -76,6 +79,8 @@ const int MOUSE_SENSITIVITY_IN_PIXEL = 10;  ///< defines the local context mouse
 
 //#define DEBUG_OCCT_SHAPE_SELECTION
 
+#define WORKAROUND_UNTIL_27523_IS_FIXED
+
 void displayedObjects(const Handle(AIS_InteractiveContext)& theAIS, AIS_ListOfInteractive& theList)
 {
   // Get from null point
@@ -109,7 +114,7 @@ QString qIntListInfo(const QIntList& theValues, const QString& theSeparator = QS
 
 XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop)
   : myWorkshop(theWorkshop), myNeedUpdate(false),
-  myIsTrihedronActive(false), myViewerBlockedRecursiveCount(0)
+  myIsTrihedronActive(true), myViewerBlockedRecursiveCount(0)
 {
   myCustomPrs = std::shared_ptr<GeomAPI_ICustomPrs>(new XGUI_CustomPrs(theWorkshop));
 }
@@ -147,6 +152,18 @@ bool XGUI_Displayer::display(ObjectPtr theObject, bool theUpdateViewer)
     bool isShading = false;
     if (aPrs.get() != NULL) {
       anAIS = aPrs->getAISObject(anAIS);
+      if (anAIS.get()) {
+        // correct deviation coefficient for 
+        Handle(AIS_InteractiveObject) anAISPrs = anAIS->impl<Handle(AIS_InteractiveObject)>();
+        if (!anAISPrs.IsNull()) {
+          Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(anAISPrs);
+          if (!aShapePrs.IsNull()) {
+            TopoDS_Shape aShape = aShapePrs->Shape();
+            if (!aShape.IsNull())
+              ModuleBase_Tools::setDefaultDeviationCoefficient(aShape, anAISPrs->Attributes());
+          }
+        }
+      }
     } else {
       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
       if (aResult.get() != NULL) {
@@ -169,6 +186,11 @@ bool XGUI_Displayer::display(ObjectPtr theObject, bool theUpdateViewer)
           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;
@@ -226,15 +248,6 @@ bool XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS,
 
     emit objectDisplayed(theObject, theAIS);
     activate(anAISIO, myActiveSelectionModes, theUpdateViewer);
-    // the fix from VPA for more suitable selection of sketcher lines
-    if(anAISIO->Width() > 1) {
-      for(int aModeIdx = 0; aModeIdx < myActiveSelectionModes.length(); ++aModeIdx) {
-        int aMode = myActiveSelectionModes.value(aModeIdx);
-        double aPrecision = (aMode == getSelectionMode(TopAbs_VERTEX))? 20 : 
-                                                    (anAISIO->Width() + 2);
-        aContext->SetSelectionSensitivity(anAISIO, aMode, aPrecision);
-      }
-    }
   } 
   if (theUpdateViewer)
     updateViewer();
@@ -258,6 +271,7 @@ bool XGUI_Displayer::erase(ObjectPtr theObject, const bool theUpdateViewer)
     if (!anAIS.IsNull()) {
       emit beforeObjectErase(theObject, anObject);
       aContext->Remove(anAIS, false/*update viewer*/);
+      ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::erase -- Remove");
       aErased = true;
     }
   }
@@ -332,8 +346,20 @@ bool XGUI_Displayer::redisplay(ObjectPtr theObject, bool theUpdateViewer)
       if (aNeedToRestoreSelection)
         myWorkshop->module()->storeSelection();
 
+#ifdef WORKAROUND_UNTIL_27523_IS_FIXED
+      if (!myActiveSelectionModes.contains(0))
+        aContext->Activate(aAISIO, 0);
+#endif
+
       aContext->Redisplay(aAISIO, false);
 
+#ifdef WORKAROUND_UNTIL_27523_IS_FIXED
+      if (!myActiveSelectionModes.contains(0))
+        aContext->Deactivate(aAISIO, 0);
+#endif
+
+      ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::redisplay -- Redisplay");
+
       if (aNeedToRestoreSelection)
         myWorkshop->module()->restoreSelection();
 
@@ -378,6 +404,7 @@ void XGUI_Displayer::deactivate(ObjectPtr theObject, const bool theUpdateViewer)
     deactivateAIS(anAIS);
     // the selection from the previous activation modes should be cleared manually (#26172)
     aContext->LocalContext()->ClearOutdatedSelection(anAIS, true);
+    ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::deactivate -- ClearOutdatedSelection");
     if (theUpdateViewer)
       updateViewer();
   }
@@ -459,6 +486,38 @@ 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)
@@ -477,9 +536,10 @@ void XGUI_Displayer::activateObjects(const QIntList& theModes, const QObjectPtrL
   }
   QString anInfoStr = anInfo.join(", ");
 
-  qDebug(QString("activateObjects: aModes[%1] = %2, myActiveSelectionModes[%3] = %4, objects = %5").
-    arg(aModes.size()).arg(qIntListInfo(aModes)).
-    arg(myActiveSelectionModes.size()).arg(qIntListInfo(myActiveSelectionModes)).
+  qDebug(QString("activateObjects: new modes%1, active modes%2, objects[%3] = %4").
+    arg(getModesInfo(aModes)).
+    arg(getModesInfo(myActiveSelectionModes)).
+    arg(theObjList.size()).
     arg(anInfoStr).
     toStdString().c_str());
 #endif
@@ -526,13 +586,6 @@ void XGUI_Displayer::activateObjects(const QIntList& theModes, const QObjectPtrL
     if (activate(anAISIO, myActiveSelectionModes, false))
       isActivationChanged = true;
   }
-  if (!aTrihedron.IsNull()) {
-    foreach(int aMode, myActiveSelectionModes)
-      aContext->SetSelectionSensitivity(aTrihedron, aMode, 20);
-  }
-  // VSV It seems that there is no necessity to update viewer on activation
-  //if (theUpdateViewer && isActivationChanged)
-  //  updateViewer();
 }
 
 bool XGUI_Displayer::isActive(ObjectPtr theObject) const
@@ -586,7 +639,7 @@ void XGUI_Displayer::setSelected(const  QList<ModuleBase_ViewerPrsPtr>& theValue
     }
     if (!aShapesToBeSelected.IsEmpty())
       XGUI_Displayer::AddOrRemoveSelectedShapes(aContext, aShapesToBeSelected);
-  } else {
+  } 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) {
@@ -600,6 +653,7 @@ void XGUI_Displayer::setSelected(const  QList<ModuleBase_ViewerPrsPtr>& theValue
       }
     }
   }
+  ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::setSelected -- AddOrRemoveSelected/UnhilightCurrents(no local context)");
   if (theUpdateViewer)
     updateViewer();
 }
@@ -631,6 +685,7 @@ 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");
@@ -645,6 +700,7 @@ void deactivateObject(Handle(AIS_InteractiveContext) theContext,
 {
   if (!theObject.IsNull()) {
     theContext->Deactivate(theObject);
+    ModuleBase_Tools::selectionInfo(theContext, "XGUI_Displayer::deactivateObject -- Deactivate");
     //if (theClear) {
       //theObject->ClearSelected();
       //  theContext->LocalContext()->ClearOutdatedSelection(theObject, true);
@@ -840,7 +896,22 @@ void XGUI_Displayer::activateAIS(const Handle(AIS_InteractiveObject)& theIO,
 {
   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
   if (!aContext.IsNull()) {
-    aContext->Activate(theIO, theMode, false);
+    if (myWorkshop->module()) {
+      int aMode = (theMode > 8)? theMode : AIS_Shape::SelectionType(theMode);
+      aContext->Activate(theIO, theMode, false);
+    } else
+      aContext->Activate(theIO, theMode, false);
+
+    // the fix from VPA for more suitable selection of sketcher lines
+    double aPrecision = theIO->Width() + 2;
+    if (theMode == getSelectionMode(TopAbs_VERTEX)) 
+      aPrecision = ModuleBase_Preferences::resourceMgr()->doubleValue("Viewer", "point-selection-sensitivity", 20);
+    else if ((theMode == getSelectionMode(TopAbs_EDGE)) || (theMode == getSelectionMode(TopAbs_WIRE)))
+      aPrecision = theIO->Width() + 
+                   ModuleBase_Preferences::resourceMgr()->doubleValue("Viewer", "edge-selection-sensitivity", 2);
+    aContext->SetSelectionSensitivity(theIO, theMode, aPrecision);
+
+    ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::activateAIS -- Activate");
 
 #ifdef DEBUG_ACTIVATE_AIS
     ObjectPtr anObject = getObject(theIO);
@@ -858,9 +929,10 @@ void XGUI_Displayer::deactivateAIS(const Handle(AIS_InteractiveObject)& theIO, c
   if (!aContext.IsNull()) {
     if (theMode == -1)
       aContext->Deactivate(theIO);
-    else
+    else 
       aContext->Deactivate(theIO, theMode);
-
+    ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::deactivateAIS -- Deactivate");
+   
 #ifdef DEBUG_DEACTIVATE_AIS
     ObjectPtr anObject = getObject(theIO);
     anInfo.append(ModuleBase_Tools::objectInfo((*anIt)));
@@ -928,6 +1000,7 @@ bool XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool theUpdateViewer)
     Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
     if (!anAISIO.IsNull() && aContext->IsDisplayed(anAISIO)) {
       aContext->Remove(anAISIO, false/*update viewer*/);
+      ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::eraseAIS -- Remove");
       aErased = true;
     }
   }
@@ -1109,6 +1182,7 @@ bool XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO,
   bool isDeactivated = false;
   for (; itr.More(); itr.Next() ) {
     Standard_Integer aMode = itr.Value();
+    int aShapeMode = (aMode > 8)? aMode : AIS_Shape::SelectionType(aMode);
     if (!theModes.contains(aMode)) {
       deactivateAIS(theIO, aMode);
       isDeactivated = true;
@@ -1121,6 +1195,7 @@ bool XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO,
     // the selection from the previous activation modes should be cleared manually (#26172)
     theIO->ClearSelected();
     aContext->LocalContext()->ClearOutdatedSelection(theIO, true);
+    ModuleBase_Tools::selectionInfo(aContext, "XGUI_Displayer::activate -- ClearSelected/ClearOutdatedSelection");
     // For performance issues
     //if (theUpdateViewer)
     //  updateViewer();