Opennurbs Opencascade 性能比较 之 NurbsCurve

Opennurbs Opencascade 性能分析

测试代码

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

测试代码

	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 rat = 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, rat, 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->SetKnot(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* pt = new double[4]{ occCv.Value(ii).X(), occCv.Value(ii).Y(), occCv.Value(ii).Z(), occW->Value(ii) };
				nurbs->SetCV(index++, ON::point_style::euclidean_rational, pt);
				delete pt;
			}
		return nurbs;
}

测试结果

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

opennurbs的耗时为opencascade耗时的 58%
读者可以构造其他单侧,也可以测试Nurbs曲线的其他API

上一篇:javascript – d3 v4中的曲线张力很奇怪


下一篇:在Python中拟合分箱的对数正态数据