问题:针对导入的部分面无法获取大小,同时也无法判断点是否在面上。但是OBB可以获取大小
解决方法:通过面拟合转换gp_Pln,然后获取面的内外边,重新修剪生成新的TopoDS_Face
疑问:本人对OCC中各种面的特性不是很了解有知道的老大可以帮忙普及一下:
TopoDS_Face
BRepAdaptor_Surface
GeomAbs_Plane
Geom_Plane
GeomPlate_Surface
gp_Pln
以下是实现的参数部分代码,通过UV提取点,判断点是否在面上。
//如果获取的包容盒小于步距,获取一下OBB包容盒判断是否大于2,大于2开始面转换
if (aUmax - aUmin < uStep || aVmax - aVmin < vStep)
{
Bnd_OBB obb;
BRepBndLib::AddOBB(aFace, obb, Standard_True, Standard_False);
if (2 * obb.XHSize() > 2 || 2 * obb.YHSize() > 2 || 2 * obb.ZHSize() > 2)
{
//判断面的类型 转换面类型 获取面的边界 修建获取新的有界面 针对平面
if (aSurface.GetType() == GeomAbs_SurfaceOfRevolution || aSurface.GetType() == GeomAbs_BSplineSurface)//回旋曲面//样条曲面
{
TopLoc_Location theTopLoc_Location = aFace.Location();
Handle(Geom_Surface) geomSurface = aSurface.Surface().Surface();
Handle(Geom_BSplineSurface) bsplineSurface = GeomConvert::SurfaceToBSplineSurface(geomSurface);
GeomConvert_SurfToAnaSurf converter(bsplineSurface);
converter.SetConvType(GeomConvert_Simplest);
converter.SetTarget(GeomAbs_Plane);
geomSurface = converter.ConvertToAnalytical(1);
gp_Pln thegp_Pln;
if (converter.IsCanonical(geomSurface))
{
Standard_CString aRotatedEntityTypeName = geomSurface->DynamicType()->Name();
if (geomSurface->IsKind(STANDARD_TYPE(Geom_Plane)))
{
Handle(Geom_Plane) theGeom_Plane = Handle(Geom_Plane)::DownCast(geomSurface);
theGeom_Plane->Transform(theTopLoc_Location);
if (theGeom_Plane.IsNull())
{
return 0;
}
thegp_Pln = theGeom_Plane->Pln();
TopoDS_Wire outerWire = ShapeAnalysis::OuterWire(aFace);
std::vector<TopoDS_Wire> innerHoles;
// 遍历面上的每个边界线 (TopoDS_Wire)
for (TopExp_Explorer wireExp(aFace, TopAbs_WIRE); wireExp.More(); wireExp.Next()) {
TopoDS_Wire wire = TopoDS::Wire(wireExp.Current());
if (!wire.IsSame(outerWire))
{
innerHoles.push_back(wire); // 内孔
}
}
BRepBuilderAPI_MakeFace faceBuilder(thegp_Pln, outerWire);
// 添加内孔
for (const auto& holeWire : innerHoles) {
faceBuilder.Add(holeWire);
}
// 生成新的有限平面
aFace = faceBuilder.Face();
aSurface = BRepAdaptor_Surface(aFace);
aUmin = aSurface.FirstUParameter();
aUmax = aSurface.LastUParameter();
aVmin = aSurface.FirstVParameter();
aVmax = aSurface.LastVParameter();
}
}
}
}
}