19NurbsSurfaceEvaluator::
20NurbsSurfaceEvaluator() {
23 _u_knots_dirty =
true;
24 _v_knots_dirty =
true;
25 _u_basis_dirty =
true;
26 _v_basis_dirty =
true;
32NurbsSurfaceEvaluator::
33~NurbsSurfaceEvaluator() {
42reset(
int num_u_vertices,
int num_v_vertices) {
43 int num_vertices = num_u_vertices * num_v_vertices;
45 _vertices.reserve(num_vertices);
46 _num_u_vertices = num_u_vertices;
47 _num_v_vertices = num_v_vertices;
49 for (
int i = 0; i < num_vertices; i++) {
52 _u_knots_dirty =
true;
53 _v_knots_dirty =
true;
54 _u_basis_dirty =
true;
55 _v_basis_dirty =
true;
66 nassertr(ui >= 0 && ui < _num_u_vertices &&
67 vi >= 0 && vi < _num_v_vertices, empty_node_path);
69 return vert(ui, vi).get_space(rel_to);
80 const PN_stdfloat values[],
int num_values) {
81 nassertv(ui >= 0 && ui < _num_u_vertices &&
82 vi >= 0 && vi < _num_v_vertices);
85 for (
int n = 0; n < num_values; n++) {
100 nassertv(i >= 0 && i < (
int)_u_knots.size());
109 if (_u_knots_dirty) {
110 ((NurbsSurfaceEvaluator *)
this)->recompute_u_knots();
112 nassertr(i >= 0 && i < (
int)_u_knots.size(), 0.0f);
122 if (_u_knots_dirty) {
126 if (_num_u_vertices > _u_order - 1) {
127 double min_value = _u_knots[_u_order - 1];
128 double max_value = _u_knots[_num_u_vertices];
129 double range = (max_value - min_value);
131 for (Knots::iterator ki = _u_knots.begin(); ki != _u_knots.end(); ++ki) {
132 (*ki) = ((*ki) - min_value) / range;
134 _u_basis_dirty =
true;
145 if (_v_knots_dirty) {
148 nassertv(i >= 0 && i < (
int)_v_knots.size());
157 if (_v_knots_dirty) {
158 ((NurbsSurfaceEvaluator *)
this)->recompute_v_knots();
160 nassertr(i >= 0 && i < (
int)_v_knots.size(), 0.0f);
170 if (_v_knots_dirty) {
174 if (_num_v_vertices > _v_order - 1) {
175 double min_value = _v_knots[_v_order - 1];
176 double max_value = _v_knots[_num_v_vertices];
177 double range = (max_value - min_value);
179 for (Knots::iterator ki = _v_knots.begin(); ki != _v_knots.end(); ++ki) {
180 (*ki) = ((*ki) - min_value) / range;
182 _v_basis_dirty =
true;
192evaluate(
const NodePath &rel_to)
const {
193 if (_u_basis_dirty) {
196 if (_v_basis_dirty) {
202 get_vertices(vecs, rel_to);
207 &vecs[0], &_vertices[0],
208 _num_u_vertices, _num_v_vertices);
214void NurbsSurfaceEvaluator::
215output(std::ostream &out)
const {
228void NurbsSurfaceEvaluator::
229get_vertices(NurbsSurfaceEvaluator::Vert4Array &verts,
const NodePath &rel_to)
const {
230 int num_vertices = (int)_vertices.size();
231 verts.reserve(verts.size() + num_vertices);
233 for (vi = 0; vi < num_vertices; vi++) {
234 NodePath space = _vertices[vi].get_space(rel_to);
235 const LVecBase4 &vertex = _vertices[vi].get_vertex();
237 verts.push_back(vertex);
240 const LMatrix4 &mat = transform->get_mat();
241 verts.push_back(vertex * mat);
254void NurbsSurfaceEvaluator::
255get_vertices(NurbsSurfaceEvaluator::Vert3Array &verts,
const NodePath &rel_to)
const {
256 int num_vertices = (int)_vertices.size();
257 verts.reserve(verts.size() + num_vertices);
259 for (vi = 0; vi < num_vertices; vi++) {
260 const NodePath &space = _vertices[vi].get_space(rel_to);
261 LVecBase4 vertex = _vertices[vi].get_vertex();
264 const LMatrix4 &mat = transform->get_mat();
265 vertex = vertex * mat;
267 LPoint3 v3(vertex[0] / vertex[3], vertex[1] / vertex[3], vertex[2] / vertex[3]);
275void NurbsSurfaceEvaluator::
279 _u_knots.reserve(num_knots);
281 PN_stdfloat value = 0.0f;
284 while (i < _u_order) {
285 _u_knots.push_back(value);
288 while (i < num_knots - _u_order) {
290 _u_knots.push_back(value);
294 while (i < num_knots) {
295 _u_knots.push_back(value);
299 _u_knots_dirty =
false;
305void NurbsSurfaceEvaluator::
309 _v_knots.reserve(num_knots);
311 PN_stdfloat value = 0.0f;
314 while (i < _v_order) {
315 _v_knots.push_back(value);
318 while (i < num_knots - _v_order) {
320 _v_knots.push_back(value);
324 while (i < num_knots) {
325 _v_knots.push_back(value);
329 _v_knots_dirty =
false;
335void NurbsSurfaceEvaluator::
337 if (_u_knots_dirty) {
338 ((NurbsSurfaceEvaluator *)
this)->recompute_u_knots();
341 _u_basis.clear(_u_order);
342 if (_num_u_vertices > _u_order - 1) {
343 int min_knot = _u_order;
344 int max_knot = _num_u_vertices;
346 for (
int i = min_knot; i <= max_knot; i++) {
347 nassertv(i - 1 >= 0 && i < (
int)_u_knots.size());
348 if (_u_knots[i - 1] < _u_knots[i]) {
350 _u_basis.append_segment(i - _u_order, &_u_knots[i - _u_order]);
355 _u_basis_dirty =
false;
361void NurbsSurfaceEvaluator::
363 if (_v_knots_dirty) {
364 ((NurbsSurfaceEvaluator *)
this)->recompute_v_knots();
367 _v_basis.clear(_v_order);
368 if (_num_v_vertices > _v_order - 1) {
369 int min_knot = _v_order;
370 int max_knot = _num_v_vertices;
372 for (
int i = min_knot; i <= max_knot; i++) {
373 nassertv(i - 1 >= 0 && i < (
int)_v_knots.size());
374 if (_v_knots[i - 1] < _v_knots[i]) {
376 _v_basis.append_segment(i - _v_order, &_v_knots[i - _v_order]);
381 _v_basis_dirty =
false;
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
bool is_empty() const
Returns true if the NodePath contains no nodes.
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
This class is an abstraction for evaluating NURBS surfaces.
void set_extended_vertices(int ui, int vi, int d, const PN_stdfloat values[], int num_values)
Simultaneously sets several extended values in the slots d through (d + num_values - 1) from the num_...
void reset(int num_u_vertices, int num_v_vertices)
Resets all the vertices and knots to their default values, and sets the surface up with the indicated...
set_u_knot
Sets the value of the nth knot.
get_v_knot
Returns the value of the nth knot.
set_v_knot
Sets the value of the nth knot.
get_num_v_knots
Returns the number of knot values in the surface in the V direction.
void normalize_u_knots()
Normalizes the knot sequence so that the parametric range of the surface in the U direction is 0 .
get_num_u_knots
Returns the number of knot values in the surface in the U direction.
NodePath get_vertex_space(int ui, int vi, const NodePath &rel_to) const
Returns the coordinate space of the nth control vertex of the surface, expressed as a NodePath.
void normalize_v_knots()
Normalizes the knot sequence so that the parametric range of the surface in the U direction is 0 .
get_u_knot
Returns the value of the nth knot.
The result of a NurbsSurfaceEvaluator.
This represents a single control vertex in a NurbsEvaluator.
void set_extended_vertex(int d, PN_stdfloat value)
Sets an n-dimensional vertex value.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.