对比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倍