From: kgv Date: Wed, 20 Jun 2018 11:56:09 +0000 (+0300) Subject: 0029885: Visualization, AIS_Manipulator - Translation is done in wrong direction... X-Git-Tag: OCCT_VC2017_73~95 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=12280e4bfc2bfecd278b4c242fd651cb87d70700 0029885: Visualization, AIS_Manipulator - Translation is done in wrong direction depending on Camera orientation 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. --- diff --git a/src/AIS/AIS_Manipulator.cxx b/src/AIS/AIS_Manipulator.cxx index 7a8d382936..d0794af9f6 100644 --- a/src/AIS/AIS_Manipulator.cxx +++ b/src/AIS/AIS_Manipulator.cxx @@ -17,13 +17,11 @@ #include #include +#include #include -#include -#include #include -#include -#include #include +#include #include #include #include @@ -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 index 0000000000..65773fa4c3 --- /dev/null +++ b/tests/v3d/manipulator/translate2 @@ -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