15 #include "qtessInputEntry.h" 16 #include "qtessSurface.h" 17 #include "qtessGlobals.h" 18 #include "config_egg_qtess.h" 20 #include "string_utils.h" 31 QtessInputEntry(
const string &name) {
34 _auto_place = QtessGlobals::_auto_place;
35 _auto_distribute = QtessGlobals::_auto_distribute;
36 _curvature_ratio = QtessGlobals::_curvature_ratio;
47 void QtessInputEntry::
49 _node_names = copy._node_names;
51 _num_tris = copy._num_tris;
54 _per_isoparam = copy._per_isoparam;
57 _surfaces = copy._surfaces;
58 _num_patches = copy._num_patches;
59 _auto_place = copy._auto_place;
60 _auto_distribute = copy._auto_distribute;
61 _curvature_ratio = copy._curvature_ratio;
62 _importance = copy._importance;
63 _constrain_u = copy._constrain_u;
64 _constrain_v = copy._constrain_v;
74 int operator ()(
double a,
double b)
const {
75 return fabs(a - b) < 0.00001;
88 int operator ()(
double a)
const {
89 return fabs(a - _v) < 0.00001;
102 void QtessInputEntry::
103 set_uv(
int u,
int v,
const string params[],
int num_params) {
109 for (i = 0; i <= _num_u; i++) {
112 for (i = 0; i <= _num_v; i++) {
117 for (i = 0; i < num_params; i++) {
118 const string ¶m = params[i];
120 if (param[0] ==
'!' && param.size() > 2) {
122 if (!string_to_double(param.substr(2), value)) {
124 <<
"Ignoring invalid parameter: " << param <<
"\n";
126 switch (tolower(param[1])) {
129 _iso_u.erase(remove_if(_iso_u.begin(), _iso_u.end(),
136 _iso_v.erase(remove_if(_iso_v.begin(), _iso_v.end(),
143 <<
"Ignoring invalid parameter: " << params[i] <<
"\n";
148 if (!string_to_double(param.substr(1), value)) {
150 <<
"Ignoring invalid parameter: " << param <<
"\n";
152 switch (tolower(param[0])) {
155 _iso_u.push_back(value);
160 _iso_v.push_back(value);
165 <<
"Ignoring invalid parameter: " << params[i] <<
"\n";
172 sort(_iso_u.begin(), _iso_u.end());
173 sort(_iso_v.begin(), _iso_v.end());
174 _iso_u.erase(unique(_iso_u.begin(), _iso_u.end(),
DoublesAlmostEqual()), _iso_u.end());
175 _iso_v.erase(unique(_iso_v.begin(), _iso_v.end(),
DoublesAlmostEqual()), _iso_v.end());
214 const string &name = surface->get_name();
216 NodeNames::const_iterator nni;
217 for (nni = _node_names.begin();
218 nni != _node_names.end();
230 if (qtess_cat.is_debug()) {
232 <<
"Assigning importance of " << _importance*100.0
233 <<
"% to " << name <<
"\n";
244 if (nni == _node_names.begin() && _constrain_u==NULL) {
246 _constrain_u = surface;
248 if (_type == T_match_uu) {
259 if (nni == _node_names.begin() && _constrain_v==NULL) {
261 _constrain_v = surface;
263 if (_type == T_match_vv) {
273 if (qtess_cat.is_debug()) {
275 <<
"Assigning minimum of " << _num_u <<
" in U to " 282 if (qtess_cat.is_debug()) {
284 <<
"Assigning minimum of " << _num_v <<
" in V to " 291 _surfaces.push_back(surface);
292 if (_auto_distribute) {
293 _num_patches += surface->
get_score(_curvature_ratio);
316 bool aim_for_tris =
false;
318 if (_type == T_num_tris && _num_patches > 0.0) {
322 if (_auto_distribute) {
323 set_per_score(sqrt(0.5 * (
double)_num_tris / _num_patches / tri_factor));
325 set_per_isoparam(sqrt(0.5 * (
double)_num_tris / _num_patches / tri_factor));
330 Surfaces::iterator si;
331 for (si = _surfaces.begin(); si != _surfaces.end(); ++si) {
341 if (!_iso_u.empty() && !_iso_v.empty() && !_auto_place) {
344 surface->
tesselate_uv(_num_u, _num_v, _auto_place, _curvature_ratio);
363 if (aim_for_tris && attempts < 10 &&
364 (
double)total_tris / (
double)_num_tris > 1.1) {
368 set_num_tris(_num_tris);
369 return count_tris(tri_factor * total_tris / _num_tris, attempts + 1);
386 for (di = iso.begin(); di != iso.end(); ++di) {
387 while ((*di) > (double)expect) {
389 out <<
" !" << axis << expect;
391 if ((*di)==(double)expect) {
396 out <<
" " << axis << *di;
406 void QtessInputEntry::
407 output(ostream &out)
const {
408 NodeNames::const_iterator nni;
409 for (nni = _node_names.begin();
410 nni != _node_names.end();
412 out << (*nni) <<
" ";
416 bool show_auto =
false;
432 out << _num_u <<
" " << _num_v;
440 out <<
"i" << _per_isoparam;
445 out << _importance * 100.0 <<
"%";
465 out <<
"minu " << _num_u;
469 out <<
"minv " << _num_v;
477 out <<
" " << (_auto_place?
"":
"!") <<
"ap" 478 <<
" " << (_auto_distribute?
"":
"!") <<
"ad";
479 if (_auto_place || _auto_distribute) {
480 out <<
" ar" << _curvature_ratio;
490 void QtessInputEntry::
491 write(ostream &out,
int indent_level)
const {
492 indent(out, indent_level) << (*this) <<
"\n";
bool matches(const string &candidate) const
Returns true if the candidate string matches the pattern, false otherwise.
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...
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.
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.
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...
double get_score(double ratio)
Computes the curvature/stretch score for the surface, if it has not been already computed, and returns the net surface score.
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.
An STL function object to determine if two doubles are very nearly equal.
void tesselate_specific(const pvector< double > &u_list, const pvector< double > &v_list)
Sets the surface up to tesselate itself at specific isoparams only.
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.
An STL function object to determine if a double is vert nearly equal the supplied value ...
Type match(QtessSurface *surface)
Tests the surface to see if it matches any of the regular expressions that define this node entry...
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, automatically with u x v quads.
static void output_extra(ostream &out, const pvector< double > &iso, char axis)
This function is used to identify the extra isoparams in the list added by user control.
This class can be used to test for string matches against standard Unix-shell filename globbing conve...
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...