0029993: Visualization - AIS_TextLabel computes selection primitive only for attachme...
authormzernova <mzernova@opencascade.com>
Tue, 3 Dec 2019 09:32:39 +0000 (12:32 +0300)
committerbugmaster <bugmaster@opencascade.com>
Mon, 6 Jul 2020 15:31:13 +0000 (18:31 +0300)
The text label is selected as a rectangle (adds a sensitive object - Select3D_SensitiveFace).
The bounding box has been resized to fit the sensitive rectangle.
Transform persistent has been added to AIS_TextLabel to correctly position the sensitive rectangle.
The findConnectedObject function has also been changed to correctly set transform persistence.

src/AIS/AIS_TextLabel.cxx
src/AIS/AIS_TextLabel.hxx
src/SelectMgr/SelectMgr_ViewerSelector3d.cxx
src/ViewerTest/ViewerTest_ObjectCommands.cxx
tests/3rdparty/fonts/A2
tests/3rdparty/fonts/A7
tests/bugs/vis/bug24837_2

index 6fb02a2..3217ebf 100644 (file)
@@ -24,6 +24,7 @@
 #include <Prs3d_Text.hxx>
 #include <Prs3d_TextAspect.hxx>
 
+#include <Select3D_SensitiveFace.hxx>
 #include <Select3D_SensitivePoint.hxx>
 #include <SelectMgr_Selection.hxx>
 #include <SelectMgr_EntityOwner.hxx>
@@ -272,55 +273,34 @@ void AIS_TextLabel::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePr
       Handle(Prs3d_TextAspect) anAsp = myDrawer->TextAspect();
       gp_Pnt aPosition = Position();
 
+      const Standard_Boolean isTextZoomable = anAsp->Aspect()->GetTextZoomable();
+      if (myHasOrientation3D)
+      {
+        anAsp->Aspect()->SetTextZoomable (myHasFlipping ? Standard_True : Standard_False);
+        SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_ZoomPers, aPosition));
+        aPosition = gp::Origin();
+      }
+      else if (isTextZoomable
+            || TransformPersistence().IsNull()
+            || TransformPersistence()->Mode() != Graphic3d_TMF_2d)
+      {
+        Handle(Graphic3d_TransformPers) aTrsfPers =
+          new Graphic3d_TransformPers (isTextZoomable ? Graphic3d_TMF_RotatePers : Graphic3d_TMF_ZoomRotatePers, aPosition);
+        SetTransformPersistence (aTrsfPers);
+        aPosition = gp::Origin();
+      }
+
+      gp_Pnt aCenterOfLabel;
+      Standard_Real aWidth, aHeight;
+
+      Standard_Boolean isInit = calculateLabelParams (aPosition, aCenterOfLabel, aWidth, aHeight);
       if (myHasOrientation3D)
       {
-        Standard_Boolean isInit = Standard_False;
         if (myHasFlipping)
         {
-          // Get width and height of text
-          Font_FTFontParams aFontParams;
-          aFontParams.PointSize  = (unsigned int )anAsp->Height();
-          aFontParams.Resolution = GetContext()->CurrentViewer()->DefaultRenderingParams().Resolution;
-          if (Handle(Font_FTFont) aFont = Font_FTFont::FindAndCreate (anAsp->Aspect()->Font(), anAsp->Aspect()->GetTextFontAspect(), aFontParams))
-          {
-            isInit = Standard_True;
-            const NCollection_String aText (myText.ToExtString());
-            Font_Rect aBndBox = aFont->BoundingBox (aText, anAsp->HorizontalJustification(), anAsp->VerticalJustification());
-            Standard_Real aWidth = Abs (aBndBox.Width());
-            Standard_Real aHeight = Abs (aBndBox.Height());
-            gp_Pnt aCenterOfLabel = aPosition;
-
-            if (anAsp->VerticalJustification() == Graphic3d_VTA_BOTTOM)
-            {
-              aCenterOfLabel.ChangeCoord() += myOrientation3D.YDirection().XYZ() * aHeight * 0.5;
-            }
-            else if (anAsp->VerticalJustification() == Graphic3d_VTA_TOP)
-            {
-              aCenterOfLabel.ChangeCoord() -= myOrientation3D.YDirection().XYZ() * aHeight * 0.5;
-            }
-            if (anAsp->HorizontalJustification() == Graphic3d_HTA_LEFT)
-            {
-              aCenterOfLabel.ChangeCoord() += myOrientation3D.XDirection().XYZ() * aWidth * 0.5;
-            }
-            else if (anAsp->HorizontalJustification() == Graphic3d_HTA_RIGHT)
-            {
-              aCenterOfLabel.ChangeCoord() -= myOrientation3D.XDirection().XYZ() * aWidth * 0.5;
-            }
-
-            if (!anAsp->Aspect()->GetTextZoomable()
-             && (TransformPersistence().IsNull()
-              || TransformPersistence()->Mode() == Graphic3d_TMF_ZoomPers))
-            {
-              anAsp->Aspect()->SetTextZoomable (Standard_True);
-              SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_ZoomPers, aPosition));
-              aPosition = gp::Origin();
-            }
-
-            gp_Ax2 aFlippingAxes (aCenterOfLabel, myOrientation3D.Direction(), myOrientation3D.XDirection());
-            Prs3d_Root::CurrentGroup (thePrs)->SetFlippingOptions (Standard_True, aFlippingAxes);
-          }
+          gp_Ax2 aFlippingAxes (aCenterOfLabel, myOrientation3D.Direction(), myOrientation3D.XDirection());
+          Prs3d_Root::CurrentGroup (thePrs)->SetFlippingOptions (Standard_True, aFlippingAxes);
         }
