]> OCCT Git - occt.git/commitdiff
Rebase 0033746: Visualization - Unexpected moving with AIS_ViewCube CR33746_1
authorsshutina <svetlana.shutina@opencascade.com>
Mon, 15 Sep 2025 16:00:53 +0000 (17:00 +0100)
committersshutina <svetlana.shutina@opencascade.com>
Mon, 15 Sep 2025 16:01:14 +0000 (17:01 +0100)
Fixed angle calculation for view rotation.
Added draw command vmousebutton to test mouse button events.

src/Draw/TKViewerTest/ViewerTest/ViewerTest_ViewerCommands.cxx
src/Visualization/TKV3d/AIS/AIS_ViewController.cxx
src/Visualization/TKV3d/V3d/V3d_View.hxx
tests/v3d/bugs/bug33746 [new file with mode: 0644]

index 24749e6b88c4dfe6c7352cb07bd6bc95f9e20a40..685b0c40d164be79c96fdd90eda2cb023da66a64 100644 (file)
@@ -6375,6 +6375,106 @@ static Standard_Integer VMoveTo(Draw_Interpretor& theDI,
   return 0;
 }
 
+//=======================================================================
+//function : VMouseButton
+//purpose  : Emulates mouse button event
+//=======================================================================
+static Standard_Integer VMouseButton(Draw_Interpretor& /*theDI*/,
+  Standard_Integer theNbArgs,
+  const char** theArgVec)
+{
+  const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
+  const Handle(V3d_View)& aView = ViewerTest::CurrentView();
+  if (aContext.IsNull())
+  {
+    Message::SendFail("Error: no active viewer");
+    return 1;
+  }
+
+  if (theNbArgs < 6)
+  {
+    Message::SendFail("Syntax error: wrong number arguments");
+    return 1;
+  }
+
+  Aspect_VKeyMouse aButton = Aspect_VKeyMouse_LeftButton;
+  Standard_Boolean isPressButton = false;
+
+  Graphic3d_Vec2i aMousePos(IntegerLast(), IntegerLast());
+  for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
+  {
+    TCollection_AsciiString anArgStr(theArgVec[anArgIter]);
+    anArgStr.LowerCase();
+    if (anArgStr == "-button")
+    {
+      if (anArgIter + 1 < theNbArgs)
+      {
+        ++anArgIter;
+        TCollection_AsciiString aButtonStr(theArgVec[anArgIter]);
+        if (aButtonStr == "left")
+        {
+          aButton = Aspect_VKeyMouse_LeftButton;
+        }
+        else if (aButtonStr == "right")
+        {
+          aButton = Aspect_VKeyMouse_RightButton;
+        }
+        else if (aButtonStr == "middle")
+        {
+          aButton = Aspect_VKeyMouse_MiddleButton;
+        }
+      }
+    }
+    else if (anArgStr == "-up")
+    {
+      isPressButton = false;
+    }
+    else if (anArgStr == "-down")
+    {
+      isPressButton = true;
+    }
+    else if (aMousePos.x() == IntegerLast()
+      && anArgStr.IsIntegerValue())
+    {
+      aMousePos.x() = anArgStr.IntegerValue();
+    }
+    else if (aMousePos.y() == IntegerLast()
+      && anArgStr.IsIntegerValue())
+    {
+      aMousePos.y() = anArgStr.IntegerValue();
+    }
+    else
+    {
+      Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
+      return 1;
+    }
+  }
+
+  if (aMousePos.x() == IntegerLast()
+    || aMousePos.y() == IntegerLast())
+  {
+    Message::SendFail("Syntax error: wrong number of arguments");
+    return 1;
+  }
+
+  if (isPressButton)
+  {
+    ViewerTest::CurrentEventManager()->ResetPreviousMoveTo();
+    ViewerTest::CurrentEventManager()->PressMouseButton(aMousePos, aButton, Aspect_VKeyFlags_NONE, false);
+    ViewerTest::CurrentEventManager()->UpdateMousePosition(aMousePos, Aspect_VKeyMouse_NONE, Aspect_VKeyFlags_NONE, false);
+    ViewerTest::CurrentEventManager()->FlushViewEvents(ViewerTest::GetAISContext(), aView, true);
+  }
+  else
+  {
+    ViewerTest::CurrentEventManager()->UpdateMousePosition(aMousePos, Aspect_VKeyMouse_NONE, Aspect_VKeyFlags_NONE, false);
+    ViewerTest::CurrentEventManager()->FlushViewEvents(ViewerTest::GetAISContext(), aView, true);
+    ViewerTest::CurrentEventManager()->ReleaseMouseButton(aMousePos, aButton, Aspect_VKeyFlags_NONE, false);
+    ViewerTest::CurrentEventManager()->FlushViewEvents(ViewerTest::GetAISContext(), aView, true);
+  }
+
+  return 0;
+}
+
 //=================================================================================================
 
 static Standard_Integer VSelectByAxis(Draw_Interpretor& theDI,
@@ -14081,6 +14181,14 @@ Emulate cursor movement to pixel position (x,y).
  -reset resets current highlighting.
 )" /* [vmoveto] */);
 
