27                    int num_u_vertices, 
int num_v_vertices) :
    31   _num_u_vertices(num_u_vertices),
    32   _num_v_vertices(num_v_vertices)
    43   int num_segments = num_u_segments * num_v_segments;
    45   _composed.reserve(num_segments);
    46   for (
int i = 0; i < num_segments; i++) {
    47     _composed.push_back(ComposedMats());
    50   for (
int vi = 0; vi < num_v_segments; vi++) {
    51     const LMatrix4 &v_basis_transpose = _v_basis.
get_basis(vi);
    54     nassertv(vn >= 0 && vn + v_order - 1 < _num_v_vertices);
    56     for (
int ui = 0; ui < num_u_segments; ui++) {
    57       const LMatrix4 &u_basis_mat = _u_basis.
get_basis(ui);
    60       nassertv(un >= 0 && un + u_order - 1 < _num_u_vertices);
    64       LMatrix4 geom_x, geom_y, geom_z, geom_w;
    70       for (
int uni = 0; uni < 4; uni++) {
    71         for (
int vni = 0; vni < 4; vni++) {
    72           if (uni < u_order && vni < v_order) {
    73             const LVecBase4 &vec = vecs[verti(un + uni, vn + vni)];
    74             geom_x(uni, vni) = vec[0];
    75             geom_y(uni, vni) = vec[1];
    76             geom_z(uni, vni) = vec[2];
    77             geom_w(uni, vni) = vec[3];
    86       nassertv(i >= 0 && i < (
int)_composed.size());
    87       ComposedMats &result = _composed[i];
    88       result._x = u_basis_mat * geom_x * v_basis_transpose;
    89       result._y = u_basis_mat * geom_y * v_basis_transpose;
    90       result._z = u_basis_mat * geom_z * v_basis_transpose;
    91       result._w = u_basis_mat * geom_w * v_basis_transpose;
   111   int i = segi(ui, vi);
   112   nassertv(i >= 0 && i < (
int)_composed.size());
   114   PN_stdfloat u2 = u*u;
   115   LVecBase4 uvec(u*u2, u2, u, 1.0f);
   116   PN_stdfloat v2 = v*v;
   117   LVecBase4 vvec(v*v2, v2, v, 1.0f);
   119   PN_stdfloat weight = vvec.dot(uvec * _composed[i]._w);
   121   point.set(vvec.dot(uvec * _composed[i]._x) / weight,
   122             vvec.dot(uvec * _composed[i]._y) / weight,
   123             vvec.dot(uvec * _composed[i]._z) / weight);
   133   int i = segi(ui, vi);
   134   nassertv(i >= 0 && i < (
int)_composed.size());
   136   PN_stdfloat u2 = u*u;
   137   LVecBase4 uvec(u*u2, u2, u, 1.0f);
   138   LVecBase4 duvec(3.0f * u2, 2.0f * u, 1.0f, 0.0f);
   139   PN_stdfloat v2 = v*v;
   140   LVecBase4 vvec(v*v2, v2, v, 1.0f);
   141   LVecBase4 dvvec(3.0f * v2, 2.0f * v, 1.0f, 0.0f);
   143   LVector3 utan(vvec.dot(duvec * _composed[i]._x),
   144                  vvec.dot(duvec * _composed[i]._y),
   145                  vvec.dot(duvec * _composed[i]._z));
   147   LVector3 vtan(dvvec.dot(uvec * _composed[i]._x),
   148                  dvvec.dot(uvec * _composed[i]._y),
   149                  dvvec.dot(uvec * _composed[i]._z));
   151   normal = utan.cross(vtan);
   160   int i = segi(ui, vi);
   161   nassertr(i >= 0 && i < (
int)_composed.size(), 0.0f);
   163   PN_stdfloat u2 = u*u;
   164   LVecBase4 uvec(u*u2, u2, u, 1.0f);
   165   PN_stdfloat v2 = v*v;
   166   LVecBase4 vvec(v*v2, v2, v, 1.0f);
   168   PN_stdfloat weight = vvec.dot(uvec * _composed[i]._w);
   172   const LMatrix4 &v_basis_transpose = _v_basis.
get_basis(vi);
   173   const LMatrix4 &u_basis_mat = _u_basis.
get_basis(ui);
   183   for (
int uni = 0; uni < 4; uni++) {
   184     for (
int vni = 0; vni < 4; vni++) {
   185       if (uni < u_order && vni < v_order) {
   191   LMatrix4 composed = u_basis_mat * geom * v_basis_transpose;
   192   return vvec.dot(uvec * composed) / weight;
   203                              PN_stdfloat result[], 
int num_values)
 const {
   204   int i = segi(ui, vi);
   205   nassertv(i >= 0 && i < (
int)_composed.size());
   207   PN_stdfloat u2 = u*u;
   208   LVecBase4 uvec(u*u2, u2, u, 1.0f);
   209   PN_stdfloat v2 = v*v;
   210   LVecBase4 vvec(v*v2, v2, v, 1.0f);
   212   PN_stdfloat weight = vvec.dot(uvec * _composed[i]._w);
   216   const LMatrix4 &v_basis_transpose = _v_basis.
get_basis(vi);
   217   const LMatrix4 &u_basis_mat = _u_basis.
get_basis(ui);
   224   for (
int n = 0; n < num_values; n++) {
   228     for (
int uni = 0; uni < 4; uni++) {
   229       for (
int vni = 0; vni < 4; vni++) {
   230         if (uni < u_order && vni < v_order) {
   237     LMatrix4 composed = u_basis_mat * geom * v_basis_transpose;
   238     result[n] = vvec.dot(uvec * composed) / weight;
   246 int NurbsSurfaceResult::
   247 find_u_segment(PN_stdfloat u) {
   257   if (_last_u_segment != -1 && (u >= _last_u_from && u < _last_u_to)) {
   258     return _last_u_segment;
   264     _last_u_segment = segment;
   265     _last_u_from = _u_basis.
get_from(segment);
   266     _last_u_to = _u_basis.
get_to(segment);
   276 int NurbsSurfaceResult::
   277 r_find_u_segment(PN_stdfloat u, 
int top, 
int bot)
 const {
   282   int mid = (top + bot) / 2;
   285   PN_stdfloat from = _u_basis.
get_from(mid);
   286   PN_stdfloat to = _u_basis.
get_to(mid);
   289     return r_find_u_segment(u, top, mid - 1);
   291   } 
else if (to <= u) {
   293     return r_find_u_segment(u, mid + 1, bot);
   306 int NurbsSurfaceResult::
   307 find_v_segment(PN_stdfloat v) {
   317   if (_last_v_segment != -1 && (v >= _last_v_from && v < _last_v_to)) {
   318     return _last_v_segment;
   324     _last_v_segment = segment;
   325     _last_v_from = _v_basis.
get_from(segment);
   326     _last_v_to = _v_basis.
get_to(segment);
   336 int NurbsSurfaceResult::
   337 r_find_v_segment(PN_stdfloat v, 
int top, 
int bot)
 const {
   342   int mid = (top + bot) / 2;
   345   PN_stdfloat from = _v_basis.
get_from(mid);
   346   PN_stdfloat to = _v_basis.
get_to(mid);
   349     return r_find_v_segment(v, top, mid - 1);
   351   } 
else if (to <= v) {
   353     return r_find_v_segment(v, mid + 1, bot);
 NurbsSurfaceResult(const NurbsBasisVector &u_basis, const NurbsBasisVector &v_basis, const LVecBase4 vecs[], const NurbsVertex *verts, int num_u_vertices, int num_v_vertices)
The constructor automatically builds up the result as the product of the indicated set of basis matri...
const LMatrix4 & get_basis(int segment) const
Returns the basis matrix associated with the nth segment.
int get_num_segments() const
Returns the number of piecewise continuous segments in the curve.
void transpose()
Transposes the basis matrices stored in the vector.
PN_stdfloat get_from(int segment) const
Returns the t value of the beginning of this segment.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_vertex_index(int segment) const
Returns the vertex index of the nth segment.
PN_stdfloat get_start_v() const
Returns the first legal value of v on the surface.
PN_stdfloat get_to(int segment) const
Returns the t value of the end of this segment.
This represents a single control vertex in a NurbsEvaluator.
PN_stdfloat get_end_v() const
Returns the last legal value of v on the surface.
int get_order() const
Returns the order of the segments in the curve.
PN_stdfloat get_start_u() const
Returns the first legal value of u on the surface.
This encapsulates a series of matrices that are used to represent the sequential segments of a NurbsC...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PN_stdfloat get_end_u() const
Returns the last legal value of u on the surface.
void eval_segment_point(int ui, int vi, PN_stdfloat u, PN_stdfloat v, LVecBase3 &point) const
Evaluates the point on the surface corresponding to the indicated value in parametric time within the...
PN_stdfloat get_extended_vertex(int d) const
Returns an n-dimensional vertex value.
void eval_segment_normal(int ui, int vi, PN_stdfloat u, PN_stdfloat v, LVecBase3 &normal) const
As eval_segment_point, but computes the normal to the surface at the indicated point.
PN_stdfloat eval_segment_extended_point(int ui, int vi, PN_stdfloat u, PN_stdfloat v, int d) const
Evaluates the surface in n-dimensional space according to the extended vertices associated with the s...
void eval_segment_extended_points(int ui, int vi, PN_stdfloat u, PN_stdfloat v, int d, PN_stdfloat result[], int num_values) const
Simultaneously performs eval_extended_point on a contiguous sequence of dimensions.