30QtessInputEntry(
const string &name) {
33 _auto_place = QtessGlobals::_auto_place;
34 _auto_distribute = QtessGlobals::_auto_distribute;
35 _curvature_ratio = QtessGlobals::_curvature_ratio;
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;
68class DoublesAlmostEqual {
70 int operator ()(
double a,
double b)
const {
71 return fabs(a - b) < 0.00001;
79class DoubleAlmostMatches {
81 DoubleAlmostMatches(
double v) : _v(v) {}
82 int operator ()(
double a)
const {
83 return fabs(a - _v) < 0.00001;
94set_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;
380void QtessInputEntry::
381output(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;
462void QtessInputEntry::
463write(std::ostream &out,
int indent_level)
const {
464 indent(out, indent_level) << (*this) <<
"\n";
This class can be used to test for string matches against standard Unix- shell filename globbing conv...
bool matches(const std::string &candidate) const
Returns true if the candidate string matches the pattern, false otherwise.
Stores one entry in the qtess input file.
Type match(QtessSurface *surface)
Tests the surface to see if it matches any of the regular expressions that define this node entry.
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...
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...
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.
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...
A reference to an EggNurbsSurface in the egg file, and its parameters as set by the user input file a...
int count_tris() const
Returns the number of triangles that will be generated by the current tesselation parameters.
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 tesselate_per_isoparam(double pi, bool autoplace, double ratio)
Sets the surface up to tesselate itself to a uniform amount per isoparam.
void omit()
Sets up the surface to omit itself from the output.
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.
double count_patches() const
Returns the number of patches the NURBS contains.
void set_min_v(int min_v)
Specifies the absolute minimum number of segments allowed in the V direction.
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.
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,...
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.
void set_importance(double importance2)
Sets the importance of the surface, as a ratio in proportion to the square of its size.
void tesselate_specific(const pvector< double > &u_list, const pvector< double > &v_list)
Sets the surface up to tesselate itself at specific isoparams only.
This is our own Panda specialization on the default STL vector.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
double string_to_double(const string &str, string &tail)
A string-interface wrapper around the C library strtol().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.