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