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

Opennurbs Opencascade 性能比较 之 NurbsSurface

叶元凯
2023-12-01

对比opencascade 和opennurbs NurbsSurface计算效率:
构造Nurbs球面,测试耗时:
opencascade 程序执行时间 :22172.6ms
opennurbs 程序执行时间 :11970.9ms
opencascade 的耗时是opennurbs 耗时的1.85倍

static ON_NurbsSurface* ToOpenNurbsSurface(const  Handle(Geom_BSplineSurface) surface) {
	int m_dim = 3;
	bool isUPeriodic = surface->IsUPeriodic();
	bool isVPeriodic = surface->IsVPeriodic();
	int m_is_rat = (surface->IsURational() || surface->IsVRational()) ? 1 : 0;
	int m_order[2] = { surface->UDegree() + 1,  surface->VDegree() + 1 };
	int m_cv_count[2] = { surface->NbUPoles() + (isUPeriodic ? 1 : 0 ),  surface->NbVPoles() + (isVPeriodic ? 1 : 0) };

	auto nurbs = ON_NurbsSurface::New(m_dim, m_is_rat, m_order[0], m_order[1], m_cv_count[0], m_cv_count[1]);
	// knotsU
	auto OCCknotsU = surface->UKnots();
	int nbUknots = OCCknotsU.Length();

	int indexU = 0;
	for (int i = 1; i <= nbUknots; i++)
	{
		int uMulti = surface->UMultiplicity(i);
		if (!isUPeriodic && (i == 1 || i == nbUknots)) {
			uMulti--;
		}
		while (uMulti > 0) {
			nurbs->m_knot[0][indexU++] = OCCknotsU.Value(i);
			uMulti--;
		}
	}
	// knotsV
	auto OCCknotsV = surface->VKnots();
	int nbVknots = OCCknotsV.Length();
	int indexV = 0;
	for (int i = 1; i <= nbVknots; i++)
	{
		int vMulti = surface->VMultiplicity(i);
		if (!isVPeriodic && (i == 1 || i == nbVknots)) {
			vMulti--;
		}
		while (vMulti > 0) {
			nurbs->m_knot[1][indexV++] = OCCknotsV.Value(i);
			vMulti--;
		}
	}
	// CVs
	auto poles = surface->Poles();
	for (int i = 1; i <= m_cv_count[0]; i++) {
		for (int j = 1; j <= m_cv_count[1]; j++) {
			auto pt = poles.Value(i, j);
			double w = surface->Weight(i, j);
			int beginPosition = (i - 1)*nurbs->m_cv_stride[0] + (j - 1)*nurbs->m_cv_stride[1];
			nurbs->m_cv[beginPosition + 0] = pt.X() * w;
			nurbs->m_cv[beginPosition + 1] = pt.Y() * w;
			nurbs->m_cv[beginPosition + 2] = pt.Z() * w;
			if (m_is_rat) {
				nurbs->m_cv[beginPosition + 3] = w;
			}
		}
	}

	return nurbs;
}
void testCostTime() {
	int N = 10000;
	gp_Ax3 ccs;
	Handle(Geom_SphericalSurface) occtS = new Geom_SphericalSurface(ccs, 10);
	Handle(Geom_BSplineSurface) occNurbs = GeomConvert::SurfaceToBSplineSurface(occtS);
	//  OCCT
	double time = 0;
	LARGE_INTEGER nFreq;
	LARGE_INTEGER nBeginTime;
	LARGE_INTEGER nEndTime;
	QueryPerformanceFrequency(&nFreq);
	QueryPerformanceCounter(&nBeginTime);//开始计时  
	//gp_Ax2 A;
	//Handle2(Geom_Curve) ResCurve = new Geom_Circle(A, 10);
	//Handle2(Geom_TrimmedCurve) myTrimmed = new Geom_TrimmedCurve(ResCurve, 0, M_PI);
	//Handle2(Geom_BSplineCurve) occtNurbsCurve = GeomConvert::CurveToBSplineCurve(myTrimmed);
	//gp_Pnt P;
	//gp_Vec V1;
	//gp_Vec V2;
	//gp_Vec V3;
	//for (int i = 0; i <= N; i++) {
	//	const Standard_Real U = i * M_PI / N;
	//	occtNurbsCurve->D0(U, P);
	//	occtNurbsCurve->D1(U, P, V1);
	//	//occtNurbsCurve->D2(U, P, V1, V2);
	//	//occtNurbsCurve->D3(U, P, V1, V2, V3);
	//}

	gp_Pnt P;
	for (int i = 0; i <= N; i++) {
		for (int j = 0; j <= N; j++) {
			double u = i * 2 * M_PI / N;
			double v = j * M_PI / N - M_PI / 2;
			occNurbs->D0(u, v, P);
		}
	}

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



	ON_NurbsSurface s;
	ON_Sphere* sphere1 = new ON_Sphere(ON_Point(), 10.0);
	ON_3dPoint pt;
	sphere1->GetNurbForm(s);
	//OPENNURBS
	double time2 = 0;
	LARGE_INTEGER nFreq2;
	LARGE_INTEGER nBeginTime2;
	LARGE_INTEGER nEndTime2;
	QueryPerformanceFrequency(&nFreq2);
	QueryPerformanceCounter(&nBeginTime2);//开始计时  
	//ON_Plane plane;
	//ON_Circle circleA = ON_Circle(plane, 10);
	//ON_NurbsCurve *curveA = ON_NurbsCurve::New();
	//circleA.GetNurbForm(*curveA);
	//ON_3dPoint pt;
	//double *v = new double[12];
	//for (int i = 0; i <= N; i++) {
	//	const double u2 = i * M_PI / N;
	//	pt = curveA->PointAt(u2);
	//	bool rc = curveA->Evaluate(u2, 1, 3, v);
	//	//bool rc2 = curveA->Evaluate(u2, 2, 3, v);
	//	//bool rc3 = curveA->Evaluate(u2, 3, 3, v);
	//}


	for (int i = 0; i <= N; i++) {
		for (int j = 0; j <= N; j++) {
			double u = i * 2 * M_PI / N;
			double v = j * M_PI / N - M_PI / 2;
			pt = s.PointAt(u, v);
		}
	}

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


构造Nurbs球面,测试耗时:
opencascade 程序执行时间 :22172.6ms
opennurbs 程序执行时间 :11970.9ms

opencascade 的耗时是opennurbs 耗时的1.85倍

 类似资料: