Salome HOME
Fix for the issue #19726 : Placement failed because of wrong name in face selection.
[modules/shaper.git] / src / XGUI / XGUI_Displayer.cpp
index c96dd3e7c5da6069654347f5919aa02fd7961f97..096749adb72ec4a89e3729695329a17e895a349e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2020  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
 #include <SelectMgr_ListIteratorOfListOfFilter.hxx>
 #include <SelectMgr_SelectionManager.hxx>
 #include <TColStd_ListIteratorOfListOfInteger.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
 
 #include <StdSelect_ViewerSelector3d.hxx>
 
 #include <TColStd_MapOfTransient.hxx>
 #include <TColStd_MapIteratorOfMapOfTransient.hxx>
+#include <Standard_Version.hxx>
 
 #ifdef TINSPECTOR
 #include <inspector/VInspectorAPI_CallBack.hxx>
 
 #include <set>
 
+#ifdef _MSC_VER
+#pragma warning(disable: 4702)
+#endif
+
 /// defines the local context mouse selection sensitivity
 const int MOUSE_SENSITIVITY_IN_PIXEL = 10;
 
@@ -105,7 +111,11 @@ const int MOUSE_SENSITIVITY_IN_PIXEL = 10;
 void displayedObjects(const Handle(AIS_InteractiveContext)& theAIS, AIS_ListOfInteractive& theList)
 {
   // Get from null point
-  theAIS->DisplayedObjects(theList, true);
+#if OCC_VERSION_HEX < 0x070400
+       theAIS->DisplayedObjects(theList, true);
+#else
+       theAIS->DisplayedObjects(theList);
+#endif
 }
 
 QString qIntListInfo(const QIntList& theValues, const QString& theSeparator = QString(", "))
@@ -120,9 +130,12 @@ QString qIntListInfo(const QIntList& theValues, const QString& theSeparator = QS
 
 //**************************************************************
 XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop)
-: myWorkshop(theWorkshop), myNeedUpdate(false),
-  myViewerBlockedRecursiveCount(0), myIsFirstAISContextUse(true)
+: myWorkshop(theWorkshop),
+  myViewerBlockedRecursiveCount(0),
+  myContextId(0),
+  myNeedUpdate(false)
 {
+  BRepMesh_IncrementalMesh::SetParallelDefault(Standard_True);
 }
 
 //**************************************************************
@@ -153,6 +166,8 @@ bool XGUI_Displayer::display(ObjectPtr theObject, bool theUpdateViewer)
         aScreen->setViewScale(getViewScale());
       }
       anAIS = aPrs->getAISObject(anAIS);
+      if (anAIS.get())
+        myWorkshop->module()->customizePresentation(theObject, anAIS);
     } else {
       anAIS = myWorkshop->module()->createPresentation(theObject);
       isShading = true;
@@ -200,10 +215,8 @@ bool XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS,
     //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);
+    aContext->Display(anAISIO, aDispMode, 0, false, AIS_DS_Displayed);
     #ifdef TINSPECTOR
     if (getCallBack()) getCallBack()->Display(anAISIO);
     #endif
@@ -293,45 +306,37 @@ bool XGUI_Displayer::redisplay(ObjectPtr theObject, bool theUpdateViewer)
   }
 
   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
