|
在Open Cascade中如何实现在实体上得到鼠标的当前位置点
这个标题写的很长,希望大家能够理解我的意思,呵呵。被这个问题困扰了好几天,后来到OCC的论坛上去问了关于这个实现的问题,没有得到很好的答复,后来,经过了3天左右的反复试验,对于一个正方体来说(就是说鼠标所在射线的投影与实体只有两个交点的情况),是可以了,对复杂的物体是不是也能够实现,还有待考证。
用到的方法就是在上一贴的基础上,加入对视图中已有物体的面的一个遍历,求出交点,加入一个队列中,在进行比较。还是看源代码吧,应该还是比较清晰的,如有什么问题,请在后面留言。
gp_Pnt CCMMSoftWareView::ConvertClickToPointOnSelectedSurface(Standard_Integer x, Standard_Integer y,
Handle_V3d_View aView)
{
TopExp_Explorer exp;
// 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.
gp_Pnt ResultPoint=ElSLib::Value (projected_pnt.X (), projected_pnt.Y (), view_plane);
GC_MakeLine line(ResultPoint,proj_orientation);
gp_Pnt a3dPnt;
TColgp_SequenceOfPnt aSquence;
for(exp.Init(aShape,TopAbs_FACE);exp.More();exp.Next())
{
TopoDS_Face aFace=TopoDS::Face(exp.Current());
BRepAdaptor_Surface aSurface(aFace);
const GeomAdaptor_Surface &geomAdapSurf=aSurface.Surface(); //这个平面为实际平面
const Handle_Geom_Surface &geomSurf=geomAdapSurf.Surface(); //此平面转换成了无限的平面
GeomAPI_IntCS intCS;
Standard_Real U,V,W,u1,v1,u2,v2;
u1=geomAdapSurf.FirstUParameter();
u2=geomAdapSurf.LastUParameter();
v1=geomAdapSurf.FirstVParameter();
v2=geomAdapSurf.LastVParameter();
intCS.Perform(line.Value(),geomSurf);
if(intCS.IsDone())
{
if(intCS.NbPoints()!=0)
{
intCS.Parameters(1,U,V,W);
if(U>u1 && U<u2 && V>v1 && V<v2)
{
a3dPnt= gp_Pnt(intCS.Point(1).XYZ());
aSquence.Append(a3dPnt);
}
}
}
}
GC_MakeLine anotherLine(aSquence.First(),aSquence.Last());
Handle_Geom_Line Geomline=anotherLine.Value();
gp_Lin gpLine=Geomline->Lin();
if(gpLine.Direction().IsEqual(proj_orientation,Precision::Angular()))
return aSquence.Last();
else if (gpLine.Direction().IsOpposite(proj_orientation,Precision::Angular()))
return aSquence.First();
else
return gp_Pnt(0.,0.,0.);
return gp_Pnt(0.,0.,0.);
} |
|