0030523: Visualization - Highlighting does not work anymore
authorBenjamin Bihler <benjamin.bihler@compositence.de>
Wed, 6 Mar 2019 12:02:29 +0000 (15:02 +0300)
committerapn <apn@opencascade.com>
Thu, 7 Mar 2019 15:06:49 +0000 (18:06 +0300)
Added hints about ZLayer consideration and changing highlight colors to documentation
of AIS_InteractiveContext::SetHighlightStyle() method.

AIS_InteractiveContext::MoveTo() now checks if highlighting style does not use immediate layer
and performs full Redraw() instead of RedrawImmediate().

Improved parsing of ZLayer names within vdisplay, vzlayer and vselprops commands.
vreadpixel now reports syntax errors on wrong input.

src/AIS/AIS_InteractiveContext.hxx
src/AIS/AIS_InteractiveContext_1.cxx
src/ViewerTest/ViewerTest.cxx
src/ViewerTest/ViewerTest.hxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/v3d/materials/bug27818_2

index ff39816..5cbf653 100644 (file)
@@ -198,6 +198,21 @@ public: //! @name highlighting management
   const Handle(Prs3d_Drawer)& HighlightStyle (const Prs3d_TypeOfHighlight theStyleType) const { return myStyles[theStyleType]; }
 
   //! Setup highlight style settings.
+  //! It is preferred modifying existing style returned by method HighlightStyle()
+  //! instead of creating a new drawer.
+  //!
+  //! If a new highlight style is created, its presentation Zlayer should be checked,
+  //! otherwise highlighting might not work as expected.
+  //! Default values are:
+  //!  - Prs3d_TypeOfHighlight_Dynamic:      Graphic3d_ZLayerId_Top,
+  //!    object highlighting is drawn on top of main scene within Immediate Layers,
+  //!    so that V3d_View::RedrawImmediate() will be enough to see update;
+  //!  - Prs3d_TypeOfHighlight_LocalDynamic: Graphic3d_ZLayerId_Topmost,
+  //!    object parts highlighting is drawn on top of main scene within Immediate Layers
+  //!    with depth cleared (even overlapped geometry will be revealed);
+  //!  - Prs3d_TypeOfHighlight_Selected:     Graphic3d_ZLayerId_UNKNOWN,
+  //!    object highlighting is drawn on top of main scene within the same layer
+  //!    as object itself (e.g. Graphic3d_ZLayerId_Default by default) and increased priority.
   void SetHighlightStyle (const Prs3d_TypeOfHighlight theStyleType,
                           const Handle(Prs3d_Drawer)& theStyle) { myStyles[theStyleType] = theStyle; }
 
@@ -212,6 +227,14 @@ public: //! @name highlighting management
   }
 
   //! Setup the style of dynamic highlighting.
+  //! It is preferred modifying existing style returned by method HighlightStyle()
+  //! instead of creating a new drawer.
+  //!
+  //! If a new highlight style is created, its presentation Zlayer should be checked,
+  //! otherwise highlighting might not work as expected.
+  //! Default value is Graphic3d_ZLayerId_Top,
+  //! object highlighting is drawn on top of main scene within Immediate Layers,
+  //! so that V3d_View::RedrawImmediate() will be enough to see update;
   void SetHighlightStyle (const Handle(Prs3d_Drawer)& theStyle) { myStyles[Prs3d_TypeOfHighlight_Dynamic] = theStyle; }
 
   //! Returns current selection style settings.
@@ -1262,6 +1285,10 @@ protected: //! @name internal methods
     return myStyles[!theOwner.IsNull() && theOwner->ComesFromDecomposition() ? Prs3d_TypeOfHighlight_LocalDynamic : Prs3d_TypeOfHighlight_Dynamic];
   }
 
+  //! Return TRUE if highlight style of owner requires full viewer redraw.
+  Standard_EXPORT Standard_Boolean isSlowHiStyle (const Handle(SelectMgr_EntityOwner)& theOwner,
+                                                  const Handle(V3d_Viewer)& theViewer) const;
+
   //! Helper function that returns correct selection style for the object:
   //! if custom style is defined via object's highlight drawer, it will be used. Otherwise,
   //! selection style of interactive context will be returned.
index ce73686..e20b0ec 100644 (file)
@@ -294,6 +294,22 @@ void AIS_InteractiveContext::highlightWithSubintensity (const Handle(SelectMgr_E
 }
 
 //=======================================================================
+//function : isSlowHiStyle
+//purpose  :
+//=======================================================================
+Standard_Boolean AIS_InteractiveContext::isSlowHiStyle (const Handle(SelectMgr_EntityOwner)& theOwner,
+                                                        const Handle(V3d_Viewer)& theViewer) const
+{
+  if (const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable()))
+  {
+    const Handle(Prs3d_Drawer)& aHiStyle = getHiStyle (anObj, myLastPicked);
+    return aHiStyle->ZLayer() == Graphic3d_ZLayerId_UNKNOWN
+       || !theViewer->ZLayerSettings (aHiStyle->ZLayer()).IsImmediate();
+  }
+  return Standard_False;
+}
+
+//=======================================================================
 //function : MoveTo
 //purpose  :
 //=======================================================================
