Geogram Version 1.8.5
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#ifndef GEOGRAM_BASIC_ATTRIBUTES
41#define GEOGRAM_BASIC_ATTRIBUTES
42
43
50
51#include <map>
52#include <typeinfo>
53#include <set>
54#include <type_traits>
55
61namespace GEO {
62
63 class AttributeStore;
64
69 class GEOGRAM_API AttributeStoreObserver {
70 public:
71
76 base_addr_(nullptr), size_(0), dimension_(0),
77 disconnected_(false) {
78 }
79
87 void notify(
88 Memory::pointer base_addr, index_t size, index_t dim
89 ) {
90 base_addr_ = base_addr;
91 size_ = size;
92 dimension_ = dim;
93 }
94
99 index_t size() const {
100 return size_;
101 }
102
108 return dimension_;
109 }
110
118 return size_ * dimension_;
119 }
120
126
132
140 void disconnect() {
141 base_addr_ = nullptr;
142 size_ = 0;
143 dimension_ = 0;
144 disconnected_ = true;
145 }
146
147 protected:
148 Memory::pointer base_addr_;
149 index_t size_;
150 index_t dimension_;
151 bool disconnected_;
152 };
153
154
155 /*********************************************************************/
156
157
162 class GEOGRAM_API AttributeStoreCreator : public Counted {
163 public:
164
169
176
177
178 private:
179 std::string element_type_name_;
180 std::string element_typeid_name_;
181 };
182
188
194 class GEOGRAM_API AttributeStore {
195 public:
206
211
212
223 const std::string& type_name
224 ) const = 0;
225
231 virtual std::string element_typeid_name() const = 0;
232
237 index_t size() const {
238 return cached_size_;
239 }
240
247 return cached_capacity_;
248 }
249
254 virtual void resize(index_t new_size) = 0;
255
261 virtual void reserve(index_t new_capacity) = 0;
262
268 virtual void clear(bool keep_memory = false) = 0;
269
275 bool has_observers() const {
276 return !observers_.empty();
277 }
278
285 return dimension_;
286 }
287
297 virtual void redim(index_t dim) = 0;
298
299
317 virtual void apply_permutation(
318 const vector<index_t>& permutation
319 );
320
338 virtual void compress(const vector<index_t>& old2new);
339
347 virtual void zero();
348
354 virtual AttributeStore* clone() const = 0;
355
356
362 void copy_item(index_t to, index_t from) {
363 geo_debug_assert(from < cached_size_);
364 geo_debug_assert(to < cached_size_);
365 index_t item_size = element_size_ * dimension_;
366 Memory::copy(
367 cached_base_addr_+to*item_size,
368 cached_base_addr_+from*item_size,
369 item_size
370 );
371 }
372
378
383 void* data() {
384 return cached_base_addr_;
385 }
386
391 const void* data() const {
392 return cached_base_addr_;
393 }
394
399 size_t element_size() const {
400 return size_t(element_size_);
401 }
402
412 const std::string& element_type_name
413 ) {
414 return (
415 type_name_to_creator_.find(element_type_name) !=
416 type_name_to_creator_.end()
417 );
418 }
419
429 const std::string& element_typeid_name
430 ) {
431 return (
432 typeid_name_to_type_name_.find(element_typeid_name) !=
433 typeid_name_to_type_name_.end()
434 );
435 }
436
444 const std::string& element_type_name,
445 index_t dimension
446 ) {
447 geo_assert(element_type_name_is_known(element_type_name));
448 return type_name_to_creator_[element_type_name]->
449 create_attribute_store(dimension);
450 }
451
460 const std::string& element_typeid_name
461 ) {
462 geo_assert(element_typeid_name_is_known(element_typeid_name));
463 return typeid_name_to_type_name_[element_typeid_name];
464 }
465
475 const std::string& element_type_name
476 ) {
477 geo_assert(element_type_name_is_known(element_type_name));
478 return type_name_to_typeid_name_[element_type_name];
479 }
480
492 AttributeStoreCreator* creator,
493 const std::string& element_type_name,
494 const std::string& element_typeid_name
495 ) {
496 if(element_type_name_is_known(element_type_name)) {
497 Logger::warn("Attributes") << element_type_name
498 << " already registered"
499 << std::endl;
500 if(element_typeid_name_is_known(element_typeid_name)) {
501 bool already_registered_attribute_has_same_type = (
502 type_name_to_typeid_name_[element_type_name] ==
503 element_typeid_name
504 );
505 geo_assert(already_registered_attribute_has_same_type);
506 }
507 }
508 type_name_to_creator_[element_type_name] = creator;
509 typeid_name_to_type_name_[element_typeid_name] = element_type_name;
510 type_name_to_typeid_name_[element_type_name] = element_typeid_name;
511 }
512
513 protected:
522 virtual void notify(
523 Memory::pointer base_addr, index_t size, index_t dim
524 );
525
535
544
545
546 protected:
547 index_t element_size_;
548 index_t dimension_;
549 Memory::pointer cached_base_addr_;
550 index_t cached_size_;
551 index_t cached_capacity_;
552 std::set<AttributeStoreObserver*> observers_;
553 Process::spinlock lock_;
554
555 static std::map<std::string, AttributeStoreCreator_var>
556 type_name_to_creator_;
557
558 static std::map<std::string, std::string>
559 typeid_name_to_type_name_;
560
561 static std::map<std::string, std::string>
562 type_name_to_typeid_name_;
563
564 friend class AttributeStoreObserver;
565 };
566
567 /*********************************************************************/
568
574 template <class T> class TypedAttributeStore : public AttributeStore {
575 public:
576
584 AttributeStore(index_t(sizeof(T)),dim) {
585 }
586
587 void resize(index_t new_size) override {
588 store_.resize(new_size*dimension_);
589 notify(
590 store_.empty() ? nullptr : Memory::pointer(store_.data()),
591 new_size,
592 dimension_
593 );
594 }
595
596 void reserve(index_t new_capacity) override {
597 if(new_capacity > capacity()) {
598 store_.reserve(new_capacity*dimension_);
599 cached_capacity_ = new_capacity;
600 notify(
601 store_.empty() ? nullptr : Memory::pointer(store_.data()),
602 size(),
603 dimension_
604 );
605 }
606 }
607
608 void clear(bool keep_memory=false) override {
609 if(keep_memory) {
610 store_.resize(0);
611 } else {
612 store_.clear();
613 }
614 notify(nullptr, 0, dimension_);
615 }
616
617
618 void redim(index_t dim) override {
619 if(dim == dimension()) {
620 return;
621 }
622 vector<T> new_store(size()*dim);
623 new_store.reserve(capacity()*dim);
624 index_t copy_dim = std::min(dim, dimension());
625 for(index_t i = 0; i < size(); ++i) {
626 for(index_t c = 0; c < copy_dim; ++c) {
627 new_store[dim * i + c] = store_[dimension_ * i + c];
628 }
629 }
630 store_.swap(new_store);
631 notify(
632 store_.empty() ? nullptr : Memory::pointer(store_.data()),
633 size(),
634 dim
635 );
636 }
637
639 const std::string& type_name
640 ) const override {
641 return type_name == typeid(T).name();
642 }
643
644 std::string element_typeid_name() const override {
645 return typeid(T).name();
646 }
647
648 AttributeStore* clone() const override {
649 TypedAttributeStore<T>* result =
651 result->resize(size());
652 result->store_ = store_;
653 return result;
654 }
655
656 vector<T>& get_vector() {
657 return store_;
658 }
659
660 protected:
661 void notify(
662 Memory::pointer base_addr, index_t size, index_t dim
663 ) override {
664 AttributeStore::notify(base_addr, size, dim);
665 geo_assert(size*dim <= store_.size());
666 }
667
668 private:
669 vector<T> store_;
670 };
671
672 /*********************************************************************/
673
678 template <class T>
680 public:
685 return new TypedAttributeStore<T>(dim);
686 }
687 };
688
689 /*********************************************************************/
690
695 template <class T> class geo_register_attribute_type {
696 public:
706 geo_register_attribute_type(const std::string& type_name) {
708 new TypedAttributeStoreCreator<T>, type_name, typeid(T).name()
709 );
710 if(type_name == "bool") {
712 type_name,
715 );
716 } else {
718 type_name,
719 read_ascii_attribute<T>,
720 write_ascii_attribute<T>
721 );
722 }
723 }
724 };
725
726 /*********************************************************************/
727
732 class GEOGRAM_API AttributesManager {
733 public:
738
739
744
750 index_t nb() const {
751 return index_t(attributes_.size());
752 }
753
760
767 index_t size() const {
768 return size_;
769 }
770
777 return capacity_;
778 }
779
786 void resize(index_t new_size);
787
794 void reserve(index_t new_capacity);
795
804 void clear(bool keep_attributes, bool keep_memory = false);
805
806
810 void zero();
811
820 void bind_attribute_store(const std::string& name, AttributeStore* as);
821
828 AttributeStore* find_attribute_store(const std::string& name);
829
837 const std::string& name
838 ) const;
839
840
847 bool is_defined(const std::string& name) const {
848 return (find_attribute_store(name) != nullptr);
849 }
850
856 void delete_attribute_store(const std::string& name);
857
864
881 const vector<index_t>& permutation
882 );
883
899 void compress(const vector<index_t>& old2new);
900
905 void copy(const AttributesManager& rhs);
906
907
914 void copy_item(index_t to, index_t from);
915
922
923
933 const std::string& name, const std::string& new_name
934 );
935
945 const std::string& old_name, const std::string& new_name
946 );
947
948 private:
957
965 const AttributesManager& operator=(const AttributesManager& rhs);
966
967 private:
968 index_t size_;
969 index_t capacity_;
970 std::map<std::string, AttributeStore*> attributes_;
971 } ;
972
973
974 /*********************************************************************/
975
976
981 template <class T> class AttributeBase : public AttributeStoreObserver {
982 public:
983
988 manager_(nullptr),
989 store_(nullptr) {
990 }
991
1001 AttributeBase(AttributesManager& manager, const std::string& name) :
1002 manager_(nullptr),
1003 store_(nullptr) {
1004 bind(manager, name);
1005 }
1006
1012 bool is_bound() const {
1013 return (store_ != nullptr && !disconnected_);
1014 }
1015
1020 void unbind() {
1022 // If the AttributesManager was destroyed before, do not
1023 // do anything. This can occur in Lua scripting when using
1024 // Attribute wrapper objects.
1025 if(!disconnected_) {
1026 unregister_me(store_);
1027 }
1028 manager_ = nullptr;
1029 store_ = nullptr;
1030 }
1031
1041 void bind(AttributesManager& manager, const std::string& name) {
1042 geo_assert(!is_bound());
1043 manager_ = &manager;
1044 store_ = manager_->find_attribute_store(name);
1045 if(store_ == nullptr) {
1046 store_ = new TypedAttributeStore<T>();
1047 manager_->bind_attribute_store(name,store_);
1048 } else {
1049 geo_assert(store_->elements_type_matches(typeid(T).name()));
1050 }
1051 register_me(store_);
1052 }
1053
1054
1064 AttributesManager& manager, const std::string& name
1065 ) {
1066 geo_assert(!is_bound());
1067 manager_ = &manager;
1068 store_ = manager_->find_attribute_store(name);
1069 if(store_ != nullptr) {
1070 geo_assert(store_->elements_type_matches(typeid(T).name()));
1071 register_me(store_);
1072 return true;
1073 }
1074 return false;
1075 }
1076
1086 AttributesManager& manager, const std::string& name
1087 ) {
1088 if( is_bound() ) {
1089 unbind();
1090 }
1091 store_ = manager.find_attribute_store(name);
1092 if(store_ != nullptr) {
1093 if( !store_->elements_type_matches(typeid(T).name()) ) {
1094 store_ = nullptr;
1095 return false;
1096 }
1097 manager_ = &manager;
1098 register_me(store_);
1099 return true;
1100 }
1101 return false;
1102 }
1103
1112 const std::string& name,
1114 ) {
1115 geo_assert(!is_bound());
1116 manager_ = &manager;
1117 geo_assert(manager_->find_attribute_store(name) == nullptr);
1118 store_ = new TypedAttributeStore<T>(dimension);
1119 manager_->bind_attribute_store(name,store_);
1120 register_me(store_);
1121 }
1122
1129 void destroy() {
1131 unregister_me(store_);
1132 manager_->delete_attribute_store(store_);
1133 store_ = nullptr;
1134 manager_ = nullptr;
1135 }
1136
1146 void redim(index_t new_dim) {
1148 store_->redim(new_dim);
1149 }
1150
1159 if(is_bound()) {
1160 unbind();
1161 }
1162 }
1163
1164
1172 static bool is_defined(
1173 AttributesManager& manager, const std::string& name,
1174 index_t dim = 0
1175 ) {
1177 return (
1178 store != nullptr &&
1179 store->elements_type_matches(typeid(T).name()) &&
1180 ((dim == 0) || (store->dimension() == dim))
1181 );
1182 }
1183
1188 index_t size() const {
1189 return size_;
1190 }
1191
1196 void zero() {
1198 store_->zero();
1199 }
1200
1211 return(
1212 dynamic_cast<TypedAttributeStore<T>*>(store_) != nullptr
1213 );
1214 }
1215
1227 TypedAttributeStore<T>* typed_store =
1228 dynamic_cast<TypedAttributeStore<T>*>(store_);
1229 geo_assert(typed_store != nullptr);
1230 return typed_store->get_vector();
1231 }
1232
1239 const vector<T>& get_vector() const {
1240 TypedAttributeStore<T>* typed_store =
1241 dynamic_cast<TypedAttributeStore<T>*>(store_);
1242 geo_assert(typed_store != nullptr);
1243 return typed_store->get_vector();
1244 }
1245
1251 return manager_;
1252 }
1253
1254 protected:
1255 AttributesManager* manager_;
1256 AttributeStore* store_;
1257 } ;
1258
1259 /*********************************************************************/
1260
1267 template <class T> class Attribute : public AttributeBase<T> {
1268 public:
1270
1276 static void static_test_type() {
1277 // Attributes are only implemented for classes that
1278 // can be copied with memcpy() and read/written to
1279 // files using fread()/fwrite()
1280#if __GNUG__ && __GNUC__ < 5
1281 static_assert(
1282 __has_trivial_copy(T),
1283 "Attribute only implemented for types that can be copied with memcpy()"
1284 );
1285#else
1286 static_assert(
1287 std::is_trivially_copyable<T>::value,
1288 "Attribute only implemented for types that can be copied with memcpy()"
1289 );
1290#endif
1291 }
1292
1298 }
1299
1309 Attribute(AttributesManager& manager, const std::string& name) :
1310 superclass(manager, name) {
1312 }
1313
1321 return ((T*)(void*)superclass::base_addr_)[i];
1322 }
1323
1329 const T& operator[](index_t i) const {
1331 return ((const T*)(void*)superclass::base_addr_)[i];
1332 }
1333
1339 void fill(const T& val) {
1340 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1341 (*this)[i] = val;
1342 }
1343 }
1344
1351 void copy(const Attribute<T>& rhs) {
1352 geo_assert(rhs.size() == superclass::size());
1354 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1355 (*this)[i] = rhs[i];
1356 }
1357 }
1358
1363 T* data() {
1364 return (T*)AttributeStoreObserver::base_addr_;
1365 }
1366
1371 const T* data() const {
1372 return (const T*)AttributeStoreObserver::base_addr_;
1373 }
1374
1375
1376 private:
1380 Attribute(const Attribute<T>& rhs);
1384 Attribute<T>& operator=(const Attribute<T>& rhs);
1385 };
1386
1387 /*********************************************************************/
1388
1397 template <> class Attribute<bool> : public AttributeBase<Numeric::uint8> {
1398 public:
1400
1401 Attribute() : superclass() {
1402 }
1403
1404 Attribute(AttributesManager& manager, const std::string& name) :
1405 superclass(manager,name) {
1406 }
1407
1408 class BoolAttributeAccessor;
1409
1410
1415 class ConstBoolAttributeAccessor {
1416 public:
1421 const Attribute<bool>& attribute,
1422 index_t index
1423 ) :
1424 attribute_(&attribute),
1425 index_(index) {
1426 }
1427
1432 operator bool() const {
1433 return (attribute_->element(index_) != 0);
1434 }
1435
1436 private:
1437 const Attribute<bool>* attribute_;
1438 index_t index_;
1439
1440 friend class BoolAttributeAccessor;
1441 };
1442
1447 class BoolAttributeAccessor {
1448 public:
1453 Attribute<bool>& attribute,
1454 index_t index
1455 ) :
1456 attribute_(&attribute),
1457 index_(index) {
1458 }
1459
1464 operator bool() const {
1465 return (attribute_->element(index_) != 0);
1466 }
1467
1473 BoolAttributeAccessor(const BoolAttributeAccessor& rhs) {
1474 attribute_ = rhs.attribute_;
1475 index_ = rhs.index_;
1476 }
1477
1482 BoolAttributeAccessor& operator=(bool x) {
1483 attribute_->element(index_) = Numeric::uint8(x);
1484 return *this;
1485 }
1486
1492 BoolAttributeAccessor& operator=(
1493 const BoolAttributeAccessor& rhs
1494 ) {
1495 if(&rhs != this) {
1496 attribute_->element(index_) =
1497 rhs.attribute_->element(rhs.index_);
1498 }
1499 return *this;
1500 }
1501
1507 BoolAttributeAccessor& operator=(
1508 const ConstBoolAttributeAccessor& rhs
1509 ) {
1510 attribute_->element(index_) =
1511 rhs.attribute_->element(rhs.index_);
1512 return *this;
1513 }
1514
1515 private:
1516 Attribute<bool>* attribute_;
1517 index_t index_;
1518 };
1519
1520
1521 BoolAttributeAccessor operator[](index_t i) {
1522 return BoolAttributeAccessor(*this,i);
1523 }
1524
1525 ConstBoolAttributeAccessor operator[](index_t i) const {
1526 return ConstBoolAttributeAccessor(*this,i);
1527 }
1528
1534 void fill(bool val) {
1535 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1536 element(i) = Numeric::uint8(val);
1537 }
1538 }
1539
1540 protected:
1541
1542 friend class BoolAttributeAccessor;
1543 friend class ConstBoolAttributeAccessor;
1544
1552 return ((Numeric::uint8*)superclass::base_addr_)[i];
1553 }
1554
1562 return ((const Numeric::uint8*)superclass::base_addr_)[i];
1563 }
1564
1565 private:
1569 Attribute(const Attribute<bool>& rhs);
1573 Attribute<bool>& operator=(const Attribute<bool>& rhs);
1574 } ;
1575
1576 /***********************************************************/
1577
1582 class GEOGRAM_API ScalarAttributeAdapterBase :
1583 public AttributeStoreObserver {
1584
1585 public:
1590 ET_NONE=0,
1591 ET_UINT8=1,
1592 ET_INT8=2,
1593 ET_UINT32=3,
1594 ET_INT32=4,
1595 ET_FLOAT32=5,
1596 ET_FLOAT64=6,
1597 ET_VEC2=7,
1598 ET_VEC3=8
1599 };
1600
1601
1606 class Accessor {
1607 public:
1608 Accessor(
1609 ScalarAttributeAdapterBase& attribute,
1610 index_t index
1611 ) : attribute_(attribute), index_(index) {
1612 }
1613
1614 operator double() const {
1615 return attribute_.get_element_as_double(index_);
1616 }
1617
1618 void operator=(double x) {
1619 attribute_.set_element_as_double(index_, x);
1620 }
1621
1622 private:
1623 ScalarAttributeAdapterBase& attribute_;
1624 index_t index_;
1625 };
1626
1632 public:
1634 const ScalarAttributeAdapterBase& attribute,
1635 index_t index
1636 ) : attribute_(attribute), index_(index) {
1637 }
1638
1639 operator double() const {
1640 return attribute_.get_element_as_double(index_);
1641 }
1642
1643 private:
1644 const ScalarAttributeAdapterBase& attribute_;
1645 index_t index_;
1646 };
1647
1652 manager_(nullptr),
1653 store_(nullptr),
1654 element_type_(ET_NONE),
1655 element_index_(index_t(-1)) {
1656 }
1657
1668 const AttributesManager& manager, const std::string& name
1669 ) :
1670 manager_(nullptr),
1671 store_(nullptr) {
1672 bind_if_is_defined(manager, name);
1673 }
1674
1680 bool is_bound() const {
1681 return (store_ != nullptr);
1682 }
1683
1688 void unbind() {
1689 geo_assert(is_bound());
1690 unregister_me(const_cast<AttributeStore*>(store_));
1691 manager_ = nullptr;
1692 store_ = nullptr;
1693 element_type_ = ET_NONE;
1694 element_index_ = index_t(-1);
1695 }
1696
1707 const AttributesManager& manager, const std::string& name
1708 );
1709
1718 if(is_bound()) {
1719 unbind();
1720 }
1721 }
1722
1732 static bool is_defined(
1733 const AttributesManager& manager, const std::string& name
1734 );
1735
1740 index_t size() const {
1741 return (store_ == nullptr) ? 0 : store_->size();
1742 }
1743
1752 return element_type_;
1753 }
1754
1762 return element_index_;
1763 }
1764
1770 return store_;
1771 }
1772
1773
1781 static bool can_be_bound_to(const AttributeStore* store) {
1782 return element_type(store) != ET_NONE;
1783 }
1784
1793
1794 protected:
1803 static std::string attribute_base_name(const std::string& name);
1804
1813 static index_t attribute_element_index(const std::string& name);
1814
1823
1832 double result = 0.0;
1833 switch(element_type()) {
1834 case ET_UINT8:
1835 result = double(get_element<Numeric::uint8>(i));
1836 break;
1837 case ET_INT8:
1838 result = double(get_element<Numeric::int8>(i));
1839 break;
1840 case ET_UINT32:
1841 result = double(get_element<Numeric::uint32>(i));
1842 break;
1843 case ET_INT32:
1844 result = double(get_element<Numeric::int32>(i));
1845 break;
1846 case ET_FLOAT32:
1847 result = double(get_element<Numeric::float32>(i));
1848 break;
1849 case ET_FLOAT64:
1850 result = double(get_element<Numeric::float64>(i));
1851 break;
1852 case ET_VEC2:
1853 result = double(get_element<Numeric::float64>(i,2));
1854 break;
1855 case ET_VEC3:
1856 result = double(get_element<Numeric::float64>(i,3));
1857 break;
1858 case ET_NONE:
1860 }
1861 return result;
1862 }
1863
1872 template <class T> T get_element(index_t i,index_t multiplier=1) const {
1873 geo_debug_assert(is_bound());
1874 geo_debug_assert(i < size());
1875 return static_cast<const T*>(store_->data())[
1876 (i * store_->dimension() * multiplier) +
1877 element_index_
1878 ];
1879 }
1880
1887 double set_element_as_double(index_t i, double value) {
1888 double result = 0.0;
1889 switch(element_type()) {
1890 case ET_UINT8:
1891 set_element<Numeric::uint8>(Numeric::uint8(value), i);
1892 break;
1893 case ET_INT8:
1894 set_element<Numeric::int8>(Numeric::int8(value),i);
1895 break;
1896 case ET_UINT32:
1897 set_element<Numeric::uint32>(Numeric::uint32(value),i);
1898 break;
1899 case ET_INT32:
1900 set_element<Numeric::int32>(Numeric::int32(value),i);
1901 break;
1902 case ET_FLOAT32:
1903 set_element<Numeric::float32>(Numeric::float32(value),i);
1904 break;
1905 case ET_FLOAT64:
1906 set_element<Numeric::float64>(Numeric::float64(value),i);
1907 break;
1908 case ET_VEC2:
1909 set_element<Numeric::float64>(Numeric::float64(value),i,2);
1910 break;
1911 case ET_VEC3:
1912 set_element<Numeric::float64>(Numeric::float64(value),i,3);
1913 break;
1914 case ET_NONE:
1916 }
1917 return result;
1918 }
1919
1929 template <class T> void set_element(
1930 T value, index_t i, index_t multiplier=1
1931 ) const {
1932 geo_debug_assert(is_bound());
1933 geo_debug_assert(i < size());
1934 const_cast<T*>(static_cast<const T*>(store_->data()))[
1935 (i * store_->dimension() * multiplier) +
1936 element_index_
1937 ] = value;
1938 }
1939
1940 protected:
1941 const AttributesManager* manager_;
1942 const AttributeStore* store_;
1943 ElementType element_type_;
1944 index_t element_index_;
1945 };
1946
1947 /***********************************************************/
1948
1954 public:
1956 }
1957
1959 const AttributesManager& manager, const std::string& name
1960 ) : ScalarAttributeAdapterBase(manager, name) {
1961 }
1962
1971 return get_element_as_double(i);
1972 }
1973 };
1974
1975 /***********************************************************/
1976
1982 public:
1984 }
1985
1987 const AttributesManager& manager, const std::string& name
1988 ) : ScalarAttributeAdapterBase(manager, name) {
1989 }
1990
1991 Accessor operator[](index_t i) {
1992 return Accessor(*this, i);
1993 }
1994
1995 ConstAccessor operator[](index_t i) const {
1996 return ConstAccessor(*this, i);
1997 }
1998
1999 protected:
2000 };
2001
2002
2003}
2004
2005#endif
2006
#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:195
Common include file, providing basic definitions. Should be included before anything else by all head...
Base class for Attributes, that manipulates an attribute stored in an AttributesManager.
Definition attributes.h:981
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 tyopes...
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.
Definition attributes.h:987
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:162
~AttributeStoreCreator() override
AttributeStoreCreator destructor.
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:69
AttributeStoreObserver()
Creates a new uninitialied AttributeStore.
Definition attributes.h:75
void register_me(AttributeStore *store)
Registers this observer to an AttributeStore.
index_t size() const
Gets the size.
Definition attributes.h:99
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:87
index_t nb_elements() const
Gets the total number of elements.
Definition attributes.h:117
void disconnect()
Disconnects this AttributeStoreObserver from its AttributeStore.
Definition attributes.h:140
void unregister_me(AttributeStore *store)
Unregisters this observer from an AttributeStore.
index_t dimension() const
Gets the dimension.
Definition attributes.h:107
Notifies a set of AttributeStoreObservers each time the stored array changes size and/or base address...
Definition attributes.h:194
void * data()
Gets a pointer to the stored data.
Definition attributes.h:383
AttributeStore(index_t elemsize, index_t dim=1)
AttributeStore constructor.
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:443
bool has_observers() const
Tests whether observers listen to this AttributeStore.
Definition attributes.h:275
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:474
static void register_attribute_creator(AttributeStoreCreator *creator, const std::string &element_type_name, const std::string &element_typeid_name)
Registers a new element type.
Definition attributes.h:491
index_t size() const
Gets the size.
Definition attributes.h:237
const void * data() const
Gets a pointer to the stored data.
Definition attributes.h:391
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...
index_t capacity() const
Gets the capacity.
Definition attributes.h:246
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:411
virtual void compress(const vector< index_t > &old2new)
Compresses the stored attributes, by applying an index mapping that fills-in the gaps.
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:362
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:428
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.
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:284
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:459
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.
size_t element_size() const
Gets the element size.
Definition attributes.h:399
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.
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.
static void static_test_type()
Tests at compile time whether type can be used in an Attribute. If not the case generates a compile-t...
Managers a set of attributes attached to an object.
Definition attributes.h:732
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 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:750
bool rename_attribute(const std::string &old_name, const std::string &new_name)
Renames an attribute.
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.
bool is_defined(const std::string &name) const
Tests whether an attribute is defined.
Definition attributes.h:847
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:767
void clear(bool keep_attributes, bool keep_memory=false)
Clears this AttributesManager.
index_t capacity() const
Gets the capacity.
Definition attributes.h:776
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
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.
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:679
AttributeStore * create_attribute_store(index_t dim) override
Creates a new attribute store.
Definition attributes.h:684
Stores an array of elements of a given type, and notifies a set of AttributeStoreObservers each time ...
Definition attributes.h:574
TypedAttributeStore(index_t dim=1)
Creates a new empty attribute store.
Definition attributes.h:583
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:661
void clear(bool keep_memory=false) override
Resizes this AttributeStore to 0.
Definition attributes.h:608
AttributeStore * clone() const override
Creates a new AttributeStore that is a carbon copy of this AttributeStore.
Definition attributes.h:648
void resize(index_t new_size) override
Resizes this AttributeStore.
Definition attributes.h:587
std::string element_typeid_name() const override
Gets the typeid name of the element type stored in this AttributeStore.
Definition attributes.h:644
void reserve(index_t new_capacity) override
Reserves memory.
Definition attributes.h:596
bool elements_type_matches(const std::string &type_name) const override
Tests whether this AttributeStore stores elements of a given type.
Definition attributes.h:638
void redim(index_t dim) override
Sets the dimension.
Definition attributes.h:618
Helper class to register new attribute types.
Definition attributes.h:695
geo_register_attribute_type(const std::string &type_name)
geo_register_attribute_type constructor
Definition attributes.h:706
Vector with aligned memory allocation.
Definition memory.h:623
Functions to read and write structured files.
Generic logging mechanism.
Types and functions for memory manipulation.
byte * pointer
Pointer to unsigned byte(s)
Definition memory.h:92
float float32
Definition numeric.h:102
uint8_t uint8
Definition numeric.h:90
int8_t int8
Definition numeric.h:78
double float64
Definition numeric.h:105
int32_t int32
Definition numeric.h:84
uint32_t uint32
Definition numeric.h:96
int spinlock
Definition psm.h:125
Global Vorpaline namespace.
Definition algorithm.h:64
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:228
geo_index_t index_t
The type for storing and manipulating indices.
Definition numeric.h:287
SmartPointer< AttributeStoreCreator > AttributeStoreCreator_var
An automatic reference-counted pointer to an AttributeStoreCreator.
Definition attributes.h:187
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:204
Types and functions for numbers manipulation.
Function and classes for process manipulation.