-    // 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
-    // parameter is changed.
-    //bool isEqualShapes = false;
-    //ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
-    //if (aResult.get() != NULL) {
-    //  Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(aAISIO);
-    //  if (!aShapePrs.IsNull()) {
-    //    std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aResult);
-    //    if (aShapePtr.get()) {
-    //      const TopoDS_Shape& aOldShape = aShapePrs->Shape();
-    //      if (!aOldShape.IsNull())
-    //        isEqualShapes = aOldShape.IsEqual(aShapePtr->impl<TopoDS_Shape>());
-    //    }
-    //  }
-    //}
-    // Customization of presentation
-    //bool isCustomized = customizeObject(theObject);
-    #ifdef DEBUG_FEATURE_REDISPLAY
-      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)
-      if (aAISObj.get() && myWorkshop->facesPanel())
-        myWorkshop->facesPanel()->customizeObject(theObject, aAISObj);
+    ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+    if (aResult.get()) {
+      // Set color
+      std::vector<int> aColor;
+      ModelAPI_Tools::getColor(aResult, aColor);
+      if (aColor.size() > 0) {
+        Quantity_Color
+          aCol(aColor[0] / 255., aColor[1] / 255., aColor[2] / 255., Quantity_TOC_RGB);
+        aAISIO->SetColor(aCol);
+      }
+      // Set deflection
+      double aDeflection = ModelAPI_Tools::getDeflection(aResult);
+      if ((aDeflection >= 0) && (aDeflection != aAISObj->getDeflection()))
+        aAISObj->setDeflection(aDeflection);
+
+      // Set transparency
+      double aTransparency = ModelAPI_Tools::getTransparency(aResult);
+      if ((aTransparency >= 0) && (aTransparency != aAISObj->getTransparency()))
+        aAISObj->setTransparency(aTransparency);
+
+      // Set Iso-Lines
+      Handle(ModuleBase_ResultPrs) aResPrs = Handle(ModuleBase_ResultPrs)::DownCast(aAISIO);
+      if (!aResPrs.IsNull())
+        aResPrs->updateIsoLines();
+    }
+    //myWorkshop->module()->storeSelection();
 
-    myWorkshop->module()->storeSelection();
+//#ifdef CLEAR_OUTDATED_SELECTION_BEFORE_REDISPLAY
+    //myWorkshop->selector()->deselectPresentation(aAISIO);
+//#endif
 
-#ifdef CLEAR_OUTDATED_SELECTION_BEFORE_REDISPLAY
-    myWorkshop->selector()->deselectPresentation(aAISIO);
-#endif
     if (aContext->IsDisplayed(aAISIO))
       aContext->Redisplay(aAISIO, false);
     else {
@@ -342,7 +347,7 @@ bool XGUI_Displayer::redisplay(ObjectPtr theObject, bool theUpdateViewer)
       #endif
 
       //if (aNeedToRestoreSelection)
-    myWorkshop->module()->restoreSelection();
+    //myWorkshop->module()->restoreSelection();
 
     aRedisplayed = true;
     #ifdef DEBUG_FEATURE_REDISPLAY
@@ -583,7 +588,8 @@ ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO)
     if (!theIO.IsNull()) {
       anAISObj->setImpl(new Handle(AIS_InteractiveObject)(theIO));
     }
-    anObject = myWorkshop->module()->findPresentedObject(anAISObj);
+    if (myWorkshop->module())
+      anObject = myWorkshop->module()->findPresentedObject(anAISObj);
   }
   return anObject;
 }
@@ -630,16 +636,16 @@ void XGUI_Displayer::updateViewer() const
 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const
 {
   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
-  if (!aContext.IsNull() && myIsFirstAISContextUse/*&& !aContext->HasOpenedContext()*/) {
-    XGUI_Displayer* aDisplayer = (XGUI_Displayer*)this;
-    aDisplayer->myIsFirstAISContextUse = false;
+  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);
+    // Do not modify default drawer. The same is done in ModuleBase_ResultPrs
+    //aContext->DefaultDrawer()->VIsoAspect()->SetNumber(0);
+    //aContext->DefaultDrawer()->UIsoAspect()->SetNumber(0);
 
-    ModuleBase_IViewer::DefaultHighlightDrawer = aContext->HighlightStyle();
     // 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();
@@ -649,10 +655,45 @@ Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const
 
     //ModuleBase_IViewer::DefaultHighlightDrawer->SetDeviationCoefficient(aDeflection);
     //aSelStyle->SetDeviationCoefficient(aDeflection);
+
+    Handle(AIS_Trihedron) aTrihedron = myWorkshop->viewer()->trihedron();
+    if (!aTrihedron.IsNull())
+      ModuleBase_Tools::setPointBallHighlighting(aTrihedron.get());
   }
   return aContext;
 }
 
