Salome HOME
Issue #1412: Activate selection mode FACES for sketcher only in operations with selector:
[modules/shaper.git] / src / XGUI / XGUI_Displayer.cpp
index 978d6154936421e9f0332bbd4520b7a4e65fb3b4..2b3b043e43e6ea506b533149e2a585c6befcd0ec 100644 (file)
@@ -25,6 +25,7 @@
 #include <ModuleBase_ResultPrs.h>
 #include <ModuleBase_Tools.h>
 #include <ModuleBase_IModule.h>
+#include <ModuleBase_ViewerPrs.h>
 
 #include <GeomAPI_Shape.h>
 #include <GeomAPI_IPresentable.h>
@@ -41,6 +42,7 @@
 #include <AIS_Axis.hxx>
 #include <AIS_Plane.hxx>
 #include <AIS_Point.hxx>
+#include <AIS_Selection.hxx>
 #include <TColStd_ListIteratorOfListOfInteger.hxx>
 #include <SelectMgr_ListOfFilter.hxx>
 #include <SelectMgr_ListIteratorOfListOfFilter.hxx>
@@ -71,6 +73,11 @@ const int MOUSE_SENSITIVITY_IN_PIXEL = 10;  ///< defines the local context mouse
 
 //#define DEBUG_COMPOSILID_DISPLAY
 // Workaround for bug #25637
+
+//#define DEBUG_OCCT_SHAPE_SELECTION
+
+#define WORKAROUND_UNTIL_27523_IS_FIXED
+
 void displayedObjects(const Handle(AIS_InteractiveContext)& theAIS, AIS_ListOfInteractive& theList)
 {
   // Get from null point
@@ -104,7 +111,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));
 }
@@ -161,7 +168,10 @@ bool XGUI_Displayer::display(ObjectPtr theObject, bool theUpdateViewer)
         std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aResult);
         if (aShapePtr.get() != NULL) {
           anAIS = AISObjectPtr(new GeomAPI_AISObject());
-          anAIS->setImpl(new Handle(AIS_InteractiveObject)(new ModuleBase_ResultPrs(aResult)));
+          Handle(AIS_InteractiveObject) anAISPrs = myWorkshop->module()->createPresentation(aResult);
+          if (anAISPrs.IsNull())
+            anAISPrs = new ModuleBase_ResultPrs(aResult);
+          anAIS->setImpl(new Handle(AIS_InteractiveObject)(anAISPrs));
           //anAIS->createShape(aShapePtr);
           isShading = true;
         }
@@ -176,7 +186,7 @@ bool XGUI_Displayer::display(ObjectPtr theObject, bool theUpdateViewer)
   return aDisplayed;
 }
 
-bool canBeShaded(Handle(AIS_InteractiveObject) theAIS)
+bool canBeShaded(Handle(AIS_InteractiveObject) theAIS, ModuleBase_IModule* theModule)
 {
   Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(theAIS);
   if (!aShapePrs.IsNull()) {
@@ -188,10 +198,7 @@ bool canBeShaded(Handle(AIS_InteractiveObject) theAIS)
       return false;
     else {
       // Check that the presentation is not a sketch
-      Handle(ModuleBase_ResultPrs) aPrs = Handle(ModuleBase_ResultPrs)::DownCast(theAIS);
-      if (!aPrs.IsNull()) 
-        return !aPrs->isSketchMode();
-      return true;
+      return theModule->canBeShaded(theAIS);
     }
   }
   return false;
@@ -327,8 +334,18 @@ 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
+
       if (aNeedToRestoreSelection)
         myWorkshop->module()->restoreSelection();
 
@@ -439,7 +456,9 @@ bool XGUI_Displayer::isVisible(XGUI_Displayer* theDisplayer, const ObjectPtr& th
       }
     }
   }
-  else {
+  // 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<ResultPtr> aResults = aFeature->results();
@@ -452,6 +471,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)
@@ -470,9 +521,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
@@ -541,7 +593,7 @@ bool XGUI_Displayer::isActive(ObjectPtr theObject) const
   aContext->ActivatedModes(anAIS, aModes);
   return aModes.Extent() > 0;
 }
