Easy3D 2.5.3
property.h
1/********************************************************************
2 * Copyright (C) 2015-2021 by Liangliang Nan <liangliang.nan@gmail.com>
3 * Copyright (C) 2001-2005 by Computer Graphics Group, RWTH Aachen
4 * Copyright (C) 2011-2013 by Graphics & Geometry Group, Bielefeld University
5 *
6 * The code in this file is partly from Surface_mesh (v1.1) with
7 * modifications and enhancement:
8 * https://opensource.cit-ec.de/projects/surface_mesh
9 * The original code was distributed under the GNU GPL License.
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Library General Public License
13 * as published by the Free Software Foundation, version 2.
14 *
15 * This library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 ********************************************************************/
24
25#ifndef EASY3D_CORE_PROPERTIES_H
26#define EASY3D_CORE_PROPERTIES_H
27
28#include <vector>
29#include <string>
30#include <iostream>
31#include <algorithm>
32#include <typeinfo>
33#include <cassert>
34
35
36namespace easy3d {
37
41 {
42 public:
43
45 explicit BasePropertyArray(const std::string& name) : name_(name) {}
46
48 virtual ~BasePropertyArray() = default;
49
51 virtual void reserve(size_t n) = 0;
52
54 virtual void resize(size_t n) = 0;
55
57 virtual void shrink_to_fit() = 0;
58
60 virtual void push_back() = 0;
61
63 virtual void reset(size_t idx) = 0;
64
66 virtual bool transfer(const BasePropertyArray& other) = 0;
68 virtual bool transfer(const BasePropertyArray& other, std::size_t from, std::size_t to) = 0;
69
71 virtual void swap(size_t i0, size_t i1) = 0;
72
74 virtual void copy(size_t from, size_t to) = 0;
75
77 virtual BasePropertyArray* clone () const = 0;
78
80 virtual BasePropertyArray* empty_clone () const = 0;
81
83 virtual const std::type_info& type() const = 0;
84
86 const std::string& name() const { return name_; }
87
89 void set_name(const std::string& n) { name_ = n; }
90
93 bool is_same(const BasePropertyArray& other) const
94 {
95 return (name() == other.name() && type() == other.type());
96 }
97
98 protected:
99
100 std::string name_;
101 };
102
103
104
105 //== CLASS DEFINITION =========================================================
106
109 template <class T>
111 {
112 public:
113
114 typedef T value_type;
115 typedef std::vector<value_type> vector_type;
116 typedef typename vector_type::reference reference;
117 typedef typename vector_type::const_reference const_reference;
118
119 explicit PropertyArray(const std::string& name, T t=T()) : BasePropertyArray(name), value_(t) {}
120
121
122 public: // virtual interface of BasePropertyArray
123
124 void reserve(size_t n) override
125 {
126 data_.reserve(n);
127 }
128
129 void resize(size_t n) override
130 {
131 data_.resize(n, value_);
132 }
133
134 void push_back() override
135 {
136 data_.push_back(value_);
137 }
138
139 void reset(size_t idx) override
140 {
141 data_[idx] = value_;
142 }
143
144 bool transfer(const BasePropertyArray& other) override
145 {
146 const auto pa = dynamic_cast<const PropertyArray*>(&other);
147 if(pa != nullptr){
148 std::copy((*pa).data_.begin(), (*pa).data_.end(), data_.end()-(*pa).data_.size());
149 return true;
150 }
151 return false;
152 }
153
154 bool transfer(const BasePropertyArray& other, std::size_t from, std::size_t to) override
155 {
156 const auto pa = dynamic_cast<const PropertyArray*>(&other);
157 if (pa != nullptr)
158 {
159 data_[to] = (*pa)[from];
160 return true;
161 }
162
163 return false;
164 }
165
166 void shrink_to_fit() override
167 {
168 vector_type(data_).swap(data_);
169 }
170
171 void swap(size_t i0, size_t i1) override
172 {
173 T d(data_[i0]);
174 data_[i0]=data_[i1];
175 data_[i1]=d;
176 }
177
178 void copy(size_t from, size_t to) override
179 {
180 data_[to]=data_[from];
181 }
182
183 BasePropertyArray* clone() const override
184 {
185 auto p = new PropertyArray<T>(name_, value_);
186 p->data_ = data_;
187 return p;
188 }
189
191 {
192 auto p = new PropertyArray<T>(this->name_, this->value_);
193 return p;
194 }
195
196 const std::type_info& type() const override { return typeid(T); }
197
198
199 public:
200
202 const T* data() const
203 {
204 return &data_[0];
205 }
206
207
209 std::vector<T>& vector()
210 {
211 return data_;
212 }
213
214
216 reference operator[](size_t _idx)
217 {
218 assert( size_t(_idx) < data_.size() );
219 return data_[_idx];
220 }
221
223 const_reference operator[](size_t _idx) const
224 {
225 assert( size_t(_idx) < data_.size());
226 return data_[_idx];
227 }
228
229
230 private:
231 vector_type data_;
232 value_type value_;
233 };
234
235
236 // specialization for bool properties
237 template <>
238 inline const bool*
240 {
241 assert(false);
242 return nullptr;
243 }
244
245
246
247 //== CLASS DEFINITION =========================================================
248
251 template <class T>
253 {
254 public:
255
256 typedef typename PropertyArray<T>::reference reference;
257 typedef typename PropertyArray<T>::const_reference const_reference;
258
259 friend class PropertyContainer;
260
261 public:
262
263 explicit Property(PropertyArray<T> *p = nullptr) : parray_(p) {}
264
265 void reset()
266 {
267 parray_ = nullptr;
268 }
269
270 operator bool() const
271 {
272 return parray_ != nullptr;
273 }
274
275 virtual reference operator[](size_t i)
276 {
277 assert(parray_ != nullptr);
278 return (*parray_)[i];
279 }
280
281 virtual const_reference operator[](size_t i) const
282 {
283 assert(parray_ != nullptr);
284 return (*parray_)[i];
285 }
286
287 const T* data() const
288 {
289 assert(parray_ != nullptr);
290 return parray_->data();
291 }
292
293 std::vector<T>& vector()
294 {
295 assert(parray_ != nullptr);
296 return parray_->vector();
297 }
298
299 const std::vector<T>& vector() const
300 {
301 assert(parray_ != nullptr);
302 return parray_->vector();
303 }
304
305 PropertyArray<T>& array()
306 {
307 assert(parray_ != nullptr);
308 return *parray_;
309 }
310
311 const PropertyArray<T>& array() const
312 {
313 assert(parray_ != nullptr);
314 return *parray_;
315 }
316
318 const std::string& name() const {
319 assert(parray_ != nullptr);
320 return parray_->name();
321 }
322
324 void set_name(const std::string& n) {
325 assert(parray_ != nullptr);
326 parray_->set_name(n);
327 }
328
329 private:
330 PropertyArray<T>* parray_;
331 };
332
333
334
335 //== CLASS DEFINITION =========================================================
336
337
341 {
342 public:
343
344 // default constructor
345 PropertyContainer() : size_(0) {}
346
347 // destructor (deletes all property arrays)
348 virtual ~PropertyContainer() { clear(); }
349
350 // copy constructor: performs deep copy of property arrays
351 PropertyContainer(const PropertyContainer& _rhs) { operator=(_rhs); }
352
353 // assignment: performs deep copy of property arrays
354 PropertyContainer& operator=(const PropertyContainer& _rhs)
355 {
356 if (this != &_rhs)
357 {
358 clear();
359 parrays_.resize(_rhs.n_properties());
360 size_ = _rhs.size();
361 for (size_t i=0; i<parrays_.size(); ++i)
362 parrays_[i] = _rhs.parrays_[i]->clone();
363 }
364 return *this;
365 }
366
367 void transfer(const PropertyContainer& _rhs)
368 {
369 for(auto pa : parrays_) {
370 for (auto rpa : _rhs.parrays_) {
371 if(pa->is_same (*rpa)){
372 pa->transfer(*rpa);
373 break;
374 }
375 }
376 }
377 }
378
379 // Copy properties that don't already exist from another container
380 void copy_properties(const PropertyContainer& _rhs)
381 {
382 for (auto rpa : _rhs.parrays_)
383 {
384 bool property_already_exists = false;
385 for(auto pa : parrays_)
386 if (rpa->is_same(*pa))
387 {
388 property_already_exists = true;
389 break;
390 }
391
392 if (property_already_exists)
393 continue;
394
395 parrays_.push_back(rpa->empty_clone());
396 parrays_.back()->resize(size_);
397 }
398 }
399
400 // Transfer one element with all properties
401 // WARNING: properties must be the same in the two containers
402 bool transfer(const PropertyContainer& _rhs, std::size_t from, std::size_t to)
403 {
404 bool out = true;
405 for(std::size_t i=0; i<parrays_.size(); ++i)
406 if (!(parrays_[i]->transfer(* _rhs.parrays_[i], from, to)))
407 out = false;
408 return out;
409 }
410
411 // returns the current size of the property arrays
412 size_t size() const { return size_; }
413
414 // returns the number of property arrays
415 size_t n_properties() const { return parrays_.size(); }
416
417 // returns a vector of all property names
418 std::vector<std::string> properties() const
419 {
420 std::vector<std::string> names;
421 for(auto pa : parrays_)
422 names.push_back(pa->name());
423 return names;
424 }
425
426
427 // add a property with name \c name and default value \c t
428 template <class T> Property<T> add(const std::string& name, const T t=T())
429 {
430 // if a property with this name already exists, return an invalid property
431 for(auto pa : parrays_)
432 {
433 if (pa->name() == name)
434 {
435 LOG(ERROR) << "A property with name \""
436 << name << "\" already exists. Returning invalid property.";
437 return Property<T>();
438 }
439 }
440
441 // otherwise add the property
442 auto p = new PropertyArray<T>(name, t);
443 p->resize(size_);
444 parrays_.push_back(p);
445 return Property<T>(p);
446 }
447
448
449 // get a property by its name. returns invalid property if it does not exist.
450 template <class T> Property<T> get(const std::string& name) const
451 {
452 for(auto pa : parrays_)
453 if (pa->name() == name)
454 return Property<T>(dynamic_cast<PropertyArray<T>*>(pa));
455 return Property<T>();
456 }
457
458
459 // returns a property if it exists, otherwise it creates it first.
460 template <class T> Property<T> get_or_add(const std::string& name, const T t=T())
461 {
462 Property<T> p = get<T>(name);
463 if (!p) p = add<T>(name, t);
464 return p;
465 }
466
467
468 // get the type of property by its name. returns typeid(void) if it does not exist.
469 const std::type_info& get_type(const std::string& name) const
470 {
471 for(auto pa : parrays_)
472 if (pa->name() == name)
473 return pa->type();
474 return typeid(void);
475 }
476
477
478 // delete a property. Returns true on success.
479 template <class T> bool remove(Property<T>& h)
480 {
481 auto it=parrays_.begin(), end=parrays_.end();
482 for (; it!=end; ++it)
483 {
484 if (*it == h.parray_)
485 {
486 delete *it;
487 parrays_.erase(it);
488 h.reset();
489 return true;
490 }
491 }
492 return false;
493 }
494
495 // delete a property by name. Returns true on success.
496 bool remove(const std::string& name)
497 {
498 auto it=parrays_.begin(), end=parrays_.end();
499 for (; it!=end; ++it)
500 {
501 if ((*it)->name() == name)
502 {
503 delete *it;
504 parrays_.erase(it);
505 return true;
506 }
507 }
508 return false;
509 }
510
511 // rename a property. Returns true on success.
512 bool rename(const std::string& old_name, const std::string& new_name)
513 {
514 assert(!old_name.empty());
515 assert(!new_name.empty());
516 auto it=parrays_.begin(), end=parrays_.end();
517 for (; it!=end; ++it)
518 {
519 if ((*it)->name() == old_name)
520 {
521 (*it)->set_name(new_name);
522 return true;
523 }
524 }
525 return false;
526 }
527
528
529 // delete all properties
530 void clear()
531 {
532 for(auto pa : parrays_)
533 delete pa;
534 parrays_.clear();
535 size_ = 0;
536 }
537
538
539 // reserve memory for n entries in all arrays
540 void reserve(size_t n) const
541 {
542 for(auto pa : parrays_)
543 pa->reserve(n);
544 }
545
546 // resize all arrays to size n
547 void resize(size_t n)
548 {
549 for(auto pa : parrays_)
550 pa->resize(n);
551 size_ = n;
552 }
553
554 // resize the vector of properties to n, deleting all other properties
555 void resize_property_array(size_t n)
556 {
557 if (parrays_.size()<=n) {
558 // Liangliang: we should add "parrays_.resize(n);" here?
559 return;
560 }
561 for (std::size_t i=n; i<parrays_.size(); ++i)
562 delete parrays_[i];
563 parrays_.resize(n);
564 }
565
566 // free unused space in all arrays
567 void shrink_to_fit() const
568 {
569 for(auto pa : parrays_)
570 pa->shrink_to_fit();
571 }
572
573 // add a new element to each vector
574 void push_back()
575 {
576 for(auto pa : parrays_)
577 pa->push_back();
578 ++size_;
579 }
580
581 // reset element to its default property values
582 void reset(size_t idx)
583 {
584 for(auto pa : parrays_)
585 pa->reset(idx);
586 }
587
588 // swap elements i0 and i1 in all arrays
589 void swap(size_t i0, size_t i1) const
590 {
591 for(auto pa : parrays_)
592 pa->swap(i0, i1);
593 }
594
595 // swap content with other Property_container
596 void swap (PropertyContainer& other)
597 {
598 this->parrays_.swap (other.parrays_);
599 std::swap(this->size_, other.size_);
600 }
601
602 // copy 'from' -> 'to' in all arrays
603 void copy(size_t from, size_t to) const
604 {
605 for(auto pa : parrays_)
606 pa->copy(from, to);
607 }
608
609 const std::vector<BasePropertyArray*>& arrays() const { return parrays_; }
610 std::vector<BasePropertyArray*>& arrays() { return parrays_; }
611
612 private:
613 std::vector<BasePropertyArray*> parrays_;
614 size_t size_;
615 };
616
617} // namespace easy3d
618
619#endif // EASY3D_CORE_PROPERTIES_H
Base class for a property array.
Definition: property.h:41
virtual ~BasePropertyArray()=default
Destructor.
virtual bool transfer(const BasePropertyArray &other, std::size_t from, std::size_t to)=0
Copy the property[from] of other to this->property[to].
const std::string & name() const
Return the name of the property.
Definition: property.h:86
virtual void swap(size_t i0, size_t i1)=0
Let two elements swap their storage place.
virtual BasePropertyArray * clone() const =0
Return a deep copy of self.
virtual void push_back()=0
Extend the number of elements by one.
virtual void reserve(size_t n)=0
Reserve memory for n elements.
virtual BasePropertyArray * empty_clone() const =0
Return a empty copy of self.
virtual void resize(size_t n)=0
Resize storage to hold n elements.
bool is_same(const BasePropertyArray &other) const
Definition: property.h:93
virtual void copy(size_t from, size_t to)=0
Let copy 'from' -> 'to'.
virtual const std::type_info & type() const =0
Return the type_info of the property.
virtual void shrink_to_fit()=0
Free unused memory.
virtual void reset(size_t idx)=0
Reset element to default value.
virtual bool transfer(const BasePropertyArray &other)=0
Copy the entire properties from other.
BasePropertyArray(const std::string &name)
Default constructor.
Definition: property.h:45
void set_name(const std::string &n)
Set the name of the property.
Definition: property.h:89
Implementation of a generic property array.
Definition: property.h:111
void push_back() override
Extend the number of elements by one.
Definition: property.h:134
const std::type_info & type() const override
Return the type_info of the property.
Definition: property.h:196
reference operator[](size_t _idx)
Access the i'th element. No range check is performed!
Definition: property.h:216
void swap(size_t i0, size_t i1) override
Let two elements swap their storage place.
Definition: property.h:171
void copy(size_t from, size_t to) override
Let copy 'from' -> 'to'.
Definition: property.h:178
const T * data() const
Get pointer to array (does not work for T==bool)
Definition: property.h:202
BasePropertyArray * clone() const override
Return a deep copy of self.
Definition: property.h:183
bool transfer(const BasePropertyArray &other, std::size_t from, std::size_t to) override
Copy the property[from] of other to this->property[to].
Definition: property.h:154
BasePropertyArray * empty_clone() const override
Return a empty copy of self.
Definition: property.h:190
void reserve(size_t n) override
Reserve memory for n elements.
Definition: property.h:124
void shrink_to_fit() override
Free unused memory.
Definition: property.h:166
void reset(size_t idx) override
Reset element to default value.
Definition: property.h:139
std::vector< T > & vector()
Get reference to the underlying vector.
Definition: property.h:209
const_reference operator[](size_t _idx) const
Const access to the i'th element. No range check is performed!
Definition: property.h:223
void resize(size_t n) override
Resize storage to hold n elements.
Definition: property.h:129
bool transfer(const BasePropertyArray &other) override
Copy the entire properties from other.
Definition: property.h:144
Implementation of generic property container.
Definition: property.h:341
Implementation of a generic property.
Definition: property.h:253
const std::string & name() const
Return the name of the property.
Definition: property.h:318
void set_name(const std::string &n)
Set the name of the property.
Definition: property.h:324
Definition: collider.cpp:182
void swap(Matrix< FT > &, Matrix< FT > &)
Definition: matrix.h:1439