-
         gp_Ax2 anOrientation = myOrientation3D;
         anOrientation.SetLocation (aPosition);
         Standard_Boolean aHasOwnAnchor = HasOwnAnchorPoint();
@@ -328,7 +308,7 @@ void AIS_TextLabel::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePr
         {
           aHasOwnAnchor = Standard_False; // always not using own anchor if flipping
         }
-        Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (thePrs), anAsp, myText, myOrientation3D, aHasOwnAnchor);
+        Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (thePrs), anAsp, myText, anOrientation, aHasOwnAnchor);
         if (myHasFlipping && isInit)
         {
           Prs3d_Root::CurrentGroup (thePrs)->SetFlippingOptions (Standard_False, gp_Ax2());
@@ -336,7 +316,21 @@ void AIS_TextLabel::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePr
       }
       else
       {
-        Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (thePrs), anAsp, myText, Position());
+        Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (thePrs), anAsp, myText, aPosition);
+      }
+
+      if (isInit)
+      {
+        const Standard_Real aDx = aWidth * 0.5;
+        const Standard_Real aDy = aHeight * 0.5;
+        gp_Trsf aLabelPlane = calculateLabelTrsf (aPosition, aCenterOfLabel);
+
+        gp_Pnt aMinPnt = gp_Pnt (-aDx, -aDy, 0.0).Transformed (aLabelPlane);
+        gp_Pnt aMaxPnt = gp_Pnt ( aDx,  aDy, 0.0).Transformed (aLabelPlane);
+
+        Graphic3d_BndBox4f& aBox = Prs3d_Root::CurrentGroup (thePrs)->ChangeBoundingBox();
+        aBox.Add (Graphic3d_Vec4 ((float) aMinPnt.X(), (float) aMinPnt.Y(), (float) aMinPnt.Z(), 1.0));
+        aBox.Add (Graphic3d_Vec4 ((float) aMaxPnt.X(), (float) aMaxPnt.Y(), (float) aMaxPnt.Z(), 1.0));
       }
 
       break;
