00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "isoPlacer.h"
00016 #include "qtessSurface.h"
00017 #include "subdivSegment.h"
00018 #include "nurbsSurfaceResult.h"
00019 #include "pvector.h"
00020
00021
00022
00023
00024
00025
00026
00027 void IsoPlacer::
00028 get_scores(int subdiv, int across, double ratio,
00029 NurbsSurfaceResult *surf, bool s) {
00030 _maxi = subdiv - 1;
00031
00032 _cscore.clear();
00033 _sscore.clear();
00034
00035 _cscore.reserve(_maxi);
00036 _sscore.reserve(_maxi);
00037
00038
00039
00040 int i = 0;
00041 for (i = 0; i < _maxi; i++) {
00042 _cscore.push_back(0.0);
00043 _sscore.push_back(0.0);
00044 }
00045
00046 int a;
00047 for (a = 0; a <= across; a++) {
00048 double v = (double)a / (double)across;
00049
00050 LVecBase3 p1, p2, p3, pnext;
00051 LVecBase3 v1, v2;
00052 if (s) {
00053 surf->eval_point(0.0, v, p3);
00054 } else {
00055 surf->eval_point(v, 0.0, p3);
00056 }
00057 int num_points = 1;
00058
00059 for (i = -1; i < _maxi; i++) {
00060 double u = (double)(i+1) / (double)(_maxi+1);
00061 if (s) {
00062 surf->eval_point(u, v, pnext);
00063 } else {
00064 surf->eval_point(v, u, pnext);
00065 }
00066
00067
00068
00069 if (!pnext.almost_equal(p3)) {
00070 num_points++;
00071 p1 = p2;
00072 p2 = p3;
00073 p3 = pnext;
00074
00075 v1 = v2;
00076 v2 = p3 - p2;
00077 double vlength = length(v2);
00078 v2 /= vlength;
00079
00080 if (i >= 0) {
00081 _sscore[i] += vlength;
00082 }
00083
00084 if (num_points >= 3) {
00085
00086
00087 double d = v1.dot(v2);
00088
00089 _cscore[i] += acos(max(min(d, 1.0), -1.0));
00090 }
00091 }
00092 }
00093 }
00094
00095
00096 _cint.clear();
00097 _cint.reserve(_maxi + 1);
00098
00099 double net = 0.0;
00100 double ad = (double)(across+1);
00101 _cint.push_back(0.0);
00102 for (i = 0; i < _maxi; i++) {
00103 net += _cscore[i]/ad + ratio * _sscore[i]/ad;
00104 _cint.push_back(net);
00105 }
00106 }
00107
00108
00109
00110
00111
00112
00113 void IsoPlacer::
00114 place(int count, pvector<double> &iso_points) {
00115 int i;
00116
00117
00118 double avg_curve = 0.0;
00119 for (i = 0; i < _maxi; i++) {
00120 avg_curve += _cscore[i];
00121 }
00122 avg_curve /= (double)_maxi;
00123
00124
00125
00126 typedef pvector<int> BendPoints;
00127 BendPoints bpoints;
00128 BendPoints::iterator bi, bnext;
00129
00130 typedef pvector<SubdivSegment> Segments;
00131 Segments segments;
00132 Segments::iterator si;
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 bi = bpoints.begin();
00152 int min_separation = _maxi/count;
00153 while (bi != bpoints.end()) {
00154 bnext = bi;
00155 ++bnext;
00156
00157 if (bnext != bpoints.end() && (*bnext) - (*bi) < min_separation) {
00158
00159 if (_cscore[*bnext] > _cscore[*bi]) {
00160 *bi = *bnext;
00161 }
00162 bpoints.erase(bnext);
00163 } else {
00164
00165 bi = bnext;
00166 }
00167 }
00168
00169
00170
00171 while (count - 1 < (int)bpoints.size()) {
00172 bi = bpoints.begin();
00173 BendPoints::iterator mi = bi;
00174 for (++bi; bi != bpoints.end(); ++bi) {
00175 if (_cscore[*bi] < _cscore[*mi]) {
00176 mi = bi;
00177 }
00178 }
00179 bpoints.erase(mi);
00180 }
00181
00182
00183 bi = bpoints.begin();
00184 int last = 0;
00185 for (bi = bpoints.begin(); bi != bpoints.end(); ++bi) {
00186 segments.push_back(SubdivSegment(&_cint[0], last, *bi));
00187 last = *bi;
00188 }
00189 segments.push_back(SubdivSegment(&_cint[0], last, _maxi));
00190
00191 int nr = count - segments.size();
00192
00193
00194
00195
00196
00197
00198
00199
00200 double net_score = _cint[_maxi];
00201 nassertv(net_score > 0.0);
00202 int ns = 0;
00203 for (si = segments.begin(); si != segments.end(); ++si) {
00204 (*si)._num_cuts = (int)floor(nr * (*si).get_score() / net_score);
00205 nassertv((*si)._num_cuts <= nr);
00206 ns += (*si)._num_cuts;
00207 }
00208
00209
00210 nr -= ns;
00211 while (nr > 0) {
00212 si = min_element(segments.begin(), segments.end());
00213 (*si)._num_cuts++;
00214 nr--;
00215 }
00216
00217
00218 for (si = segments.begin(); si != segments.end(); ++si) {
00219 (*si).cut();
00220 }
00221
00222
00223 iso_points.erase(iso_points.begin(), iso_points.end());
00224
00225 iso_points.push_back(0.0);
00226 for (si = segments.begin(); si != segments.end(); ++si) {
00227 pvector<int>::iterator ci;
00228 for (ci = (*si)._cuts.begin(); ci != (*si)._cuts.end(); ++ci) {
00229 iso_points.push_back((*ci+1) / (double)(_maxi+1));
00230 }
00231 iso_points.push_back(((*si)._t+1) / (double)(_maxi+1));
00232 }
00233
00234
00235 iso_points.back() = 1.0;
00236 }
00237
00238