标签:infinite ble == key VID standard extc red builder
想用鼠标在线条(TopoDS_Edge/TopoDS_Wire)、面(TopoDS_Face)或任意形状(TopoDS_Shape)上,随机选择一个点,需要先将鼠标屏幕坐标转为模型空间坐标,然后计算空间坐标到模型的最近点。
当模型较为复杂或网格模型,速度会有所降低。
第一步:坐标转换
Handle(V3d_View) view3d = ...;
V3d_Coordinate XEye,YEye,ZEye,XAt,YAt,ZAt; view3d->Eye(XEye,YEye,ZEye); view3d->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); Standard_Real x, y, z; view3d->Convert(scP.x, scP.y, x, y, z); gp_Pnt tempPnt(x, y, z);
TopoDS_Wire sh = ...;
gp_Pnt aPnt;
gp_Dir aDir;
pickNearestPoint(tempPnt,EyeDir, Sh, aPnt,aDir,TopAbs_EDGE);
第二步:计算最近点
Standard_Real DistanceOut(const TopoDS_Shape& S1, const TopoDS_Shape& S2)
{
Bnd_Box BBox1, BBox2;
BRepBndLib::Add(S1, BBox1);
BRepBndLib::Add(S2, BBox2);
return BBox1.Distance(BBox2);
}
Standard_Real DistanceIn(const TopoDS_Shape& S1, const TopoDS_Shape& S2)
{
Bnd_Box LBBox, SBBox;
BRepBndLib::Add(S1, SBBox);
BRepBndLib::Add(S2, LBBox);
Standard_Real LXmin, LYmin, LZmin, LXmax, LYmax, LZmax,
SXmin, SYmin, SZmin, SXmax, SYmax, SZmax;
SBBox.Get(SXmin, SYmin, SZmin,
SXmax, SYmax, SZmax);
LBBox.Get(LXmin, LYmin, LZmin,
LXmax, LYmax, LZmax);
//Compute the max distance between input shapes------------//
gp_XYZ Lmin(LXmin, LYmin, LZmin),
Lmax(LXmax, LYmax, LZmax);
gp_XYZ Smin(SXmin, SYmin, SZmin),
Smax(SXmax, SYmax, SZmax);
Lmax.Subtract(Lmin);
Smax.Subtract(Smin);
return Lmax.Modulus() + Smax.Modulus() + DistanceOut(S1, S2);
}
bool pickNearestPoint(const gp_Pnt& P, const gp_Dir& viewDir, const TopoDS_Shape &S, gp_Pnt& relPoint, gp_Dir& faceNormal,bool onlyEdges) { if (S.IsNull()) return false; if (onlyEdges) { TopTools_IndexedMapOfShape M; TopExp::MapShapes(S, TopAbs_EDGE, M); int count = M.Extent(); if (count == 0) return false; gp_Pnt tempProjPnt; gp_Dir tempProjPntFaceNormal; double maxDis = Precision::Infinite(), dis; bool isOk = false; for (int i = 1; i <= count; i++) { const TopoDS_Edge &E = TopoDS::Edge(M.FindKey(i)); if (pickNearestPoint(P,viewDir,E, tempProjPnt, tempProjPntFaceNormal,false)) { dis = tempProjPnt.Distance(P); if (dis < maxDis) { maxDis = dis; relPoint = tempProjPnt; } isOk = true; } } return isOk; } else { double d = DistanceIn(BRepBuilderAPI_MakeVertex(P), S); gp_Vec Vsup(viewDir.XYZ() * 2 * d); TopoDS_Edge tempEdge = BRepBuilderAPI_MakeEdge(P.Translated(-1 * Vsup), P.Translated(Vsup)/*EyePoint*/); bool ok = false; //速度快 if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) { if (S.ShapeType() == TopAbs_EDGE) { BRepExtrema_ExtCC ext(tempEdge, TopoDS::Edge(S)); if (ext.IsDone() && ext.NbExt() > 0) { //get min distance double distance = Precision::Infinite(); for (int i = 1; i <= ext.NbExt(); i++) { Standard_Real d = ext.SquareDistance(i); if (d < distance) { relPoint = ext.PointOnE2(i); distance = d; ok = true; } } } } }
}
return true;
}
更多精彩请关注公众号
标签:infinite ble == key VID standard extc red builder
原文地址:https://www.cnblogs.com/occi/p/14711707.html