@@ -355,10 +349,110 @@ void AIS_TextLabel::ComputeSelection (const Handle(SelectMgr_Selection)& theSele
   {
     case 0:
     {
-      Handle(SelectMgr_EntityOwner)   anEntityOwner   = new SelectMgr_EntityOwner (this, 10);
-      Handle(Select3D_SensitivePoint) aSensitivePoint = new Select3D_SensitivePoint (anEntityOwner, Position());
-      theSelection->Add (aSensitivePoint);
+      Handle(SelectMgr_EntityOwner) anEntityOwner   = new SelectMgr_EntityOwner (this, 10);
+
+      gp_Pnt aPosition = Position();
+      if (!TransformPersistence().IsNull() && TransformPersistence()->Mode() != Graphic3d_TMF_2d)
+      {
+        aPosition = gp::Origin();
+      }
+
+      gp_Pnt aCenterOfLabel;
+      Standard_Real aWidth, aHeight;
+
+      if (!calculateLabelParams (aPosition, aCenterOfLabel, aWidth, aHeight))
+      {
+        Handle(Select3D_SensitivePoint) aTextSensitive = new Select3D_SensitivePoint (anEntityOwner, aPosition);
+        theSelection->Add (aTextSensitive);
+        break;
+      }
+
+      const Standard_Real aDx = aWidth * 0.5;
+      const Standard_Real aDy = aHeight * 0.5;
+      gp_Trsf aLabelPlane = calculateLabelTrsf (aPosition, aCenterOfLabel);
+
+      // sensitive planar rectangle for text
+      TColgp_Array1OfPnt aRectanglePoints (1, 5);
+      aRectanglePoints.ChangeValue (1) = gp_Pnt (-aDx, -aDy, 0.0).Transformed (aLabelPlane);
+      aRectanglePoints.ChangeValue (2) = gp_Pnt (-aDx,  aDy, 0.0).Transformed (aLabelPlane);
+      aRectanglePoints.ChangeValue (3) = gp_Pnt ( aDx,  aDy, 0.0).Transformed (aLabelPlane);
+      aRectanglePoints.ChangeValue (4) = gp_Pnt ( aDx, -aDy, 0.0).Transformed (aLabelPlane);
+      aRectanglePoints.ChangeValue (5) = aRectanglePoints.Value (1);
+
+      Handle(Select3D_SensitiveFace) aTextSensitive =
+        new Select3D_SensitiveFace (anEntityOwner, aRectanglePoints, Select3D_TOS_INTERIOR);
+      theSelection->Add (aTextSensitive);
+
       break;
     }
   }
 }
