0031193: Visualization - OpenGl_Flipping wrong text position if local transformation set
authornds <nds@opencascade.com>
Tue, 27 Aug 2019 05:26:23 +0000 (08:26 +0300)
committermzernova <mzernova@opencascade.com>
Wed, 29 Apr 2020 13:36:23 +0000 (16:36 +0300)
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
src/AIS/AIS_TextLabel.hxx
src/OpenGl/OpenGl_Flipper.cxx
src/OpenGl/OpenGl_Text.cxx
src/ViewerTest/ViewerTest_ObjectCommands.cxx
tests/bugs/vis/bug31193 [new file with mode: 0644]

index cd99f68..6fb02a2 100644 (file)
@@ -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());
index 4386ff4..cccdcd2 100644 (file)
@@ -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:
index b3322df..ff45c16 100755 (executable)
@@ -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();
 }
 
 // =======================================================================
index a3c5be6..d9551e0 100644 (file)
@@ -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<Standard_Real> (aCurrentWorldViewMat * aModViewMat);
   }
   else
index 95995ad..e4f4fd0 100644 (file)
@@ -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 (file)
index 0000000..133fe1f
--- /dev/null
@@ -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