0025672: V3d_View::ConvertToGrid doesn't work for grid if the grid plane's origin...
authorapl <apl@opencascade.com>
Thu, 16 Apr 2015 09:41:21 +0000 (12:41 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 16 Apr 2015 09:42:32 +0000 (12:42 +0300)
Patched V3d_View::ConverToGrid method to fix the problem
Added test function "vprivilegedplane" for setting/printing grid plane's coordinate system
Added test case bugs/vis/bug25672 to check the issue
remarks from kgv
Warnings eliminating (similar to CR25671)

src/V3d/V3d_View_4.cxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/bugs/vis/bug25672 [new file with mode: 0644]

index f31649b..88d7cf3 100644 (file)
@@ -178,20 +178,17 @@ Graphic3d_Vertex V3d_View::Compute (const Graphic3d_Vertex & AVertex) const
   // project ray from camera onto grid plane
   if (!myCamera->IsOrthographic())
   {
-    gp_Vec aPointFromCamera = gp_Vec (myCamera->Eye(), gp_Pnt (x1, y1, z1));
-    aPointFromCamera.Normalize();
-
-    Standard_Real aT = - gp_Vec (myCamera->Eye().XYZ()).Dot (aPlaneNormal) / 
-                                  aPointFromCamera.Dot (aPlaneNormal);
-    aPointOnPlane = gp_Vec (myCamera->Eye().XYZ()) + aPointFromCamera * aT;
-  } else
+    gp_Vec aDirCamera2Point       = gp_Vec (myCamera->Eye(), gp_Pnt (x1, y1, z1)).Normalized();
+    gp_Vec aVecCamera2Orig        = gp_Vec (myCamera->Eye(), gp_Pnt (x0, y0, z0));
+    Standard_Real aDistPointPlane = aVecCamera2Orig.Dot (aPlaneNormal) / aDirCamera2Point.Dot (aPlaneNormal);
+    aPointOnPlane = gp_Vec (myCamera->Eye().XYZ()) + aDirCamera2Point * aDistPointPlane;
+  }
+  else
   {
-    gp_Vec aPointFromCamera (myCamera->Direction());
-    gp_Vec aPointOnCamera (gp_Vec (x1, y1, z1) - aPointFromCamera);
-
-    Standard_Real aT = - aPointOnCamera.Dot (aPlaneNormal) / 
-                          aPointFromCamera.Dot (aPlaneNormal);
-    aPointOnPlane = aPointOnCamera + aPointFromCamera * aT;
+    gp_Vec aDirCamera             = myCamera->Direction();
+    gp_Vec aVecOrig2Point         = gp_Vec (gp_Pnt (x0, y0, z0), gp_Pnt (x1, y1, z1));
+    Standard_Real aDistPointPlane = aVecOrig2Point.Dot (aPlaneNormal) / aDirCamera.Dot (aPlaneNormal);
+    aPointOnPlane = gp_Vec (x1, y1, z1) + aDirCamera * aDistPointPlane;
   }
 
   if (IsRectangular) {
index 38956c9..607da14 100644 (file)
@@ -4937,6 +4937,71 @@ static int VGrid (Draw_Interpretor& /*theDI*/,
 }
 
 //==============================================================================
+//function : VPriviledgedPlane
+//purpose  :
+//==============================================================================
+
+static int VPriviledgedPlane (Draw_Interpretor& theDI,
+                              Standard_Integer  theArgNb,
+                              const char**      theArgVec)
+{
+  if (theArgNb != 1 && theArgNb != 7 && theArgNb != 10)
+  {
+    std::cerr << "Error: wrong number of arguments! See usage:\n";
+    theDI.PrintHelp (theArgVec[0]);
+    return 1;
+  }
+
+  // get the active viewer
+  Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
+  if (aViewer.IsNull())
+  {
+    std::cerr << "Error: no active viewer. Please call vinit.\n";
+    return 1;
+  }
+
+  if (theArgNb == 1)
+  {
+    gp_Ax3 aPriviledgedPlane = aViewer->PrivilegedPlane();
+    const gp_Pnt& anOrig = aPriviledgedPlane.Location();
+    const gp_Dir& aNorm = aPriviledgedPlane.Direction();
+    const gp_Dir& aXDir = aPriviledgedPlane.XDirection();
+    theDI << "Origin: " << anOrig.X() << " " << anOrig.Y() << " " << anOrig.Z() << " "
+          << "Normal: " << aNorm.X() << " " << aNorm.Y() << " " << aNorm.Z() << " "
+          << "X-dir: "  << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
+    return 0;
+  }
+
+  Standard_Integer anArgIdx = 1;
+  Standard_Real anOrigX = Draw::Atof (theArgVec[anArgIdx++]);
+  Standard_Real anOrigY = Draw::Atof (theArgVec[anArgIdx++]);
+  Standard_Real anOrigZ = Draw::Atof (theArgVec[anArgIdx++]);
+  Standard_Real aNormX  = Draw::Atof (theArgVec[anArgIdx++]);
+  Standard_Real aNormY  = Draw::Atof (theArgVec[anArgIdx++]);
+  Standard_Real aNormZ  = Draw::Atof (theArgVec[anArgIdx++]);
+
+  gp_Ax3 aPriviledgedPlane;
+  gp_Pnt anOrig (anOrigX, anOrigY, anOrigZ);
+  gp_Dir aNorm (aNormX, aNormY, aNormZ);
+  if (theArgNb > 7)
+  {
+    Standard_Real aXDirX = Draw::Atof (theArgVec[anArgIdx++]);
+    Standard_Real aXDirY = Draw::Atof (theArgVec[anArgIdx++]);
+    Standard_Real aXDirZ = Draw::Atof (theArgVec[anArgIdx++]);
+    gp_Dir aXDir (aXDirX, aXDirY, aXDirZ);
+    aPriviledgedPlane = gp_Ax3 (anOrig, aNorm, aXDir);
+  }
+  else
+  {
+    aPriviledgedPlane = gp_Ax3 (anOrig, aNorm);
+  }
+
+  aViewer->SetPrivilegedPlane (aPriviledgedPlane);
+
+  return 0;
+}
+
+//==============================================================================
 //function : VConvert
 //purpose  :
 //==============================================================================
@@ -4949,7 +5014,7 @@ static int VConvert (Draw_Interpretor& theDI,
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cerr << "No active view. Please call vinit.\n";
+    std::cerr << "Error: no active view. Please call vinit.\n";
     return 1;
   }
 
@@ -8390,6 +8455,13 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     " : Mode - rectangular or circular"
     " : Type - lines or points",
     __FILE__, VGrid, group);
