如何获取指定平面的最大内切圆,UG中没有直接获取的函数,我们可以通过一系列操作获取最内切圆
1、效果展示

2、实现方法
1、获取面的长宽,计算点集间距(点击间距越小,计算精度越高,但是执行时间更长)
//计算面的长宽
std::vector<NXOpen::NXObject *> sellist(1);
sellist[0] = faceObj;
NXOpen::Point3d ptanchor(0.0, 0.0, 0.0);
std::vector<NXOpen::Point3d> boxpoints;
std::vector<NXOpen::Point3d> tmpdir;
std::vector<double> edgelength;
NXOpen::Point3d ptorigin;
NXOpen::Point3d ptextreme;
double pdvolume;
theSession->Measurement()->GetBoundingBoxProperties(sellist, 0, ptanchor, false, boxpoints, tmpdir, edgelength, &ptorigin, &ptextreme, &pdvolume);
//判断U、V的值
double uValue = 0.0;
double vValue = 0.0;
double length = 0.0;
for(int i=0; i<edgelength.size(); i++){
double v = edgelength[i];
if(std::fabs(v) > 0.0000001){
if(uValue < v){
uValue = v;
}
if(vValue < 0.0000001 || vValue > v){
vValue = v;
}
}
}
2、根据面做点集
std::vector<NXOpen::Point *> KKTools::createPointSets(NXOpen::Face* face,double uValue,double vValue,double tolerance){
std::vector<NXOpen::Point *> pointVec;
if(face == NULL){
return pointVec;
}
Part *workPart(theSession->Parts()->Work());
//创建点集
NXOpen::Features::PointSet *nullNXOpen_Features_PointSet(NULL);
NXOpen::Features::PointSetBuilder *pointSetBuilder1 = workPart->Features()->CreatePointSetBuilder(nullNXOpen_Features_PointSet);
//点集类型
pointSetBuilder1->SetType(NXOpen::Features::PointSetBuilder::TypesFacePoints);
//子类型
pointSetBuilder1->SetFacePointsBy(NXOpen::Features::PointSetBuilder::FacePointsTypePattern);
//选择面
pointSetBuilder1->SingleFaceObject()->SetValue(face);
//阵列定义
//点数
pointSetBuilder1->NumberOfPointsInUDirectionExpression()->SetValue(uValue/tolerance);
pointSetBuilder1->NumberOfPointsInVDirectionExpression()->SetValue(vValue/tolerance);
// pointSetBuilder1->NumberOfPointsInUDirectionExpression()->SetValue(20);
// pointSetBuilder1->NumberOfPointsInVDirectionExpression()->SetValue(20);
//阵列限制
pointSetBuilder1->SetPatternLimitsBy(NXOpen::Features::PointSetBuilder::PatternLimitsTypePercentages);
pointSetBuilder1->PatternLimitsStartingUValue()->SetFormula("0");
pointSetBuilder1->PatternLimitsEndingUValue()->SetFormula("100");
pointSetBuilder1->PatternLimitsStartingVValue()->SetFormula("0");
pointSetBuilder1->PatternLimitsEndingVValue()->SetFormula("100");
NXOpen::NXObject *nXObject1 = pointSetBuilder1->Commit();
pointSetBuilder1->Destroy();
if(nXObject1 != NULL) {
NXOpen::Features::PointSet *pointSet1(dynamic_cast<NXOpen::Features::PointSet *>(nXObject1));
if (pointSet1) {
pointSet1->HideBody();
pointVec = pointSet1->GetPoints();
}
}
return pointVec;
}
3、遍历点集,计算每个点到所有边的最短距离,遍历所有的点的最短距离,找到最大值,即获得最大内切圆半径以及圆心点
MIN_CICLE_INFO minInfo;//记录最大内切圆
minInfo.distance = -1.0;
if(pointVec.size() > 0){//判断点集不为空
std::vector<NXOpen::DisplayableObject *> objects2;
for(auto edge : faceObj->GetEdges()){
objects2.push_back(edge);//获取面的所有边
}
for(auto obj : pointVec){
//判断点在面内
double point[3];
point[0] = obj->Coordinates().X;
point[1] = obj->Coordinates().Y;
point[2] = obj->Coordinates().Z;
int pt_status;
UF_MODL_ask_point_containment(point,faceObj->Tag(),&pt_status);
if(pt_status == 1){//点在面内
std::vector<NXOpen::DisplayableObject *> objects1(1);
objects1[0] = obj;
//计算点到所有边的最小距离
NXOpen::Point3d pt1;
NXOpen::Point3d pt2;
bool isapproximate;
double minDistance = theSession->Measurement()->GetDistance(NXOpen::Measurement::AlternateDistanceMinimum, true, objects1, objects2, &pt1, &pt2, &isapproximate);
if(minDistance > 0){
//判断是否是最大距离
if(minInfo.distance < minDistance){
minInfo.distance = minDistance;
minInfo.center = pt1;
minInfo.point = pt2;
}
}
}
}
}
4、绘制圆
NXOpen::Arc* KKTools::createCicle(NXOpen::Face* face,NXOpen::Point* objPoint,double radius){
if(face == NULL || objPoint == NULL){
return NULL;
}
NXOpen::Arc *arcObj = NULL;
Part *workPart(theSession->Parts()->Work());
//获取面的法向
NXOpen::Direction *measureDir = workPart->Directions()->CreateDirection(face, NXOpen::Sense::SenseReverse, NXOpen::SmartObject::UpdateOptionWithinModeling);
//创建平面
NXOpen::Plane *plane = workPart->Planes()->CreatePlane(measureDir->Origin(), measureDir->Vector(), NXOpen::SmartObject::UpdateOptionWithinModeling);
NXOpen::NXMatrix *nXMatrix1 = workPart->NXMatrices()->Create(plane->Matrix());
//画圆
NXOpen::Arc *arc = workPart->Curves()->CreateArc(objPoint->Coordinates(), nXMatrix1, radius, 0.0, ( 360.0 * DEGRA ));
return arc;
}
3、总结
这个方法可以粗略计算最大内切圆半径,供刀具选择参考使用,如果点集数量过大,会导致程序计算缓慢且需要内存量比较大,建议使用100*100的点集基本可以秒出。
2991

被折叠的 条评论
为什么被折叠?