+//**************************************************************
+void XGUI_Displayer::setSelectionColor(const std::vector<int>& theColor)
+{
+  Handle(AIS_InteractiveContext) aContext = AISContext();
+  if (!aContext.IsNull()) {
+    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);
+  }
+}
+
+
+//**************************************************************
+std::vector<int> XGUI_Displayer::selectionColor() const
+{
+  std::vector<int> 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 aColor;
+}
+
+
 //**************************************************************
 Handle(SelectMgr_AndFilter) XGUI_Displayer::GetFilter()
 {
@@ -672,7 +713,7 @@ bool XGUI_Displayer::displayAIS(AISObjectPtr theAIS, const bool toActivateInSele
   Handle(AIS_InteractiveContext) aContext = AISContext();
   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
   if (!aContext.IsNull() && !anAISIO.IsNull()) {
-    aContext->Display(anAISIO, theDisplayMode, 0, false/*update viewer*/, true, AIS_DS_Displayed);
+    aContext->Display(anAISIO, theDisplayMode, 0, false/*update viewer*/, AIS_DS_Displayed);
     #ifdef TINSPECTOR
     if (getCallBack()) getCallBack()->Display(anAISIO);
     #endif
@@ -1001,9 +1042,9 @@ void XGUI_Displayer::getPresentations(const ObjectPtr& theObject,
     ModelAPI_Tools::allResults(aFeature, aResults);
     std::list<ResultPtr>::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<Handle(AIS_InteractiveObject)>();
+      AISObjectPtr aCurAISObj = getAISObject(*anIt);
+      if (aCurAISObj.get() != NULL) {
+        Handle(AIS_InteractiveObject) anAIS = aCurAISObj->impl<Handle(AIS_InteractiveObject)>();
         if (!anAIS.IsNull() && !thePresentations.Contains(anAIS))
           thePresentations.Add(anAIS);
       }
@@ -1027,7 +1068,6 @@ void XGUI_Displayer::displayTrihedron(bool theToDisplay) const
                         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);
@@ -1067,7 +1107,7 @@ void XGUI_Displayer::AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) th
   /// OCCT: to write about the problem that active owners method returns one owner several times
   QList<size_t> aSelectedIds; // Remember of selected address in order to avoid duplicates
   for (; anOwnersIt.More(); anOwnersIt.Next()) {
-    anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value());
+    anOwner = anOwnersIt.Value();
     if (aSelectedIds.contains((size_t)anOwner.get()))
       continue;
     aSelectedIds.append((size_t)anOwner.get());
@@ -1075,6 +1115,14 @@ void XGUI_Displayer::AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) th
     Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(anOwner);
     if (!BROwnr.IsNull() && BROwnr->HasShape()) {
       const TopoDS_Shape& aShape = BROwnr->Shape();
+
+      Handle(ModuleBase_ResultPrs) aResPrs =
+          Handle(ModuleBase_ResultPrs)::DownCast(BROwnr->Selectable());
+      TopoDS_Shape aRealShape;
+      if (!aResPrs.IsNull()) {
+        aRealShape = aResPrs->originalShape();
+      }
+
       if (aShape.IsNull())
         continue;
 
@@ -1091,7 +1139,15 @@ void XGUI_Displayer::AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) th
           // 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)) {
+        bool isSame = ModuleBase_Tools::isSameShape(aParameterShape, aShape);
+        if (!isSame) {
+          // In case of using HideFaces panel we can have instead of an original shape
+          // a compaund of faces which represent original shape with hidden faces.
+          // So, we have to compare the parameter with original shape
+          if (!aRealShape.IsNull())
+            isSame = ModuleBase_Tools::isSameShape(aParameterShape, aRealShape);
+        }
+        if (isSame) {
           Handle(AIS_InteractiveObject) anOwnerPresentation =
             Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
           NCollection_Map<Handle(AIS_InteractiveObject)> aPresentations =
@@ -1110,7 +1166,7 @@ void XGUI_Displayer::AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) th
           Handle(AIS_Shape) anOwnerPresentation =
                             Handle(AIS_Shape)::DownCast(anOwner->Selectable());
           const TopoDS_Shape& aPresentationShape = anOwnerPresentation->Shape();
-          if (aParameterShape.IsSame(anOwnerPresentation->Shape()) &&
+          if (aParameterShape.IsSame(aPresentationShape) &&
               !aCompsolidPresentations.Contains(anOwnerPresentation))
             aCompsolidPresentations.Add(anOwnerPresentation);
         }