Mouse position on object

Hello,

I am currently using this code to get 3D mouse position from 2D coords
http://pastebin.com/jHQwd5GW

But say mouse is over a shape, it will ignore the shape.
What is the best way to get the 3D mouse position on an object?
You could possibly create a line in the the eye direction and check for intersections, the intersection would be the mouse pos.
Is this the best way to do it?

Thank you for any tips!
I uploaded a file with two methods that help

Attachments: 
Daniel Park's picture

This is the code I used and it works effectively.

Call this method on each click.
///
/// \brief View::getMousePositionWithObjects
/// \param point
/// \return
///
/// If an object is highlighted return mouse position with
/// Intersection of objects.
/// If no object is highlighted return the true mouse position.
gp_Pnt View::getMousePositionWithObjects(const QPoint point)
{
if (myContext->HasDetected()) {
myContext->InitDetected();
Handle_AIS_InteractiveObject hObj = myContext->DetectedInteractive();
if(!hObj.IsNull()) {
Handle_AIS_Shape hShape = Handle_AIS_Shape::DownCast(hObj);
if(!hShape.IsNull()) {
const TopoDS_Shape &shape = hShape->Shape();
gp_Lin line = viewCalc.createLineFromViewEye(point.x(), point.y(), aView);
gp_Pnt intersectPoint = occCalc.intersectLineThroughShape(shape, line);
return intersectPoint;
} else {
//Handle_AIS_Shape null
}
} else {
//Handle_AIS_InteractiveObject null
}
} else {
return getTrueMousePosition(point);
}
}

Required methods:
gp_Lin ViewCalculations::createLineFromViewEye(Standard_Real x, Standard_Real y, Handle(V3d_View) view)
{
Standard_Real Xp = x, Yp = y;
Standard_Real Xv, Yv, Zv;
Standard_Real Vx, Vy, Vz;

view->Convert( Xp, Yp, Xv, Yv, Zv );
view->Proj( Vx, Vy, Vz );

return gp_Lin(gp_Pnt(Xv, Yv, Zv), gp_Dir(Vx, Vy, Vz));
}

gp_Pnt OCCCalculations::intersectLineThroughShape(const TopoDS_Shape &shapeToIntersect, const gp_Lin &lineForIntersecting)
{
IntCurvesFace_ShapeIntersector shapeIntersector;
shapeIntersector.Load(shapeToIntersect, Precision::Confusion());
shapeIntersector.Perform(lineForIntersecting, -RealLast(), RealLast());

return shapeIntersector.Pnt(1);
}

Hope that helps someone.

Daniel Park's picture

You will also need these two methods:

gp_Pnt View::getTrueMousePosition(const QPoint point)
{
gp_Pnt point3d = viewCalc.convert2DPointTo3DPoint(point.x(),point.y(),aView); // convert2DPointTo3DPoint convert2DpointTo3DPointOnPlane
gp_Pnt pointTest(point3d.X(),point3d.Y(),point3d.Z());
return pointTest;
}

gp_Pnt ViewCalculations::convert2DPointTo3DPoint(Standard_Real x, Standard_Real y, Handle(V3d_View) aView)
{
V3d_Coordinate XEye,YEye,ZEye,XAt,YAt,ZAt;
aView->Eye(XEye,YEye,ZEye);
aView->At(XAt,YAt,ZAt);
gp_Pnt EyePoint(XEye,YEye,ZEye);
gp_Pnt AtPoint(XAt,YAt,ZAt);

gp_Vec EyeVector(EyePoint,AtPoint);
gp_Dir EyeDir(EyeVector);

gp_Pln PlaneOfTheView = gp_Pln(AtPoint,EyeDir);
Standard_Real X,Y,Z;
aView->Convert(int(x),int(y),X,Y,Z);
gp_Pnt ConvertedPoint(X,Y,Z);
gp_Pnt2d ConvertedPointOnPlane = ProjLib::Project(PlaneOfTheView,ConvertedPoint);

gp_Pnt ResultPoint = ElSLib::Value(ConvertedPointOnPlane.X(),
ConvertedPointOnPlane.Y(),
PlaneOfTheView);

return ResultPoint;
}