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