@@ -372,6 +388,11 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  th
     // method call. As result it is necessary to rehighligt it with mySelectionColor.
     if (!myLastPicked.IsNull() && myLastPicked->HasSelectable())
     {
+      if (isSlowHiStyle (myLastPicked, theView->Viewer()))
+      {
+        theView->Viewer()->Invalidate();
+      }
+
       clearDynamicHighlight();
       toUpdateViewer = Standard_True;
     }
@@ -387,6 +408,11 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  th
        && (!myLastPicked->IsSelected()
          || myToHilightSelected))
       {
+        if (isSlowHiStyle (myLastPicked, theView->Viewer()))
+        {
+          theView->Viewer()->Invalidate();
+        }
+
         highlightWithColor (myLastPicked, theView->Viewer());
         toUpdateViewer = Standard_True;
       }
@@ -405,6 +431,11 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  th
     && !myLastPicked.IsNull()
      && myLastPicked->HasSelectable())
     {
+      if (isSlowHiStyle (myLastPicked, theView->Viewer()))
+      {
+        theView->Viewer()->Invalidate();
+      }
+
       clearDynamicHighlight();
       toUpdateViewer = Standard_True;
     }
@@ -422,7 +453,14 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  th
     }
     else
     {
-      theView->Viewer()->RedrawImmediate();
+      if (theView->IsInvalidated())
+      {
+        theView->Viewer()->Redraw();
+      }
+      else
+      {
+        theView->Viewer()->RedrawImmediate();
+      }
     }
   }
 
index d52acd1..c51d9bc 100644 (file)
@@ -402,6 +402,75 @@ Standard_Boolean ViewerTest::ParseShadingModel (Standard_CString              th
 }
 
 //=======================================================================
+//function : parseZLayer
+//purpose  :
+//=======================================================================
+Standard_Boolean ViewerTest::parseZLayer (Standard_CString theArg,
+                                          Standard_Boolean theToAllowInteger,
+                                          Graphic3d_ZLayerId& theLayer)
+{
+  TCollection_AsciiString aName (theArg);
+  aName.LowerCase();
+  if (aName == "default"
+   || aName == "def")
+  {
+    theLayer = Graphic3d_ZLayerId_Default;
+  }
+  else if (aName == "top")
+  {
+    theLayer = Graphic3d_ZLayerId_Top;
+  }
+  else if (aName == "topmost")
+  {
+    theLayer = Graphic3d_ZLayerId_Topmost;
+  }
+  else if (aName == "overlay"
+        || aName == "toposd")
+  {
+    theLayer = Graphic3d_ZLayerId_TopOSD;
+  }
+  else if (aName == "underlay"
+        || aName == "botosd")
+  {
+    theLayer = Graphic3d_ZLayerId_BotOSD;
+  }
+  else if (aName == "undefined")
+  {
+    theLayer = Graphic3d_ZLayerId_UNKNOWN;
+  }
+  else if (!GetAISContext().IsNull())
+  {
+    const Handle(V3d_Viewer)& aViewer = ViewerTest::GetAISContext()->CurrentViewer();
+    TColStd_SequenceOfInteger aLayers;
+    aViewer->GetAllZLayers (aLayers);
+    for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
+    {
+      Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
+      if (TCollection_AsciiString::IsSameString (aSettings.Name(), aName, Standard_False))
+      {
+        theLayer = aLayeriter.Value();
+        return true;
+      }
+    }
+
+    if (!theToAllowInteger
+     || !aName.IsIntegerValue())
+    {
+      return false;
+    }
+    Graphic3d_ZLayerId aLayer = aName.IntegerValue();
+    if (aLayer == Graphic3d_ZLayerId_UNKNOWN
+     || std::find (aLayers.begin(), aLayers.end(), aLayer) != aLayers.end())
+    {
+      theLayer = aLayer;
+      return true;
+    }
+    return false;
+  }
+  return true;
+}
+
+//=======================================================================
 //function : GetTypeNames
 //purpose  :
 //=======================================================================
@@ -4634,22 +4703,17 @@ static int VDisplay2 (Draw_Interpretor& theDI,
         aTrsfPers = Graphic3d_TransformPers::FromDeprecatedParams (aTrsfPers->Mode(), aPnt);
       }
     }