+
+//=======================================================================
+//function : calculateLabelParams
+//purpose  :
+//=======================================================================
+Standard_Boolean AIS_TextLabel::calculateLabelParams (const gp_Pnt& thePosition,
+                                                      gp_Pnt& theCenterOfLabel,
+                                                      Standard_Real& theWidth,
+                                                      Standard_Real& theHeight) const
+{
+  // Get width and height of text
+  Handle(Prs3d_TextAspect) anAsp = myDrawer->TextAspect();
+  Font_FTFontParams aFontParams;
+  aFontParams.PointSize = (unsigned int) anAsp->Height();
+  aFontParams.Resolution = GetContext()->CurrentViewer()->DefaultRenderingParams().Resolution;
+
+  Handle(Font_FTFont) aFont = Font_FTFont::FindAndCreate (anAsp->Aspect()->Font(),
+                                                          anAsp->Aspect()->GetTextFontAspect(),
+                                                          aFontParams);
+  if (aFont.IsNull())
+  { 
+    return Standard_False;
+  }
+
+  const NCollection_String aText (myText.ToExtString());
+  Font_Rect aBndBox = aFont->BoundingBox (aText, anAsp->HorizontalJustification(), anAsp->VerticalJustification());
+  theWidth = Abs (aBndBox.Width());
+  theHeight = Abs (aBndBox.Height());
+
+  theCenterOfLabel = thePosition;
+  if (anAsp->VerticalJustification() == Graphic3d_VTA_BOTTOM)
+  {
+    theCenterOfLabel.ChangeCoord() += myOrientation3D.YDirection().XYZ() * theHeight * 0.5;
+  }
+  else if (anAsp->VerticalJustification() == Graphic3d_VTA_TOP)
+  {
+    theCenterOfLabel.ChangeCoord() -= myOrientation3D.YDirection().XYZ() * theHeight * 0.5;
+  }
+  if (anAsp->HorizontalJustification() == Graphic3d_HTA_LEFT)
+  {
+    theCenterOfLabel.ChangeCoord() += myOrientation3D.XDirection().XYZ() * theWidth * 0.5;
+  }
+  else if (anAsp->HorizontalJustification() == Graphic3d_HTA_RIGHT)
+  {
+    theCenterOfLabel.ChangeCoord() -= myOrientation3D.XDirection().XYZ() * theWidth * 0.5;
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : calculateLabelTrsf
+//purpose  :
+//=======================================================================
+gp_Trsf AIS_TextLabel::calculateLabelTrsf (const gp_Pnt& thePosition, gp_Pnt& theCenterOfLabel) const
+{
+  const Standard_Real anAngle = myDrawer->TextAspect()->Aspect()->TextAngle() * M_PI / 180.0;
+  const gp_Ax1 aRotAxis (thePosition, gp_Dir (0.0, 0.0, 1.0));
+
+  gp_Ax2 anOrientation = myOrientation3D;
+  anOrientation.Rotate (aRotAxis, anAngle);
+  theCenterOfLabel.Rotate (aRotAxis, anAngle);
+
+  gp_Trsf aLabelPlane;
+  aLabelPlane.SetTransformation (anOrientation, gp::XOY());
+  aLabelPlane.SetTranslationPart (theCenterOfLabel.XYZ());
+
+  return aLabelPlane;
+}
index cccdcd2..b3ae257 100644 (file)
@@ -121,7 +121,7 @@ public:
   //! and the colour of backgroubd for the TODT_DEKALE TextDisplayType.
   Standard_EXPORT void SetColorSubTitle (const Quantity_Color& theColor);
 
-private:
+protected:
 
   //! Compute
   Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
@@ -132,6 +132,16 @@ private:
   Standard_EXPORT virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
                                                  const Standard_Integer             theMode) Standard_OVERRIDE;
 
+  //! Calculate label center, width and height
+  Standard_EXPORT Standard_Boolean calculateLabelParams (const gp_Pnt& thePosition,
+                                                         gp_Pnt& theCenterOfLabel,
+                                                         Standard_Real& theWidth,
+                                                         Standard_Real& theHeight) const;
+
+  //! Calculate label transformation
+  Standard_EXPORT gp_Trsf calculateLabelTrsf (const gp_Pnt& thePosition,
+                                              gp_Pnt& theCenterOfLabel) const;
+
 protected:
 
   TCollection_ExtendedString myText;
index 478d3d7..7c3f95c 100644 (file)
@@ -130,7 +130,7 @@ void SelectMgr_ViewerSelector3d::DisplaySensitive (const Handle(V3d_View)& theVi
     {
       if (aSelIter.Value()->GetSelectionState() == SelectMgr_SOS_Activated)
       {
-        SelectMgr::ComputeSensitivePrs (aStruct, aSelIter.Value(), anObj->Transformation(), Handle(Graphic3d_TransformPers)());
+        SelectMgr::ComputeSensitivePrs (aStruct, aSelIter.Value(), anObj->Transformation(), anObj->TransformPersistence());
       }
     }
 
index d2c3aa1..3db6e67 100644 (file)
@@ -4254,6 +4254,10 @@ static Handle(AIS_InteractiveObject) findConnectedObject (const TCollection_Asci
     aConnected->SetDisplayMode (aPrs->DisplayMode());
   }
   aConnected->Connect (aPrs, aPrs->LocalTransformationGeom());
+  if (!aPrs->TransformPersistence().IsNull())
+  {
+    aConnected->SetTransformPersistence (aPrs->TransformPersistence());
+  }
   ViewerTest::Display (theName, aConnected, false);
   return aConnected;
 }
index b616e5b..3081622 100755 (executable)
@@ -67,3 +67,6 @@ vdrawtext OC21 OpenCascade -pos -200 -200 300 -color FF0005   -halign left -vali
 
 vglinfo
 checkview -screenshot -3d -path ${imagedir}/${test_image}.png
+
+vsensdis
+checkview -screenshot -3d -path ${imagedir}/${test_image}_sensitive.png
\ No newline at end of file
index b0a0d74..d2d756e 100644 (file)
@@ -29,7 +29,7 @@ box b 1 2 3
 vdisplay -dispMode 1 b
 vselprops localSelHighlight -dispMode 1 -material SILVER -color WHITE
 vselmode b FACE 1
-vselect 250 250
+vselect 190 250
 
 vglinfo
 vdump ${imagedir}/${casename}.png
index 8cac47c..50a8d6b 100644 (file)
@@ -38,3 +38,6 @@ vsetlocation b1 0 -3 0
 vconnect bc 0 -6 0 b1 b2 tb1 tb2
 set anImage ${imagedir}/${casename}_2_3.png
 vdump ${anImage}
+
+vsensdis
+vdump $imagedir/${casename}_sensitive.png