NX2306 C++二次开发系列(10)获取平面的最大内切圆

如何获取指定平面的最大内切圆,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的点集基本可以秒出。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

守护暗神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值