Confine Mouse Movement in a 3D plane?

Hi, everybody:

How can I confine movuse movement in a 3D plane when I interactivly draw in a 3D viewer? V3D_View has convert method, but it seems to have no concise control on how it does this conversion. If I have to contruct two planes to do projection or intersection computation, how can I get the 2D plane attached on the screen?

Stephane Routelous's picture

see http://www.opencascade.com/phorum/read.php?f=1&i=2729&t=2728

and after project aResultPoint to your plane.

Stephane
http://www.exotk.org

P Dolbey's picture

I know it seems old hat now, but I'm revisiting this concept as part of my Qt4 OCC toolkit. Did anyone keep a copy of the code - the old *phorum* and any gems of information it contained are now long. I have the basis of a solution for a non-snapping grid - it should be certainly shorter than the code that sits behind ConverToGrid ( I think its based on a fairly convoluted function called ProjectToPlane ). I've looked at the model in occsketcher, but it doesn't seem to map well if you change PrivilegedPlane and I'm concerned of accuracy. One of the other problems I find is that whenever you find a function that looks like it might help, you discover its a private/protected mamber of a class, and I don't want to customise the interface specs to open them out, or use inheritance to circumvent this protection.

My solution will use a triangle shape function method to interpolate the mappping the mouse x,y to known forward projection points of 3 non-colinear points in the PrivilegedPlane. Its a technique I used a long time ago with OpenGL and gluUnProject, and should run quicky, but I can't believe its the BEST solution with OpenCASCADE. Does anybody know what is?

Pete

Mark's picture

Is your code available somewhere? I'm writing a program using qt3 and occ.

Thanks
Mark
http://cam.occ.googlepages.com/

P Dolbey's picture

Hi Mark,

I've got a small Qt4 bottle drawer demo based on an SDI model thats available on
http://myweb.tiscali.co.uk/dolbey/QtOpenCascade/

The discussion thread is on
http://www.opencascade.org/org/forum/thread_10338/

This is based on OCC 6.1, Qt 4.2.1 both compiled under VS2005 - there may be binary incompatibilities with using mixed compilations of OCC and Qt4 on different MS compilers.

I haven't yet added the point in plane code to the downloadable code yet. Since it was uploaded I've added some simple grid and view management functionality and I am currently trying to simplify the input/output code for the various file formats.

I think that most of the standard demos are obfuscating the *real* code by bad design. For instance, its my conjecture that views should be responsible for rendering images and sending appropriate events to the parent application. I don't know if my little library will come out any better but I'm trying to apply MVC principles in its design. In the case of the IO/routines, the demos are performing both import/export and GUI in the same class.

The point in plane code works of a kind, but I'm seeing some inaccuracy when I try to apply a precision < 1 world unit. However it should be up on the site during the week - look for the Doxygen release version to go up 0.3. (I didn't know if anyone else would be interested this week) - If I leave out the new i/o class (QtOCCInputOutput) it should be up in the next couple of days.

Pete

If you've got any comments about the code (i.e. how it might be better), put them in a post on this forum.

P Dolbey's picture

A long long time ago I went on a training course for CAS.CADE 1.5. I've kept most of the training materials, but haven't read them for years. Anyway for info, here's the old Matra documented way (updated a bit) for mapping screen points to 3d points on a plane - in my code I use the privileged plane of the view which can be used as a grid. (myPrecision is a constant set say to 0.01 for 2DPs).

Enjoy

Pete

/*!
ConvertToPlane convert 2d window position to 3d point on priviledged plane.
*/
Standard_Boolean QtOCCViewWidget::ConvertToPlane(const Standard_Integer Xs,
const Standard_Integer Ys,
Standard_Real& X,
Standard_Real& Y,
Standard_Real& Z,
Standard_Boolean usePrecision)
{
Standard_Real Xp = Xs, Yp = Ys;
Standard_Real Xv, Yv, Zv;
Standard_Real Vx, Vy, Vz;
gp_Pln aPlane(myView->Viewer()->PrivilegedPlane());
myView->Convert( Xp, Yp, Xv, Yv, Zv );
myView->Proj( Vx, Vy, Vz );
gp_Lin aLine(gp_Pnt(Xv, Yv, Zv), gp_Dir(Vx, Vy, Vz));
IntAna_IntConicQuad theIntersection (aLine, aPlane, Precision::Angular());
if (theIntersection.IsDone())
{
if (!theIntersection.IsParallel())
{
if (theIntersection.NbPoints() > 0)
{
gp_Pnt theSolution(theIntersection.Point(1));
X = theSolution.X();
Y = theSolution.Y();
Z = theSolution.Z();
if (usePrecision)
{
X = (X < 0. ? -1 : (X > 0. ? 1 : 0.)) * floor((abs(X)) / myPrecision) * myPrecision;
Y = (Y < 0. ? -1 : (Y > 0. ? 1 : 0.)) * floor((abs(Y)) / myPrecision) * myPrecision;
Z = (Z < 0. ? -1 : (Z > 0. ? 1 : 0.)) * floor((abs(Z)) / myPrecision) * myPrecision;
}
return Standard_True;
}
}
}
return Standard_False;
}

fhchina's picture

Thanks.

I have used a part of your code. I am in progress. But I think I should make my idea more concise. I want to make a user draw on the screen JUST AS HE/SHE DRAW ON A 3D PLANE IN A 3D SPACE. So it is possible to appear a diamond when user is actually drawing a squire on that 3D plane. What I want to know is if I should project the point on screen(i.e., the view plane on 3D view reference frame) to that 3D plane, as you said, or develop a Geom_Line perpendicular to the view plane and intersect with that 3D plane( as what I do)?