-    else if (aNameCase == "-layer")
+    else if (aNameCase == "-layer"
+          || aNameCase == "-zlayer")
     {
-      if (++anArgIter >= theArgNb)
-      {
-        std::cerr << "Error: wrong syntax at " << aName << ".\n";
-        return 1;
-      }
-
-      TCollection_AsciiString aValue (theArgVec[anArgIter]);
-      if (!aValue.IsIntegerValue())
+      ++anArgIter;
+      if (anArgIter >= theArgNb
+      || !ViewerTest::ParseZLayer (theArgVec[anArgIter], aZLayer)
+      ||  aZLayer == Graphic3d_ZLayerId_UNKNOWN)
       {
         std::cerr << "Error: wrong syntax at " << aName << ".\n";
         return 1;
       }
-
-      aZLayer = aValue.IntegerValue();
     }
     else if (aNameCase == "-view"
           || aNameCase == "-inview")
index 2c5cdcd..a4d1165 100644 (file)
 #include <Aspect_TypeOfMarker.hxx>
 #include <Draw_Interpretor.hxx>
 #include <Graphic3d_TypeOfShadingModel.hxx>
-#include <Standard_Integer.hxx>
-#include <Standard_CString.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Macro.hxx>
+#include <Graphic3d_ZLayerId.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <TColStd_HArray1OfTransient.hxx>
 #include <TopTools_ListOfShape.hxx>
@@ -213,6 +210,26 @@ public:
   Standard_EXPORT static Standard_Boolean ParseShadingModel (Standard_CString              theArg,
                                                              Graphic3d_TypeOfShadingModel& theModel);
 
+  //! Parses ZLayer name.
+  //! @param theArg [in] layer name or enumeration alias
+  //! @param theLayer [out] layer index
+  //! @return TRUE if layer has been identified, note that Graphic3d_ZLayerId_UNKNOWN is also valid value
+  static Standard_Boolean ParseZLayerName (Standard_CString theArg,
+                                           Graphic3d_ZLayerId& theLayer)
+  {
+    return parseZLayer (theArg, false, theLayer);
+  }
+
+  //! Parses ZLayer name.
+  //! @param theArg [in] layer name, enumeration alias or index (of existing Layer)
+  //! @param theLayer [out] layer index
+  //! @return TRUE if layer has been identified, note that Graphic3d_ZLayerId_UNKNOWN is also valid value
+  static Standard_Boolean ParseZLayer (Standard_CString theArg,
+                                       Graphic3d_ZLayerId& theLayer)
+  {
+    return parseZLayer (theArg, true, theLayer);
+  }
+
 private:
 
   //! Parses RGB(A) color argument(s) specified within theArgVec[0], theArgVec[1], theArgVec[2] and theArgVec[3].
@@ -225,6 +242,15 @@ private:
                                                       Quantity_ColorRGBA& theColor,
                                                       bool theToParseAlpha);
 
+  //! Parses ZLayer name.
+  //! @param theArg [in] layer name, enumeration alias or index (of existing Layer)
+  //! @param theToAllowInteger [in] when TRUE, the argument will be checked for existing layer index
+  //! @param theLayer [out] layer index
+  //! @return TRUE if layer has been identified, note that Graphic3d_ZLayerId_UNKNOWN is also valid value
+  Standard_EXPORT static Standard_Boolean parseZLayer (Standard_CString theArg,
+                                                       Standard_Boolean theToAllowInteger,
+                                                       Graphic3d_ZLayerId& theLayer);
+
   //! Returns a window class that implements standard behavior of
   //! all windows of the ViewerTest. This includes usual Open CASCADE
   //! view conventions for mouse buttons (e.g. Ctrl+MB1 for zoom,
index ba4e3e6..3056b3c 100644 (file)
@@ -4759,56 +4759,18 @@ static int VZLayer (Draw_Interpretor& theDI,
     ++anArgIter;
   }
 
-  TCollection_AsciiString aFirstArg (theArgVec[anArgIter]);
-  if (aFirstArg.IsIntegerValue())
   {
-    ++anArgIter;
-    aLayerId = aFirstArg.IntegerValue();
-  }
-  else
-  {
-    aFirstArg.LowerCase();
-    if (aFirstArg == "default"
-     || aFirstArg == "def")
-    {
-      aLayerId = Graphic3d_ZLayerId_Default;
-      ++anArgIter;
-    }
-    else if (aFirstArg == "top")
-    {
-      aLayerId = Graphic3d_ZLayerId_Top;
-      ++anArgIter;
-    }
-    else if (aFirstArg == "topmost")
-    {
-      aLayerId = Graphic3d_ZLayerId_Topmost;
-      ++anArgIter;
-    }
-    else if (aFirstArg == "overlay"
-          || aFirstArg == "toposd")
-    {
-      aLayerId = Graphic3d_ZLayerId_TopOSD;
-      ++anArgIter;
-    }
-    else if (aFirstArg == "underlay"
-          || aFirstArg == "botosd")
+    TCollection_AsciiString aFirstArg (theArgVec[anArgIter]);
+    if (aFirstArg.IsIntegerValue())
     {
-      aLayerId = Graphic3d_ZLayerId_BotOSD;
       ++anArgIter;
+      aLayerId = aFirstArg.IntegerValue();
     }
     else
     {
-      TColStd_SequenceOfInteger aLayers;
-      aViewer->GetAllZLayers (aLayers);
-      for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
+      if (ViewerTest::ParseZLayerName (aFirstArg.ToCString(), aLayerId))
       {
-        Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
-        if (TCollection_AsciiString::IsSameString (aSettings.Name(), aFirstArg, Standard_False))
-        {
-          aLayerId = aLayeriter.Value();
-          ++anArgIter;
-          break;
-        }
+        ++anArgIter;
       }
     }
   }
