当前位置: 首页 > 工具软件 > OpenNURBS > 使用案例 >

Opennurbs Opencascade 性能比较 之 NurbsCurve

曾珂
2023-12-01

测试代码

测试了 NurbsCurve 的 基础API :
D0点
D1一阶导
D2二阶导

高级API可以看成是 基础 API的组合。
最近距离/反求参数 : 用到了 D0 D1
长度/表面积/体积计算: 用到了 D0 D1
曲率计算: 用到了 D1 D2
求交计算: 用到了 D0 D1,有的求交方法会用到曲率
离散算法: D0

基础API效率测试代码

	int main()
	{
		Geom_BSplineCurve*  nurbs = ;
		int N = 10000000;
		double time = 0;
		LARGE_INTEGER nFreq;
		LARGE_INTEGER nBeginTime;
		LARGE_INTEGER nEndTime;
		QueryPerformanceFrequency(&nFreq);
		QueryPerformanceCounter(&nBeginTime);//开始计时  
		for (int i = 0; i < N; i++)
		{
			gp_Pnt pt;
			gp_Vec v1;
			gp_Vec v2;
			nurbs.D0(i*M_PI * 2 / N, pt);
			nurbs.D1(i*M_PI * 2 / N, pt,v1);
			nurbs.D2(i*M_PI * 2 / N, pt, v1, v2);

		}
		QueryPerformanceCounter(&nEndTime);//停止计时  
		time = (double)(nEndTime.QuadPart - nBeginTime.QuadPart) / (double)nFreq.QuadPart;//计算程序执行时间单位为s  
		cout << "opencascade 程序执行时间 :" << time * 1000 << "ms" << endl;

		ON_NurbsCurve* opennurbs = ToOpenNurbsCurve(nurbs);

		double time2 = 0;
		LARGE_INTEGER nFreq2;
		LARGE_INTEGER nBeginTime2;
		LARGE_INTEGER nEndTime2;
		QueryPerformanceFrequency(&nFreq2);
		QueryPerformanceCounter(&nBeginTime2);//开始计时  
		for (int i = 0; i < N; i++)
		{
			ON_3dPoint point;
			ON_3dVector first_derivative;
			ON_3dVector second_derivative;
			auto pt = opennurbs->PointAt(i*M_PI * 2 / N);
			auto b1 = opennurbs->Ev1Der(i*M_PI * 2 / N, point, first_derivative);
			auto b2 = opennurbs->Ev2Der(i*M_PI * 2 / N, point, first_derivative, second_derivative);

		}
		QueryPerformanceCounter(&nEndTime2);//停止计时  
		time2 = (double)(nEndTime2.QuadPart - nBeginTime2.QuadPart) / (double)nFreq2.QuadPart;//计算程序执行时间单位为s  
		cout << "opennurbs 程序执行时间 :" << time2 * 1000 << "ms" << endl;
	}

曲线转化代码:

static ON_NurbsCurve* ToOpenNurbsCurve(const  Handle(Geom_BSplineCurve) curve) {
	bool isPeriodic = curve->IsPeriodic();
	int isRat = curve->IsRational() ? 1 : 0;
	int order = curve->Degree() + 1;
	int nBcv = curve->NbPoles() + (isPeriodic ? 1 : 0);
	int nBKs = nBcv + order;
	auto OCCknots = curve->Knots();
	int index = 0;
	int nbK = curve->NbKnots();
	auto nurbs = ON_NurbsCurve::New(3, isRat, order, nBcv);
	// fill 
	for (int i = 1; i <= nbK; i++)
	{
		int multi = curve->Multiplicity(i);
		if (!isPeriodic && (i == 1 || i == nbK)) {
			multi--;
		}
		while (multi > 0) {
			nurbs->m_knot[index++] = OCCknots.Value(i);
			multi--;
		}
	}
	auto occCv = curve->Poles();
	auto occW = curve->Weights();
	index = 0;
	for (int i = 1; i <= nBcv; i++)
	{
		int ii = i;
		if (isPeriodic && i == nBcv) {
			ii = 1;
		}
		double w = (occW == NULL)? 1 : occW->Value(ii);
		int base = (i-1) * nurbs->m_cv_stride;
		auto pt = occCv.Value(ii);
		nurbs->m_cv[base + 0] = pt.X() * w;
		nurbs->m_cv[base + 1] = pt.Y() * w;
		nurbs->m_cv[base + 2] = pt.Z() * w;
		if (isRat) {
			nurbs->m_cv[base + 3] = w;
		}
	}
	return nurbs;

}

测试结果

测试了一个圆和半圆转Nurbs:
opencascade 程序执行时间 :3463.91ms
opennurbs 程序执行时间 :2008.1ms
opennurbs的耗时为opencascade耗时的 58%

读者也可以在自己机器上测试下对比效果~

 类似资料: