static Point3f NURBSEvaluateSurface(int uOrder, const Float *uKnot, int ucp, Float u, int vOrder, const Float *vKnot, int vcp, Float v, const Homogeneous3 *cp, Vector3f *dpdu, Vector3f *dpdv) { Homogeneous3 *iso = ALLOCA(Homogeneous3, std::max(uOrder, vOrder)); int uOffset = KnotOffset(uKnot, uOrder, ucp, u); int uFirstCp = uOffset - uOrder + 1; Assert(uFirstCp >= 0 && uFirstCp + uOrder - 1 < ucp); for (int i = 0; i < uOrder; ++i) iso[i] = NURBSEvaluate(vOrder, vKnot, &cp[uFirstCp + i], vcp, ucp, v); int vOffset = KnotOffset(vKnot, vOrder, vcp, v); int vFirstCp = vOffset - vOrder + 1; Assert(vFirstCp >= 0 && vFirstCp + vOrder - 1 < vcp); Homogeneous3 P = NURBSEvaluate(uOrder, uKnot, iso - uFirstCp, ucp, 1, u, dpdu); if (dpdv) { for (int i = 0; i < vOrder; ++i) iso[i] = NURBSEvaluate(uOrder, uKnot, &cp[(vFirstCp + i) * ucp], ucp, 1, u); (void)NURBSEvaluate(vOrder, vKnot, iso - vFirstCp, vcp, 1, v, dpdv); } return Point3f(P.x / P.w, P.y / P.w, P.z / P.w); }
static Point NURBSEvaluateSurface(int uOrder, const float *uKnot, int ucp, float u, int vOrder, const float *vKnot, int vcp, float v, const Homogeneous3 *cp, Vector *dPdu, Vector *dPdv) { Homogeneous3 *iso = (Homogeneous3 *)alloca(max(uOrder, vOrder) * sizeof(Homogeneous3)); int uOffset = KnotOffset(uKnot, uOrder, ucp, u); int uFirstCp = uOffset - uOrder + 1; assert(uFirstCp >= 0 && uFirstCp + uOrder - 1 < ucp); for (int i = 0; i < uOrder; ++i) iso[i] = NURBSEvaluate(vOrder, vKnot, &cp[uFirstCp + i], vcp, ucp, v); int vOffset = KnotOffset(vKnot, vOrder, vcp, v); int vFirstCp = vOffset - vOrder + 1; assert(vFirstCp >= 0 && vFirstCp + vOrder - 1 < vcp); Homogeneous3 P = NURBSEvaluate(uOrder, uKnot, iso - uFirstCp, ucp, 1, u, dPdu); if (dPdv) { for (int i = 0; i < vOrder; ++i) iso[i] = NURBSEvaluate(uOrder, uKnot, &cp[(vFirstCp+i)*ucp], ucp, 1, u); (void)NURBSEvaluate(vOrder, vKnot, iso - vFirstCp, vcp, 1, v, dPdv); } return Point(P.x/P.w, P.y/P.w, P.z/P.w);; }