]> OCCT Git - occt.git/commitdiff
0033514: Visualization - Scaled view twists zoom persistence objects
authordrochalo <diogo.lopes@opencascade.com>
Tue, 24 Oct 2023 13:44:14 +0000 (14:44 +0100)
committerdpasukhi <dmitry.pasukhin@opencascade.com>
Fri, 17 May 2024 08:31:06 +0000 (08:31 +0000)
Added flag to transform persistence to handle axial scaling.
Modified manipulator's zoom transform persistence to fit in axial scaling events.
Added tests for cases 27832 and 33514.
Logic change on Graphic3d_TransformPers::Apply for Graphic3d_TMF_AxialScalePers.
Logic fixes in AIS_Manipulator to integrate axial scale in both zoomable and unzoomable states.

src/AIS/AIS_Manipulator.cxx
src/Graphic3d/Graphic3d_Camera.cxx
src/Graphic3d/Graphic3d_TransModeFlags.hxx
src/Graphic3d/Graphic3d_TransformPers.hxx
src/ViewerTest/ViewerTest.cxx
tests/v3d/manipulator/bug33514 [new file with mode: 0644]
tests/v3d/trihedron/bug27832 [new file with mode: 0644]

index bf93dbfc102dd629b24c9be1bc27d3365bfb343e..76b82782b8b61a3638a3f04ac7870a31fdf2e82d 100644 (file)
@@ -843,10 +843,18 @@ void AIS_Manipulator::updateTransformation()
   if (myIsZoomPersistentMode)
   {
     if (TransformPersistence().IsNull()
-    ||  TransformPersistence()->Mode() != Graphic3d_TMF_ZoomPers
+    ||  TransformPersistence()->Mode() != Graphic3d_TMF_AxialZoomPers
     || !TransformPersistence()->AnchorPoint().IsEqual (myPosition.Location(), 0.0))
     {
-      setTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_ZoomPers, myPosition.Location()));
+      setTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_AxialZoomPers, myPosition.Location()));
+    }
+  }
+  else
+  {
+    if (TransformPersistence().IsNull()
+    || TransformPersistence()->Mode() != Graphic3d_TMF_AxialScalePers)
+    {
+      setTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_AxialScalePers, myPosition.Location()));
     }
   }
 }
@@ -931,7 +939,7 @@ void AIS_Manipulator::SetZoomPersistence (const Standard_Boolean theToEnable)
 
   if (!theToEnable)
   {
-    setTransformPersistence (Handle(Graphic3d_TransformPers)());
+    setTransformPersistence (new (Graphic3d_TransformPers)(Graphic3d_TMF_AxialScalePers));
   }
 
   updateTransformation();