-void XGUI_Displayer::setSelected(const  QList<ModuleBase_ViewerPrs>& theValues, bool theUpdateViewer)
+void XGUI_Displayer::setSelected(const  QList<ModuleBase_ViewerPrsPtr>& theValues, bool theUpdateViewer)
 {
   Handle(AIS_InteractiveContext) aContext = AISContext();
   if (aContext.IsNull())
@@ -549,12 +601,19 @@ void XGUI_Displayer::setSelected(const  QList<ModuleBase_ViewerPrs>& theValues,
   if (aContext->HasOpenedContext()) {
     aContext->UnhilightSelected(false);
     aContext->ClearSelected(false);
-    foreach (ModuleBase_ViewerPrs aPrs, theValues) {
-      const TopoDS_Shape& aShape = aPrs.shape();
-      if (!aShape.IsNull()) {
+    NCollection_Map<TopoDS_Shape> aShapesToBeSelected;
+
+    foreach (ModuleBase_ViewerPrsPtr aPrs, theValues) {
+      const GeomShapePtr& aGeomShape = aPrs->shape();
+      if (aGeomShape.get() && !aGeomShape->isNull()) {
+        const TopoDS_Shape& aShape = aGeomShape->impl<TopoDS_Shape>();
+#ifdef DEBUG_OCCT_SHAPE_SELECTION
         aContext->AddOrRemoveSelected(aShape, false);
+#else
+        aShapesToBeSelected.Add(aShape);
+#endif
       } else {
-        ObjectPtr anObject = aPrs.object();
+        ObjectPtr anObject = aPrs->object();
         ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
         if (aResult.get() && isVisible(aResult)) {
           AISObjectPtr anObj = myResult2AISObjectMap[aResult];
@@ -570,11 +629,13 @@ void XGUI_Displayer::setSelected(const  QList<ModuleBase_ViewerPrs>& theValues,
         }
       }
     }
+    if (!aShapesToBeSelected.IsEmpty())
+      XGUI_Displayer::AddOrRemoveSelectedShapes(aContext, aShapesToBeSelected);
   } else {
     aContext->UnhilightCurrents(false);
     aContext->ClearCurrents(false);
-    foreach (ModuleBase_ViewerPrs aPrs, theValues) {
-      ObjectPtr anObject = aPrs.object();
+    foreach (ModuleBase_ViewerPrsPtr aPrs, theValues) {
+      ObjectPtr anObject = aPrs->object();
       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
       if (aResult.get() && isVisible(aResult)) {
         AISObjectPtr anObj = myResult2AISObjectMap[aResult];
@@ -824,7 +885,11 @@ 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);
 
 #ifdef DEBUG_ACTIVATE_AIS
     ObjectPtr anObject = getObject(theIO);
@@ -842,9 +907,9 @@ 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);
-
+   
 #ifdef DEBUG_DEACTIVATE_AIS
     ObjectPtr anObject = getObject(theIO);
     anInfo.append(ModuleBase_Tools::objectInfo((*anIt)));
@@ -1065,7 +1130,7 @@ bool XGUI_Displayer::canBeShaded(ObjectPtr theObject) const
     return false;
 
   Handle(AIS_InteractiveObject) anAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
-  return ::canBeShaded(anAIS);
+  return ::canBeShaded(anAIS, myWorkshop->module());
 }
 
 bool XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO,
@@ -1093,6 +1158,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;
@@ -1244,3 +1310,40 @@ void XGUI_Displayer::displayTrihedron(bool theToDisplay) const
 
   updateViewer();
 }
+
+QIntList XGUI_Displayer::activeSelectionModes() const 
+{ 
+  QIntList aModes;
+  foreach (int aMode, myActiveSelectionModes) {
+    // aMode < 9 is a Shape Enum values
+    aModes << ((aMode < 9)? AIS_Shape::SelectionType(aMode) : aMode);
+  }
+  return aModes; 
+}
+
+void XGUI_Displayer::AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) theContext,
+                                      const NCollection_Map<TopoDS_Shape>& theShapesToBeSelected)
+{
+  Handle(AIS_LocalContext) aLContext = theContext->LocalContext();
+  TCollection_AsciiString aSelectionName = aLContext->SelectionName();
+  aLContext->UnhilightPicked(Standard_False);
+
+  NCollection_Map<TopoDS_Shape> aShapesSelected;
+
+  NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
+  aLContext->MainSelector()->ActiveOwners(anActiveOwners);
+  NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (anActiveOwners);
+  Handle(SelectMgr_EntityOwner) anOwner;
+  for (; anOwnersIt.More(); anOwnersIt.Next()) {
+    anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value());
+    Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(anOwner);
+    if (!BROwnr.IsNull() && BROwnr->HasShape() && theShapesToBeSelected.Contains(BROwnr->Shape())) {
+      if (aShapesSelected.Contains(BROwnr->Shape()))
+        continue;
+      AIS_Selection::Selection(aSelectionName.ToCString())->Select(anOwner);
+      anOwner->SetSelected (Standard_True);
+      aShapesSelected.Add(BROwnr->Shape());
+    }
+  }
+  aLContext->HilightPicked(Standard_False);
+}