+  addCmd("vmousebutton", VMouseButton, /* [vmousebutton] */ R"(
+vmousebutton x y -button right|left|middle -up|-down
+Emulate mouse button events.
+ -button choose button;
+ -down   press button;
+ -up     release button.
+)" /* [vmousebutton] */);
+
   addCmd("vselaxis", VSelectByAxis, /* [vselaxis] */ R"(
 vselaxis x y z dx dy dz [-onlyTop 0|1] [-display Name] [-showNormal 0|1]"
 Provides intersection by given axis and print result intersection points.
index f5955405673a1a57107bead86033927e1f87309f..709255d2cfc1e85655fb2a69f0e0a2691e2d8e91 100644 (file)
@@ -1788,8 +1788,17 @@ void AIS_ViewController::handleViewRotation(const Handle(V3d_View)& theView,
   }
   if (myGL.ViewRotation.ToStart)
   {
+
+    gp_Dir aCamDirection = aCam->Direction();
+    if (aCam->OrthogonalizedUp().IsParallel (gp::DY(), Precision::Angular()))
+    {
+      aCamDirection = aCamDirection.Dot (gp::DZ()) > 0
+                    ? gp::DZ()
+                    : gp::DZ().Reversed();
+    }
+
     gp_Trsf aTrsf;
-    aTrsf.SetTransformation(gp_Ax3(gp::Origin(), aCam->OrthogonalizedUp(), aCam->Direction()),
+    aTrsf.SetTransformation(gp_Ax3(gp::Origin(), aCam->OrthogonalizedUp(), aCamDirection),
                             gp_Ax3(gp::Origin(), gp::DZ(), gp::DX()));
     const gp_Quaternion aRot       = aTrsf.GetRotation();
     double              aRollDummy = 0.0;
@@ -1797,6 +1806,12 @@ void AIS_ViewController::handleViewRotation(const Handle(V3d_View)& theView,
                         myRotateStartYawPitchRoll[0],
                         myRotateStartYawPitchRoll[1],
                         aRollDummy);
+    if (aCamDirection.IsParallel (gp::DZ(), Precision::Angular()))
+    {
+      myRotateStartYawPitchRoll[0] = aCamDirection.IsEqual (gp::DZ(), Precision::Angular())
+                                   ? aRollDummy
+                                   : -aRollDummy;
+    }
   }
   if (toRotateAnyway)
   {
index 367acccddff886d67c93a491c9a987e702838ee9..25e2871f0581d3053194a09a5fe14d38b26b9289 100644 (file)
@@ -993,7 +993,7 @@ public:
                             const Graphic3d_BufferType& theBufferType     = Graphic3d_BT_RGB,
                             const Standard_Boolean      theToAdjustAspect = Standard_True,
                             const Graphic3d_ZLayerId theTargetZLayerId = Graphic3d_ZLayerId_BotOSD,
-                            const Standard_Integer   theIsSingleLayer  = Standard_False,
+                            const Standard_Boolean   theIsSingleLayer  = Standard_False,
                             const V3d_StereoDumpOptions theStereoOptions = V3d_SDO_MONO,
                             const Standard_CString      theLightName     = "")
   {
diff --git a/tests/v3d/bugs/bug33746 b/tests/v3d/bugs/bug33746
new file mode 100644 (file)
index 0000000..5c2f708
--- /dev/null
@@ -0,0 +1,30 @@
+puts "============"
+puts "0033746: Visualization - Unexpected moving with AIS_ViewCube"
+puts "============"
+puts ""
+
+pload MODELING VISUALIZATION
+vclear
+vinit View1
+
+box b 0 0 -100 100 20 10
+vdisplay -dispMode 1 b
+
+vviewcube c
+vcamera -navmode fly
+
+vtop
+vfit
+vmousebutton 200 200 -button left -down
+vmousebutton 201 200 -button left -up
+if { [vreadpixel 100 200 -rgb -name] == "BLACK" } { puts "Error: wrong transformation" }
+
+vdump $::imagedir/${::casename}_top.png
+
+vbottom
+vfit
+vmousebutton 200 200 -button left -down
+vmousebutton 201 200 -button left -up
+if { [vreadpixel 100 200 -rgb -name] == "BLACK" } { puts "Error: wrong transformation" }
+
+vdump $::imagedir/${::casename}_bottom.png