00001
00002
00003
00004 #include "bfilters.H"
00005 #include "stripcb.H"
00006 #include "mi.H"
00007
00008
00009
00010
00011 void
00012 EdgeStrip::draw(StripCB* cb)
00013 {
00014
00015
00016
00017
00018
00019
00020 if (empty())
00021 return;
00022
00023
00024
00025
00026
00027
00028
00029
00030 bool started = 0;
00031 for (int i=0; i<_verts.num(); i++) {
00032
00033
00034 if (!started) {
00035 cb->begin_edges(this);
00036 cb->edgeCB(_verts[i], _edges[i]);
00037 started = 1;
00038 }
00039
00040
00041 Bvert* next = next_vert(i);
00042
00043
00044 cb->edgeCB(next, _edges[i]);
00045
00046
00047
00048 if ((i == _verts.num()-1) || (_verts[i+1] != next)) {
00049 cb->end_edges(this);
00050 started = 0;
00051 }
00052 }
00053 }
00054
00055 Bedge*
00056 EdgeStrip::next_edge(
00057 Bvert* v,
00058 Bvert_list& stack,
00059 CSimplexFilter& filter
00060 )
00061 {
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 for (int i=v->degree()-1; i>=0; i--) {
00073 if (filter.accept(v->e(i))) {
00074 if (i > 0)
00075 stack += v;
00076 return v->e(i);
00077 }
00078 }
00079 return 0;
00080 }
00081
00082 void
00083 EdgeStrip::build(CBedge_list& edges, CSimplexFilter& filter)
00084 {
00085
00086
00087
00088 reset();
00089
00090 for (int k=0; k<edges.num(); k++)
00091 build(0, edges[k], filter);
00092 }
00093
00094 void
00095 EdgeStrip::build_line_strip(
00096 Bvert* v,
00097 Bedge* e,
00098 CSimplexFilter& filter,
00099 Bvert_list& stack
00100 )
00101 {
00102
00103
00104
00105
00106
00107
00108 assert(e && e->contains(v));
00109
00110 while (e) {
00111 add(v,e);
00112 e = next_edge(v = e->other_vertex(v), stack, filter);
00113 }
00114 }
00115
00116 void
00117 EdgeStrip::build(Bvert* v, Bedge* e, CSimplexFilter& filter)
00118 {
00119
00120
00121
00122
00123
00124
00125 if (!(e && filter.accept(e)))
00126 return;
00127
00128 assert(!v || e->contains(v));
00129
00130 static Bvert_list stack(64);
00131 stack.clear();
00132
00133
00134 build_line_strip(v ? v : e->v1(), e, filter, stack);
00135
00136
00137 while (!stack.empty()) {
00138 if ((v = stack.pop()) && (e = next_edge(v, stack, filter)))
00139 build_line_strip(v, e, filter, stack);
00140 }
00141 }
00142
00143 void
00144 EdgeStrip::build_with_tips(CBedge_list& edges, CSimplexFilter& filter)
00145 {
00146
00147
00148
00149
00150
00151
00152
00153
00154 set_adjacent_edges(edges.get_verts(), 1);
00155 edges.clear_flags();
00156
00157
00158 Bedge_list tips = edges.filter(ChainTipEdgeFilter(filter));
00159
00160
00161
00162 UnreachedSimplexFilter unreached;
00163 AndFilter wanted = unreached + filter;
00164
00165 int k;
00166
00167
00168 for (k=0; k<tips.num(); k++) {
00169 Bedge* e = tips[k];
00170 Bvert* v = (e->v2()->degree(filter) != 2) ? e->v2() : e->v1();
00171 build(v, e, wanted);
00172 }
00173
00174
00175 for (k=0; k<edges.num(); k++)
00176 build(0, edges[k], wanted);
00177 }
00178
00179 void
00180 EdgeStrip::build_ccw_boundaries(
00181 CBedge_list& edges,
00182 CSimplexFilter& face_filter
00183 )
00184 {
00185
00186
00187
00188
00189
00190
00191
00192 set_adjacent_edges(edges.get_verts(), 1);
00193 edges.clear_flags();
00194
00195
00196
00197 BoundaryEdgeFilter boundary(face_filter);
00198
00199
00200 Bedge_list tips = edges.filter(ChainTipEdgeFilter(boundary));
00201
00202
00203
00204 UnreachedSimplexFilter unreached;
00205 AndFilter wanted = unreached + boundary;
00206
00207 int k;
00208
00209
00210 for (k=0; k<tips.num(); k++) {
00211 Bedge* e = tips[k];
00212 Bvert* v = (e->v2()->degree(boundary) != 2) ? e->v2() : e->v1();
00213 Bface* f = e->screen_face(face_filter);
00214 assert(f);
00215
00216
00217
00218 if (f->next_vert_ccw(v) == e->other_vertex(v))
00219 build(v, e, wanted);
00220 }
00221
00222
00223 for (k=0; k<edges.num(); k++) {
00224 Bedge* e = edges[k];
00225 Bface* f = e->screen_face(face_filter);
00226 assert(f);
00227
00228
00229 build(f->leading_vert_ccw(e), e, wanted);
00230 }
00231 }
00232
00233 bool
00234 EdgeStrip::has_break(int i) const
00235 {
00236
00237
00238
00239
00240 if (empty() || (i < 0) || (i > _verts.num()))
00241 return false;
00242
00243
00244
00245 if ((i == 0) || (i == _verts.num()))
00246 return true;
00247
00248
00249 return (_verts[i] != next_vert(i-1));
00250 }
00251
00252 int
00253 EdgeStrip::num_line_strips() const
00254 {
00255
00256
00257 if (empty())
00258 return 0;
00259
00260 int ret = 1;
00261
00262
00263 for (int i=0; i<_edges.num()-1; i++)
00264 if (next_vert(i) != _verts[i+1])
00265 ret++;
00266 return ret;
00267 }
00268
00269 bool
00270 EdgeStrip::get_chain(int& k, Bvert_list& chain) const
00271 {
00272
00273
00274
00275 chain.clear();
00276
00277 if (k < 0 || k >= num())
00278 return false;
00279
00280 if (!has_break(k))
00281 return false;
00282
00283 chain += vert(k);
00284 do {
00285 chain.add(next_vert(k));
00286 } while (!has_break(++k));
00287
00288 return true;
00289 }
00290
00291 void
00292 EdgeStrip::get_chains(ARRAY<Bvert_list>& chains) const
00293 {
00294
00295
00296
00297 chains.clear();
00298
00299 Bvert_list chain;
00300 for (int k=0; get_chain(k, chain); )
00301 chains += chain;
00302 }
00303
00304 EdgeStrip
00305 EdgeStrip::get_reverse() const
00306 {
00307
00308
00309 EdgeStrip ret = *this;
00310 if (!empty()) {
00311 ret._edges.reverse();
00312 ret._verts += last();
00313 ret._verts.reverse();
00314 ret._verts.pop();
00315 }
00316 return ret;
00317 }
00318
00319 EdgeStrip
00320 EdgeStrip::get_filtered(CSimplexFilter& filter) const
00321 {
00322 EdgeStrip ret;
00323 for (int i=0; i<num(); i++)
00324 if (filter.accept(edge(i)))
00325 ret.add(vert(i), edge(i));
00326 return ret;
00327 }
00328
00329 inline Bvert*
00330 get_leading_vert(CEdgeStrip& source)
00331 {
00332 CBvert_list& verts = source.verts();
00333 CBedge_list& edges = source.edges();
00334 for (int i=0; i<verts.num(); i++)
00335 if (verts[i]->degree(SimplexFlagFilter(1)) == 1 && edges[i]->flag())
00336 return verts[i];
00337 for (int j=0; j<verts.num(); j++)
00338 if (edges[j]->flag())
00339 return verts[j];
00340 return 0;
00341 }
00342
00343 inline void
00344 add_to_strip(Bvert* v, CEdgeStrip& source, EdgeStrip& ret)
00345 {
00346 assert(v);
00347 CBvert_list& verts = source.verts();
00348 CBedge_list& edges = source.edges();
00349 int k = verts.get_index(v);
00350 assert(verts.valid_index(k) && edges[k]->flag());
00351 while (verts.valid_index(k) && edges[k]->flag()) {
00352 edges[k]->clear_flag();
00353 ret.add(verts[k], edges[k]);
00354 if (source.has_break(k+1)) {
00355 k = verts.get_index(source.next_vert(k));
00356 } else {
00357 k++;
00358 }
00359 }
00360 }
00361
00362 EdgeStrip
00363 EdgeStrip::get_unified() const
00364 {
00365 _edges.get_verts().clear_flag02();
00366 _edges.set_flags(1);
00367 EdgeStrip ret;
00368 Bvert* v = 0;
00369 while ((v = get_leading_vert(*this))) {
00370 add_to_strip(v, *this, ret);
00371 }
00372 return ret;
00373 }
00374
00375