diff --git a/src/AIS/AIS_InteractiveContext.hxx b/src/AIS/AIS_InteractiveContext.hxx index ff398168ce..5cbf65385d 100644 --- a/src/AIS/AIS_InteractiveContext.hxx +++ b/src/AIS/AIS_InteractiveContext.hxx @@ -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. diff --git a/src/AIS/AIS_InteractiveContext_1.cxx b/src/AIS/AIS_InteractiveContext_1.cxx index ce736861ce..e20b0ec2ff 100644 --- a/src/AIS/AIS_InteractiveContext_1.cxx +++ b/src/AIS/AIS_InteractiveContext_1.cxx @@ -293,6 +293,22 @@ void AIS_InteractiveContext::highlightWithSubintensity (const Handle(SelectMgr_E theOwner->HilightWithColor (myMainPM, myStyles[Prs3d_TypeOfHighlight_SubIntensity], theMode); } +//======================================================================= +//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(); + } } } diff --git a/src/ViewerTest/ViewerTest.cxx b/src/ViewerTest/ViewerTest.cxx index d52acd1f7e..c51d9bc94a 100644 --- a/src/ViewerTest/ViewerTest.cxx +++ b/src/ViewerTest/ViewerTest.cxx @@ -401,6 +401,75 @@ Standard_Boolean ViewerTest::ParseShadingModel (Standard_CString th return Standard_True; } +//======================================================================= +//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) + ++anArgIter; + if (anArgIter >= theArgNb + || !ViewerTest::ParseZLayer (theArgVec[anArgIter], aZLayer) + || aZLayer == Graphic3d_ZLayerId_UNKNOWN) { std::cerr << "Error: wrong syntax at " << aName << ".\n"; return 1; } - - TCollection_AsciiString aValue (theArgVec[anArgIter]); - if (!aValue.IsIntegerValue()) - { - std::cerr << "Error: wrong syntax at " << aName << ".\n"; - return 1; - } - - aZLayer = aValue.IntegerValue(); } else if (aNameCase == "-view" || aNameCase == "-inview") diff --git a/src/ViewerTest/ViewerTest.hxx b/src/ViewerTest/ViewerTest.hxx index 2c5cdcdee2..a4d11658b6 100644 --- a/src/ViewerTest/ViewerTest.hxx +++ b/src/ViewerTest/ViewerTest.hxx @@ -20,10 +20,7 @@ #include #include #include -#include -#include -#include -#include +#include #include #include #include @@ -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, diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index ba4e3e6e49..3056b3ca6a 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -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") + TCollection_AsciiString aFirstArg (theArgVec[anArgIter]); + if (aFirstArg.IsIntegerValue()) { - 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") - { - 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", diff --git a/tests/v3d/materials/bug27818_2 b/tests/v3d/materials/bug27818_2 index 44d02b7fd0..6eb7f604a0 100644 --- a/tests/v3d/materials/bug27818_2 +++ b/tests/v3d/materials/bug27818_2 @@ -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!" }