From ab9e277f15988c69343b64ac487163b41ec120f4 Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 27 Aug 2019 08:26:23 +0300 Subject: [PATCH] 0031193: Visualization - OpenGl_Flipping wrong text position if local transformation set Before the patch, if the values of the isReversedX/Y/Z variables were set to false, then the WorldView matrix did not change and local transformation was not applied, which caused errors. In order to correctly set the local transformation in case the text does not have its own attach point, the local transformation is set in OpenGl_Text, and the ModelWorld matrix is changed in OpenGl_Flipper, instead of the WorldView matrix. In this case, local transformation will always be applied. bugs/vis/bug31193: test case added --- src/AIS/AIS_TextLabel.cxx | 14 ++++++++++---- src/AIS/AIS_TextLabel.hxx | 7 +++++++ src/OpenGl/OpenGl_Flipper.cxx | 18 +++++++++++------- src/OpenGl/OpenGl_Text.cxx | 6 ++++++ src/ViewerTest/ViewerTest_ObjectCommands.cxx | 10 ++++++++++ tests/bugs/vis/bug31193 | 18 ++++++++++++++++++ 6 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 tests/bugs/vis/bug31193 diff --git a/src/AIS/AIS_TextLabel.cxx b/src/AIS/AIS_TextLabel.cxx index cd99f683e4..6fb02a21ef 100644 --- a/src/AIS/AIS_TextLabel.cxx +++ b/src/AIS/AIS_TextLabel.cxx @@ -37,9 +37,10 @@ IMPLEMENT_STANDARD_RTTIEXT(AIS_TextLabel,AIS_InteractiveObject) //purpose : //======================================================================= AIS_TextLabel::AIS_TextLabel() -: myText ("?"), - myHasOrientation3D (Standard_False), - myHasFlipping (Standard_False) +: myText ("?"), + myHasOrientation3D (Standard_False), + myHasOwnAnchorPoint (Standard_True), + myHasFlipping (Standard_False) { myDrawer->SetTextAspect (new Prs3d_TextAspect()); myDrawer->SetDisplayMode (0); @@ -322,7 +323,12 @@ void AIS_TextLabel::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePr gp_Ax2 anOrientation = myOrientation3D; anOrientation.SetLocation (aPosition); - Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (thePrs), anAsp, myText, myOrientation3D, !myHasFlipping); + Standard_Boolean aHasOwnAnchor = HasOwnAnchorPoint(); + if (myHasFlipping) + { + aHasOwnAnchor = Standard_False; // always not using own anchor if flipping + } + Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (thePrs), anAsp, myText, myOrientation3D, aHasOwnAnchor); if (myHasFlipping && isInit) { Prs3d_Root::CurrentGroup (thePrs)->SetFlippingOptions (Standard_False, gp_Ax2()); diff --git a/src/AIS/AIS_TextLabel.hxx b/src/AIS/AIS_TextLabel.hxx index 4386ff44b6..cccdcd2c9c 100644 --- a/src/AIS/AIS_TextLabel.hxx +++ b/src/AIS/AIS_TextLabel.hxx @@ -102,6 +102,12 @@ public: Standard_EXPORT Standard_Boolean HasFlipping() const; + //! Returns flag if text uses position as point of attach + Standard_Boolean HasOwnAnchorPoint() const { return myHasOwnAnchorPoint; } + + //! Set flag if text uses position as point of attach + void SetOwnAnchorPoint (const Standard_Boolean theOwnAnchorPoint) { myHasOwnAnchorPoint = theOwnAnchorPoint; } + //! Define the display type of the text. //! //! TODT_NORMAL Default display. Text only. @@ -131,6 +137,7 @@ protected: TCollection_ExtendedString myText; gp_Ax2 myOrientation3D; Standard_Boolean myHasOrientation3D; + Standard_Boolean myHasOwnAnchorPoint; Standard_Boolean myHasFlipping; public: diff --git a/src/OpenGl/OpenGl_Flipper.cxx b/src/OpenGl/OpenGl_Flipper.cxx index b3322df22d..ff45c16cf5 100755 --- a/src/OpenGl/OpenGl_Flipper.cxx +++ b/src/OpenGl/OpenGl_Flipper.cxx @@ -69,15 +69,19 @@ void OpenGl_Flipper::Render (const Handle(OpenGl_Workspace)& theWorkspace) const if (!myIsEnabled) { // restore matrix state - aContext->WorldViewState.Pop(); + aContext->ModelWorldState.Pop(); // Apply since we probably in the middle of something. - aContext->ApplyModelViewMatrix(); + aContext->ApplyModelWorldMatrix(); return; } - aContext->WorldViewState.Push(); - OpenGl_Mat4 aMatrixMV = aContext->WorldViewState.Current() * aContext->ModelWorldState.Current(); + aContext->ModelWorldState.Push(); + + OpenGl_Mat4 aModelWorldMatrix; + aModelWorldMatrix.Convert (aContext->ModelWorldState.Current()); + + OpenGl_Mat4 aMatrixMV = aContext->WorldViewState.Current() * aModelWorldMatrix; const OpenGl_Vec4 aMVReferenceOrigin = aMatrixMV * myReferenceOrigin; const OpenGl_Vec4 aMVReferenceX = aMatrixMV * OpenGl_Vec4 (myReferenceX.xyz() + myReferenceOrigin.xyz(), 1.0f); @@ -129,11 +133,11 @@ void OpenGl_Flipper::Render (const Handle(OpenGl_Workspace)& theWorkspace) const aTransform = aRefAxes * aTransform * aRefInv; // transform model-view matrix - aMatrixMV = aMatrixMV * aTransform; + aModelWorldMatrix = aModelWorldMatrix * aTransform; // load transformed model-view matrix - aContext->WorldViewState.SetCurrent (aMatrixMV); - aContext->ApplyWorldViewMatrix(); + aContext->ModelWorldState.SetCurrent (aModelWorldMatrix); + aContext->ApplyModelWorldMatrix(); } // ======================================================================= diff --git a/src/OpenGl/OpenGl_Text.cxx b/src/OpenGl/OpenGl_Text.cxx index a3c5be6a13..d9551e0a0e 100644 --- a/src/OpenGl/OpenGl_Text.cxx +++ b/src/OpenGl/OpenGl_Text.cxx @@ -472,6 +472,12 @@ void OpenGl_Text::setupMatrix (const Handle(OpenGl_Context)& theCtx, { OpenGl_Mat4d aCurrentWorldViewMat; aCurrentWorldViewMat.Convert (theCtx->WorldViewState.Current()); + + // apply local transformation + OpenGl_Mat4d aModelWorld; + aModelWorld.Convert (theCtx->ModelWorldState.Current()); + aCurrentWorldViewMat = aCurrentWorldViewMat * aModelWorld; + theCtx->WorldViewState.SetCurrent (aCurrentWorldViewMat * aModViewMat); } else diff --git a/src/ViewerTest/ViewerTest_ObjectCommands.cxx b/src/ViewerTest/ViewerTest_ObjectCommands.cxx index 95995ad911..e4f4fd0906 100644 --- a/src/ViewerTest/ViewerTest_ObjectCommands.cxx +++ b/src/ViewerTest/ViewerTest_ObjectCommands.cxx @@ -2539,6 +2539,15 @@ static int VDrawText (Draw_Interpretor& theDI, { aTextPrs->SetFlipping (Standard_True); } + else if (aParam == "-ownanchor") + { + if (++anArgIt >= theArgsNb) + { + std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n"; + return 1; + } + aTextPrs->SetOwnAnchorPoint (Draw::Atoi (theArgVec[anArgIt]) == 1); + } else if (aParam == "-disptype" || aParam == "-displaytype") { @@ -6512,6 +6521,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) "\n\t\t: [-noupdate]" "\n\t\t: [-plane NormX NormY NormZ DirX DirY DirZ]" "\n\t\t: [-flipping]" + "\n\t\t: [-ownanchor {0|1}=1]" "\n\t\t: Display text label at specified position.", __FILE__, VDrawText, group); diff --git a/tests/bugs/vis/bug31193 b/tests/bugs/vis/bug31193 new file mode 100644 index 0000000000..133fe1f396 --- /dev/null +++ b/tests/bugs/vis/bug31193 @@ -0,0 +1,18 @@ +puts "=============" +puts "0031193: Visualization - OpenGl_Flipping wrong text position if local transformation set" +puts "=============" + +vfont add [locate_data_file DejaVuSans.ttf] SansFont + +vinit View1 +vtrihedron trihedr + +vdrawtext Text "First line\nSecond line" -pos 10 0 0 -color red -plane 1 0 0 0 1 0 -flipping -halign center -valign top -height 50 -font SansFont + +vright +vrotate 0 3.14 0 +vlocation Text -rotate 0 0 0 0 1 0 180 + +if {[vreadpixel 67 126 rgb name] == "RED"} { puts "ERROR: the text is not flipped" } + +vdump $imagedir/${casename}.png