Geogram Version 1.9.7
A programming library of geometric algorithms
Loading...
Searching...
No Matches
attributes.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40
41#ifndef GEOGRAM_BASIC_ATTRIBUTES
42#define GEOGRAM_BASIC_ATTRIBUTES
43
51
52#include <map>
53#include <typeinfo>
54#include <set>
55#include <type_traits>
56
62namespace GEO {
63
64 class AttributeStore;
65
70 class GEOGRAM_API AttributeStoreObserver {
71 public:
72
77 base_addr_(nullptr), size_(0), dimension_(0),
78 disconnected_(false) {
79 }
80
88 void notify(
89 Memory::pointer base_addr, index_t size, index_t dim
90 ) {
91 base_addr_ = base_addr;
92 size_ = size;
93 dimension_ = dim;
94 }
95
100 index_t size() const {
101 return size_;
102 }
103
109 return dimension_;
110 }
111
119 return size_ * dimension_;
120 }
121
127 return base_addr_;
128 }
129
135
141
149 void disconnect() {
150 base_addr_ = nullptr;
151 size_ = 0;
152 dimension_ = 0;
153 disconnected_ = true;
154 }
155
162 bool disconnected() const {
163 return disconnected_;
164 }
165
166 protected:
167 Memory::pointer base_addr_;
168 index_t size_;
169 index_t dimension_;
170 bool disconnected_;
171 };
172
173
174 /*********************************************************************/
175
176
181 class GEOGRAM_API AttributeStoreCreator : public Counted {
182 public:
183
188
195
203 virtual bool elements_are_trivially_copyable() const = 0;
204
205 private:
206 std::string element_type_name_;
207 std::string element_typeid_name_;
208 };
209
215
221 class GEOGRAM_API AttributeStore {
222 public:
232 AttributeStore(size_t elemsize, index_t dim=1);
233
238
239
250 const std::string& type_name
251 ) const = 0;
252
258 virtual std::string element_typeid_name() const = 0;
259
264 index_t size() const {
265 return cached_size_;
266 }
267
274 return cached_capacity_;
275 }
276
281 virtual void resize(index_t new_size) = 0;
282
288 virtual void reserve(index_t new_capacity) = 0;
289
295 virtual void clear(bool keep_memory = false) = 0;
296
302 bool has_observers() const {
303 return !observers_.empty();
304 }
305
312 return dimension_;
313 }
314
324 virtual void redim(index_t dim) = 0;
325
326
342 virtual void apply_permutation(
343 const vector<index_t>& permutation
344 );
345
346
362 virtual void compress(const vector<index_t>& old2new);
363
368 virtual void zero();
369
375 virtual AttributeStore* clone() const = 0;
376
377
383 void copy_item(index_t to, index_t from) {
384 geo_debug_assert(from < cached_size_);
385 geo_debug_assert(to < cached_size_);
386 size_t item_size = element_size_ * dimension_;
387 if(lifecycle_.is_null()) {
388 Memory::copy(
389 cached_base_addr_+to*item_size,
390 cached_base_addr_+from*item_size,
391 item_size
392 );
393 } else {
394 lifecycle_->assign(
395 cached_base_addr_+to*item_size,
396 cached_base_addr_+from*item_size
397 );
398 }
399 }
400
406 geo_debug_assert(to < cached_size_);
407 size_t item_size = element_size_ * dimension_;
408 if(lifecycle_.is_null()) {
409 Memory::clear(
410 cached_base_addr_+to*item_size,
411 item_size
412 );
413 } else {
414 lifecycle_->reset(cached_base_addr_+to*item_size);
415 }
416 }
417
425 virtual void scale_item(index_t to, double s);
426
435 virtual void madd_item(index_t to, double s, index_t from);
436
442
447 void* data() {
448 return cached_base_addr_;
449 }
450
455 const void* data() const {
456 return cached_base_addr_;
457 }
458
463 size_t element_size() const {
464 return element_size_;
465 }
466
476 const std::string& element_type_name
477 ) {
478 return (
479 type_name_to_creator_.find(element_type_name) !=
480 type_name_to_creator_.end()
481 );
482 }
483
493 const std::string& element_typeid_name
494 ) {
495 return (
496 typeid_name_to_type_name_.find(element_typeid_name) !=
497 typeid_name_to_type_name_.end()
498 );
499 }
500
511 const std::string& element_type_name
512 ) {
513 geo_debug_assert(element_type_name_is_known(element_type_name));
514 return (
515 type_name_to_creator_[
516 element_type_name
517 ]->elements_are_trivially_copyable()
518 );
519 }
520
531 const std::string& element_typeid_name
532 ) {
533 geo_debug_assert(element_typeid_name_is_known(element_typeid_name));
534 std::string element_type_name =
535 typeid_name_to_type_name_[element_typeid_name];
536 return element_by_type_name_is_trivially_copyable(element_type_name);
537 }
538
546 const std::string& element_type_name,
547 index_t dimension
548 ) {
549 geo_assert(element_type_name_is_known(element_type_name));
550 return type_name_to_creator_[element_type_name]->
551 create_attribute_store(dimension);
552 }
553
562 const std::string& element_typeid_name
563 ) {
564 geo_assert(element_typeid_name_is_known(element_typeid_name));
565 return typeid_name_to_type_name_[element_typeid_name];
566 }
567
577 const std::string& element_type_name
578 ) {
579 geo_assert(element_type_name_is_known(element_type_name));
580 return type_name_to_typeid_name_[element_type_name];
581 }
582
594 AttributeStoreCreator* creator,
595 const std::string& element_type_name,
596 const std::string& element_typeid_name
597 );
598
607 return lifecycle_;
608 }
609
610 protected:
611
618 const vector<index_t>& permutation
619 );
620
629 virtual void notify(
630 Memory::pointer base_addr, index_t size, index_t dim
631 );
632
642
651
652
653 protected:
654 size_t element_size_;
655 index_t dimension_;
656 Memory::pointer cached_base_addr_;
657 index_t cached_size_;
658 index_t cached_capacity_;
659 LifeCycle_var lifecycle_;
660 std::set<AttributeStoreObserver*> observers_;
661 Process::spinlock lock_;
662
663 static std::map<std::string, AttributeStoreCreator_var>
664 type_name_to_creator_;
665
666 static std::map<std::string, std::string>
667 typeid_name_to_type_name_;
668
669 static std::map<std::string, std::string>
670 type_name_to_typeid_name_;
671
672 friend class AttributeStoreObserver;
673 };
674
675 /*********************************************************************/
676
682 template <class T> class TypedAttributeStore : public AttributeStore {
683 public:
684
692 AttributeStore(sizeof(T),dim) {
693 if(!std::is_trivially_copyable<T>::value) {
694 lifecycle_ = new GenericLifeCycle<T>();
695 }
696 }
697
698 void resize(index_t new_size) override {
699 store_.resize(new_size*dimension_);
700 notify(
701 store_.empty() ? nullptr : Memory::pointer(store_.data()),
702 new_size,
703 dimension_
704 );
705 }
706
707 void reserve(index_t new_capacity) override {
708 if(new_capacity > capacity()) {
709 store_.reserve(new_capacity*dimension_);
710 cached_capacity_ = new_capacity;
711 notify(
712 store_.empty() ? nullptr : Memory::pointer(store_.data()),
713 size(),
714 dimension_
715 );
716 }
717 }
718
719 void clear(bool keep_memory=false) override {
720 if(keep_memory) {
721 store_.resize(0);
722 } else {
723 store_.clear();
724 }
725 notify(nullptr, 0, dimension_);
726 }
727
728 void redim(index_t dim) override {
729 if(dim == dimension()) {
730 return;
731 }
732 vector<T> new_store(size()*dim);
733 new_store.reserve(capacity()*dim);
734 index_t copy_dim = std::min(dim, dimension());
735 for(index_t i = 0; i < size(); ++i) {
736 for(index_t c = 0; c < copy_dim; ++c) {
737 new_store[dim * i + c] = store_[dimension_ * i + c];
738 }
739 }
740 store_.swap(new_store);
741 notify(
742 store_.empty() ? nullptr : Memory::pointer(store_.data()),
743 size(),
744 dim
745 );
746 }
747
748 bool elements_type_matches(const std::string& type_name) const override {
749 return type_name == typeid(T).name();
750 }
751
752 std::string element_typeid_name() const override {
753 return typeid(T).name();
754 }
755
756 AttributeStore* clone() const override {
757 TypedAttributeStore<T>* result =
759 result->resize(size());
760 result->store_ = store_;
761 result->lifecycle_ = lifecycle_;
762 return result;
763 }
764
765 vector<T>& get_vector() {
766 return store_;
767 }
768
769 void scale_item(index_t to, double s) override {
770 geo_assert(to < size());
771 for(index_t i=0; i<dimension_; ++i) {
772 scale_value(store_[to*dimension_+i], s);
773 }
774 }
775
776 void madd_item(index_t to, double s, index_t from) override {
777 geo_assert(from < size());
778 geo_assert(to < size());
779 for(index_t i=0; i<dimension_; ++i) {
780 madd_value(
781 store_[to*dimension_+i], s, store_[from*dimension_+i]
782 );
783 }
784 }
785
786 protected:
787 void notify(
788 Memory::pointer base_addr, index_t size, index_t dim
789 ) override {
790 AttributeStore::notify(base_addr, size, dim);
791 geo_assert(size*dim <= store_.size());
792 }
793
794 template<class TT> static void scale_value(TT& to, double s) {
795 geo_argused(to);
796 geo_argused(s);
797 }
798
799 static void scale_value(uint8_t& to, double s) {
800 to = uint8_t(double(to)*s != 0.0);
801 }
802
803 static void scale_value(int32_t& to, double s) {
804 to = int32_t(double(to)*s);
805 }
806
807 static void scale_value(uint32_t& to, double s) {
808 to = uint32_t(double(to)*s);
809 }
810
811 static void scale_value(float& to, double s) {
812 to = float(double(to)*s);
813 }
814
815 static void scale_value(double& to, double s) {
816 to *= s;
817 }
818
819 template<class TT> static void madd_value(TT& to, double s, TT& from) {
820 geo_argused(to);
821 geo_argused(s);
822 geo_argused(from);
823 }
824
825 static void madd_value(uint8_t& to, double s, uint8_t& from) {
826 to = uint8_t(double(to) + s*double(from) != 0.0);
827 }
828
829 static void madd_value(int32_t& to, double s, int32_t& from) {
830 to = int32_t(double(to) + s*double(from));
831 }
832
833 static void madd_value(uint32_t& to, double s, uint32_t& from) {
834 to = uint32_t(double(to) + s*double(from));
835 }
836
837 static void madd_value(float& to, double s, float& from) {
838 to = float(double(to) + s*double(from));
839 }
840
841 static void madd_value(double& to, double s, double& from) {
842 to += s*from;
843 }
844
845
846 private:
847 vector<T> store_;
848 };
849
850 /*********************************************************************/
851
856 template <class T>
858 public:
863 return new TypedAttributeStore<T>(dim);
864 }
865
869 bool elements_are_trivially_copyable() const override {
870 return(std::is_trivially_copyable<T>::value);
871 }
872 };
873
874 /*********************************************************************/
875
880 template <class T> class geo_register_attribute_type {
881 public:
891 geo_register_attribute_type(const std::string& type_name) {
893 new TypedAttributeStoreCreator<T>, type_name, typeid(T).name()
894 );
895 if(type_name == "bool") {
897 type_name,
900 );
901 } else {
903 type_name,
904 read_ascii_attribute<T>,
905 write_ascii_attribute<T>
906 );
907 }
908 }
909 };
910
911 /*********************************************************************/
912
917 class GEOGRAM_API AttributesManager {
918 public:
923
924
929
935 index_t nb() const {
936 return index_t(attributes_.size());
937 }
938
945
952 index_t size() const {
953 return size_;
954 }
955
962 return capacity_;
963 }
964
971 void resize(index_t new_size);
972
979 void reserve(index_t new_capacity);
980
989 void clear(bool keep_attributes, bool keep_memory = false);
990
991
995 void zero();
996
1005 void bind_attribute_store(const std::string& name, AttributeStore* as);
1006
1013 AttributeStore* find_attribute_store(const std::string& name);
1014
1022 const std::string& name
1023 ) const;
1024
1025
1032 bool is_defined(const std::string& name) const {
1033 return (find_attribute_store(name) != nullptr);
1034 }
1035
1041 void delete_attribute_store(const std::string& name);
1042
1049
1066 const vector<index_t>& permutation
1067 );
1068
1084 void compress(const vector<index_t>& old2new);
1085
1090 void copy(const AttributesManager& rhs);
1091
1092
1099 void copy_item(index_t to, index_t from);
1100
1107
1108
1114
1122 void scale_item(index_t to, double s);
1123
1132 void madd_item(index_t to, double s, index_t from);
1133
1143 const std::string& name, const std::string& new_name
1144 );
1145
1155 const std::string& old_name, const std::string& new_name
1156 );
1157
1158 private:
1166 AttributesManager(const AttributesManager& rhs) = delete;
1167
1175 const AttributesManager& operator=(const AttributesManager& rhs) = delete;
1176
1177 private:
1178 index_t size_;
1179 index_t capacity_;
1180 std::map<std::string, AttributeStore*> attributes_;
1181 } ;
1182
1183
1184 /*********************************************************************/
1185
1186
1191 template <class T> class AttributeBase : public AttributeStoreObserver {
1192 public:
1193
1198 manager_(nullptr),
1199 store_(nullptr) {
1200 }
1201
1211 AttributeBase(AttributesManager& manager, const std::string& name) :
1212 manager_(nullptr),
1213 store_(nullptr) {
1214 bind(manager, name);
1215 }
1216
1222 bool is_bound() const {
1223 return (store_ != nullptr && !disconnected_);
1224 }
1225
1230 void unbind() {
1232 // If the AttributesManager was destroyed before, do not
1233 // do anything. This can occur in Lua scripting when using
1234 // Attribute wrapper objects.
1235 if(!disconnected_) {
1236 unregister_me(store_);
1237 }
1238 manager_ = nullptr;
1239 store_ = nullptr;
1240 }
1241
1251 void bind(AttributesManager& manager, const std::string& name) {
1252 geo_assert(!is_bound());
1253 manager_ = &manager;
1254 store_ = manager_->find_attribute_store(name);
1255 if(store_ == nullptr) {
1256 store_ = new TypedAttributeStore<T>();
1257 manager_->bind_attribute_store(name,store_);
1258 } else {
1259 geo_assert(store_->elements_type_matches(typeid(T).name()));
1260 }
1261 register_me(store_);
1262 }
1263
1264
1274 AttributesManager& manager, const std::string& name
1275 ) {
1276 geo_assert(!is_bound());
1277 manager_ = &manager;
1278 store_ = manager_->find_attribute_store(name);
1279 if(store_ != nullptr) {
1280 geo_assert(store_->elements_type_matches(typeid(T).name()));
1281 register_me(store_);
1282 return true;
1283 }
1284 return false;
1285 }
1286
1296 AttributesManager& manager, const std::string& name
1297 ) {
1298 if( is_bound() ) {
1299 unbind();
1300 }
1301 store_ = manager.find_attribute_store(name);
1302 if(store_ != nullptr) {
1303 if( !store_->elements_type_matches(typeid(T).name()) ) {
1304 store_ = nullptr;
1305 return false;
1306 }
1307 manager_ = &manager;
1308 register_me(store_);
1309 return true;
1310 }
1311 return false;
1312 }
1313
1322 const std::string& name,
1324 ) {
1325 geo_assert(!is_bound());
1326 manager_ = &manager;
1327 geo_assert(manager_->find_attribute_store(name) == nullptr);
1328 store_ = new TypedAttributeStore<T>(dimension);
1329 manager_->bind_attribute_store(name,store_);
1330 register_me(store_);
1331 }
1332
1339 void destroy() {
1341 unregister_me(store_);
1342 manager_->delete_attribute_store(store_);
1343 store_ = nullptr;
1344 manager_ = nullptr;
1345 }
1346
1356 void redim(index_t new_dim) {
1358 store_->redim(new_dim);
1359 }
1360
1369 if(is_bound()) {
1370 unbind();
1371 }
1372 }
1373
1374
1382 static bool is_defined(
1383 AttributesManager& manager, const std::string& name,
1384 index_t dim = 0
1385 ) {
1387 return (
1388 store != nullptr &&
1389 store->elements_type_matches(typeid(T).name()) &&
1390 ((dim == 0) || (store->dimension() == dim))
1391 );
1392 }
1393
1398 index_t size() const {
1399 return size_;
1400 }
1401
1406 void zero() {
1408 store_->zero();
1409 }
1410
1421 return(
1422 dynamic_cast<TypedAttributeStore<T>*>(store_) != nullptr
1423 );
1424 }
1425
1437 TypedAttributeStore<T>* typed_store =
1438 dynamic_cast<TypedAttributeStore<T>*>(store_);
1439 geo_assert(typed_store != nullptr);
1440 return typed_store->get_vector();
1441 }
1442
1449 const vector<T>& get_vector() const {
1450 TypedAttributeStore<T>* typed_store =
1451 dynamic_cast<TypedAttributeStore<T>*>(store_);
1452 geo_assert(typed_store != nullptr);
1453 return typed_store->get_vector();
1454 }
1455
1461 return manager_;
1462 }
1463
1464 protected:
1465 AttributesManager* manager_;
1466 AttributeStore* store_;
1467 } ;
1468
1469 /*********************************************************************/
1470
1477 template <class T> class Attribute : public AttributeBase<T> {
1478 public:
1480
1485 }
1486
1496 Attribute(AttributesManager& manager, const std::string& name) :
1497 superclass(manager, name) {
1498 }
1499
1508 return ((T*)(void*)superclass::base_addr_)[i];
1509 }
1510
1516 const T& operator[](index_t i) const {
1519 return ((const T*)(void*)superclass::base_addr_)[i];
1520 }
1521
1527 void fill(const T& val) {
1529 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1530 (*this)[i] = val;
1531 }
1532 }
1533
1540 void copy(const Attribute<T>& rhs) {
1541 geo_assert(rhs.size() == superclass::size());
1543 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1544 (*this)[i] = rhs[i];
1545 }
1546 }
1547
1552 T* data() {
1553 return (T*)AttributeStoreObserver::base_addr_;
1554 }
1555
1560 const T* data() const {
1561 return (const T*)AttributeStoreObserver::base_addr_;
1562 }
1563
1564
1565 private:
1569 Attribute(const Attribute<T>& rhs) = delete;
1573 Attribute<T>& operator=(const Attribute<T>& rhs) = delete;
1574 };
1575
1576 /*********************************************************************/
1577
1586 template <> class Attribute<bool> : public AttributeBase<Numeric::uint8> {
1587 public:
1589
1590 Attribute() : superclass() {
1591 }
1592
1593 Attribute(AttributesManager& manager, const std::string& name) :
1594 superclass(manager,name) {
1595 }
1596
1597 class BoolAttributeAccessor;
1598
1599
1604 class ConstBoolAttributeAccessor {
1605 public:
1610 const Attribute<bool>& attribute,
1611 index_t index
1612 ) :
1613 attribute_(&attribute),
1614 index_(index) {
1615 }
1616
1621 operator bool() const {
1622 return (attribute_->element(index_) != 0);
1623 }
1624
1625 private:
1626 const Attribute<bool>* attribute_;
1627 index_t index_;
1628
1629 friend class BoolAttributeAccessor;
1630 };
1631
1636 class BoolAttributeAccessor {
1637 public:
1642 Attribute<bool>& attribute,
1643 index_t index
1644 ) :
1645 attribute_(&attribute),
1646 index_(index) {
1647 }
1648
1653 operator bool() const {
1654 return (attribute_->element(index_) != 0);
1655 }
1656
1662 BoolAttributeAccessor(const BoolAttributeAccessor& rhs) {
1663 attribute_ = rhs.attribute_;
1664 index_ = rhs.index_;
1665 }
1666
1671 BoolAttributeAccessor& operator=(bool x) {
1672 attribute_->element(index_) = Numeric::uint8(x);
1673 return *this;
1674 }
1675
1681 BoolAttributeAccessor& operator=(
1682 const BoolAttributeAccessor& rhs
1683 ) {
1684 if(&rhs != this) {
1685 attribute_->element(index_) =
1686 rhs.attribute_->element(rhs.index_);
1687 }
1688 return *this;
1689 }
1690
1696 BoolAttributeAccessor& operator=(
1697 const ConstBoolAttributeAccessor& rhs
1698 ) {
1699 attribute_->element(index_) =
1700 rhs.attribute_->element(rhs.index_);
1701 return *this;
1702 }
1703
1704 private:
1705 Attribute<bool>* attribute_;
1706 index_t index_;
1707 };
1708
1709
1710 BoolAttributeAccessor operator[](index_t i) {
1711 return BoolAttributeAccessor(*this,i);
1712 }
1713
1714 ConstBoolAttributeAccessor operator[](index_t i) const {
1715 return ConstBoolAttributeAccessor(*this,i);
1716 }
1717
1723 void fill(bool val) {
1724 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1725 element(i) = Numeric::uint8(val);
1726 }
1727 }
1728
1735 void copy(const Attribute<bool>& rhs) {
1736 geo_assert(rhs.size() == superclass::size());
1738 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1739 element(i) = rhs.element(i);
1740 }
1741 }
1742
1743 protected:
1744
1745 friend class BoolAttributeAccessor;
1746 friend class ConstBoolAttributeAccessor;
1747
1755 return ((Numeric::uint8*)superclass::base_addr_)[i];
1756 }
1757
1765 return ((const Numeric::uint8*)superclass::base_addr_)[i];
1766 }
1767
1768 private:
1772 Attribute(const Attribute<bool>& rhs) = delete;
1776 Attribute<bool>& operator=(const Attribute<bool>& rhs) = delete;
1777 } ;
1778
1779 /***********************************************************/
1780
1785 class GEOGRAM_API ScalarAttributeAdapterBase :
1786 public AttributeStoreObserver {
1787
1788 public:
1793 ET_NONE=0,
1794 ET_UINT8=1,
1795 ET_INT8=2,
1796 ET_UINT32=3,
1797 ET_INT32=4,
1798 ET_FLOAT32=5,
1799 ET_FLOAT64=6,
1800 ET_VEC2=7,
1801 ET_VEC3=8
1802 };
1803
1804
1809 class Accessor {
1810 public:
1811 Accessor(
1812 ScalarAttributeAdapterBase& attribute,
1813 index_t index
1814 ) : attribute_(attribute), index_(index) {
1815 }
1816
1817 operator double() const {
1818 return attribute_.get_element_as_double(index_);
1819 }
1820
1821 void operator=(double x) {
1822 attribute_.set_element_as_double(index_, x);
1823 }
1824
1825 private:
1826 ScalarAttributeAdapterBase& attribute_;
1827 index_t index_;
1828 };
1829
1835 public:
1837 const ScalarAttributeAdapterBase& attribute,
1838 index_t index
1839 ) : attribute_(attribute), index_(index) {
1840 }
1841
1842 operator double() const {
1843 return attribute_.get_element_as_double(index_);
1844 }
1845
1846 private:
1847 const ScalarAttributeAdapterBase& attribute_;
1848 index_t index_;
1849 };
1850
1855 manager_(nullptr),
1856 store_(nullptr),
1857 element_type_(ET_NONE),
1858 element_index_(index_t(-1)) {
1859 }
1860
1871 const AttributesManager& manager, const std::string& name
1872 ) :
1873 manager_(nullptr),
1874 store_(nullptr) {
1875 bind_if_is_defined(manager, name);
1876 }
1877
1883 bool is_bound() const {
1884 return (store_ != nullptr);
1885 }
1886
1891 void unbind() {
1892 geo_assert(is_bound());
1893 unregister_me(const_cast<AttributeStore*>(store_));
1894 manager_ = nullptr;
1895 store_ = nullptr;
1896 element_type_ = ET_NONE;
1897 element_index_ = index_t(-1);
1898 }
1899
1910 const AttributesManager& manager, const std::string& name
1911 );
1912
1921 if(is_bound()) {
1922 unbind();
1923 }
1924 }
1925
1935 static bool is_defined(
1936 const AttributesManager& manager, const std::string& name
1937 );
1938
1943 index_t size() const {
1944 return (store_ == nullptr) ? 0 : store_->size();
1945 }
1946
1955 return element_type_;
1956 }
1957
1965 return element_index_;
1966 }
1967
1973 return store_;
1974 }
1975
1976
1984 static bool can_be_bound_to(const AttributeStore* store) {
1985 return element_type(store) != ET_NONE;
1986 }
1987
1996
1997 protected:
2006 static std::string attribute_base_name(const std::string& name);
2007
2016 static index_t attribute_element_index(const std::string& name);
2017
2026
2035 double result = 0.0;
2036 switch(element_type()) {
2037 case ET_UINT8:
2038 result = double(get_element<Numeric::uint8>(i));
2039 break;
2040 case ET_INT8:
2041 result = double(get_element<Numeric::int8>(i));
2042 break;
2043 case ET_UINT32:
2044 result = double(get_element<Numeric::uint32>(i));
2045 break;
2046 case ET_INT32:
2047 result = double(get_element<Numeric::int32>(i));
2048 break;
2049 case ET_FLOAT32:
2050 result = double(get_element<Numeric::float32>(i));
2051 break;
2052 case ET_FLOAT64:
2053 result = double(get_element<Numeric::float64>(i));
2054 break;
2055 case ET_VEC2:
2056 result = double(get_element<Numeric::float64>(i,2));
2057 break;
2058 case ET_VEC3:
2059 result = double(get_element<Numeric::float64>(i,3));
2060 break;
2061 case ET_NONE:
2063 }
2064 return result;
2065 }
2066
2075 template <class T> T get_element(index_t i,index_t multiplier=1) const {
2076 geo_debug_assert(is_bound());
2077 geo_debug_assert(i < size());
2078 return static_cast<const T*>(store_->data())[
2079 (i * store_->dimension() * multiplier) +
2080 element_index_
2081 ];
2082 }
2083
2090 double set_element_as_double(index_t i, double value) {
2091 double result = 0.0;
2092 switch(element_type()) {
2093 case ET_UINT8:
2094 set_element<Numeric::uint8>(Numeric::uint8(value), i);
2095 break;
2096 case ET_INT8:
2097 set_element<Numeric::int8>(Numeric::int8(value),i);
2098 break;
2099 case ET_UINT32:
2100 set_element<Numeric::uint32>(Numeric::uint32(value),i);
2101 break;
2102 case ET_INT32:
2103 set_element<Numeric::int32>(Numeric::int32(value),i);
2104 break;
2105 case ET_FLOAT32:
2106 set_element<Numeric::float32>(Numeric::float32(value),i);
2107 break;
2108 case ET_FLOAT64:
2109 set_element<Numeric::float64>(Numeric::float64(value),i);
2110 break;
2111 case ET_VEC2:
2112 set_element<Numeric::float64>(Numeric::float64(value),i,2);
2113 break;
2114 case ET_VEC3:
2115 set_element<Numeric::float64>(Numeric::float64(value),i,3);
2116 break;
2117 case ET_NONE:
2119 }
2120 return result;
2121 }
2122
2132 template <class T> void set_element(
2133 T value, index_t i, index_t multiplier=1
2134 ) const {
2135 geo_debug_assert(is_bound());
2136 geo_debug_assert(i < size());
2137 const_cast<T*>(static_cast<const T*>(store_->data()))[
2138 (i * store_->dimension() * multiplier) +
2139 element_index_
2140 ] = value;
2141 }
2142
2143 protected:
2144 const AttributesManager* manager_;
2145 const AttributeStore* store_;
2146 ElementType element_type_;
2147 index_t element_index_;
2148 };
2149
2150 /***********************************************************/
2151
2157 public:
2159 }
2160
2162 const AttributesManager& manager, const std::string& name
2163 ) : ScalarAttributeAdapterBase(manager, name) {
2164 }
2165
2174 return get_element_as_double(i);
2175 }
2176 };
2177
2178 /***********************************************************/
2179
2185 public:
2187 }
2188
2190 const AttributesManager& manager, const std::string& name
2191 ) : ScalarAttributeAdapterBase(manager, name) {
2192 }
2193
2194 Accessor operator[](index_t i) {
2195 return Accessor(*this, i);
2196 }
2197
2198 ConstAccessor operator[](index_t i) const {
2199 return ConstAccessor(*this, i);
2200 }
2201
2202 protected:
2203 };
2204
2205
2206}
2207
2208#endif
#define geo_assert_not_reached
Sets a non reachable point in the program.
Definition assert.h:177
#define geo_assert(x)
Verifies that a condition is met.
Definition assert.h:149
#define geo_debug_assert(x)
Verifies that a condition is met.
Definition assert.h:196
Base class for Attributes, that manipulates an attribute stored in an AttributesManager.
void create_vector_attribute(AttributesManager &manager, const std::string &name, index_t dimension)
Creates and binds a new vector attribute.
AttributesManager * manager() const
Gets the AttributesManager this Attribute is bound to.
~AttributeBase()
Attribute destructor.
index_t size() const
Gets the size.
AttributeBase(AttributesManager &manager, const std::string &name)
Creates or retrieves a persistent attribute attached to a given AttributesManager.
const vector< T > & get_vector() const
Gets a const reference to the internal vector<T> used to store the attribute.
void zero()
Sets all the elements of this Attribute to zero.
bool is_bound() const
Tests whether an Attribute is bound.
void unbind()
Unbinds this Attribute.
void redim(index_t new_dim)
Sets the dimension.
void destroy()
Destroys this attribute in the AttributesManager.
vector< T > & get_vector()
Gets a reference to the internal vector<T> used to store the attribute.
bool bind_if_is_compatible(AttributesManager &manager, const std::string &name)
Binds this Attribute to an AttributesManager if it already exists in the AttributesManager and types ...
static bool is_defined(AttributesManager &manager, const std::string &name, index_t dim=0)
Tests whether an attribute with the specified name and with corresponding type exists in an Attribute...
bool can_get_vector()
Tests whether get_vector() can be called on this Attribute.
AttributeBase()
Creates an uninitialized (unbound) Attribute.
void bind(AttributesManager &manager, const std::string &name)
Binds this Attribute to an AttributesManager.
bool bind_if_is_defined(AttributesManager &manager, const std::string &name)
Binds this Attribute to an AttributesManager if it already exists in the AttributesManager.
Internal class for creating an AttributeStore from the type name of its elements.
Definition attributes.h:181
~AttributeStoreCreator() override
AttributeStoreCreator destructor.
virtual bool elements_are_trivially_copyable() const =0
Tests whether elements of this attribute can be trivially copyable.
virtual AttributeStore * create_attribute_store(index_t dimension)=0
Creates a new attribute store.
Base class for attributes. They are notified whenever the AttributeStore is modified.
Definition attributes.h:70
AttributeStoreObserver()
Creates a new uninitialied AttributeStore.
Definition attributes.h:76
void register_me(AttributeStore *store)
Registers this observer to an AttributeStore.
index_t size() const
Gets the size.
Definition attributes.h:100
void notify(Memory::pointer base_addr, index_t size, index_t dim)
Callback function, called by the AttributeStore whenever it is modified.
Definition attributes.h:88
index_t nb_elements() const
Gets the total number of elements.
Definition attributes.h:118
bool disconnected() const
Tests whether this AttributeStoreObserver was disconnected.
Definition attributes.h:162
void disconnect()
Disconnects this AttributeStoreObserver from its AttributeStore.
Definition attributes.h:149
void unregister_me(AttributeStore *store)
Unregisters this observer from an AttributeStore.
index_t dimension() const
Gets the dimension.
Definition attributes.h:108
Memory::pointer base_addr() const
Gets a pointer to the storage.
Definition attributes.h:126
Notifies a set of AttributeStoreObservers each time the stored array changes size and/or base address...
Definition attributes.h:221
void * data()
Gets a pointer to the stored data.
Definition attributes.h:447
static AttributeStore * create_attribute_store_by_element_type_name(const std::string &element_type_name, index_t dimension)
Creates an attribute store of a given type.
Definition attributes.h:545
bool has_observers() const
Tests whether observers listen to this AttributeStore.
Definition attributes.h:302
void zero_item(index_t to)
Sets an item to zero.
Definition attributes.h:405
virtual ~AttributeStore()
AttributeStore destructor.
static std::string element_typeid_name_by_element_type_name(const std::string &element_type_name)
Gets an element mangled type name from its C++ name.
Definition attributes.h:576
static void register_attribute_creator(AttributeStoreCreator *creator, const std::string &element_type_name, const std::string &element_typeid_name)
Registers a new element type.
index_t size() const
Gets the size.
Definition attributes.h:264
const void * data() const
Gets a pointer to the stored data.
Definition attributes.h:455
virtual void clear(bool keep_memory=false)=0
Resizes this AttributeStore to 0.
virtual void notify(Memory::pointer base_addr, index_t size, index_t dim)
If size or base address differ from the cached values, notify all the observers, and update the cache...
AttributeStore(size_t elemsize, index_t dim=1)
AttributeStore constructor.
index_t capacity() const
Gets the capacity.
Definition attributes.h:273
virtual void madd_item(index_t to, double s, index_t from)
Adds a scaled item to another item \detais item[to] += s * item[from].
static bool element_by_typeid_name_is_trivially_copyable(const std::string &element_typeid_name)
Tests whether an element type is trivially copyable.
Definition attributes.h:530
static bool element_type_name_is_known(const std::string &element_type_name)
Tests whether a given element type is registered in the system.
Definition attributes.h:475
void apply_permutation_with_lifecycle(const vector< index_t > &permutation)
implementation of apply_permutation() used when there is a lifecycle, that is, when attribute type is...
virtual void compress(const vector< index_t > &old2new)
Compresses the stored attributes, by applying an index mapping that fills-in the gaps.
LifeCycle * lifecycle() const
Gets the LifeCycle.
Definition attributes.h:606
virtual std::string element_typeid_name() const =0
Gets the typeid name of the element type stored in this AttributeStore.
void copy_item(index_t to, index_t from)
Copies an item.
Definition attributes.h:383
virtual AttributeStore * clone() const =0
Creates a new AttributeStore that is a carbon copy of this AttributeStore.
static bool element_typeid_name_is_known(const std::string &element_typeid_name)
Tests whether a given element type is registered in the system.
Definition attributes.h:492
void register_observer(AttributeStoreObserver *observer)
Registers an observer.
virtual void apply_permutation(const vector< index_t > &permutation)
Applies a permutation to the stored attributes.
virtual void resize(index_t new_size)=0
Resizes this AttributeStore.
virtual void scale_item(index_t to, double s)
Scales an item.
void unregister_observer(AttributeStoreObserver *observer)
Unregisters an observer.
virtual void redim(index_t dim)=0
Sets the dimension.
index_t dimension() const
Gets the dimension.
Definition attributes.h:311
static std::string element_type_name_by_element_typeid_name(const std::string &element_typeid_name)
Gets an element type name from its mangled name.
Definition attributes.h:561
virtual bool elements_type_matches(const std::string &type_name) const =0
Tests whether this AttributeStore stores elements of a given type.
void swap_items(index_t i, index_t j)
Swaps two items.
static bool element_by_type_name_is_trivially_copyable(const std::string &element_type_name)
Tests whether an element type is trivially copyable.
Definition attributes.h:510
size_t element_size() const
Gets the element size.
Definition attributes.h:463
virtual void reserve(index_t new_capacity)=0
Reserves memory.
virtual void zero()
Zeroes all the memory associated with this AttributeStore.
BoolAttributeAccessor(Attribute< bool > &attribute, index_t index)
BoolAttributeAccessor constructor.
BoolAttributeAccessor & operator=(const BoolAttributeAccessor &rhs)
Copies a bool from another attribute.
BoolAttributeAccessor & operator=(const ConstBoolAttributeAccessor &rhs)
Copies a bool from another attribute.
BoolAttributeAccessor & operator=(bool x)
Assigns a bool to a BoolAttributeAccessor.
BoolAttributeAccessor(const BoolAttributeAccessor &rhs)
Copy-constructor.
ConstBoolAttributeAccessor(const Attribute< bool > &attribute, index_t index)
ConstBoolAttributeAccessor constructor.
Numeric::uint8 & element(index_t i)
Gets a modifiable element by index.
void fill(bool val)
Sets all the elements in this attribute to a specified value.
const Numeric::uint8 & element(index_t i) const
Gets an element by index.
void copy(const Attribute< bool > &rhs)
Copies all the values from another attribute.
Manages an attribute attached to a set of object.
Attribute(AttributesManager &manager, const std::string &name)
Creates or retrieves a persistent attribute attached to a given AttributesManager.
const T & operator[](index_t i) const
Gets an element by index.
Attribute()
Creates an uninitialized (unbound) Attribute.
T * data()
Gets the pointer to the data.
void fill(const T &val)
Sets all the elements in this attribute to a specified value.
const T * data() const
Gets the pointer to the data.
T & operator[](index_t i)
Gets a modifiable element by index.
void copy(const Attribute< T > &rhs)
Copies all the values from another attribute.
Managers a set of attributes attached to an object.
Definition attributes.h:917
void delete_attribute_store(AttributeStore *as)
Deletes an AttributeStore.
void compress(const vector< index_t > &old2new)
Compresses the stored attributes, by applying an index mapping that fills-in the gaps.
void zero_item(index_t to)
Sets an item to zero.
void copy(const AttributesManager &rhs)
Copies all the attributes from another AttributesManager.
AttributesManager()
Constructs a new empty AttributesManager.
index_t nb() const
Gets the number of attributes.
Definition attributes.h:935
bool rename_attribute(const std::string &old_name, const std::string &new_name)
Renames an attribute.
void scale_item(index_t to, double s)
Scales an item.
const AttributeStore * find_attribute_store(const std::string &name) const
Finds an AttributeStore by name.
void apply_permutation(const vector< index_t > &permutation)
Applies a permutation to the stored attributes.
AttributeStore * find_attribute_store(const std::string &name)
Finds an AttributeStore by name.
void bind_attribute_store(const std::string &name, AttributeStore *as)
Binds an AttributeStore with the specified name. Ownership of this AttributeStore is transferred to t...
void list_attribute_names(vector< std::string > &names) const
Gets the names of all the attributes in this AttributeStore.
~AttributesManager()
AttributesManager destructor.
void copy_item(index_t to, index_t from)
Copies all the attributes of an item into another one.
void madd_item(index_t to, double s, index_t from)
Adds a scaled item to another item \detais item[to] += s * item[from].
bool is_defined(const std::string &name) const
Tests whether an attribute is defined.
void swap_items(index_t i, index_t j)
Swaps all the attributes of two items.
index_t size() const
Gets the size.
Definition attributes.h:952
void clear(bool keep_attributes, bool keep_memory=false)
Clears this AttributesManager.
index_t capacity() const
Gets the capacity.
Definition attributes.h:961
void delete_attribute_store(const std::string &name)
Deletes an AttributeStore by name.
bool copy_attribute(const std::string &name, const std::string &new_name)
Copies an attribute.
void zero()
Zeroes all the attributes.
void reserve(index_t new_capacity)
Pre-allocates memory for a number of items.
void resize(index_t new_size)
Resizes all the attributes managed by this AttributesManager.
Base class for reference-counted objects.
Definition counted.h:71
Concrete implementation of LifeCycle.
Definition life_cycle.h:252
static void register_ascii_attribute_serializer(const std::string &type_name, AsciiAttributeSerializer read, AsciiAttributeSerializer write)
Declares a new attribute type that can be read from and written to ascii files.
Manages the life cycle of an object.
Definition life_cycle.h:66
Readonly access to an attribute as a double regardless its type.
double operator[](index_t i)
Gets a property value.
Readwrite access to an attribute as a double regardless its type.
Accessor class used by ScalarAttributeAdapter to implement indexing operator.
Accessor class used by ScalarAttributeAdapter to implement indexing operator (const version).
Access to an attribute as a double regardless its type.
index_t element_index() const
Gets the element index.
T get_element(index_t i, index_t multiplier=1) const
Gets an element.
ElementType
Internal representation of the attribute.
static std::string attribute_base_name(const std::string &name)
Gets the base attribute name from a compound name.
void bind_if_is_defined(const AttributesManager &manager, const std::string &name)
Binds this Attribute to an AttributesManager if it already exists in the AttributesManager.
bool is_bound() const
Tests whether an Attribute is bound.
static index_t nb_scalar_elements_per_item(const AttributeStore *store)
Gets the number of scalar components per item in an AttributeStore.
double get_element_as_double(index_t i) const
Gets an attribute value.
~ScalarAttributeAdapterBase()
ReadonlyScalarAttributeAdapterBase destructor.
static ElementType element_type(const AttributeStore *store)
Gets the element type stored in an AttributeStore.
const AttributeStore * attribute_store() const
Gets the AttributeStore.
ScalarAttributeAdapterBase()
ScalarAttributeAdapterBase constructor.
static bool can_be_bound_to(const AttributeStore *store)
Tests whether a ScalarAttributeAdapterBase can be bound to a given attribute store.
void unbind()
Unbinds this Attribute.
static bool is_defined(const AttributesManager &manager, const std::string &name)
Tests whether an attribute with the specified name and with a type that can be converted to double ex...
ScalarAttributeAdapterBase(const AttributesManager &manager, const std::string &name)
ScalarAttributeAdapterBase constructor.
double set_element_as_double(index_t i, double value)
Sets an attribute value.
void set_element(T value, index_t i, index_t multiplier=1) const
Sets an element.
static index_t attribute_element_index(const std::string &name)
Gets the base attribute name from a compound name.
index_t size() const
Gets the size.
ElementType element_type() const
Gets the internal representation of the elements.
A smart pointer with reference-counted copy semantics.
Implementation of AttributeStoreCreator for a specific type.
Definition attributes.h:857
AttributeStore * create_attribute_store(index_t dim) override
Creates a new attribute store.
Definition attributes.h:862
bool elements_are_trivially_copyable() const override
Tests whether elements of this attribute can be trivially copyable.
Definition attributes.h:869
Stores an array of elements of a given type, and notifies a set of AttributeStoreObservers each time ...
Definition attributes.h:682
void scale_item(index_t to, double s) override
Scales an item.
Definition attributes.h:769
TypedAttributeStore(index_t dim=1)
Creates a new empty attribute store.
Definition attributes.h:691
void notify(Memory::pointer base_addr, index_t size, index_t dim) override
If size or base address differ from the cached values, notify all the observers, and update the cache...
Definition attributes.h:787
void clear(bool keep_memory=false) override
Resizes this AttributeStore to 0.
Definition attributes.h:719
AttributeStore * clone() const override
Creates a new AttributeStore that is a carbon copy of this AttributeStore.
Definition attributes.h:756
void resize(index_t new_size) override
Resizes this AttributeStore.
Definition attributes.h:698
std::string element_typeid_name() const override
Gets the typeid name of the element type stored in this AttributeStore.
Definition attributes.h:752
void reserve(index_t new_capacity) override
Reserves memory.
Definition attributes.h:707
bool elements_type_matches(const std::string &type_name) const override
Tests whether this AttributeStore stores elements of a given type.
Definition attributes.h:748
void madd_item(index_t to, double s, index_t from) override
Adds a scaled item to another item \detais item[to] += s * item[from].
Definition attributes.h:776
void redim(index_t dim) override
Sets the dimension.
Definition attributes.h:728
Helper class to register new attribute types.
Definition attributes.h:880
geo_register_attribute_type(const std::string &type_name)
geo_register_attribute_type constructor
Definition attributes.h:891
Vector with aligned memory allocation.
Definition memory.h:660
Functions to read and write structured files.
Common include file, providing basic definitions. Should be included before anything else by all head...
Implementation of generic object lifecycle service.
Generic logging mechanism.
Types and functions for memory manipulation.
byte * pointer
Pointer to unsigned byte(s)
Definition memory.h:104
float float32
Definition numeric.h:147
uint8_t uint8
Definition numeric.h:135
int8_t int8
Definition numeric.h:123
double float64
Definition numeric.h:150
int32_t int32
Definition numeric.h:129
uint32_t uint32
Definition numeric.h:141
std::atomic_flag spinlock
A lightweight synchronization structure.
Global Vorpaline namespace.
Definition basic.h:55
bool write_ascii_attribute< bool >(FILE *file, Memory::pointer base_addr, index_t nb_elements)
Writes an ASCII attribute to a file.
Definition geofile.h:232
void geo_argused(const T &)
Suppresses compiler warnings about unused parameters.
Definition argused.h:60
geo_index_t index_t
The type for storing and manipulating indices.
Definition numeric.h:329
SmartPointer< AttributeStoreCreator > AttributeStoreCreator_var
An automatic reference-counted pointer to an AttributeStoreCreator.
Definition attributes.h:214
bool read_ascii_attribute< bool >(FILE *file, Memory::pointer base_addr, index_t nb_elements)
Reads an ASCII attribute from a file.
Definition geofile.h:208
Types and functions for numbers manipulation.
Function and classes for process manipulation.