30 QtessInputEntry(
const string &name) {
33 _auto_place = QtessGlobals::_auto_place;
34 _auto_distribute = QtessGlobals::_auto_distribute;
35 _curvature_ratio = QtessGlobals::_curvature_ratio;
44 void QtessInputEntry::
46 _node_names = copy._node_names;
48 _num_tris = copy._num_tris;
51 _per_isoparam = copy._per_isoparam;
54 _surfaces = copy._surfaces;
55 _num_patches = copy._num_patches;
56 _auto_place = copy._auto_place;
57 _auto_distribute = copy._auto_distribute;
58 _curvature_ratio = copy._curvature_ratio;
59 _importance = copy._importance;
60 _constrain_u = copy._constrain_u;
61 _constrain_v = copy._constrain_v;
68 class DoublesAlmostEqual {
70 int operator ()(
double a,
double b)
const {
71 return fabs(a - b) < 0.00001;
79 class DoubleAlmostMatches {
81 DoubleAlmostMatches(
double v) : _v(v) {}
82 int operator ()(
double a)
const {
83 return fabs(a - _v) < 0.00001;
93 void QtessInputEntry::
94 set_uv(
int u,
int v,
const string params[],
int num_params) {
100 for (i = 0; i <= _num_u; i++) {
103 for (i = 0; i <= _num_v; i++) {
108 for (i = 0; i < num_params; i++) {
109 const string ¶m = params[i];
111 if (param[0] ==
'!' && param.size() > 2) {
115 <<
"Ignoring invalid parameter: " << param <<
"\n";
117 switch (tolower(param[1])) {
120 _iso_u.erase(remove_if(_iso_u.begin(), _iso_u.end(),
121 DoubleAlmostMatches(value)),
127 _iso_v.erase(remove_if(_iso_v.begin(), _iso_v.end(),
128 DoubleAlmostMatches(value)),
134 <<
"Ignoring invalid parameter: " << params[i] <<
"\n";
141 <<
"Ignoring invalid parameter: " << param <<
"\n";
143 switch (tolower(param[0])) {
146 _iso_u.push_back(value);
151 _iso_v.push_back(value);
156 <<
"Ignoring invalid parameter: " << params[i] <<
"\n";
163 sort(_iso_u.begin(), _iso_u.end());
164 sort(_iso_v.begin(), _iso_v.end());
165 _iso_u.erase(unique(_iso_u.begin(), _iso_u.end(), DoublesAlmostEqual()), _iso_u.end());
166 _iso_v.erase(unique(_iso_v.begin(), _iso_v.end(), DoublesAlmostEqual()), _iso_v.end());
198 const string &name = surface->get_name();
200 NodeNames::const_iterator nni;
201 for (nni = _node_names.begin();
202 nni != _node_names.end();
214 if (qtess_cat.is_debug()) {
216 <<
"Assigning importance of " << _importance*100.0
217 <<
"% to " << name <<
"\n";
227 if (nni == _node_names.begin() && _constrain_u==
nullptr) {
229 _constrain_u = surface;
231 if (_type == T_match_uu) {
242 if (nni == _node_names.begin() && _constrain_v==
nullptr) {
244 _constrain_v = surface;
246 if (_type == T_match_vv) {
256 if (qtess_cat.is_debug()) {
258 <<
"Assigning minimum of " << _num_u <<
" in U to " 265 if (qtess_cat.is_debug()) {
267 <<
"Assigning minimum of " << _num_v <<
" in V to " 274 _surfaces.push_back(surface);
275 if (_auto_distribute) {
276 _num_patches += surface->
get_score(_curvature_ratio);
296 bool aim_for_tris =
false;
298 if (_type == T_num_tris && _num_patches > 0.0) {
301 if (_auto_distribute) {
302 set_per_score(sqrt(0.5 * (
double)_num_tris / _num_patches / tri_factor));
304 set_per_isoparam(sqrt(0.5 * (
double)_num_tris / _num_patches / tri_factor));
309 Surfaces::iterator si;
310 for (si = _surfaces.begin(); si != _surfaces.end(); ++si) {
320 if (!_iso_u.empty() && !_iso_v.empty() && !_auto_place) {
323 surface->
tesselate_uv(_num_u, _num_v, _auto_place, _curvature_ratio);
342 if (aim_for_tris && attempts < 10 &&
343 (
double)total_tris / (
double)_num_tris > 1.1) {
346 set_num_tris(_num_tris);
347 return count_tris(tri_factor * total_tris / _num_tris, attempts + 1);
362 for (di = iso.begin(); di != iso.end(); ++di) {
363 while ((*di) > (double)expect) {
365 out <<
" !" << axis << expect;
367 if ((*di)==(double)expect) {
372 out <<
" " << axis << *di;
380 void QtessInputEntry::
381 output(std::ostream &out)
const {
382 NodeNames::const_iterator nni;
383 for (nni = _node_names.begin();
384 nni != _node_names.end();
386 out << (*nni) <<
" ";
390 bool show_auto =
false;
406 out << _num_u <<
" " << _num_v;
414 out <<
"i" << _per_isoparam;
419 out << _importance * 100.0 <<
"%";
439 out <<
"minu " << _num_u;
443 out <<
"minv " << _num_v;
451 out <<
" " << (_auto_place?
"":
"!") <<
"ap" 452 <<
" " << (_auto_distribute?
"":
"!") <<
"ad";
453 if (_auto_place || _auto_distribute) {
454 out <<
" ar" << _curvature_ratio;
462 void QtessInputEntry::
463 write(std::ostream &out,
int indent_level)
const {
464 indent(out, indent_level) << (*this) <<
"\n";
A reference to an EggNurbsSurface in the egg file, and its parameters as set by the user input file a...
double string_to_double(const string &str, string &tail)
A string-interface wrapper around the C library strtol().
int count_tris() const
Returns the number of triangles that will be generated by the current tesselation parameters.
void set_importance(double importance2)
Sets the importance of the surface, as a ratio in proportion to the square of its size.
int count_tris(double tri_factor=1.0, int attempts=0)
Determines the tesselation u,v amounts of each attached surface, and stores this information in the s...
void set_match_v(QtessSurface **match_v, bool match_v_to_v)
Indicates the surface to which this surface must match in its V direction.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool matches(const std::string &candidate) const
Returns true if the candidate string matches the pattern, false otherwise.
void set_match_u(QtessSurface **match_u, bool match_u_to_u)
Indicates the surface to which this surface must match in its U direction.
void set_min_v(int min_v)
Specifies the absolute minimum number of segments allowed in the V direction.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Stores one entry in the qtess input file.
void add_extra_u_isoparam(double u)
May be called a number of times before set_uv() to add specific additional isoparams to the tesselati...
static void output_extra(std::ostream &out, const pvector< double > &iso, char axis)
This function is used to identify the extra isoparams in the list added by user control.
double get_score(double ratio)
Computes the curvature/stretch score for the surface, if it has not been already computed,...
void set_min_u(int min_u)
Specifies the absolute minimum number of segments allowed in the U direction.
void omit()
Sets up the surface to omit itself from the output.
void tesselate_specific(const pvector< double > &u_list, const pvector< double > &v_list)
Sets the surface up to tesselate itself at specific isoparams only.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void tesselate_per_isoparam(double pi, bool autoplace, double ratio)
Sets the surface up to tesselate itself to a uniform amount per isoparam.
void tesselate_per_score(double pi, bool autoplace, double ratio)
Sets the surface up to tesselate itself according to its computed curvature score in both dimensions.
double count_patches() const
Returns the number of patches the NURBS contains.
Type match(QtessSurface *surface)
Tests the surface to see if it matches any of the regular expressions that define this node entry.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void tesselate_uv(int u, int v, bool autoplace, double ratio)
Sets the surface up to tesselate itself uniformly at u x v, or if autoplace is true,...
This class can be used to test for string matches against standard Unix- shell filename globbing conv...
void add_extra_v_isoparam(double u)
May be called a number of times before set_uv() to add specific additional isoparams to the tesselati...