1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-26 10:19:45 +03:00

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.
This commit is contained in:
kgv 2018-06-20 14:56:09 +03:00
parent 68dcee028d
commit 12280e4bfc
2 changed files with 70 additions and 49 deletions

View File

@ -17,13 +17,11 @@
#include <AIS_InteractiveContext.hxx> #include <AIS_InteractiveContext.hxx>
#include <AIS_ManipulatorOwner.hxx> #include <AIS_ManipulatorOwner.hxx>
#include <Extrema_ExtElC.hxx>
#include <gce_MakeDir.hxx> #include <gce_MakeDir.hxx>
#include <GeomAPI_ExtremaCurveCurve.hxx>
#include <GeomAPI_IntCS.hxx>
#include <Geom_Circle.hxx> #include <Geom_Circle.hxx>
#include <Geom_Line.hxx>
#include <Geom_Plane.hxx>
#include <Geom_Transformation.hxx> #include <Geom_Transformation.hxx>
#include <IntAna_IntConicQuad.hxx>
#include <Prs3d_Arrow.hxx> #include <Prs3d_Arrow.hxx>
#include <Prs3d_Root.hxx> #include <Prs3d_Root.hxx>
#include <Prs3d_ShadingAspect.hxx> #include <Prs3d_ShadingAspect.hxx>
@ -416,40 +414,56 @@ Standard_Boolean AIS_Manipulator::ObjectTransformation (const Standard_Integer t
switch (myCurrentMode) switch (myCurrentMode)
{ {
case AIS_MM_Translation: case AIS_MM_Translation:
case AIS_MM_Scaling:
{ {
gp_Lin aLine (myStartPick, myAxes[myCurrentIndex].Position().Direction()); const gp_Lin aLine (myStartPosition.Location(), myAxes[myCurrentIndex].Position().Direction());
Handle(Geom_Curve) anInputCurve = new Geom_Line (anInputLine); Extrema_ExtElC anExtrema (anInputLine, aLine, Precision::Angular());
Handle(Geom_Curve) aCurve = new Geom_Line (aLine); if (!anExtrema.IsDone()
GeomAPI_ExtremaCurveCurve anExtrema (anInputCurve, aCurve); || anExtrema.NbExt() != 1)
gp_Pnt aP1, aP2; {
anExtrema.NearestPoints (aP1, aP2); // translation cannot be done co-directed with camera
const gp_Pnt aNewPosition = aP2; return Standard_False;
}
Extrema_POnCurv anExPnts[2];
anExtrema.Points (1, anExPnts[0], anExPnts[1]);
const gp_Pnt aNewPosition = anExPnts[1].Value();
if (!myHasStartedTransformation) if (!myHasStartedTransformation)
{ {
myStartPick = aNewPosition; myStartPick = aNewPosition;
myHasStartedTransformation = Standard_True; myHasStartedTransformation = Standard_True;
return Standard_True; return Standard_True;
} }
else if (aNewPosition.Distance (myStartPick) < Precision::Confusion())
if (aNewPosition.Distance (myStartPick) < Precision::Confusion())
{ {
return Standard_False; return Standard_False;
} }
gp_Trsf aNewTrsf; gp_Trsf aNewTrsf;
aNewTrsf.SetTranslation (gp_Vec(myStartPick, aNewPosition)); if (myCurrentMode == AIS_MM_Translation)
theTrsf *= aNewTrsf; {
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; return Standard_True;
} }
case AIS_MM_Rotation: case AIS_MM_Rotation:
{ {
const gp_Pnt aPosLoc = myStartPosition.Location(); const gp_Pnt aPosLoc = myStartPosition.Location();
const gp_Ax1 aCurrAxis = getAx1FromAx2Dir (myStartPosition, myCurrentIndex); const gp_Ax1 aCurrAxis = getAx1FromAx2Dir (myStartPosition, myCurrentIndex);
IntAna_IntConicQuad aIntersector (anInputLine, gp_Pln (aPosLoc, aCurrAxis.Direction()), Precision::Angular(), Precision::Intersection());
Handle(Geom_Curve) anInputCurve = new Geom_Line (anInputLine);
Handle(Geom_Surface) aSurface = new Geom_Plane (aPosLoc, aCurrAxis.Direction());
GeomAPI_IntCS aIntersector (anInputCurve, aSurface);
if (!aIntersector.IsDone() || aIntersector.NbPoints() < 1) if (!aIntersector.IsDone() || aIntersector.NbPoints() < 1)
{ {
return Standard_False; return Standard_False;
@ -495,36 +509,6 @@ Standard_Boolean AIS_Manipulator::ObjectTransformation (const Standard_Integer t
myPrevState = anAngle; myPrevState = anAngle;
return Standard_True; 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: case AIS_MM_None:
{ {
return Standard_False; return Standard_False;

View File

@ -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