Easy3D 2.6.1
Loading...
Searching...
No Matches
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 <algorithm>
31#include <typeinfo>
32#include <cassert>
33
34#include <easy3d/util/logging.h>
35
36
37namespace easy3d {
38
44 {
45 public:
50 explicit BasePropertyArray(const std::string& name) : name_(name) {}
51
53 virtual ~BasePropertyArray() = default;
54
59 virtual void reserve(size_t n) = 0;
60
65 virtual void resize(size_t n) = 0;
66
68 virtual void shrink_to_fit() = 0;
69
71 virtual void push_back() = 0;
72
77 virtual void reset(size_t idx) = 0;
78
84 virtual bool transfer(const BasePropertyArray& other) = 0;
92 virtual bool transfer(const BasePropertyArray& other, std::size_t from, std::size_t to) = 0;
93
99 virtual void swap(size_t i0, size_t i1) = 0;
100
106 virtual void copy(size_t from, size_t to) = 0;
107
112 virtual BasePropertyArray* clone() const = 0;
113
118 virtual BasePropertyArray* empty_clone() const = 0;
119
124 virtual const std::type_info& type() const = 0;
125
130 const std::string& name() const { return name_; }
131
136 void set_name(const std::string& n) { name_ = n; }
137
143 bool is_same(const BasePropertyArray& other) const
144 {
145 return (name() == other.name() && type() == other.type());
146 }
147
148 protected:
149
150 std::string name_;
151 };
152
153
154
155 //== CLASS DEFINITION =========================================================
156
162 template <class T>
164 {
165 public:
166 typedef T value_type;
167 typedef std::vector<value_type> vector_type;
168 typedef typename vector_type::reference reference;
169 typedef typename vector_type::const_reference const_reference;
170
176 explicit PropertyArray(const std::string& name, T t=T()) : BasePropertyArray(name), value_(t) {}
177
178
179 public: // virtual interface of BasePropertyArray
180
181 void reserve(size_t n) override
182 {
183 data_.reserve(n);
184 }
185
186 void resize(size_t n) override
187 {
188 data_.resize(n, value_);
189 }
190
191 void push_back() override
192 {
193 data_.push_back(value_);
194 }
195
196 void reset(size_t idx) override
197 {
198 data_[idx] = value_;
199 }
200
201 bool transfer(const BasePropertyArray& other) override
202 {
203 const auto pa = dynamic_cast<const PropertyArray*>(&other);
204 if(pa != nullptr){
205 std::copy((*pa).data_.begin(), (*pa).data_.end(), data_.end()-(*pa).data_.size());
206 return true;
207 }
208 return false;
209 }
210
211 bool transfer(const BasePropertyArray& other, std::size_t from, std::size_t to) override
212 {
213 const auto pa = dynamic_cast<const PropertyArray*>(&other);
214 if (pa != nullptr)
215 {
216 data_[to] = (*pa)[from];
217 return true;
218 }
219
220 return false;
221 }
222
223 void shrink_to_fit() override
224 {
225 vector_type(data_).swap(data_);
226 }
227
228 void swap(size_t i0, size_t i1) override
229 {
230 T d(data_[i0]);
231 data_[i0]=data_[i1];
232 data_[i1]=d;
233 }
234
235 void copy(size_t from, size_t to) override
236 {
237 data_[to]=data_[from];
238 }
239
240 BasePropertyArray* clone() const override
241 {
242 auto p = new PropertyArray<T>(name_, value_);
243 p->data_ = data_;
244 return p;
245 }
246
248 {
249 auto p = new PropertyArray<T>(this->name_, this->value_);
250 return p;
251 }
252
253 const std::type_info& type() const override { return typeid(T); }
254
255
256 public:
261 const T* data() const
262 {
263 return &data_[0];
264 }
265
270 std::vector<T>& vector()
271 {
272 return data_;
273 }
274
281 {
282 assert( size_t(_idx) < data_.size() );
283 return data_[_idx];
284 }
285
291 const_reference operator[](size_t _idx) const
292 {
293 assert( size_t(_idx) < data_.size());
294 return data_[_idx];
295 }
296
297 private:
298 vector_type data_;
299 value_type value_;
300 };
301
302
307 template <>
308 inline const bool*
310 {
311 assert(false);
312 return nullptr;
313 }
314
315
316
317 //== CLASS DEFINITION =========================================================
318
324 template <class T>
326 {
327 public:
330
331 friend class PropertyContainer;
332
333 public:
338 explicit Property(PropertyArray<T> *p = nullptr) : parray_(p) {}
339
341 virtual ~Property() = default;
342
346 void reset()
347 {
348 parray_ = nullptr;
349 }
350
355 operator bool() const
356 {
357 return parray_ != nullptr;
358 }
359
365 virtual reference operator[](size_t i)
366 {
367 assert(parray_ != nullptr);
368 return (*parray_)[i];
369 }
370
376 virtual const_reference operator[](size_t i) const
377 {
378 assert(parray_ != nullptr);
379 return (*parray_)[i];
380 }
381
386 const T* data() const
387 {
388 assert(parray_ != nullptr);
389 return parray_->data();
390 }
391
396 std::vector<T>& vector()
397 {
398 assert(parray_ != nullptr);
399 return parray_->vector();
400 }
401
406 const std::vector<T>& vector() const
407 {
408 assert(parray_ != nullptr);
409 return parray_->vector();
410 }
411
417 {
418 assert(parray_ != nullptr);
419 return *parray_;
420 }
421
426 const PropertyArray<T>& array() const
427 {
428 assert(parray_ != nullptr);
429 return *parray_;
430 }
431
436 const std::string& name() const {
437 assert(parray_ != nullptr);
438 return parray_->name();
439 }
440
445 void set_name(const std::string& n) {
446 assert(parray_ != nullptr);
447 parray_->set_name(n);
448 }
449
450 private:
451 PropertyArray<T>* parray_;
452 };
453
454
455 //== CLASS DEFINITION =========================================================
456
457
463 {
464 public:
468 PropertyContainer() : size_(0) {}
469
473 virtual ~PropertyContainer() { clear(); }
474
480
487 {
488 if (this != &_rhs)
489 {
490 clear();
491 parrays_.resize(_rhs.n_properties());
492 size_ = _rhs.size();
493 for (size_t i=0; i<parrays_.size(); ++i)
494 parrays_[i] = _rhs.parrays_[i]->clone();
495 }
496 return *this;
497 }
498
503 void transfer(const PropertyContainer& _rhs) const
504 {
505 for(auto pa : parrays_) {
506 for (auto rpa : _rhs.parrays_) {
507 if(pa->is_same(*rpa)){
508 pa->transfer(*rpa);
509 break;
510 }
511 }
512 }
513 }
514
520 {
521 for (auto rpa : _rhs.parrays_)
522 {
523 bool property_already_exists = false;
524 for(auto pa : parrays_)
525 if (rpa->is_same(*pa))
526 {
527 property_already_exists = true;
528 break;
529 }
530
531 if (property_already_exists)
532 continue;
533
534 parrays_.push_back(rpa->empty_clone());
535 parrays_.back()->resize(size_);
536 }
537 }
538
547 bool transfer(const PropertyContainer& _rhs, std::size_t from, std::size_t to) const
548 {
549 bool out = true;
550 for(std::size_t i=0; i<parrays_.size(); ++i)
551 if (!(parrays_[i]->transfer(* _rhs.parrays_[i], from, to)))
552 out = false;
553 return out;
554 }
555
560 size_t size() const { return size_; }
561
566 size_t n_properties() const { return parrays_.size(); }
567
572 std::vector<std::string> properties() const
573 {
574 std::vector<std::string> names(parrays_.size());
575 for(std::size_t i=0; i<parrays_.size(); ++i)
576 names[i] = parrays_[i]->name();
577 return names;
578 }
579
587 template <class T> Property<T> add(const std::string& name, const T t=T())
588 {
589 // if a property with this name already exists, return an invalid property
590 for(auto pa : parrays_)
591 {
592 if (pa->name() == name)
593 {
594 LOG(ERROR) << "A property with name \""
595 << name << "\" already exists. Returning invalid property.";
596 return Property<T>();
597 }
598 }
599
600 // otherwise add the property
601 auto p = new PropertyArray<T>(name, t);
602 p->resize(size_);
603 parrays_.push_back(p);
604 return Property<T>(p);
605 }
606
613 template <class T> Property<T> get(const std::string& name) const
614 {
615 for(auto pa : parrays_)
616 if (pa->name() == name)
617 return Property<T>(dynamic_cast<PropertyArray<T>*>(pa));
618 return Property<T>();
619 }
620
628 template <class T> Property<T> get_or_add(const std::string& name, const T t=T())
629 {
630 Property<T> p = get<T>(name);
631 if (!p) p = add<T>(name, t);
632 return p;
633 }
634
640 const std::type_info& get_type(const std::string& name) const
641 {
642 for(auto pa : parrays_)
643 if (pa->name() == name)
644 return pa->type();
645 return typeid(void);
646 }
647
654 template <class T> bool remove(Property<T>& h)
655 {
656 auto it=parrays_.begin(), end=parrays_.end();
657 for (; it!=end; ++it)
658 {
659 if (*it == h.parray_)
660 {
661 delete *it;
662 parrays_.erase(it);
663 h.reset();
664 return true;
665 }
666 }
667 return false;
668 }
669
675 bool remove(const std::string& name)
676 {
677 auto it=parrays_.begin(), end=parrays_.end();
678 for (; it!=end; ++it)
679 {
680 if ((*it)->name() == name)
681 {
682 delete *it;
683 parrays_.erase(it);
684 return true;
685 }
686 }
687 return false;
688 }
689
696 bool rename(const std::string& old_name, const std::string& new_name)
697 {
698 assert(!old_name.empty());
699 assert(!new_name.empty());
700 auto it=parrays_.begin(), end=parrays_.end();
701 for (; it!=end; ++it)
702 {
703 if ((*it)->name() == old_name)
704 {
705 (*it)->set_name(new_name);
706 return true;
707 }
708 }
709 return false;
710 }
711
715 void clear()
716 {
717 for(auto pa : parrays_)
718 delete pa;
719 parrays_.clear();
720 size_ = 0;
721 }
722
727 void reserve(size_t n) const
728 {
729 for(auto pa : parrays_)
730 pa->reserve(n);
731 }
732
737 void resize(size_t n)
738 {
739 for(auto pa : parrays_)
740 pa->resize(n);
741 size_ = n;
742 }
743
749 {
750 if (parrays_.size()<=n) {
751 // Liangliang: we should add "parrays_.resize(n);" here?
752 return;
753 }
754 for (std::size_t i=n; i<parrays_.size(); ++i)
755 delete parrays_[i];
756 parrays_.resize(n);
757 }
758
762 void shrink_to_fit() const
763 {
764 for(auto pa : parrays_)
765 pa->shrink_to_fit();
766 }
767
772 {
773 for(auto pa : parrays_)
774 pa->push_back();
775 ++size_;
776 }
777
782 void reset(size_t idx) const {
783 for(auto pa : parrays_)
784 pa->reset(idx);
785 }
786
792 void swap(size_t i0, size_t i1) const
793 {
794 for(auto pa : parrays_)
795 pa->swap(i0, i1);
796 }
797
802 void swap(PropertyContainer& other) noexcept {
803 this->parrays_.swap(other.parrays_);
804 std::swap(this->size_, other.size_);
805 }
806
812 void copy(size_t from, size_t to) const
813 {
814 for(auto pa : parrays_)
815 pa->copy(from, to);
816 }
817
822 const std::vector<BasePropertyArray*>& arrays() const { return parrays_; }
827 std::vector<BasePropertyArray*>& arrays() { return parrays_; }
828
829 private:
830 std::vector<BasePropertyArray*> parrays_;
831 size_t size_;
832 };
833
834} // namespace easy3d
835
836#endif // EASY3D_CORE_PROPERTIES_H
virtual ~BasePropertyArray()=default
Destructor.
virtual bool transfer(const BasePropertyArray &other, std::size_t from, std::size_t to)=0
Copies a property from one index to another.
const std::string & name() const
Returns the name of the property.
Definition property.h:130
virtual void swap(size_t i0, size_t i1)=0
Swaps the storage place of two elements.
virtual BasePropertyArray * clone() const =0
Returns a deep copy of the property array.
virtual void push_back()=0
Extend the number of elements by one.
virtual void reserve(size_t n)=0
Reserves memory for n elements.
virtual BasePropertyArray * empty_clone() const =0
Returns an empty copy of the property array.
virtual void resize(size_t n)=0
Resizes storage to hold n elements.
bool is_same(const BasePropertyArray &other) const
Tests if two properties are the same.
Definition property.h:143
virtual void copy(size_t from, size_t to)=0
Copies an element from one index to another.
virtual const std::type_info & type() const =0
Returns the type information of the property.
virtual void shrink_to_fit()=0
Free unused memory.
virtual void reset(size_t idx)=0
Resets an element to its default value.
virtual bool transfer(const BasePropertyArray &other)=0
Copies the entire properties from another property array.
BasePropertyArray(const std::string &name)
Default constructor.
Definition property.h:50
void set_name(const std::string &n)
Sets the name of the property.
Definition property.h:136
Implementation of a generic property array.
Definition property.h:164
std::vector< value_type > vector_type
The vector type of the property.
Definition property.h:167
void push_back() override
Extend the number of elements by one.
Definition property.h:191
const std::type_info & type() const override
Returns the type information of the property.
Definition property.h:253
T value_type
The value type of the property.
Definition property.h:166
reference operator[](size_t _idx)
Accesses the i-th element. No range check is performed.
Definition property.h:280
void swap(size_t i0, size_t i1) override
Swaps the storage place of two elements.
Definition property.h:228
void copy(size_t from, size_t to) override
Copies an element from one index to another.
Definition property.h:235
const T * data() const
Gets a pointer to the array (does not work for T == bool).
Definition property.h:261
BasePropertyArray * clone() const override
Returns a deep copy of the property array.
Definition property.h:240
PropertyArray(const std::string &name, T t=T())
Constructor.
Definition property.h:176
bool transfer(const BasePropertyArray &other, std::size_t from, std::size_t to) override
Copies a property from one index to another.
Definition property.h:211
BasePropertyArray * empty_clone() const override
Returns an empty copy of the property array.
Definition property.h:247
void reserve(size_t n) override
Reserves memory for n elements.
Definition property.h:181
void shrink_to_fit() override
Free unused memory.
Definition property.h:223
void reset(size_t idx) override
Resets an element to its default value.
Definition property.h:196
std::vector< T > & vector()
Gets a reference to the underlying vector.
Definition property.h:270
const_reference operator[](size_t _idx) const
Const access to the i-th element. No range check is performed.
Definition property.h:291
vector_type::const_reference const_reference
The const reference type of the property.
Definition property.h:169
void resize(size_t n) override
Resizes storage to hold n elements.
Definition property.h:186
vector_type::reference reference
The reference type of the property.
Definition property.h:168
bool transfer(const BasePropertyArray &other) override
Copies the entire properties from another property array.
Definition property.h:201
void shrink_to_fit() const
Frees unused space in all arrays.
Definition property.h:762
bool remove(const std::string &name)
Removes a property by its name.
Definition property.h:675
void copy_properties(const PropertyContainer &_rhs)
Copies properties that don't already exist from another container.
Definition property.h:519
void swap(size_t i0, size_t i1) const
Swaps elements i0 and i1 in all arrays.
Definition property.h:792
size_t size() const
Returns the current size of the property arrays.
Definition property.h:560
void swap(PropertyContainer &other) noexcept
Swaps content with another property container.
Definition property.h:802
Property< T > add(const std::string &name, const T t=T())
Adds a property with a given name and default value.
Definition property.h:587
bool transfer(const PropertyContainer &_rhs, std::size_t from, std::size_t to) const
Transfers one element with all properties.
Definition property.h:547
std::vector< BasePropertyArray * > & arrays()
Returns the vector of property arrays.
Definition property.h:827
virtual ~PropertyContainer()
Destructor. Deletes all property arrays.
Definition property.h:473
bool rename(const std::string &old_name, const std::string &new_name)
Renames a property.
Definition property.h:696
void resize(size_t n)
Resizes all arrays to size n.
Definition property.h:737
void reserve(size_t n) const
Reserves memory for n entries in all arrays.
Definition property.h:727
size_t n_properties() const
Returns the number of property arrays.
Definition property.h:566
PropertyContainer(const PropertyContainer &_rhs)
Copy constructor. Performs deep copy of property arrays.
Definition property.h:479
Property< T > get(const std::string &name) const
Gets a property by its name.
Definition property.h:613
PropertyContainer()
Default constructor.
Definition property.h:468
Property< T > get_or_add(const std::string &name, const T t=T())
Gets or adds a property by its name.
Definition property.h:628
const std::vector< BasePropertyArray * > & arrays() const
Returns the vector of property arrays (read-only).
Definition property.h:822
void reset(size_t idx) const
Resets an element to its default property values.
Definition property.h:782
void transfer(const PropertyContainer &_rhs) const
Transfers properties from another property container.
Definition property.h:503
bool remove(Property< T > &h)
Removes a property.
Definition property.h:654
void resize_property_array(size_t n)
Resizes the vector of properties to n, deleting all other properties.
Definition property.h:748
void clear()
Deletes all properties.
Definition property.h:715
std::vector< std::string > properties() const
Returns a vector of all property names.
Definition property.h:572
void push_back()
Adds a new element to each vector.
Definition property.h:771
const std::type_info & get_type(const std::string &name) const
Gets the type information of a property by its name.
Definition property.h:640
PropertyContainer & operator=(const PropertyContainer &_rhs)
Assignment operator. Performs deep copy of property arrays.
Definition property.h:486
void copy(size_t from, size_t to) const
Copies an element from one index to another in all arrays.
Definition property.h:812
Implementation of a generic property.
Definition property.h:326
const std::string & name() const
Returns the name of the property.
Definition property.h:436
virtual const_reference operator[](size_t i) const
Const access to the i-th element.
Definition property.h:376
const T * data() const
Gets a pointer to the array.
Definition property.h:386
const PropertyArray< T > & array() const
Const access to the property array.
Definition property.h:426
PropertyArray< T > & array()
Gets a reference to the property array.
Definition property.h:416
PropertyArray< T >::const_reference const_reference
The const reference type of the property.
Definition property.h:329
virtual ~Property()=default
Destructor.
virtual reference operator[](size_t i)
Accesses the i-th element.
Definition property.h:365
std::vector< T > & vector()
Gets a reference to the underlying vector.
Definition property.h:396
const std::vector< T > & vector() const
Const access to the underlying vector.
Definition property.h:406
Property(PropertyArray< T > *p=nullptr)
Constructor.
Definition property.h:338
void reset()
Resets the property.
Definition property.h:346
PropertyArray< T >::reference reference
The reference type of the property.
Definition property.h:328
void set_name(const std::string &n)
Sets the name of the property.
Definition property.h:445
Definition collider.cpp:182