34 _egg_surface(egg_surface)
36 _nurbs = make_nurbs_surface(_egg_surface, LMatrix4d::ident_mat());
37 _has_vertex_color = _egg_surface->has_vertex_color();
44 _match_u = _match_v =
nullptr;
45 _tess_u = _tess_v = 0;
59 if (_nurbs ==
nullptr) {
63 record_vertex_extras();
65 _nurbs->normalize_u_knots();
66 _nurbs->normalize_v_knots();
67 _nurbs_result = _nurbs->evaluate();
69 _num_u = _nurbs->get_num_u_segments();
70 _num_v = _nurbs->get_num_v_segments();
72 if (QtessGlobals::_respect_egg) {
92 if (_nurbs ==
nullptr) {
97 _u_placer.get_scores(_nurbs->get_num_u_segments() * 100,
98 _nurbs->get_num_v_segments() * 2,
99 ratio, _nurbs_result,
true);
100 _v_placer.get_scores(_nurbs->get_num_v_segments() * 100,
101 _nurbs->get_num_u_segments() * 2,
102 ratio, _nurbs_result,
false);
106 return _u_placer.get_total_score() * _v_placer.get_total_score() * _importance2;
119 PT(
EggGroup) group = do_uniform_tesselate(tris);
120 PT(
EggNode) new_node = group.p();
121 if (new_node ==
nullptr) {
122 new_node =
new EggComment(_egg_surface->get_name(),
123 "Omitted NURBS surface.");
127 nassertr(parent !=
nullptr, 0);
128 parent->remove_child(_egg_surface);
142 if (_tess_u == 0 || _tess_v == 0) {
143 out << get_name() <<
" : omit\n";
145 }
else if (_iso_u.empty() || _iso_v.empty()) {
146 out << get_name() <<
" : " << _tess_u <<
" " << _tess_v <<
"\n";
149 out << get_name() <<
" : " << _iso_u.back() <<
" " << _iso_v.back();
191 _tess_u = (int)_iso_u.size() - 1;
192 _tess_v = (int)_iso_v.size() - 1;
200 if (_num_u == 0 || _num_v == 0) {
204 _tess_u = max(_min_u, (
int)floor(_num_u * _importance * pi + 0.5));
205 _tess_v = max(_min_v, (
int)floor(_num_v * _importance * pi + 0.5));
225 _tess_u = max(_min_u, (
int)floor(_u_placer.get_total_score() * _importance * pi + 0.5));
226 _tess_v = max(_min_v, (
int)floor(_v_placer.get_total_score() * _importance * pi + 0.5));
245 _u_placer.place(u, _iso_u);
246 _v_placer.place(v, _iso_v);
247 _tess_u = (int)_iso_u.size() - 1;
248 _tess_v = (int)_iso_v.size() - 1;
258 record_vertex_extras() {
259 int num_u_vertices = _egg_surface->get_num_u_cvs();
260 int num_v_vertices = _egg_surface->get_num_v_cvs();
262 for (
int ui = 0; ui < num_u_vertices; ui++) {
263 for (
int vi = 0; vi < num_v_vertices; vi++) {
264 int i = _egg_surface->get_vertex_index(ui, vi);
265 EggVertex *egg_vertex = _egg_surface->get_vertex(i);
268 EggVertex::GroupRef::const_iterator gi;
271 int d = get_joint_membership_index(joint);
273 _nurbs->set_extended_vertex(ui, vi, d, membership);
277 EggMorphVertexList::const_iterator dxi;
278 for (dxi = egg_vertex->_dxyzs.begin();
279 dxi != egg_vertex->_dxyzs.end();
281 const string &morph_name = (*dxi).get_name();
282 LVector3 delta = LCAST(PN_stdfloat, (*dxi).get_offset());
283 int d = get_dxyz_index(morph_name);
284 _nurbs->set_extended_vertices(ui, vi, d, delta.get_data(), 3);
288 EggMorphColorList::const_iterator dri;
289 for (dri = egg_vertex->_drgbas.begin();
290 dri != egg_vertex->_drgbas.end();
292 const string &morph_name = (*dri).get_name();
293 const LVector4 &delta = (*dri).get_offset();
294 int d = get_drgba_index(morph_name);
295 _nurbs->set_extended_vertices(ui, vi, d, delta.get_data(), 4);
307 if (_match_u !=
nullptr) {
311 <<
"No surface to match " << get_name() <<
" to in U.\n";
313 if (qtess_cat.is_debug()) {
315 <<
"Matching " << get_name() <<
" in U to " << m->get_name()
316 <<
" in " << (_match_u_to_u?
'U':
'V') <<
".\n";
319 _tess_u = m->_tess_u;
322 _tess_u = m->_tess_v;
328 if (_match_v !=
nullptr) {
332 <<
"No surface to match " << get_name() <<
" in V.\n";
334 if (qtess_cat.is_debug()) {
336 <<
"Matching " << get_name() <<
" in V to " << m->get_name()
337 <<
" in " << (_match_v_to_v?
'V':
'U') <<
".\n";
340 _tess_v = m->_tess_v;
343 _tess_v = m->_tess_u;
355 do_uniform_tesselate(
int &tris)
const {
358 if (_tess_u == 0 || _tess_v == 0) {
360 if (qtess_cat.is_debug()) {
362 << get_name() <<
" : omit\n";
372 int num_u = _tess_u + 1;
373 int num_v = _tess_v + 1;
375 if (qtess_cat.is_debug()) {
376 qtess_cat.debug() << get_name() <<
" : " << tris <<
"\n";
379 assert(_iso_u.empty() || (
int)_iso_u.size() == num_u);
380 assert(_iso_v.empty() || (
int)_iso_v.size() == num_v);
383 int num_verts = num_u * num_v;
387 group->add_child(vpool);
394 VertexList new_verts;
395 new_verts.reserve(num_verts);
401 NVertexCollection n_collection;
403 for (vi = 0; vi < num_v; vi++) {
404 if (_iso_v.empty()) {
405 v = (double)vi / (
double)(num_v-1);
407 v = _iso_v[vi] / _iso_v.back();
409 for (ui = 0; ui < num_u; ui++) {
410 if (_iso_u.empty()) {
411 u = (double)ui / (
double)(num_u-1);
413 u = _iso_u[ui] / _iso_u.back();
416 PT(
EggVertex) egg_vertex = evaluate_vertex(u, v);
417 vpool->add_vertex(egg_vertex);
418 new_verts.push_back(egg_vertex);
419 n_collection[egg_vertex->
get_pos3()].insert(egg_vertex);
422 nassertr((
int)new_verts.size() == num_verts,
nullptr);
425 for (vi = 1; vi < num_v; vi++) {
426 for (ui = 1; ui < num_u; ui++) {
428 poly->
add_vertex(new_verts[vi*num_u + (ui-1)]);
429 poly->add_vertex(new_verts[(vi-1)*num_u + (ui-1)]);
430 poly->add_vertex(new_verts[(vi-1)*num_u + ui]);
431 poly->add_vertex(new_verts[vi*num_u + ui]);
433 poly->copy_attributes(*_egg_surface);
438 if (poly->recompute_polygon_normal()) {
440 group->add_child(poly);
450 NVertexCollection::const_iterator nci;
451 for (nci = n_collection.begin(); nci != n_collection.end(); ++nci) {
452 const NVertexGroup &group = (*nci).second;
456 LNormald normal = LNormald::zero();
458 NVertexGroup::const_iterator ngi;
459 for (ngi = group.begin(); ngi != group.end(); ++ngi) {
461 EggVertex::PrimitiveRef::const_iterator pri;
466 nassertr(egg_primitive->has_normal(),
nullptr);
467 normal += egg_primitive->get_normal();
473 normal /= (double)num_polys;
478 for (ngi = group.begin(); ngi != group.end(); ++ngi) {
480 if (egg_vertex->has_normal()) {
481 if (normal.dot(egg_vertex->get_normal()) < 0.0) {
483 egg_vertex->set_normal(-egg_vertex->get_normal());
487 egg_vertex->set_normal(normal);
501 evaluate_vertex(
double u,
double v)
const {
506 _nurbs_result->eval_point(u, v, point);
507 _nurbs_result->eval_normal(u, v, normal);
512 PN_stdfloat length = normal.length();
513 if (length > 0.0001f) {
515 egg_vertex->set_normal(LCAST(
double, normal));
518 egg_vertex->
set_pos(LCAST(
double, point));
519 egg_vertex->
set_uv(LVecBase2d(u, v));
522 if (_has_vertex_color) {
524 _nurbs_result->eval_extended_points(u, v, 0, &rgba[0], 4);
525 egg_vertex->set_color(rgba);
529 JointTable::const_iterator jti;
530 for (jti = _joint_table.begin(); jti != _joint_table.end(); ++jti) {
532 int d = (*jti).second;
534 double membership = _nurbs_result->eval_extended_point(u, v, d);
535 if (membership > 0.0) {
541 MorphTable::const_iterator mti;
542 for (mti = _dxyz_table.begin(); mti != _dxyz_table.end(); ++mti) {
543 const string &morph_name = (*mti).first;
544 int d = (*mti).second;
547 _nurbs_result->eval_extended_points(u, v, d, &delta[0], 3);
548 if (!delta.almost_equal(LVector3::zero())) {
553 for (mti = _drgba_table.begin(); mti != _drgba_table.end(); ++mti) {
554 const string &morph_name = (*mti).first;
555 int d = (*mti).second;
558 _nurbs_result->eval_extended_points(u, v, d, &delta[0], 4);
559 if (!delta.almost_equal(LVector4::zero())) {