+  theCommands.Add ("vpriviledgedplane",
+    "vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]"
+    "\n\t\t:   Ox, Oy, Oz - plane origin"
+    "\n\t\t:   Nx, Ny, Nz - plane normal direction"
+    "\n\t\t:   Xx, Xy, Xz - plane x-reference axis direction"
+    "\n\t\t: Sets or prints viewer's priviledged plane geometry.",
+    __FILE__, VPriviledgedPlane, group);
   theCommands.Add ("vconvert",
     "vconvert v [Mode={window|view}]"
     "\n\t\t: vconvert x y [Mode={window|view|grid|ray}]"
diff --git a/tests/bugs/vis/bug25672 b/tests/bugs/vis/bug25672
new file mode 100644 (file)
index 0000000..52a340c
--- /dev/null
@@ -0,0 +1,47 @@
+puts "============"
+puts "CR25672"
+puts "============"
+puts ""
+#############################################################################################################
+# V3d_View::ConvertToGrid doesn't work for grid if the grid plane's origin is not identical to camera origin.
+#############################################################################################################
+pload VISUALIZATION
+vinit View1
+
+set view_scale 60.630934227306405
+set view_proj {0.577 -0.577 0.577}
+set view_up {-0.408 0.408 0.816}
+set view_at {5 5 5}
+set view_eye {15 -5 15}
+set view_zmin -300.0
+set view_zmax  300.0
+vviewparams -scale $view_scale -eye {*}$view_eye -at {*}$view_at -proj {*}$view_proj -up {*}$view_up
+vzrange $view_zmin $view_zmax
+vgrid r l -10 10 1 1 0
+
+set vconvert_res [vconvert 5.0 5.0 0.0 grid]
+
+checkreal "vconvert 5.0 5.0 0.0 grid, X" [lindex $vconvert_res 2] 5.0 1e-7 0.0
+checkreal "vconvert 5.0 5.0 0.0 grid, Y" [lindex $vconvert_res 3] 5.0 1e-7 0.0
+checkreal "vconvert 5.0 5.0 0.0 grid, Z" [lindex $vconvert_res 4] 0.0 1e-7 0.0
+
+vpriviledgedplane 20 20 30 0 0 1 1 0 0
+
+set vconvert_res [vconvert 5.0 5.0 30.0 grid]
+
+checkreal "vconvert 5.0 5.0 30.0 grid, X" [lindex $vconvert_res 2]  5.0 1e-7 0.0
+checkreal "vconvert 5.0 5.0 30.0 grid, Y" [lindex $vconvert_res 3]  5.0 1e-7 0.0
+checkreal "vconvert 5.0 5.0 30.0 grid, Z" [lindex $vconvert_res 4] 30.0 1e-7 0.0
+
+vcamera -persp
+
+vpriviledgedplane 10 5 10 0 0 1 1 0 0
+
+set vconvert_res [vconvert 5.0 5.0 10.0 grid]
+
+checkreal "vconvert 5.0 5.0 10.0 grid, X" [lindex $vconvert_res 2]  5.0 1e-7 0.0
+checkreal "vconvert 5.0 5.0 10.0 grid, Y" [lindex $vconvert_res 3]  5.0 1e-7 0.0
+checkreal "vconvert 5.0 5.0 10.0 grid, Z" [lindex $vconvert_res 4] 10.0 1e-7 0.0
+
+# do not save any image
+set only_screen 0