Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

simplex_array.H

Go to the documentation of this file.
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  * SimplexArray:
00011  *
00012  *      Convenience array for Bsimplex derived types.
00013  *      L is the list type itself; T is Bsimplex*,
00014  *      Bvert*, Bedge* or Bface* (or derived types).
00015  *
00016  *      Note: null pointers should never be added to the list.
00017  *
00018  *****************************************************************/
00019 template <class L, class T>
00020 class SimplexArray : public ARRAY<T> {
00021  public:
00022 
00023    //******** MANAGERS ********
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    //******** CONVENIENCE ********
00035 
00036    // Clear all the flags
00037    void clear_flags() const {
00038       for (int i=0; i<num(); i++)
00039          (*this)[i]->clear_flag();
00040    }
00041 
00042    // Set all the flags
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    // Increment all the flags
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    // Clear a particular bit on all the simplices:
00055    void clear_bits(uint b) const {
00056       for (int i=0; i<num(); i++)
00057          (*this)[i]->clear_bit(b);
00058    }
00059 
00060    // Set a particular bit on all the simplices:
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    // If whole list is from same mesh, returns the mesh:
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    // Returns true if the list is empty or they all belong to
00077    // the same mesh
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    // delete all elements:
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();    // g++ on macosx requires this->pop()
00096       if (indexing_was_on)      //  instead of just pop()
00097          begin_index();
00098    }
00099 
00100    //******** SET OPERATIONS ********
00101 
00102    // Return true if every element of list is also an element of this
00103    // (evaluates to true if list is empty):
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    // Return true if any element of list is also an element of this
00114    // (evaluates to false if list is empty):
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    // Return true if list has exactly the same elements as this:
00125    bool same_elements(const L& list) const {
00126       return contains_all(list) && list.contains_all(*this);
00127    }
00128 
00129    // Return true if any element occurs more than once:
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    // Return the elements of this list, without duplicates
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    // Return elements common to this and list:
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    // Return union of this and list
00168    // (result does not contain duplicates):
00169    L union_no_duplicates(const L& list) const {
00170       return (*this + list).unique_elements();
00171    }
00172 
00173    // Returns elements of this that are not also in list
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    //******** SimplexFilter METHODS ********
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    // Returns true if all simplices satisfy the given filter
00198    // (if empty, returns true)
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    // Returns true if any simplices satisfy the given filter
00207    // (if empty, returns false)
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    // Returns the first simplex satisfied by the filter:
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    //******** SELECTED ELEMENTS ********
00232 
00233    // Convenience: get the selected or unselected elements
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    //******** ARRAY OPERATORS ********
00242 
00243    // Append elements of list to this one:
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    // Concatenate this list with another, producing a new list:
00253    L operator+(const L& list) const {
00254       L ret = *this;
00255       ret.append(list);
00256       return ret;
00257    }
00258 
00259    //******** ARRAY VIRTUAL METHODS ********
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     * IndexData:
00291     *
00292     *    Used to store element indices WRT a particular SimplexArray.
00293     *
00294     *****************************************************************/
00295    class IndexData : public SimplexData {
00296     public:
00297 
00298       //******** MANAGERS ********
00299 
00300       IndexData(uint key, Bsimplex* s) :
00301          SimplexData(key, s), _index(-1) {}
00302 
00303       //******** ACCESSORS ********
00304 
00305       int  index()                 const   { return _index; }
00306       void set_index(int i)                { _index = i; }
00307 
00308     protected:
00309       int  _index;
00310    };
00311 
00312    //******** ARRAY INDEXING ********
00313 
00314    // On the given simplex, find the data owned by this list:
00315    IndexData* lookup_data(const T& s) const {
00316       return s ? (IndexData*)s->find_data((uint)this) : 0;
00317    }
00318 
00319    // Similar to lookup_data() but creates the data if needed
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    //******** ARRAY VIRTUAL METHODS ********
00326 
00327    virtual void  append_ele(const T& s) {
00328       // Don't permit NULL pointers to be inserted
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 // Actual classes based on above template:
00338 class Bsimplex_list;    // defined below
00339 class Bvert_list;       // defined in bedge.H
00340 class Bedge_list;       // defined in bvert.H
00341 class Bface_list;       // defined in Bface.H
00342 
00343 /************************************************************
00344  * Bsimplex_list
00345  ************************************************************/
00346 typedef const Bsimplex_list CBsimplex_list;
00347 class Bsimplex_list : public SimplexArray<Bsimplex_list,Bsimplex*> {
00348  public:
00349    //******** MANAGERS ********
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

Generated on Mon Sep 18 11:39:33 2006 for jot by  doxygen 1.4.4