|
在Open Cascade中转换当前鼠标坐标为视图空间坐标
在利用OCC进行交互选择的时候,经常要知道当前鼠标点的位置对应于3d视图中的空间坐标,但在OCC中想要得到它的位置的话,要经过一系列的变换才行。
OCC在View类中(V3d_VIew)中有相应的转换函数,Convert(……)函数,可以把当前点转换到3d视图中的对应与重合与屏幕平面上,对于2d的应用应该是可以对付对付的,但要用于3d,要进行适当的转换,通过获取视图的视点(eye point) 和观测点(at point) ,找到当前的投影平面,利用convert得到的鼠标在屏幕平面上的投影,在将此点投影到当前的投影平面上,得到坐标。代码如下:
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(x,y,X,Y,Z);
gp_Pnt ConvertedPoint(X,Y,Z);
gp_Pnt2d ConvertedPointOnPlane=ProjLib:roject(PlaneOfTheView,ConvertedPoint);
gp_Pnt ResultPoint=ElSLib::Value(ConvertedPointOnPlane.X(), ConvertedPointOnPlane.Y(), PlaneOfTheView);
上述转换能得到相应的正确的在投影平面上的点,不过如果在利用这个函数的过程中再利用旋转的命令的话,视图会发生严重的抖动,因为在此函数中调用了视图的Eye点和at点,这两个点在旋转时有一个是会变化的,所以如果要用到旋转的话,可是对此函数进行改进,代码如下:
//IMPROVE of the Stephane's method, rotate the object, display well
//Avoid using the Eye(....) function
ASSERT(!aView.IsNull ()) ; //view_not_null
// Make a plane perpendicular to the projection orientation.
Standard_Real x_ori, y_ori, z_ori;
aView->roj (x_ori, y_ori, z_ori);
gp_Dir proj_orientation (x_ori, y_ori, z_ori);
gp_Pln view_plane = gp_Pln (gp_Pnt (0, 0, 0), proj_orientation);
// Convert the 2d point into a 3d point.
Standard_Real xp, yp, zp;
aView->Convert (x, y, xp, yp, zp);
gp_Pnt converted_pnt (xp, yp, zp);
// Project the converted point in the plane.
gp_Pnt2d projected_pnt = ProjLib:roject (view_plane, converted_pnt);
// Get a 3d point from this 2d point.
return ElSLib::Value (projected_pnt.X (), projected_pnt.Y (), view_plane);
明天将继续如何在建好的模型上,选取点 |
|