index ee7204fe8e3065ff573acfc3d69b90936f557e5b..e1fc21edfca2e5ea58d0f5e855b9a4bf023a7879 100644 (file)
@@ -309,6 +309,10 @@ void Graphic3d_Camera::SetUp (const gp_Dir& theUp)
 // =======================================================================
 void Graphic3d_Camera::SetAxialScale (const gp_XYZ& theAxialScale)
 {
+  Standard_OutOfRange_Raise_if (theAxialScale.X() <= 0.0 
+                             || theAxialScale.Y() <= 0.0 
+                             || theAxialScale.Z() <= 0.0, 
+                               "Graphic3d_Camera::SetAxialScale, bad coefficient");
   if (AxialScale().IsEqual (theAxialScale, 0.0))
   {
     return;
index 0c9f329362ee0720b99ba1eb753746365490811d..d06a8329a186ab6c87b75d0e14aba9a1277b4462 100644 (file)
 //! Transform Persistence Mode defining whether to lock in object position, rotation and / or zooming relative to camera position.
 enum Graphic3d_TransModeFlags
 {
-  Graphic3d_TMF_None           = 0x0000,                  //!< no persistence attributes (normal 3D object)
-  Graphic3d_TMF_ZoomPers       = 0x0002,                  //!< object does not resize
-  Graphic3d_TMF_RotatePers     = 0x0008,                  //!< object does not rotate;
-  Graphic3d_TMF_TriedronPers   = 0x0020,                  //!< object behaves like trihedron - it is fixed at the corner of view and does not resizing (but rotating)
-  Graphic3d_TMF_2d             = 0x0040,                  //!< object is defined in 2D screen coordinates (pixels) and does not resize, pan and rotate
-  Graphic3d_TMF_CameraPers     = 0x0080,                  //!< object is in front of the camera
-  Graphic3d_TMF_OrthoPers      = 0x0100,                  //!< object is forced to be rendered with orthographic projection.
+  Graphic3d_TMF_None           = 0x0000,                      //!< no persistence attributes (normal 3D object)
+  Graphic3d_TMF_ZoomPers       = 0x0002,                      //!< object does not resize
+  Graphic3d_TMF_RotatePers     = 0x0008,                      //!< object does not rotate;
+  Graphic3d_TMF_TriedronPers   = 0x0020,                      //!< object behaves like trihedron - it is fixed at the corner of view and does not resizing (but rotating)
+  Graphic3d_TMF_2d             = 0x0040,                      //!< object is defined in 2D screen coordinates (pixels) and does not resize, pan and rotate
+  Graphic3d_TMF_CameraPers     = 0x0080,                      //!< object is in front of the camera
+  Graphic3d_TMF_OrthoPers      = 0x0100,                      //!< object is forced to be rendered with orthographic projection.
+  Graphic3d_TMF_AxialScalePers = 0x0200,                      //!< object does not resize with axial scale
   Graphic3d_TMF_ZoomRotatePers = Graphic3d_TMF_ZoomPers
-                               | Graphic3d_TMF_RotatePers //!< object doesn't resize and rotate
+                               | Graphic3d_TMF_RotatePers,    //!< object doesn't resize and rotate
+  Graphic3d_TMF_AxialZoomPers  = Graphic3d_TMF_ZoomPers
+                               | Graphic3d_TMF_AxialScalePers //!< object does not visually resize with either object or axial scale
 };
 
 //! Bitwise OR operator for transform persistence mode flags. Be aware that some flags combinations are not valid.
index d0f70ba64c2d55af14f495b4e598e06171fec968..36dc3636a126dfc57aaf50283aab2e09678130ea 100644 (file)
@@ -40,6 +40,9 @@ DEFINE_STANDARD_HANDLE(Graphic3d_TransformPers, Standard_Transient)
 //! Beware that Graphic3d_RenderingParams::ResolutionRatio() will be ignored!
 //! For other Persistence flags, normal (world) length units will apply.
 //!
+//! Graphic3d_TMF_AxialPers and Graphic3d_TMF_AxialZoomPers defines persistence in the axial scale,
+//! i.e., keeps the object visual coherence when the camera's axial scale is changed.
+//! Meant to be used by objects such as Manipulators and trihedrons.
 //! WARNING: Graphic3d_TMF_None is not permitted for defining instance of this class - NULL handle should be used for this purpose!
 class Graphic3d_TransformPers : public Standard_Transient
 {
@@ -64,13 +67,19 @@ public:
     return (theMode & Graphic3d_TMF_OrthoPers) != 0;
   }
 
+  //! Return true if specified mode is axial transformation persistence.
+  static Standard_Boolean IsAxial (Graphic3d_TransModeFlags theMode)
+  {
+    return (theMode & Graphic3d_TMF_AxialScalePers) != 0;
+  }
+
 public:
 
   //! Set transformation persistence.
   Graphic3d_TransformPers (const Graphic3d_TransModeFlags theMode)
   : myMode (theMode)
   {
-    if (IsZoomOrRotate (theMode))
+    if (IsZoomOrRotate (theMode) || IsAxial (theMode))
     {
       SetPersistence (theMode, gp_Pnt(0.0, 0.0, 0.0));
     }
@@ -119,6 +128,9 @@ public:
   //! Return true for Graphic3d_TMF_OrthoPers mode.
   Standard_Boolean IsOrthoPers () const { return IsOrthoPers (myMode); }
 
+  //! Return true for Graphic3d_TMF_AxialScalePers modes.
+  Standard_Boolean IsAxial() const { return IsAxial (myMode); }
+
   //! Transformation persistence mode flags.
   Graphic3d_TransModeFlags Mode() const { return myMode; }
 
@@ -130,7 +142,7 @@ public:
   void SetPersistence (const Graphic3d_TransModeFlags theMode,
                        const gp_Pnt& thePnt)
   {
-    if (!IsZoomOrRotate (theMode))
+    if (!IsZoomOrRotate (theMode) && !IsAxial (theMode))
     {
       throw Standard_ProgramError("Graphic3d_TransformPers::SetPersistence(), wrong persistence mode.");
     }
@@ -163,7 +175,7 @@ public:
   //! Return the anchor point for zoom/rotate transformation persistence.
   gp_Pnt AnchorPoint() const
   {
-    if (!IsZoomOrRotate())
+    if (!IsZoomOrRotate() && !IsAxial())
     {
       throw Standard_ProgramError("Graphic3d_TransformPers::AnchorPoint(), wrong persistence mode.");
     }
@@ -174,7 +186,7 @@ public:
   //! Set the anchor point for zoom/rotate transformation persistence.
   void SetAnchorPoint (const gp_Pnt& thePnt)
   {
-    if (!IsZoomOrRotate())
+    if (!IsZoomOrRotate() && !IsAxial())
     {
       throw Standard_ProgramError("Graphic3d_TransformPers::SetAnchorPoint(), wrong persistence mode.");
     }
@@ -448,6 +460,10 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
       }
     }
 
+    Graphic3d_TransformUtils::Scale (aWorldView,
+                                     1.0 / theCamera->AxialScale().X(),
+                                     1.0 / theCamera->AxialScale().Y(),
+                                     1.0 / theCamera->AxialScale().Z());
     Graphic3d_TransformUtils::Translate (aWorldView, aCenter.X(), aCenter.Y(), aCenter.Z());
     Graphic3d_TransformUtils::Scale     (aWorldView, aScale,      aScale,      aScale);
   }
@@ -517,6 +533,14 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
       aWorldView.SetValue (2, 2, aRotMat.GetColumn (2).z());
     }
 
+    if (IsAxial())
+    {
+      Graphic3d_TransformUtils::Scale (aWorldView,
+                                       1.0 / theCamera->AxialScale().X(),
+                                       1.0 / theCamera->AxialScale().Y(),
+                                       1.0 / theCamera->AxialScale().Z());
+    }
+
     if ((myMode & Graphic3d_TMF_ZoomPers) != 0)
     {
       // lock zooming
index 43aced25af00d2e8753c32968cafe1ef1b040fad..dced0cf3f938d2e4762f64556239f46f0319c906 100644 (file)
@@ -4798,6 +4798,14 @@ inline Standard_Boolean parseTrsfPersFlag (const TCollection_AsciiString& theFla
   {
     theFlags = Graphic3d_TMF_TriedronPers;
   }
+  else if (theFlagString == "axial")
+  {
+    theFlags = Graphic3d_TMF_AxialScalePers;
+  }
+  else if (theFlagString == "zoomaxial")
+  {
+    theFlags = Graphic3d_TMF_AxialZoomPers;
+  }
   else if (theFlagString == "none")
   {
     theFlags = Graphic3d_TMF_None;
@@ -6648,7 +6656,7 @@ If last 3 optional parameters are not set prints numbers of U-, V- isolines and
 
   addCmd ("vdisplay", VDisplay2, /* [vdisplay] */ R"(
 vdisplay [-noupdate|-update] [-mutable] [-neutral]
-         [-trsfPers {zoom|rotate|zoomRotate|trihedron|none}=none]
+         [-trsfPers {zoom|rotate|zoomRotate|trihedron|axial|zoomaxial|none}=none]
             [-trsfPersPos X Y [Z]] [-3d]
             [-2d|-trihedron [{top|bottom|left|right|topLeft
                             |topRight|bottomLeft|bottomRight}
diff --git a/tests/v3d/manipulator/bug33514 b/tests/v3d/manipulator/bug33514
new file mode 100644 (file)
index 0000000..60a2ecf
--- /dev/null
@@ -0,0 +1,53 @@
+puts "========"
+puts "0033514: Visualization - Scaled view twists zoom persistence objects"
+puts "========"
+puts ""
+
+pload MODELING VISUALIZATION
+vinit
+box b 10 10 10
+vdisplay b
+vfit
+vsetdispmode 1
+vmanipulator vm -attach b
+vscale 1 3 10
+vviewparams -scale 6.28866 -proj 0.57735 -0.57735 0.57735 -up -0.408248 0.408248 0.816497 -at 0 10 30
+
+
+set color_1 [vreadpixel 235 170 -rgb -name]
+set color_2 [vreadpixel 223 155 -rgb -name]
+set color_3 [vreadpixel 235 155 -rgb -name]
+
+if {$color_1 != "RED3"} {
+  puts "ERROR: trihedron does not maintain position"
+  puts "       additional investigation is needed"
+  puts "       expected color is: RED3"
+  puts "       current color is:  $color_1"
+}
+
+if {$color_2 != "BLUE3"} {
+  puts "ERROR: trihedron does not maintain position"
+  puts "       additional investigation is needed"
+  puts "       expected color is: BLUE3"
+  puts "       current color is:  $color_2"
+}
+
+if {$color_3 != "GREEN3"} {
+  puts "ERROR: trihedron does not maintain position"
+  puts "       additional investigation is needed"
+  puts "       expected color is: GREEN3"
+  puts "       current color is:  $color_3"
+}
+
+vdump $imagedir/${casename}.png
+
+vclear
+box b 10 10 10
+vdisplay b
+vfit
+vsetdispmode 1
+vmanipulator vm -attach b -zoomable 1
+vscale 1 3 10
+vviewparams -scale 4.28866 -proj 0.57735 -0.57735 0.57735 -up -0.408248 0.408248 0.816497 -at 0 10 30
+
+vdump $imagedir/${casename}_zoomable.png
diff --git a/tests/v3d/trihedron/bug27832 b/tests/v3d/trihedron/bug27832
new file mode 100644 (file)
index 0000000..e8ae56d
--- /dev/null
@@ -0,0 +1,46 @@
+puts "========"
+puts "0027832: Visualization - Scaled zbuffer trihedron"
+puts "========"
+puts ""
+
+pload MODELING VISUALIZATION
+vinit
+box b 10 10 10
+vdisplay b
+vfit
+vsetdispmode 1
+vzbufftrihedron -on
+#draw initial picture of box without visual scale
+vdump $imagedir/${casename}_unscaled.png
+
+#draw picture of box after visual scale
+#and zoomed out
+vscale 1 3 10
+vzoom 1.0
+
+set color_1 [vreadpixel 55 360 -rgb -name]
+set color_2 [vreadpixel 50 350 -rgb -name]
+set color_3 [vreadpixel 55 355 -rgb -name]
+
+if {$color_1 != "RED3"} {
+  puts "ERROR: trihedron does not maintain position"
+  puts "       additional investigation is needed"
+  puts "       expected color is: RED3"
+  puts "       current color is:  $color_1"
+}
+
+if {$color_2 != "BLUE3"} {
+  puts "ERROR: trihedron does not maintain position"
+  puts "       additional investigation is needed"
+  puts "       expected color is: BLUE3"
+  puts "       current color is:  $color_2"
+}
+
+if {$color_3 != "GREEN3"} {
+  puts "ERROR: trihedron does not maintain position"
+  puts "       additional investigation is needed"
+  puts "       expected color is: GREEN3"
+  puts "       current color is:  $color_3"
+}
+
+vdump $imagedir/${casename}_scaled.png