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