0029885: Visualization, AIS_Manipulator - Translation is done in wrong direction...
authorkgv <kgv@opencascade.com>
Wed, 20 Jun 2018 11:56:09 +0000 (14:56 +0300)
committerkgv <kgv@opencascade.com>
Sat, 23 Jun 2018 10:33:10 +0000 (13:33 +0300)
AIS_Manipulator::ObjectTransformation() has ceased to use undefined point for myStartPick initialization within AIS_MM_Translation mode.
AIS_MM_Scaling cas has been merged into AIS_MM_Translation to reduce code duplication.
Extrema_ExtElC/IntAna_IntConicQuad are now used directly instead of more generic GeomAPI_ExtremaCurveCurve/GeomAPI_IntCS.

src/AIS/AIS_Manipulator.cxx
tests/v3d/manipulator/translate2 [new file with mode: 0644]

index 7a8d382..d0794af 100644 (file)
 
 #include <AIS_InteractiveContext.hxx>
 #include <AIS_ManipulatorOwner.hxx>
+#include <Extrema_ExtElC.hxx>
 #include <gce_MakeDir.hxx>
-#include <GeomAPI_ExtremaCurveCurve.hxx>
-#include <GeomAPI_IntCS.hxx>
 #include <Geom_Circle.hxx>
-#include <Geom_Line.hxx>
-#include <Geom_Plane.hxx>
 #include <Geom_Transformation.hxx>
+#include <IntAna_IntConicQuad.hxx>
 #include <Prs3d_Arrow.hxx>
 #include <Prs3d_Root.hxx>
 #include <Prs3d_ShadingAspect.hxx>
