Geogram Version 1.9.2
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
44
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
133
141 void disconnect() {
142 base_addr_ = nullptr;
143 size_ = 0;
144 dimension_ = 0;
145 disconnected_ = true;
146 }
147
148 protected:
149 Memory::pointer base_addr_;
150 index_t size_;
151 index_t dimension_;
152 bool disconnected_;
153 };
154
155
156 /*********************************************************************/
157
158
163 class GEOGRAM_API AttributeStoreCreator : public Counted {
164 public:
165
170
177
178
179 private:
180 std::string element_type_name_;
181 std::string element_typeid_name_;
182 };
183
189
195 class GEOGRAM_API AttributeStore {
196 public:
207
212
213
224 const std::string& type_name
225 ) const = 0;
226
232 virtual std::string element_typeid_name() const = 0;
233
238 index_t size() const {
239 return cached_size_;
240 }
241
248 return cached_capacity_;
249 }
250
255 virtual void resize(index_t new_size) = 0;
256
262 virtual void reserve(index_t new_capacity) = 0;
263
269 virtual void clear(bool keep_memory = false) = 0;
270
276 bool has_observers() const {
277 return !observers_.empty();
278 }
279
286 return dimension_;
287 }
288
298 virtual void redim(index_t dim) = 0;
299
300
318 virtual void apply_permutation(
319 const vector<index_t>& permutation
320 );
321
339 virtual void compress(const vector<index_t>& old2new);
340
348 virtual void zero();
349
355 virtual AttributeStore* clone() const = 0;
356
357
363 void copy_item(index_t to, index_t from) {
364 geo_debug_assert(from < cached_size_);
365 geo_debug_assert(to < cached_size_);
366 index_t item_size = element_size_ * dimension_;
367 Memory::copy(
368 cached_base_addr_+to*item_size,
369 cached_base_addr_+from*item_size,
370 item_size
371 );
372 }
373
379 geo_debug_assert(to < cached_size_);
380 index_t item_size = element_size_ * dimension_;
381 Memory::clear(
382 cached_base_addr_+to*item_size,
383 item_size
384 );
385 }
386
394 virtual void scale_item(index_t to, double s);
395
404 virtual void madd_item(index_t to, double s, index_t from);
405
411
416 void* data() {
417 return cached_base_addr_;
418 }
419
424 const void* data() const {
425 return cached_base_addr_;
426 }
427
432 size_t element_size() const {
433 return size_t(element_size_);
434 }
435
445 const std::string& element_type_name
446 ) {
447 return (
448 type_name_to_creator_.find(element_type_name) !=
449 type_name_to_creator_.end()
450 );
451 }
452
462 const std::string& element_typeid_name
463 ) {
464 return (
465 typeid_name_to_type_name_.find(element_typeid_name) !=
466 typeid_name_to_type_name_.end()
467 );
468 }
469
477 const std::string& element_type_name,
478 index_t dimension
479 ) {
480 geo_assert(element_type_name_is_known(element_type_name));
481 return type_name_to_creator_[element_type_name]->
482 create_attribute_store(dimension);
483 }
484
493 const std::string& element_typeid_name
494 ) {
495 geo_assert(element_typeid_name_is_known(element_typeid_name));
496 return typeid_name_to_type_name_[element_typeid_name];
497 }
498
508 const std::string& element_type_name
509 ) {
510 geo_assert(element_type_name_is_known(element_type_name));
511 return type_name_to_typeid_name_[element_type_name];
512 }
513
525 AttributeStoreCreator* creator,
526 const std::string& element_type_name,
527 const std::string& element_typeid_name
528 ) {
529 if(element_type_name_is_known(element_type_name)) {
530 Logger::warn("Attributes") << element_type_name
531 << " already registered"
532 << std::endl;
533 if(element_typeid_name_is_known(element_typeid_name)) {
534 bool already_registered_attribute_has_same_type = (
535 type_name_to_typeid_name_[element_type_name] ==
536 element_typeid_name
537 );
538 geo_assert(already_registered_attribute_has_same_type);
539 }
540 }
541 type_name_to_creator_[element_type_name] = creator;
542 typeid_name_to_type_name_[element_typeid_name] = element_type_name;
543 type_name_to_typeid_name_[element_type_name] = element_typeid_name;
544 }
545
546 protected:
555 virtual void notify(
556 Memory::pointer base_addr, index_t size, index_t dim
557 );
558
568
577
578
579 protected:
580 index_t element_size_;
581 index_t dimension_;
582 Memory::pointer cached_base_addr_;
583 index_t cached_size_;
584 index_t cached_capacity_;
585 std::set<AttributeStoreObserver*> observers_;
586 Process::spinlock lock_;
587
588 static std::map<std::string, AttributeStoreCreator_var>
589 type_name_to_creator_;
590
591 static std::map<std::string, std::string>
592 typeid_name_to_type_name_;
593
594 static std::map<std::string, std::string>
595 type_name_to_typeid_name_;
596
597 friend class AttributeStoreObserver;
598 };
599
600 /*********************************************************************/
601
607 template <class T> class TypedAttributeStore : public AttributeStore {
608 public:
609
617 AttributeStore(index_t(sizeof(T)),dim) {
618 }
619
620 void resize(index_t new_size) override {
621 store_.resize(new_size*dimension_);
622 notify(
623 store_.empty() ? nullptr : Memory::pointer(store_.data()),
624 new_size,
625 dimension_
626 );
627 }
628
629 void reserve(index_t new_capacity) override {
630 if(new_capacity > capacity()) {
631 store_.reserve(new_capacity*dimension_);
632 cached_capacity_ = new_capacity;
633 notify(
634 store_.empty() ? nullptr : Memory::pointer(store_.data()),
635 size(),
636 dimension_
637 );
638 }
639 }
640
641 void clear(bool keep_memory=false) override {
642 if(keep_memory) {
643 store_.resize(0);
644 } else {
645 store_.clear();
646 }
647 notify(nullptr, 0, dimension_);
648 }
649
650
651 void redim(index_t dim) override {
652 if(dim == dimension()) {
653 return;
654 }
655 vector<T> new_store(size()*dim);
656 new_store.reserve(capacity()*dim);
657 index_t copy_dim = std::min(dim, dimension());
658 for(index_t i = 0; i < size(); ++i) {
659 for(index_t c = 0; c < copy_dim; ++c) {
660 new_store[dim * i + c] = store_[dimension_ * i + c];
661 }
662 }
663 store_.swap(new_store);
664 notify(
665 store_.empty() ? nullptr : Memory::pointer(store_.data()),
666 size(),
667 dim
668 );
669 }
670
672 const std::string& type_name
673 ) const override {
674 return type_name == typeid(T).name();
675 }
676
677 std::string element_typeid_name() const override {
678 return typeid(T).name();
679 }
680
681 AttributeStore* clone() const override {
682 TypedAttributeStore<T>* result =
684 result->resize(size());
685 result->store_ = store_;
686 return result;
687 }
688
689 vector<T>& get_vector() {
690 return store_;
691 }
692
693 void scale_item(index_t to, double s) override {
694 geo_assert(to < size());
695 for(index_t i=0; i<dimension_; ++i) {
696 scale_value(store_[to*dimension_+i], s);
697 }
698 }
699
700 void madd_item(index_t to, double s, index_t from) override {
701 geo_assert(from < size());
702 geo_assert(to < size());
703 for(index_t i=0; i<dimension_; ++i) {
704 madd_value(
705 store_[to*dimension_+i], s, store_[from*dimension_+i]
706 );
707 }
708 }
709
710 protected:
711 void notify(
712 Memory::pointer base_addr, index_t size, index_t dim
713 ) override {
714 AttributeStore::notify(base_addr, size, dim);
715 geo_assert(size*dim <= store_.size());
716 }
717
718 template<class TT> static void scale_value(TT& to, double s) {
719 geo_argused(to);
720 geo_argused(s);
721 }
722
723 static void scale_value(uint8_t& to, double s) {
724 to = uint8_t(double(to)*s != 0.0);
725 }
726
727 static void scale_value(int32_t& to, double s) {
728 to = int32_t(double(to)*s);
729 }
730
731 static void scale_value(uint32_t& to, double s) {
732 to = uint32_t(double(to)*s);
733 }
734
735 static void scale_value(float& to, double s) {
736 to = float(double(to)*s);
737 }
738
739 static void scale_value(double& to, double s) {
740 to *= s;
741 }
742
743 template<class TT> static void madd_value(TT& to, double s, TT& from) {
744 geo_argused(to);
745 geo_argused(s);
746 geo_argused(from);
747 }
748
749 static void madd_value(uint8_t& to, double s, uint8_t& from) {
750 to = uint8_t(double(to) + s*double(from) != 0.0);
751 }
752
753 static void madd_value(int32_t& to, double s, int32_t& from) {
754 to = int32_t(double(to) + s*double(from));
755 }
756
757 static void madd_value(uint32_t& to, double s, uint32_t& from) {
758 to = uint32_t(double(to) + s*double(from));
759 }
760
761 static void madd_value(float& to, double s, float& from) {
762 to = float(double(to) + s*double(from));
763 }
764
765 static void madd_value(double& to, double s, double& from) {
766 to += s*from;
767 }
768
769
770 private:
771 vector<T> store_;
772 };
773
774 /*********************************************************************/
775
780 template <class T>
782 public:
787 return new TypedAttributeStore<T>(dim);
788 }
789 };
790
791 /*********************************************************************/
792
797 template <class T> class geo_register_attribute_type {
798 public:
808 geo_register_attribute_type(const std::string& type_name) {
810 new TypedAttributeStoreCreator<T>, type_name, typeid(T).name()
811 );
812 if(type_name == "bool") {
814 type_name,
817 );
818 } else {
820 type_name,
821 read_ascii_attribute<T>,
822 write_ascii_attribute<T>
823 );
824 }
825 }
826 };
827
828 /*********************************************************************/
829
834 class GEOGRAM_API AttributesManager {
835 public:
840
841
846
852 index_t nb() const {
853 return index_t(attributes_.size());
854 }
855
862
869 index_t size() const {
870 return size_;
871 }
872
879 return capacity_;
880 }
881
888 void resize(index_t new_size);
889
896 void reserve(index_t new_capacity);
897
906 void clear(bool keep_attributes, bool keep_memory = false);
907
908
912 void zero();
913
922 void bind_attribute_store(const std::string& name, AttributeStore* as);
923
930 AttributeStore* find_attribute_store(const std::string& name);
931
939 const std::string& name
940 ) const;
941
942
949 bool is_defined(const std::string& name) const {
950 return (find_attribute_store(name) != nullptr);
951 }
952
958 void delete_attribute_store(const std::string& name);
959
966
983 const vector<index_t>& permutation
984 );
985
1001 void compress(const vector<index_t>& old2new);
1002
1007 void copy(const AttributesManager& rhs);
1008
1009
1016 void copy_item(index_t to, index_t from);
1017
1024
1025
1031
1039 void scale_item(index_t to, double s);
1040
1049 void madd_item(index_t to, double s, index_t from);
1050
1060 const std::string& name, const std::string& new_name
1061 );
1062
1072 const std::string& old_name, const std::string& new_name
1073 );
1074
1075 private:
1084
1092 const AttributesManager& operator=(const AttributesManager& rhs);
1093
1094 private:
1095 index_t size_;
1096 index_t capacity_;
1097 std::map<std::string, AttributeStore*> attributes_;
1098 } ;
1099
1100
1101 /*********************************************************************/
1102
1103
1108 template <class T> class AttributeBase : public AttributeStoreObserver {
1109 public:
1110
1115 manager_(nullptr),
1116 store_(nullptr) {
1117 }
1118
1128 AttributeBase(AttributesManager& manager, const std::string& name) :
1129 manager_(nullptr),
1130 store_(nullptr) {
1131 bind(manager, name);
1132 }
1133
1139 bool is_bound() const {
1140 return (store_ != nullptr && !disconnected_);
1141 }
1142
1147 void unbind() {
1149 // If the AttributesManager was destroyed before, do not
1150 // do anything. This can occur in Lua scripting when using
1151 // Attribute wrapper objects.
1152 if(!disconnected_) {
1153 unregister_me(store_);
1154 }
1155 manager_ = nullptr;
1156 store_ = nullptr;
1157 }
1158
1168 void bind(AttributesManager& manager, const std::string& name) {
1169 geo_assert(!is_bound());
1170 manager_ = &manager;
1171 store_ = manager_->find_attribute_store(name);
1172 if(store_ == nullptr) {
1173 store_ = new TypedAttributeStore<T>();
1174 manager_->bind_attribute_store(name,store_);
1175 } else {
1176 geo_assert(store_->elements_type_matches(typeid(T).name()));
1177 }
1178 register_me(store_);
1179 }
1180
1181
1191 AttributesManager& manager, const std::string& name
1192 ) {
1193 geo_assert(!is_bound());
1194 manager_ = &manager;
1195 store_ = manager_->find_attribute_store(name);
1196 if(store_ != nullptr) {
1197 geo_assert(store_->elements_type_matches(typeid(T).name()));
1198 register_me(store_);
1199 return true;
1200 }
1201 return false;
1202 }
1203
1213 AttributesManager& manager, const std::string& name
1214 ) {
1215 if( is_bound() ) {
1216 unbind();
1217 }
1218 store_ = manager.find_attribute_store(name);
1219 if(store_ != nullptr) {
1220 if( !store_->elements_type_matches(typeid(T).name()) ) {
1221 store_ = nullptr;
1222 return false;
1223 }
1224 manager_ = &manager;
1225 register_me(store_);
1226 return true;
1227 }
1228 return false;
1229 }
1230
1239 const std::string& name,
1241 ) {
1242 geo_assert(!is_bound());
1243 manager_ = &manager;
1244 geo_assert(manager_->find_attribute_store(name) == nullptr);
1245 store_ = new TypedAttributeStore<T>(dimension);
1246 manager_->bind_attribute_store(name,store_);
1247 register_me(store_);
1248 }
1249
1256 void destroy() {
1258 unregister_me(store_);
1259 manager_->delete_attribute_store(store_);
1260 store_ = nullptr;
1261 manager_ = nullptr;
1262 }
1263
1273 void redim(index_t new_dim) {
1275 store_->redim(new_dim);
1276 }
1277
1286 if(is_bound()) {
1287 unbind();
1288 }
1289 }
1290
1291
1299 static bool is_defined(
1300 AttributesManager& manager, const std::string& name,
1301 index_t dim = 0
1302 ) {
1304 return (
1305 store != nullptr &&
1306 store->elements_type_matches(typeid(T).name()) &&
1307 ((dim == 0) || (store->dimension() == dim))
1308 );
1309 }
1310
1315 index_t size() const {
1316 return size_;
1317 }
1318
1323 void zero() {
1325 store_->zero();
1326 }
1327
1338 return(
1339 dynamic_cast<TypedAttributeStore<T>*>(store_) != nullptr
1340 );
1341 }
1342
1354 TypedAttributeStore<T>* typed_store =
1355 dynamic_cast<TypedAttributeStore<T>*>(store_);
1356 geo_assert(typed_store != nullptr);
1357 return typed_store->get_vector();
1358 }
1359
1366 const vector<T>& get_vector() const {
1367 TypedAttributeStore<T>* typed_store =
1368 dynamic_cast<TypedAttributeStore<T>*>(store_);
1369 geo_assert(typed_store != nullptr);
1370 return typed_store->get_vector();
1371 }
1372
1378 return manager_;
1379 }
1380
1381 protected:
1382 AttributesManager* manager_;
1383 AttributeStore* store_;
1384 } ;
1385
1386 /*********************************************************************/
1387
1394 template <class T> class Attribute : public AttributeBase<T> {
1395 public:
1397
1403 static void static_test_type() {
1404 // Attributes are only implemented for classes that
1405 // can be copied with memcpy() and read/written to
1406 // files using fread()/fwrite()
1407#if __GNUG__ && __GNUC__ < 5 && !__clang__
1408 static_assert(
1409 __has_trivial_copy(T),
1410 "Attribute only implemented for types that can be copied with memcpy()"
1411 );
1412#else
1413 static_assert(
1414 std::is_trivially_copyable<T>::value,
1415 "Attribute only implemented for types that can be copied with memcpy()"
1416 );
1417#endif
1418 }
1419
1425 }
1426
1436 Attribute(AttributesManager& manager, const std::string& name) :
1437 superclass(manager, name) {
1439 }
1440
1448 return ((T*)(void*)superclass::base_addr_)[i];
1449 }
1450
1456 const T& operator[](index_t i) const {
1458 return ((const T*)(void*)superclass::base_addr_)[i];
1459 }
1460
1466 void fill(const T& val) {
1467 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1468 (*this)[i] = val;
1469 }
1470 }
1471
1478 void copy(const Attribute<T>& rhs) {
1479 geo_assert(rhs.size() == superclass::size());
1481 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1482 (*this)[i] = rhs[i];
1483 }
1484 }
1485
1490 T* data() {
1491 return (T*)AttributeStoreObserver::base_addr_;
1492 }
1493
1498 const T* data() const {
1499 return (const T*)AttributeStoreObserver::base_addr_;
1500 }
1501
1502
1503 private:
1507 Attribute(const Attribute<T>& rhs);
1511 Attribute<T>& operator=(const Attribute<T>& rhs);
1512 };
1513
1514 /*********************************************************************/
1515
1524 template <> class Attribute<bool> : public AttributeBase<Numeric::uint8> {
1525 public:
1527
1528 Attribute() : superclass() {
1529 }
1530
1531 Attribute(AttributesManager& manager, const std::string& name) :
1532 superclass(manager,name) {
1533 }
1534
1535 class BoolAttributeAccessor;
1536
1537
1542 class ConstBoolAttributeAccessor {
1543 public:
1548 const Attribute<bool>& attribute,
1549 index_t index
1550 ) :
1551 attribute_(&attribute),
1552 index_(index) {
1553 }
1554
1559 operator bool() const {
1560 return (attribute_->element(index_) != 0);
1561 }
1562
1563 private:
1564 const Attribute<bool>* attribute_;
1565 index_t index_;
1566
1567 friend class BoolAttributeAccessor;
1568 };
1569
1574 class BoolAttributeAccessor {
1575 public:
1580 Attribute<bool>& attribute,
1581 index_t index
1582 ) :
1583 attribute_(&attribute),
1584 index_(index) {
1585 }
1586
1591 operator bool() const {
1592 return (attribute_->element(index_) != 0);
1593 }
1594
1600 BoolAttributeAccessor(const BoolAttributeAccessor& rhs) {
1601 attribute_ = rhs.attribute_;
1602 index_ = rhs.index_;
1603 }
1604
1609 BoolAttributeAccessor& operator=(bool x) {
1610 attribute_->element(index_) = Numeric::uint8(x);
1611 return *this;
1612 }
1613
1619 BoolAttributeAccessor& operator=(
1620 const BoolAttributeAccessor& rhs
1621 ) {
1622 if(&rhs != this) {
1623 attribute_->element(index_) =
1624 rhs.attribute_->element(rhs.index_);
1625 }
1626 return *this;
1627 }
1628
1634 BoolAttributeAccessor& operator=(
1635 const ConstBoolAttributeAccessor& rhs
1636 ) {
1637 attribute_->element(index_) =
1638 rhs.attribute_->element(rhs.index_);
1639 return *this;
1640 }
1641
1642 private:
1643 Attribute<bool>* attribute_;
1644 index_t index_;
1645 };
1646
1647
1648 BoolAttributeAccessor operator[](index_t i) {
1649 return BoolAttributeAccessor(*this,i);
1650 }
1651
1652 ConstBoolAttributeAccessor operator[](index_t i) const {
1653 return ConstBoolAttributeAccessor(*this,i);
1654 }
1655
1661 void fill(bool val) {
1662 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1663 element(i) = Numeric::uint8(val);
1664 }
1665 }
1666
1667 protected:
1668
1669 friend class BoolAttributeAccessor;
1670 friend class ConstBoolAttributeAccessor;
1671
1679 return ((Numeric::uint8*)superclass::base_addr_)[i];
1680 }
1681
1689 return ((const Numeric::uint8*)superclass::base_addr_)[i];
1690 }
1691
1692 private:
1696 Attribute(const Attribute<bool>& rhs);
1700 Attribute<bool>& operator=(const Attribute<bool>& rhs);
1701 } ;
1702
1703 /***********************************************************/
1704
1709 class GEOGRAM_API ScalarAttributeAdapterBase :
1710 public AttributeStoreObserver {
1711
1712 public:
1717 ET_NONE=0,
1718 ET_UINT8=1,
1719 ET_INT8=2,
1720 ET_UINT32=3,
1721 ET_INT32=4,
1722 ET_FLOAT32=5,
1723 ET_FLOAT64=6,
1724 ET_VEC2=7,
1725 ET_VEC3=8
1726 };
1727
1728
1733 class Accessor {
1734 public:
1735 Accessor(
1736 ScalarAttributeAdapterBase& attribute,
1737 index_t index
1738 ) : attribute_(attribute), index_(index) {
1739 }
1740
1741 operator double() const {
1742 return attribute_.get_element_as_double(index_);
1743 }
1744
1745 void operator=(double x) {
1746 attribute_.set_element_as_double(index_, x);
1747 }
1748
1749 private:
1750 ScalarAttributeAdapterBase& attribute_;
1751 index_t index_;
1752 };
1753
1759 public:
1761 const ScalarAttributeAdapterBase& attribute,
1762 index_t index
1763 ) : attribute_(attribute), index_(index) {
1764 }
1765
1766 operator double() const {
1767 return attribute_.get_element_as_double(index_);
1768 }
1769
1770 private:
1771 const ScalarAttributeAdapterBase& attribute_;
1772 index_t index_;
1773 };
1774
1779 manager_(nullptr),
1780 store_(nullptr),
1781 element_type_(ET_NONE),
1782 element_index_(index_t(-1)) {
1783 }
1784
1795 const AttributesManager& manager, const std::string& name
1796 ) :
1797 manager_(nullptr),
1798 store_(nullptr) {
1799 bind_if_is_defined(manager, name);
1800 }
1801
1807 bool is_bound() const {
1808 return (store_ != nullptr);
1809 }
1810
1815 void unbind() {
1816 geo_assert(is_bound());
1817 unregister_me(const_cast<AttributeStore*>(store_));
1818 manager_ = nullptr;
1819 store_ = nullptr;
1820 element_type_ = ET_NONE;
1821 element_index_ = index_t(-1);
1822 }
1823
1834 const AttributesManager& manager, const std::string& name
1835 );
1836
1845 if(is_bound()) {
1846 unbind();
1847 }
1848 }
1849
1859 static bool is_defined(
1860 const AttributesManager& manager, const std::string& name
1861 );
1862
1867 index_t size() const {
1868 return (store_ == nullptr) ? 0 : store_->size();
1869 }
1870
1879 return element_type_;
1880 }
1881
1889 return element_index_;
1890 }
1891
1897 return store_;
1898 }
1899
1900
1908 static bool can_be_bound_to(const AttributeStore* store) {
1909 return element_type(store) != ET_NONE;
1910 }
1911
1920
1921 protected:
1930 static std::string attribute_base_name(const std::string& name);
1931
1940 static index_t attribute_element_index(const std::string& name);
1941
1950
1959 double result = 0.0;
1960 switch(element_type()) {
1961 case ET_UINT8:
1962 result = double(get_element<Numeric::uint8>(i));
1963 break;
1964 case ET_INT8:
1965 result = double(get_element<Numeric::int8>(i));
1966 break;
1967 case ET_UINT32:
1968 result = double(get_element<Numeric::uint32>(i));
1969 break;
1970 case ET_INT32:
1971 result = double(get_element<Numeric::int32>(i));
1972 break;
1973 case ET_FLOAT32:
1974 result = double(get_element<Numeric::float32>(i));
1975 break;
1976 case ET_FLOAT64:
1977 result = double(get_element<Numeric::float64>(i));
1978 break;
1979 case ET_VEC2:
1980 result = double(get_element<Numeric::float64>(i,2));
1981 break;
1982 case ET_VEC3:
1983 result = double(get_element<Numeric::float64>(i,3));
1984 break;
1985 case ET_NONE:
1987 }
1988 return result;
1989 }
1990
1999 template <class T> T get_element(index_t i,index_t multiplier=1) const {
2000 geo_debug_assert(is_bound());
2001 geo_debug_assert(i < size());
2002 return static_cast<const T*>(store_->data())[
2003 (i * store_->dimension() * multiplier) +
2004 element_index_
2005 ];
2006 }
2007
2014 double set_element_as_double(index_t i, double value) {
2015 double result = 0.0;
2016 switch(element_type()) {
2017 case ET_UINT8:
2018 set_element<Numeric::uint8>(Numeric::uint8(value), i);
2019 break;
2020 case ET_INT8:
2021 set_element<Numeric::int8>(Numeric::int8(value),i);
2022 break;
2023 case ET_UINT32:
2024 set_element<Numeric::uint32>(Numeric::uint32(value),i);
2025 break;
2026 case ET_INT32:
2027 set_element<Numeric::int32>(Numeric::int32(value),i);
2028 break;
2029 case ET_FLOAT32:
2030 set_element<Numeric::float32>(Numeric::float32(value),i);
2031 break;
2032 case ET_FLOAT64:
2033 set_element<Numeric::float64>(Numeric::float64(value),i);
2034 break;
2035 case ET_VEC2:
2036 set_element<Numeric::float64>(Numeric::float64(value),i,2);
2037 break;
2038 case ET_VEC3:
2039 set_element<Numeric::float64>(Numeric::float64(value),i,3);
2040 break;
2041 case ET_NONE:
2043 }
2044 return result;
2045 }
2046
2056 template <class T> void set_element(
2057 T value, index_t i, index_t multiplier=1
2058 ) const {
2059 geo_debug_assert(is_bound());
2060 geo_debug_assert(i < size());
2061 const_cast<T*>(static_cast<const T*>(store_->data()))[
2062 (i * store_->dimension() * multiplier) +
2063 element_index_
2064 ] = value;
2065 }
2066
2067 protected:
2068 const AttributesManager* manager_;
2069 const AttributeStore* store_;
2070 ElementType element_type_;
2071 index_t element_index_;
2072 };
2073
2074 /***********************************************************/
2075
2081 public:
2083 }
2084
2086 const AttributesManager& manager, const std::string& name
2087 ) : ScalarAttributeAdapterBase(manager, name) {
2088 }
2089
2098 return get_element_as_double(i);
2099 }
2100 };
2101
2102 /***********************************************************/
2103
2109 public:
2111 }
2112
2114 const AttributesManager& manager, const std::string& name
2115 ) : ScalarAttributeAdapterBase(manager, name) {
2116 }
2117
2118 Accessor operator[](index_t i) {
2119 return Accessor(*this, i);
2120 }
2121
2122 ConstAccessor operator[](index_t i) const {
2123 return ConstAccessor(*this, i);
2124 }
2125
2126 protected:
2127 };
2128
2129
2130}
2131
2132#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
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.
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.
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:163
~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: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
void disconnect()
Disconnects this AttributeStoreObserver from its AttributeStore.
Definition attributes.h:141
void unregister_me(AttributeStore *store)
Unregisters this observer from an AttributeStore.
index_t dimension() const
Gets the dimension.
Definition attributes.h:108
Notifies a set of AttributeStoreObservers each time the stored array changes size and/or base address...
Definition attributes.h:195
void * data()
Gets a pointer to the stored data.
Definition attributes.h:416
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:476
bool has_observers() const
Tests whether observers listen to this AttributeStore.
Definition attributes.h:276
void zero_item(index_t to)
Sets an item to zero.
Definition attributes.h:378
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:507
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:524
index_t size() const
Gets the size.
Definition attributes.h:238
const void * data() const
Gets a pointer to the stored data.
Definition attributes.h:424
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:247
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_type_name_is_known(const std::string &element_type_name)
Tests whether a given element type is registered in the system.
Definition attributes.h:444
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:363
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:461
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:285
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:492
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:432
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:834
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:852
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.
Definition attributes.h:949
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:869
void clear(bool keep_attributes, bool keep_memory=false)
Clears this AttributesManager.
index_t capacity() const
Gets the capacity.
Definition attributes.h:878
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:781
AttributeStore * create_attribute_store(index_t dim) override
Creates a new attribute store.
Definition attributes.h:786
Stores an array of elements of a given type, and notifies a set of AttributeStoreObservers each time ...
Definition attributes.h:607
void scale_item(index_t to, double s) override
Scales an item.
Definition attributes.h:693
TypedAttributeStore(index_t dim=1)
Creates a new empty attribute store.
Definition attributes.h:616
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:711
void clear(bool keep_memory=false) override
Resizes this AttributeStore to 0.
Definition attributes.h:641
AttributeStore * clone() const override
Creates a new AttributeStore that is a carbon copy of this AttributeStore.
Definition attributes.h:681
void resize(index_t new_size) override
Resizes this AttributeStore.
Definition attributes.h:620
std::string element_typeid_name() const override
Gets the typeid name of the element type stored in this AttributeStore.
Definition attributes.h:677
void reserve(index_t new_capacity) override
Reserves memory.
Definition attributes.h:629
bool elements_type_matches(const std::string &type_name) const override
Tests whether this AttributeStore stores elements of a given type.
Definition attributes.h:671
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:700
void redim(index_t dim) override
Sets the dimension.
Definition attributes.h:651
Helper class to register new attribute types.
Definition attributes.h:797
geo_register_attribute_type(const std::string &type_name)
geo_register_attribute_type constructor
Definition attributes.h:808
Vector with aligned memory allocation.
Definition memory.h:660
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: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 algorithm.h:65
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
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:188
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.