00001 #ifndef SIMPLEX_ARRAY_H_IS_INCLUDED
00002 #define SIMPLEX_ARRAY_H_IS_INCLUDED
00003
00004 #include "bsimplex.H"
00005 #include "simplex_filter.H"
00006
00007 class SimplexFilter;
00008 typedef const SimplexFilter CSimplexFilter;
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 template <class L, class T>
00020 class SimplexArray : public ARRAY<T> {
00021 public:
00022
00023
00024
00025 SimplexArray(const ARRAY<T>& list) : ARRAY<T>(list) {}
00026 explicit SimplexArray(int n=0) : ARRAY<T>(n) {}
00027 explicit SimplexArray(T s) : ARRAY<T>() { add(s); }
00028
00029 virtual ~SimplexArray() {
00030 if (_do_index)
00031 end_index();
00032 }
00033
00034
00035
00036
00037 void clear_flags() const {
00038 for (int i=0; i<num(); i++)
00039 (*this)[i]->clear_flag();
00040 }
00041
00042
00043 void set_flags(uchar b=1) const {
00044 for (int i=0; i<num(); i++)
00045 (*this)[i]->set_flag(b);
00046 }
00047
00048
00049 void inc_flags(uchar b=1) const {
00050 for (int i=0; i<num(); i++)
00051 (*this)[i]->inc_flag(b);
00052 }
00053
00054
00055 void clear_bits(uint b) const {
00056 for (int i=0; i<num(); i++)
00057 (*this)[i]->clear_bit(b);
00058 }
00059
00060
00061 void set_bits(uint b, int x=1) const {
00062 for (int i=0; i<num(); i++)
00063 (*this)[i]->set_bit(b, x);
00064 }
00065
00066
00067 BMESH* mesh() const {
00068 if (empty()) return 0;
00069 BMESH* ret = (*this)[0]->mesh();
00070 for (int i=1; i<num(); i++)
00071 if (ret != (*this)[i]->mesh())
00072 return 0;
00073 return ret;
00074 }
00075
00076
00077
00078 bool same_mesh() const { return empty() || mesh() != NULL; }
00079
00080 ARRAY<BMESH*> get_meshes() const {
00081 ARRAY<BMESH*> ret;
00082 ret.set_unique();
00083 for (int i=0; i<num(); i++)
00084 ret += (*this)[i]->mesh();
00085
00086 return ret;
00087 }
00088
00089
00090 void delete_all() {
00091 bool indexing_was_on = _do_index;
00092 if (_do_index)
00093 end_index();
00094 while (!empty())
00095 delete this->pop();
00096 if (indexing_was_on)
00097 begin_index();
00098 }
00099
00100
00101
00102
00103
00104 bool contains_all(const L& list) const {
00105 list.clear_flags();
00106 set_flags(1);
00107 for (int i=0; i<list.num(); i++)
00108 if (list[i]->flag() == 0)
00109 return false;
00110 return true;
00111 }
00112
00113
00114
00115 bool contains_any(const L& list) const {
00116 list.clear_flags();
00117 set_flags(1);
00118 for (int i=0; i<list.num(); i++)
00119 if (list[i]->flag() == 1)
00120 return true;
00121 return false;
00122 }
00123
00124
00125 bool same_elements(const L& list) const {
00126 return contains_all(list) && list.contains_all(*this);
00127 }
00128
00129
00130 bool has_duplicates() const {
00131 clear_flags();
00132 for (int i=0; i<num(); i++) {
00133 if ((*this)[i]->flag())
00134 return true;
00135 (*this)[i]->set_flag(1);
00136 }
00137 return false;
00138 }
00139
00140
00141 L unique_elements() const {
00142 L ret(num());
00143 clear_flags();
00144 for (int i=0; i<num(); i++) {
00145 if (!(*this)[i]->flag()) {
00146 ret += (*this)[i];
00147 (*this)[i]->set_flag(1);
00148 }
00149 }
00150 return ret;
00151 }
00152
00153
00154 L intersect(const L& list) const {
00155 L ret(min(num(), list.num()));
00156 list.set_flags(1);
00157 clear_flags();
00158 for (int i=0; i<list.num(); i++) {
00159 if (list[i]->flag() == 0) {
00160 ret += list[i];
00161 list[i]->set_flag(1);
00162 }
00163 }
00164 return ret;
00165 }
00166
00167
00168
00169 L union_no_duplicates(const L& list) const {
00170 return (*this + list).unique_elements();
00171 }
00172
00173
00174 L minus(const L& list) const {
00175 L ret(num());
00176 clear_flags();
00177 list.set_flags(1);
00178 for (int i=0; i<num(); i++) {
00179 if ((*this)[i]->flag() == 0) {
00180 ret += (*this)[i];
00181 (*this)[i]->set_flag(1);
00182 }
00183 }
00184 return ret;
00185 }
00186
00187
00188
00189 L filter(CSimplexFilter& f) const {
00190 L ret;
00191 for (int i=0; i<num(); i++)
00192 if (f.accept((*this)[i]))
00193 ret += (*this)[i];
00194 return ret;
00195 }
00196
00197
00198
00199 bool all_satisfy(CSimplexFilter& f) const {
00200 for (int i=0; i<num(); i++)
00201 if (!f.accept((*this)[i]))
00202 return false;
00203 return true;
00204 }
00205
00206
00207
00208 bool any_satisfy(CSimplexFilter& f) const {
00209 for (int i=0; i<num(); i++)
00210 if (f.accept((*this)[i]))
00211 return true;
00212 return false;
00213 }
00214
00215 int num_satisfy(CSimplexFilter& f) const {
00216 int ret = 0;
00217 for (int j=0; j<num(); j++)
00218 if (f.accept((*this)[j]))
00219 ret++;
00220 return ret;
00221 }
00222
00223
00224 T first_satisfies(CSimplexFilter& f) const {
00225 for (int i=0; i<num(); i++)
00226 if (f.accept((*this)[i]))
00227 return (*this)[i];
00228 return 0;
00229 }
00230
00231
00232
00233
00234 L selected_elements() {
00235 return filter(BitSetSimplexFilter(Bsimplex::SELECTED_BIT));
00236 }
00237 L unselected_elements() {
00238 return filter(BitClearSimplexFilter(Bsimplex::SELECTED_BIT));
00239 }
00240
00241
00242
00243
00244 void append(const L& list) {
00245 if (!list.empty()) {
00246 this->realloc(num() + list.num());
00247 for (int i=0; i<list.num(); i++)
00248 *this += list[i];
00249 }
00250 }
00251
00252
00253 L operator+(const L& list) const {
00254 L ret = *this;
00255 ret.append(list);
00256 return ret;
00257 }
00258
00259
00260
00261 virtual int get_index(const T& s) const {
00262 if (_do_index) {
00263 IndexData* d = lookup_data(s);
00264 return d ? d->index() : -1;
00265 }
00266 return ARRAY<T>::get_index(s);
00267 }
00268
00269 using ARRAY<T>::num;
00270 using ARRAY<T>::empty;
00271 using ARRAY<T>::clear;
00272 using ARRAY<T>::begin_index;
00273 using ARRAY<T>::end_index;
00274
00275 protected:
00276
00277 using ARRAY<T>::_do_index;
00278
00279 virtual void set_index(const T& el, int i) const {
00280 if (_do_index)
00281 put_data(el)->set_index(i);
00282 }
00283
00284 virtual void clear_index(const T& el) const {
00285 if (_do_index)
00286 delete lookup_data(el);
00287 }
00288
00289
00290
00291
00292
00293
00294
00295 class IndexData : public SimplexData {
00296 public:
00297
00298
00299
00300 IndexData(uint key, Bsimplex* s) :
00301 SimplexData(key, s), _index(-1) {}
00302
00303
00304
00305 int index() const { return _index; }
00306 void set_index(int i) { _index = i; }
00307
00308 protected:
00309 int _index;
00310 };
00311
00312
00313
00314
00315 IndexData* lookup_data(const T& s) const {
00316 return s ? (IndexData*)s->find_data((uint)this) : 0;
00317 }
00318
00319
00320 IndexData* put_data(const T& s) const {
00321 IndexData* ret = lookup_data(s);
00322 return ret ? ret : new IndexData((uint)this, (T)s);
00323 }
00324
00325
00326
00327 virtual void append_ele(const T& s) {
00328
00329 if (s) {
00330 ARRAY<T>::append_ele(s);
00331 } else {
00332 err_msg("SimplexArray::append_ele: warning: ignoring NULL Simplex*");
00333 }
00334 }
00335 };
00336
00337
00338 class Bsimplex_list;
00339 class Bvert_list;
00340 class Bedge_list;
00341 class Bface_list;
00342
00343
00344
00345
00346 typedef const Bsimplex_list CBsimplex_list;
00347 class Bsimplex_list : public SimplexArray<Bsimplex_list,Bsimplex*> {
00348 public:
00349
00350 Bsimplex_list(int n=0) :
00351 SimplexArray<Bsimplex_list,Bsimplex*>(n) {}
00352 Bsimplex_list(CARRAY<Bsimplex*>& list) :
00353 SimplexArray<Bsimplex_list,Bsimplex*>(list) {}
00354 };
00355
00356 #endif