@@ -6323,41 +6285,52 @@ static int VReadPixel (Draw_Interpretor& theDI,
   {
     TCollection_AsciiString aParam (theArgVec[anIter]);
     aParam.LowerCase();
-    if (aParam == "rgb")
+    if (aParam == "-rgb"
+     || aParam == "rgb")
     {
       aFormat     = Image_Format_RGB;
       aBufferType = Graphic3d_BT_RGB;
     }
-    else if (aParam == "hls")
+    else if (aParam == "-hls"
+          || aParam == "hls")
     {
       aFormat     = Image_Format_RGB;
       aBufferType = Graphic3d_BT_RGB;
       toShowHls   = Standard_True;
     }
-    else if (aParam == "rgbf")
+    else if (aParam == "-rgbf"
+          || aParam == "rgbf")
     {
       aFormat     = Image_Format_RGBF;
       aBufferType = Graphic3d_BT_RGB;
     }
-    else if (aParam == "rgba")
+    else if (aParam == "-rgba"
+          || aParam == "rgba")
     {
       aFormat     = Image_Format_RGBA;
       aBufferType = Graphic3d_BT_RGBA;
     }
-    else if (aParam == "rgbaf")
+    else if (aParam == "-rgbaf"
+          || aParam == "rgbaf")
     {
       aFormat     = Image_Format_RGBAF;
       aBufferType = Graphic3d_BT_RGBA;
     }
-    else if (aParam == "depth")
+    else if (aParam == "-depth"
+          || aParam == "depth")
     {
       aFormat     = Image_Format_GrayF;
       aBufferType = Graphic3d_BT_Depth;
     }
-    else if (aParam == "name")
+    else if (aParam == "-name"
+          || aParam == "name")
     {
       toShowName = Standard_True;
     }
+    else
+    {
+      std::cout << "Syntax error at '" << aParam << "'\n";
+    }
   }
 
   Image_PixMap anImage;
@@ -12232,16 +12205,12 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
         return 1;
       }
 
-      const Standard_Integer aNewLayer = Draw::Atoi (theArgVec[++anArgIter]);
-      if (aNewLayer != Graphic3d_ZLayerId_UNKNOWN)
+      ++anArgIter;
+      Graphic3d_ZLayerId aNewLayer = Graphic3d_ZLayerId_UNKNOWN;
+      if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aNewLayer))
       {
-        TColStd_SequenceOfInteger aLayers;
-        aCtx->CurrentViewer()->GetAllZLayers (aLayers);
-        if (std::find (aLayers.begin(), aLayers.end(), aNewLayer) == aLayers.end())
-        {
-          std::cout << "Syntax error: Layer " << aNewLayer << " is undefined\n";
-          return 1;
-        }
+        std::cerr << "Error: wrong syntax at " << theArgVec[anArgIter] << ".\n";
+        return 1;
       }
 
       const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
@@ -12825,7 +12794,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     " with f option returns free memory in bytes",
     __FILE__, VMemGpu, group);
   theCommands.Add ("vreadpixel",
-    "vreadpixel xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]"
+    "vreadpixel xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [-name]"
     " : Read pixel value for active view",
     __FILE__, VReadPixel, group);
   theCommands.Add("diffimage",
index 44d02b7..6eb7f60 100644 (file)
@@ -29,7 +29,7 @@ vselect 50 200 1
 vselect 200 200 1
 vselect 350 200 1
 
-if {[vreadpixel 350 200 name rgba] != "RED3 1" || [vreadpixel 350 200 1 rgba] == [vreadpixel 200 200 1 rgba]} {
+if {[vreadpixel 350 200 name rgba] != "RED3 1" || [vreadpixel 350 200 name rgba] == [vreadpixel 200 200 name rgba]} {
   puts "ERROR: selection highlight of 3rd box is displayed with wrong color!"
 }