@@ -416,40 +414,56 @@ Standard_Boolean AIS_Manipulator::ObjectTransformation (const Standard_Integer t
   switch (myCurrentMode)
   {
     case AIS_MM_Translation:
+    case AIS_MM_Scaling:
     {
-      gp_Lin aLine (myStartPick, myAxes[myCurrentIndex].Position().Direction());
-      Handle(Geom_Curve) anInputCurve = new Geom_Line (anInputLine);
-      Handle(Geom_Curve) aCurve = new Geom_Line (aLine);
-      GeomAPI_ExtremaCurveCurve anExtrema (anInputCurve, aCurve);
-      gp_Pnt aP1, aP2;
-      anExtrema.NearestPoints (aP1, aP2);
-      const gp_Pnt aNewPosition = aP2;
+      const gp_Lin aLine (myStartPosition.Location(), myAxes[myCurrentIndex].Position().Direction());
+      Extrema_ExtElC anExtrema (anInputLine, aLine, Precision::Angular());
+      if (!anExtrema.IsDone()
+        || anExtrema.NbExt() != 1)
+      {
+        // translation cannot be done co-directed with camera
+        return Standard_False;
+      }
 
+      Extrema_POnCurv anExPnts[2];
+      anExtrema.Points (1, anExPnts[0], anExPnts[1]);
+      const gp_Pnt aNewPosition = anExPnts[1].Value();
       if (!myHasStartedTransformation)
       {
         myStartPick = aNewPosition;
         myHasStartedTransformation = Standard_True;
         return Standard_True;
       }
-
-      if (aNewPosition.Distance (myStartPick) < Precision::Confusion())
+      else if (aNewPosition.Distance (myStartPick) < Precision::Confusion())
       {
         return Standard_False;
       }
 
       gp_Trsf aNewTrsf;
-      aNewTrsf.SetTranslation (gp_Vec(myStartPick, aNewPosition));
-      theTrsf *= aNewTrsf;
+      if (myCurrentMode == AIS_MM_Translation)
+      {
+        aNewTrsf.SetTranslation (gp_Vec(myStartPick, aNewPosition));
+        theTrsf *= aNewTrsf;
+      }
+      else if (myCurrentMode == AIS_MM_Scaling)
+      {
+        if (aNewPosition.Distance (myStartPosition.Location()) < Precision::Confusion())
+        {
+          return Standard_False;
+        }
+
+        Standard_Real aCoeff = myStartPosition.Location().Distance (aNewPosition)
+                             / myStartPosition.Location().Distance (myStartPick);
+        aNewTrsf.SetScale (myPosition.Location(), aCoeff);
+        theTrsf = aNewTrsf;
+      }
       return Standard_True;
     }
     case AIS_MM_Rotation:
     {
       const gp_Pnt aPosLoc   = myStartPosition.Location();
       const gp_Ax1 aCurrAxis = getAx1FromAx2Dir (myStartPosition, myCurrentIndex);
-
-      Handle(Geom_Curve) anInputCurve = new Geom_Line (anInputLine);
-      Handle(Geom_Surface) aSurface = new Geom_Plane (aPosLoc, aCurrAxis.Direction());
-      GeomAPI_IntCS aIntersector (anInputCurve, aSurface);
+      IntAna_IntConicQuad aIntersector (anInputLine, gp_Pln (aPosLoc, aCurrAxis.Direction()), Precision::Angular(), Precision::Intersection());
       if (!aIntersector.IsDone() || aIntersector.NbPoints() < 1)
       {
         return Standard_False;
@@ -495,36 +509,6 @@ Standard_Boolean AIS_Manipulator::ObjectTransformation (const Standard_Integer t
       myPrevState = anAngle;
       return Standard_True;
     }
-    case AIS_MM_Scaling:
-    {
-      gp_Lin aLine (myStartPosition.Location(), myAxes[myCurrentIndex].Position().Direction());
-      Handle(Geom_Curve) anInputCurve = new Geom_Line (anInputLine);
-      Handle(Geom_Curve) aCurve = new Geom_Line (aLine);
-      GeomAPI_ExtremaCurveCurve anExtrema (anInputCurve, aCurve);
-      gp_Pnt aNewPosition, aTmp;
-      anExtrema.NearestPoints (aTmp, aNewPosition);
-
-      if (!myHasStartedTransformation)
-      {
-        myStartPick = aNewPosition;
-        myHasStartedTransformation = Standard_True;
-        return Standard_True;
-      }
-
-      if (aNewPosition.Distance (myStartPick) < Precision::Confusion() 
-       || aNewPosition.Distance (myStartPosition.Location()) < Precision::Confusion())
-      {
-        return Standard_False;
-      }
-
-      Standard_Real aCoeff = myStartPosition.Location().Distance (aNewPosition)
-                           / myStartPosition.Location().Distance (myStartPick);
-      gp_Trsf aNewTrsf;
-      aNewTrsf.SetScale (myPosition.Location(), aCoeff);
-
-      theTrsf = aNewTrsf;
-      return Standard_True;
-    }
     case AIS_MM_None:
     {
       return Standard_False;
diff --git a/tests/v3d/manipulator/translate2 b/tests/v3d/manipulator/translate2
new file mode 100644 (file)
index 0000000..65773fa
--- /dev/null
@@ -0,0 +1,37 @@
+puts "====================================="
+puts "0029885: Visualization, AIS_Manipulator - Translation is done in wrong direction depending on Camera orientation"
+puts "====================================="
+
+pload MODELING VISUALIZATION
+box b 500 500 1 50 100 150
+vclear
+vinit View1
+vzbufftrihedron
+vcamera -persp
+vaxo
+vdisplay -dispMode 1 b
+vfit
+vmanipulator m -attach b
+vmanipulator m -part 0 2 0
+vmanipulator m -part 1 2 0
+vmanipulator m -part 2 2 0
+vmanipulator m -part 0 3 0
+vmanipulator m -part 1 3 0
+vmanipulator m -part 2 3 0
+vmanipulator m -part 2 1 0
+vselmode m 2 0
+vselmode m 3 0
+
+vmoveto 245 220
+vselect 245 220
+vmanipulator m -startTransform 245 220
+vmanipulator m -transform 340 265
+vmanipulator m -stopTransform
+if {[vreadpixel 370 300 rgb name] == "BLACK" } { puts "Error: wrong translation" }
+
+set aLocFull [vlocation b]
+regexp {Location:\s*([ 0-9.e+-]+)} $aLocFull aLocTmp aLoc
+if { [expr abs([lindex $aLoc 0] - 46)] > 0.1 || [lindex $aLoc 1] != 0  || [lindex $aLoc 2] != 0 } { puts "Error: wrong translation" }
+
+vdump $imagedir/${casename}.png
+set to_dump_screen 0