00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef OPENMESH_PROPERTYCONTAINER
00027 #define OPENMESH_PROPERTYCONTAINER
00028
00029
00030 #ifdef NDEBUG
00031 #define OM_FORCE_STATIC_CAST
00032 #endif
00033
00034 #include <OpenMesh/Core/Utils/Property.hh>
00035
00036
00037 namespace OpenMesh
00038 {
00039
00040 class BaseKernel;
00041
00042
00044 class PropertyContainer
00045 {
00046 public:
00047
00048
00049
00050 PropertyContainer() {}
00051 virtual ~PropertyContainer() { clear(); }
00052
00053
00054
00055
00056 typedef std::vector<BaseProperty*> Properties;
00057 const Properties& properties() const { return properties_; }
00058 size_t size() const { return properties_.size(); }
00059
00060
00061
00062
00063
00064 PropertyContainer(const PropertyContainer& _rhs) { operator=(_rhs); }
00065
00066 PropertyContainer& operator=(const PropertyContainer& _rhs)
00067 {
00068 clear();
00069 properties_ = _rhs.properties_;
00070 Properties::iterator p_it=properties_.begin(), p_end=properties_.end();
00071 for (; p_it!=p_end; ++p_it)
00072 if (*p_it)
00073 *p_it = (*p_it)->clone();
00074 return *this;
00075 }
00076
00077
00078
00079
00080
00081 template <class T>
00082 BasePropHandleT<T> add(const T&, const std::string& _name="<unknown>")
00083 {
00084 Properties::iterator p_it=properties_.begin(), p_end=properties_.end();
00085 int idx=0;
00086 for ( ; p_it!=p_end && *p_it!=NULL; ++p_it, ++idx ) {};
00087 if (p_it==p_end) properties_.push_back(NULL);
00088 properties_[idx] = new PropertyT<T>(_name);
00089 return BasePropHandleT<T>(idx);
00090 }
00091
00092
00093 template <class T>
00094 BasePropHandleT<T> handle(const T&, const std::string& _name) const
00095 {
00096 Properties::const_iterator p_it = properties_.begin();
00097 for (int idx=0; p_it != properties_.end(); ++p_it, ++idx)
00098 {
00099 if (*p_it != NULL && (*p_it)->name() == _name &&
00100 dynamic_cast<PropertyT<T>*>(properties_[idx]) != NULL)
00101 {
00102 return BasePropHandleT<T>(idx);
00103 }
00104 }
00105 return BasePropHandleT<T>();
00106 }
00107
00108 BaseProperty* property( const std::string& _name ) const
00109 {
00110 Properties::const_iterator p_it = properties_.begin();
00111 for (int idx=0; p_it != properties_.end(); ++p_it, ++idx)
00112 {
00113 if (*p_it != NULL && (*p_it)->name() == _name)
00114 {
00115 return *p_it;
00116 }
00117 }
00118 return NULL;
00119 }
00120
00121 template <class T> PropertyT<T>& property(BasePropHandleT<T> _h)
00122 {
00123 assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size());
00124 assert(properties_[_h.idx()] != NULL);
00125 #ifdef OM_FORCE_STATIC_CAST
00126 return *static_cast <PropertyT<T>*> (properties_[_h.idx()]);
00127 #else
00128 PropertyT<T>* p = dynamic_cast<PropertyT<T>*>(properties_[_h.idx()]);
00129 assert(p != NULL);
00130 return *p;
00131 #endif
00132 }
00133
00134
00135 template <class T> const PropertyT<T>& property(BasePropHandleT<T> _h) const
00136 {
00137 assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size());
00138 assert(properties_[_h.idx()] != NULL);
00139 #ifdef OM_FORCE_STATIC_CAST
00140 return *static_cast<PropertyT<T>*>(properties_[_h.idx()]);
00141 #else
00142 PropertyT<T>* p = dynamic_cast<PropertyT<T>*>(properties_[_h.idx()]);
00143 assert(p != NULL);
00144 return *p;
00145 #endif
00146 }
00147
00148
00149 template <class T> void remove(BasePropHandleT<T> _h)
00150 {
00151 assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size());
00152 delete properties_[_h.idx()];
00153 properties_[_h.idx()] = NULL;
00154 }
00155
00156
00157 void clear()
00158 {
00159 std::for_each(properties_.begin(), properties_.end(), Delete());
00160 }
00161
00162
00163
00164
00165 void reserve(size_t _n) const {
00166 std::for_each(properties_.begin(), properties_.end(), Reserve(_n));
00167 }
00168
00169 void resize(size_t _n) const {
00170 std::for_each(properties_.begin(), properties_.end(), Resize(_n));
00171 }
00172
00173 void swap(size_t _i0, size_t _i1) const {
00174 std::for_each(properties_.begin(), properties_.end(), Swap(_i0, _i1));
00175 }
00176
00177
00178
00179 protected:
00180
00181 size_t _add( BaseProperty* _bp )
00182 {
00183 Properties::iterator p_it=properties_.begin(), p_end=properties_.end();
00184 size_t idx=0;
00185 for (; p_it!=p_end && *p_it!=NULL; ++p_it, ++idx) {};
00186 if (p_it==p_end) properties_.push_back(NULL);
00187 properties_[idx] = _bp;
00188 return idx;
00189 }
00190
00191 BaseProperty& _property( size_t _idx )
00192 {
00193 assert( _idx < properties_.size());
00194 assert( properties_[_idx] != NULL);
00195 BaseProperty *p = properties_[_idx];
00196 assert( p != NULL );
00197 return *p;
00198 }
00199
00200 const BaseProperty& _property( size_t _idx ) const
00201 {
00202 assert( _idx < properties_.size());
00203 assert( properties_[_idx] != NULL);
00204 BaseProperty *p = properties_[_idx];
00205 assert( p != NULL );
00206 return *p;
00207 }
00208
00209
00210 typedef Properties::iterator iterator;
00211 typedef Properties::const_iterator const_iterator;
00212 iterator begin() { return properties_.begin(); }
00213 iterator end() { return properties_.end(); }
00214 const_iterator begin() const { return properties_.begin(); }
00215 const_iterator end() const { return properties_.end(); }
00216
00217 friend class BaseKernel;
00218
00219 private:
00220
00221
00222
00223 #ifndef DOXY_IGNORE_THIS
00224 struct Reserve
00225 {
00226 Reserve(size_t _n) : n_(_n) {}
00227 void operator()(BaseProperty* _p) const { if (_p) _p->reserve(n_); }
00228 size_t n_;
00229 };
00230
00231 struct Resize
00232 {
00233 Resize(size_t _n) : n_(_n) {}
00234 void operator()(BaseProperty* _p) const { if (_p) _p->resize(n_); }
00235 size_t n_;
00236 };
00237
00238 struct Swap
00239 {
00240 Swap(size_t _i0, size_t _i1) : i0_(_i0), i1_(_i1) {}
00241 void operator()(BaseProperty* _p) const { if (_p) _p->swap(i0_, i1_); }
00242 size_t i0_, i1_;
00243 };
00244
00245 struct Delete
00246 {
00247 Delete() {}
00248 void operator()(BaseProperty* _p) const { if (_p) delete _p; _p=NULL; }
00249 };
00250 #endif
00251
00252 Properties properties_;
00253 };
00254
00255 }
00256
00257 #endif//OPENMESH_PROPERTYCONTAINER
00258