Geogram Version 1.9.6
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
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 return base_addr_;
127 }
128
134
140
148 void disconnect() {
149 base_addr_ = nullptr;
150 size_ = 0;
151 dimension_ = 0;
152 disconnected_ = true;
153 }
154
161 bool disconnected() const {
162 return disconnected_;
163 }
164
165 protected:
166 Memory::pointer base_addr_;
167 index_t size_;
168 index_t dimension_;
169 bool disconnected_;
170 };
171
172
173 /*********************************************************************/
174
175
180 class GEOGRAM_API AttributeStoreCreator : public Counted {
181 public:
182
187
194
195
196 private:
197 std::string element_type_name_;
198 std::string element_typeid_name_;
199 };
200
206
212 class GEOGRAM_API AttributeStore {
213 public:
223 AttributeStore(size_t elemsize, index_t dim=1);
224
229
230
241 const std::string& type_name
242 ) const = 0;
243
249 virtual std::string element_typeid_name() const = 0;
250
255 index_t size() const {
256 return cached_size_;
257 }
258
265 return cached_capacity_;
266 }
267
272 virtual void resize(index_t new_size) = 0;
273
279 virtual void reserve(index_t new_capacity) = 0;
280
286 virtual void clear(bool keep_memory = false) = 0;
287
293 bool has_observers() const {
294 return !observers_.empty();
295 }
296
303 return dimension_;
304 }
305
315 virtual void redim(index_t dim) = 0;
316
317
335 virtual void apply_permutation(
336 const vector<index_t>& permutation
337 );
338
356 virtual void compress(const vector<index_t>& old2new);
357
365 virtual void zero();
366
372 virtual AttributeStore* clone() const = 0;
373
374
380 void copy_item(index_t to, index_t from) {
381 geo_debug_assert(from < cached_size_);
382 geo_debug_assert(to < cached_size_);
383 size_t item_size = element_size_ * dimension_;
384 Memory::copy(
385 cached_base_addr_+to*item_size,
386 cached_base_addr_+from*item_size,
387 item_size
388 );
389 }
390
396 geo_debug_assert(to < cached_size_);
397 size_t item_size = element_size_ * dimension_;
398 Memory::clear(
399 cached_base_addr_+to*item_size,
400 item_size
401 );
402 }
403
411 virtual void scale_item(index_t to, double s);
412
421 virtual void madd_item(index_t to, double s, index_t from);
422
428
433 void* data() {
434 return cached_base_addr_;
435 }
436
441 const void* data() const {
442 return cached_base_addr_;
443 }
444
449 size_t element_size() const {
450 return element_size_;
451 }
452
462 const std::string& element_type_name
463 ) {
464 return (
465 type_name_to_creator_.find(element_type_name) !=
466 type_name_to_creator_.end()
467 );
468 }
469
479 const std::string& element_typeid_name
480 ) {
481 return (
482 typeid_name_to_type_name_.find(element_typeid_name) !=
483 typeid_name_to_type_name_.end()
484 );
485 }
486
494 const std::string& element_type_name,
495 index_t dimension
496 ) {
497 geo_assert(element_type_name_is_known(element_type_name));
498 return type_name_to_creator_[element_type_name]->
499 create_attribute_store(dimension);
500 }
501
510 const std::string& element_typeid_name
511 ) {
512 geo_assert(element_typeid_name_is_known(element_typeid_name));
513 return typeid_name_to_type_name_[element_typeid_name];
514 }
515
525 const std::string& element_type_name
526 ) {
527 geo_assert(element_type_name_is_known(element_type_name));
528 return type_name_to_typeid_name_[element_type_name];
529 }
530
542 AttributeStoreCreator* creator,
543 const std::string& element_type_name,
544 const std::string& element_typeid_name
545 );
546
547 protected:
556 virtual void notify(
557 Memory::pointer base_addr, index_t size, index_t dim
558 );
559
569
578
579
580 protected:
581 size_t element_size_;
582 index_t dimension_;
583 Memory::pointer cached_base_addr_;
584 index_t cached_size_;
585 index_t cached_capacity_;
586 std::set<AttributeStoreObserver*> observers_;
587 Process::spinlock lock_;
588
589 static std::map<std::string, AttributeStoreCreator_var>
590 type_name_to_creator_;
591
592 static std::map<std::string, std::string>
593 typeid_name_to_type_name_;
594
595 static std::map<std::string, std::string>
596 type_name_to_typeid_name_;
597
598 friend class AttributeStoreObserver;
599 };
600
601 /*********************************************************************/
602
608 template <class T> class TypedAttributeStore : public AttributeStore {
609 public:
610
618 AttributeStore(sizeof(T),dim) {
619 }
620
621 void resize(index_t new_size) override {
622 store_.resize(new_size*dimension_);
623 notify(
624 store_.empty() ? nullptr : Memory::pointer(store_.data()),
625 new_size,
626 dimension_
627 );
628 }
629
630 void reserve(index_t new_capacity) override {
631 if(new_capacity > capacity()) {
632 store_.reserve(new_capacity*dimension_);
633 cached_capacity_ = new_capacity;
634 notify(
635 store_.empty() ? nullptr : Memory::pointer(store_.data()),
636 size(),
637 dimension_
638 );
639 }
640 }
641
642 void clear(bool keep_memory=false) override {
643 if(keep_memory) {
644 store_.resize(0);
645 } else {
646 store_.clear();
647 }
648 notify(nullptr, 0, dimension_);
649 }
650
651
652 void redim(index_t dim) override {
653 if(dim == dimension()) {
654 return;
655 }
656 vector<T> new_store(size()*dim);
657 new_store.reserve(capacity()*dim);
658 index_t copy_dim = std::min(dim, dimension());
659 for(index_t i = 0; i < size(); ++i) {
660 for(index_t c = 0; c < copy_dim; ++c) {
661 new_store[dim * i + c] = store_[dimension_ * i + c];
662 }
663 }
664 store_.swap(new_store);
665 notify(
666 store_.empty() ? nullptr : Memory::pointer(store_.data()),
667 size(),
668 dim
669 );
670 }
671
672 bool elements_type_matches(const std::string& type_name) const override {
673 return type_name == typeid(T).name();
674 }
675
676 std::string element_typeid_name() const override {
677 return typeid(T).name();
678 }
679
680 AttributeStore* clone() const override {
681 TypedAttributeStore<T>* result =
683 result->resize(size());
684 result->store_ = store_;
685 return result;
686 }
687
688 vector<T>& get_vector() {
689 return store_;
690 }
691
692 void scale_item(index_t to, double s) override {
693 geo_assert(to < size());
694 for(index_t i=0; i<dimension_; ++i) {
695 scale_value(store_[to*dimension_+i], s);
696 }
697 }
698
699 void madd_item(index_t to, double s, index_t from) override {
700 geo_assert(from < size());
701 geo_assert(to < size());
702 for(index_t i=0; i<dimension_; ++i) {
703 madd_value(
704 store_[to*dimension_+i], s, store_[from*dimension_+i]
705 );
706 }
707 }
708
709 protected:
710 void notify(
711 Memory::pointer base_addr, index_t size, index_t dim
712 ) override {
713 AttributeStore::notify(base_addr, size, dim);
714 geo_assert(size*dim <= store_.size());
715 }
716
717 template<class TT> static void scale_value(TT& to, double s) {
718 geo_argused(to);
719 geo_argused(s);
720 }
721
722 static void scale_value(uint8_t& to, double s) {
723 to = uint8_t(double(to)*s != 0.0);
724 }
725
726 static void scale_value(int32_t& to, double s) {
727 to = int32_t(double(to)*s);
728 }
729
730 static void scale_value(uint32_t& to, double s) {
731 to = uint32_t(double(to)*s);
732 }
733
734 static void scale_value(float& to, double s) {
735 to = float(double(to)*s);
736 }
737
738 static void scale_value(double& to, double s) {
739 to *= s;
740 }
741
742 template<class TT> static void madd_value(TT& to, double s, TT& from) {
743 geo_argused(to);
744 geo_argused(s);
745 geo_argused(from);
746 }
747
748 static void madd_value(uint8_t& to, double s, uint8_t& from) {
749 to = uint8_t(double(to) + s*double(from) != 0.0);
750 }
751
752 static void madd_value(int32_t& to, double s, int32_t& from) {
753 to = int32_t(double(to) + s*double(from));
754 }
755
756 static void madd_value(uint32_t& to, double s, uint32_t& from) {
757 to = uint32_t(double(to) + s*double(from));
758 }
759
760 static void madd_value(float& to, double s, float& from) {
761 to = float(double(to) + s*double(from));
762 }
763
764 static void madd_value(double& to, double s, double& from) {
765 to += s*from;
766 }
767
768
769 private:
770 vector<T> store_;
771 };
772
773 /*********************************************************************/
774
779 template <class T>
781 public:
786 return new TypedAttributeStore<T>(dim);
787 }
788 };
789
790 /*********************************************************************/
791
796 template <class T> class geo_register_attribute_type {
797 public:
807 geo_register_attribute_type(const std::string& type_name) {
809 new TypedAttributeStoreCreator<T>, type_name, typeid(T).name()
810 );
811 if(type_name == "bool") {
813 type_name,
816 );
817 } else {
819 type_name,
820 read_ascii_attribute<T>,
821 write_ascii_attribute<T>
822 );
823 }
824 }
825 };
826
827 /*********************************************************************/
828
833 class GEOGRAM_API AttributesManager {
834 public:
839
840
845
851 index_t nb() const {
852 return index_t(attributes_.size());
853 }
854
861
868 index_t size() const {
869 return size_;
870 }
871
878 return capacity_;
879 }
880
887 void resize(index_t new_size);
888
895 void reserve(index_t new_capacity);
896
905 void clear(bool keep_attributes, bool keep_memory = false);
906
907
911 void zero();
912
921 void bind_attribute_store(const std::string& name, AttributeStore* as);
922
929 AttributeStore* find_attribute_store(const std::string& name);
930
938 const std::string& name
939 ) const;
940
941
948 bool is_defined(const std::string& name) const {
949 return (find_attribute_store(name) != nullptr);
950 }
951
957 void delete_attribute_store(const std::string& name);
958
965
982 const vector<index_t>& permutation
983 );
984
1000 void compress(const vector<index_t>& old2new);
1001
1006 void copy(const AttributesManager& rhs);
1007
1008
1015 void copy_item(index_t to, index_t from);
1016
1023
1024
1030
1038 void scale_item(index_t to, double s);
1039
1048 void madd_item(index_t to, double s, index_t from);
1049
1059 const std::string& name, const std::string& new_name
1060 );
1061
1071 const std::string& old_name, const std::string& new_name
1072 );
1073
1074 private:
1082 AttributesManager(const AttributesManager& rhs) = delete;
1083
1091 const AttributesManager& operator=(const AttributesManager& rhs) = delete;
1092
1093 private:
1094 index_t size_;
1095 index_t capacity_;
1096 std::map<std::string, AttributeStore*> attributes_;
1097 } ;
1098
1099
1100 /*********************************************************************/
1101
1102
1107 template <class T> class AttributeBase : public AttributeStoreObserver {
1108 public:
1109
1114 manager_(nullptr),
1115 store_(nullptr) {
1116 }
1117
1127 AttributeBase(AttributesManager& manager, const std::string& name) :
1128 manager_(nullptr),
1129 store_(nullptr) {
1130 bind(manager, name);
1131 }
1132
1138 bool is_bound() const {
1139 return (store_ != nullptr && !disconnected_);
1140 }
1141
1146 void unbind() {
1148 // If the AttributesManager was destroyed before, do not
1149 // do anything. This can occur in Lua scripting when using
1150 // Attribute wrapper objects.
1151 if(!disconnected_) {
1152 unregister_me(store_);
1153 }
1154 manager_ = nullptr;
1155 store_ = nullptr;
1156 }
1157
1167 void bind(AttributesManager& manager, const std::string& name) {
1168 geo_assert(!is_bound());
1169 manager_ = &manager;
1170 store_ = manager_->find_attribute_store(name);
1171 if(store_ == nullptr) {
1172 store_ = new TypedAttributeStore<T>();
1173 manager_->bind_attribute_store(name,store_);
1174 } else {
1175 geo_assert(store_->elements_type_matches(typeid(T).name()));
1176 }
1177 register_me(store_);
1178 }
1179
1180
1190 AttributesManager& manager, const std::string& name
1191 ) {
1192 geo_assert(!is_bound());
1193 manager_ = &manager;
1194 store_ = manager_->find_attribute_store(name);
1195 if(store_ != nullptr) {
1196 geo_assert(store_->elements_type_matches(typeid(T).name()));
1197 register_me(store_);
1198 return true;
1199 }
1200 return false;
1201 }
1202
1212 AttributesManager& manager, const std::string& name
1213 ) {
1214 if( is_bound() ) {
1215 unbind();
1216 }
1217 store_ = manager.find_attribute_store(name);
1218 if(store_ != nullptr) {
1219 if( !store_->elements_type_matches(typeid(T).name()) ) {
1220 store_ = nullptr;
1221 return false;
1222 }
1223 manager_ = &manager;
1224 register_me(store_);
1225 return true;
1226 }
1227 return false;
1228 }
1229
1238 const std::string& name,
1240 ) {
1241 geo_assert(!is_bound());
1242 manager_ = &manager;
1243 geo_assert(manager_->find_attribute_store(name) == nullptr);
1244 store_ = new TypedAttributeStore<T>(dimension);
1245 manager_->bind_attribute_store(name,store_);
1246 register_me(store_);
1247 }
1248
1255 void destroy() {
1257 unregister_me(store_);
1258 manager_->delete_attribute_store(store_);
1259 store_ = nullptr;
1260 manager_ = nullptr;
1261 }
1262
1272 void redim(index_t new_dim) {
1274 store_->redim(new_dim);
1275 }
1276
1285 if(is_bound()) {
1286 unbind();
1287 }
1288 }
1289
1290
1298 static bool is_defined(
1299 AttributesManager& manager, const std::string& name,
1300 index_t dim = 0
1301 ) {
1303 return (
1304 store != nullptr &&
1305 store->elements_type_matches(typeid(T).name()) &&
1306 ((dim == 0) || (store->dimension() == dim))
1307 );
1308 }
1309
1314 index_t size() const {
1315 return size_;
1316 }
1317
1322 void zero() {
1324 store_->zero();
1325 }
1326
1337 return(
1338 dynamic_cast<TypedAttributeStore<T>*>(store_) != nullptr
1339 );
1340 }
1341
1353 TypedAttributeStore<T>* typed_store =
1354 dynamic_cast<TypedAttributeStore<T>*>(store_);
1355 geo_assert(typed_store != nullptr);
1356 return typed_store->get_vector();
1357 }
1358
1365 const vector<T>& get_vector() const {
1366 TypedAttributeStore<T>* typed_store =
1367 dynamic_cast<TypedAttributeStore<T>*>(store_);
1368 geo_assert(typed_store != nullptr);
1369 return typed_store->get_vector();
1370 }
1371
1377 return manager_;
1378 }
1379
1380 protected:
1381 AttributesManager* manager_;
1382 AttributeStore* store_;
1383 } ;
1384
1385 /*********************************************************************/
1386
1393 template <class T> class Attribute : public AttributeBase<T> {
1394 public:
1396
1402 static void static_test_type() {
1403 // Attributes are only implemented for classes that
1404 // can be copied with memcpy() and read/written to
1405 // files using fread()/fwrite()
1406#if __GNUG__ && __GNUC__ < 5 && !__clang__
1407 static_assert(
1408 __has_trivial_copy(T),
1409 "Attribute only implemented for types that can be copied with memcpy()"
1410 );
1411#else
1412 static_assert(
1413 std::is_trivially_copyable<T>::value,
1414 "Attribute only implemented for types that can be copied with memcpy()"
1415 );
1416#endif
1417 }
1418
1424 }
1425
1435 Attribute(AttributesManager& manager, const std::string& name) :
1436 superclass(manager, name) {
1438 }
1439
1448 return ((T*)(void*)superclass::base_addr_)[i];
1449 }
1450
1456 const T& operator[](index_t i) const {
1459 return ((const T*)(void*)superclass::base_addr_)[i];
1460 }
1461
1467 void fill(const T& val) {
1469 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1470 (*this)[i] = val;
1471 }
1472 }
1473
1480 void copy(const Attribute<T>& rhs) {
1481 geo_assert(rhs.size() == superclass::size());
1483 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1484 (*this)[i] = rhs[i];
1485 }
1486 }
1487
1492 T* data() {
1493 return (T*)AttributeStoreObserver::base_addr_;
1494 }
1495
1500 const T* data() const {
1501 return (const T*)AttributeStoreObserver::base_addr_;
1502 }
1503
1504
1505 private:
1509 Attribute(const Attribute<T>& rhs) = delete;
1513 Attribute<T>& operator=(const Attribute<T>& rhs) = delete;
1514 };
1515
1516 /*********************************************************************/
1517
1526 template <> class Attribute<bool> : public AttributeBase<Numeric::uint8> {
1527 public:
1529
1530 Attribute() : superclass() {
1531 }
1532
1533 Attribute(AttributesManager& manager, const std::string& name) :
1534 superclass(manager,name) {
1535 }
1536
1537 class BoolAttributeAccessor;
1538
1539
1544 class ConstBoolAttributeAccessor {
1545 public:
1550 const Attribute<bool>& attribute,
1551 index_t index
1552 ) :
1553 attribute_(&attribute),
1554 index_(index) {
1555 }
1556
1561 operator bool() const {
1562 return (attribute_->element(index_) != 0);
1563 }
1564
1565 private:
1566 const Attribute<bool>* attribute_;
1567 index_t index_;
1568
1569 friend class BoolAttributeAccessor;
1570 };
1571
1576 class BoolAttributeAccessor {
1577 public:
1582 Attribute<bool>& attribute,
1583 index_t index
1584 ) :
1585 attribute_(&attribute),
1586 index_(index) {
1587 }
1588
1593 operator bool() const {
1594 return (attribute_->element(index_) != 0);
1595 }
1596
1602 BoolAttributeAccessor(const BoolAttributeAccessor& rhs) {
1603 attribute_ = rhs.attribute_;
1604 index_ = rhs.index_;
1605 }
1606
1611 BoolAttributeAccessor& operator=(bool x) {
1612 attribute_->element(index_) = Numeric::uint8(x);
1613 return *this;
1614 }
1615
1621 BoolAttributeAccessor& operator=(
1622 const BoolAttributeAccessor& rhs
1623 ) {
1624 if(&rhs != this) {
1625 attribute_->element(index_) =
1626 rhs.attribute_->element(rhs.index_);
1627 }
1628 return *this;
1629 }
1630
1636 BoolAttributeAccessor& operator=(
1637 const ConstBoolAttributeAccessor& rhs
1638 ) {
1639 attribute_->element(index_) =
1640 rhs.attribute_->element(rhs.index_);
1641 return *this;
1642 }
1643
1644 private:
1645 Attribute<bool>* attribute_;
1646 index_t index_;
1647 };
1648
1649
1650 BoolAttributeAccessor operator[](index_t i) {
1651 return BoolAttributeAccessor(*this,i);
1652 }
1653
1654 ConstBoolAttributeAccessor operator[](index_t i) const {
1655 return ConstBoolAttributeAccessor(*this,i);
1656 }
1657
1663 void fill(bool val) {
1664 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1665 element(i) = Numeric::uint8(val);
1666 }
1667 }
1668
1675 void copy(const Attribute<bool>& rhs) {
1676 geo_assert(rhs.size() == superclass::size());
1678 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1679 element(i) = rhs.element(i);
1680 }
1681 }
1682
1683 protected:
1684
1685 friend class BoolAttributeAccessor;
1686 friend class ConstBoolAttributeAccessor;
1687
1695 return ((Numeric::uint8*)superclass::base_addr_)[i];
1696 }
1697
1705 return ((const Numeric::uint8*)superclass::base_addr_)[i];
1706 }
1707
1708 private:
1712 Attribute(const Attribute<bool>& rhs) = delete;
1716 Attribute<bool>& operator=(const Attribute<bool>& rhs) = delete;
1717 } ;
1718
1719 /***********************************************************/
1720
1725 class GEOGRAM_API ScalarAttributeAdapterBase :
1726 public AttributeStoreObserver {
1727
1728 public:
1733 ET_NONE=0,
1734 ET_UINT8=1,
1735 ET_INT8=2,
1736 ET_UINT32=3,
1737 ET_INT32=4,
1738 ET_FLOAT32=5,
1739 ET_FLOAT64=6,
1740 ET_VEC2=7,
1741 ET_VEC3=8
1742 };
1743
1744
1749 class Accessor {
1750 public:
1751 Accessor(
1752 ScalarAttributeAdapterBase& attribute,
1753 index_t index
1754 ) : attribute_(attribute), index_(index) {
1755 }
1756
1757 operator double() const {
1758 return attribute_.get_element_as_double(index_);
1759 }
1760
1761 void operator=(double x) {
1762 attribute_.set_element_as_double(index_, x);
1763 }
1764
1765 private:
1766 ScalarAttributeAdapterBase& attribute_;
1767 index_t index_;
1768 };
1769
1775 public:
1777 const ScalarAttributeAdapterBase& attribute,
1778 index_t index
1779 ) : attribute_(attribute), index_(index) {
1780 }
1781
1782 operator double() const {
1783 return attribute_.get_element_as_double(index_);
1784 }
1785
1786 private:
1787 const ScalarAttributeAdapterBase& attribute_;
1788 index_t index_;
1789 };
1790
1795 manager_(nullptr),
1796 store_(nullptr),
1797 element_type_(ET_NONE),
1798 element_index_(index_t(-1)) {
1799 }
1800
1811 const AttributesManager& manager, const std::string& name
1812 ) :
1813 manager_(nullptr),
1814 store_(nullptr) {
1815 bind_if_is_defined(manager, name);
1816 }
1817
1823 bool is_bound() const {
1824 return (store_ != nullptr);
1825 }
1826
1831 void unbind() {
1832 geo_assert(is_bound());
1833 unregister_me(const_cast<AttributeStore*>(store_));
1834 manager_ = nullptr;
1835 store_ = nullptr;
1836 element_type_ = ET_NONE;
1837 element_index_ = index_t(-1);
1838 }
1839
1850 const AttributesManager& manager, const std::string& name
1851 );
1852
1861 if(is_bound()) {
1862 unbind();
1863 }
1864 }
1865
1875 static bool is_defined(
1876 const AttributesManager& manager, const std::string& name
1877 );
1878
1883 index_t size() const {
1884 return (store_ == nullptr) ? 0 : store_->size();
1885 }
1886
1895 return element_type_;
1896 }
1897
1905 return element_index_;
1906 }
1907
1913 return store_;
1914 }
1915
1916
1924 static bool can_be_bound_to(const AttributeStore* store) {
1925 return element_type(store) != ET_NONE;
1926 }
1927
1936
1937 protected:
1946 static std::string attribute_base_name(const std::string& name);
1947
1956 static index_t attribute_element_index(const std::string& name);
1957
1966
1975 double result = 0.0;
1976 switch(element_type()) {
1977 case ET_UINT8:
1978 result = double(get_element<Numeric::uint8>(i));
1979 break;
1980 case ET_INT8:
1981 result = double(get_element<Numeric::int8>(i));
1982 break;
1983 case ET_UINT32:
1984 result = double(get_element<Numeric::uint32>(i));
1985 break;
1986 case ET_INT32:
1987 result = double(get_element<Numeric::int32>(i));
1988 break;
1989 case ET_FLOAT32:
1990 result = double(get_element<Numeric::float32>(i));
1991 break;
1992 case ET_FLOAT64:
1993 result = double(get_element<Numeric::float64>(i));
1994 break;
1995 case ET_VEC2:
1996 result = double(get_element<Numeric::float64>(i,2));
1997 break;
1998 case ET_VEC3:
1999 result = double(get_element<Numeric::float64>(i,3));
2000 break;
2001 case ET_NONE:
2003 }
2004 return result;
2005 }
2006
2015 template <class T> T get_element(index_t i,index_t multiplier=1) const {
2016 geo_debug_assert(is_bound());
2017 geo_debug_assert(i < size());
2018 return static_cast<const T*>(store_->data())[
2019 (i * store_->dimension() * multiplier) +
2020 element_index_
2021 ];
2022 }
2023
2030 double set_element_as_double(index_t i, double value) {
2031 double result = 0.0;
2032 switch(element_type()) {
2033 case ET_UINT8:
2034 set_element<Numeric::uint8>(Numeric::uint8(value), i);
2035 break;
2036 case ET_INT8:
2037 set_element<Numeric::int8>(Numeric::int8(value),i);
2038 break;
2039 case ET_UINT32:
2040 set_element<Numeric::uint32>(Numeric::uint32(value),i);
2041 break;
2042 case ET_INT32:
2043 set_element<Numeric::int32>(Numeric::int32(value),i);
2044 break;
2045 case ET_FLOAT32:
2046 set_element<Numeric::float32>(Numeric::float32(value),i);
2047 break;
2048 case ET_FLOAT64:
2049 set_element<Numeric::float64>(Numeric::float64(value),i);
2050 break;
2051 case ET_VEC2:
2052 set_element<Numeric::float64>(Numeric::float64(value),i,2);
2053 break;
2054 case ET_VEC3:
2055 set_element<Numeric::float64>(Numeric::float64(value),i,3);
2056 break;
2057 case ET_NONE:
2059 }
2060 return result;
2061 }
2062
2072 template <class T> void set_element(
2073 T value, index_t i, index_t multiplier=1
2074 ) const {
2075 geo_debug_assert(is_bound());
2076 geo_debug_assert(i < size());
2077 const_cast<T*>(static_cast<const T*>(store_->data()))[
2078 (i * store_->dimension() * multiplier) +
2079 element_index_
2080 ] = value;
2081 }
2082
2083 protected:
2084 const AttributesManager* manager_;
2085 const AttributeStore* store_;
2086 ElementType element_type_;
2087 index_t element_index_;
2088 };
2089
2090 /***********************************************************/
2091
2097 public:
2099 }
2100
2102 const AttributesManager& manager, const std::string& name
2103 ) : ScalarAttributeAdapterBase(manager, name) {
2104 }
2105
2114 return get_element_as_double(i);
2115 }
2116 };
2117
2118 /***********************************************************/
2119
2125 public:
2127 }
2128
2130 const AttributesManager& manager, const std::string& name
2131 ) : ScalarAttributeAdapterBase(manager, name) {
2132 }
2133
2134 Accessor operator[](index_t i) {
2135 return Accessor(*this, i);
2136 }
2137
2138 ConstAccessor operator[](index_t i) const {
2139 return ConstAccessor(*this, i);
2140 }
2141
2142 protected:
2143 };
2144
2145
2146}
2147
2148#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:180
~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
bool disconnected() const
Tests whether this AttributeStoreObserver was disconnected.
Definition attributes.h:161
void disconnect()
Disconnects this AttributeStoreObserver from its AttributeStore.
Definition attributes.h:148
void unregister_me(AttributeStore *store)
Unregisters this observer from an AttributeStore.
index_t dimension() const
Gets the dimension.
Definition attributes.h:107
Memory::pointer base_addr() const
Gets a pointer to the storage.
Definition attributes.h:125
Notifies a set of AttributeStoreObservers each time the stored array changes size and/or base address...
Definition attributes.h:212
void * data()
Gets a pointer to the stored data.
Definition attributes.h:433
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:493
bool has_observers() const
Tests whether observers listen to this AttributeStore.
Definition attributes.h:293
void zero_item(index_t to)
Sets an item to zero.
Definition attributes.h:395
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:524
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:255
const void * data() const
Gets a pointer to the stored data.
Definition attributes.h:441
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:264
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:461
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:380
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:478
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:302
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:509
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:449
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.
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:833
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:851
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:948
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:868
void clear(bool keep_attributes, bool keep_memory=false)
Clears this AttributesManager.
index_t capacity() const
Gets the capacity.
Definition attributes.h:877
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:780
AttributeStore * create_attribute_store(index_t dim) override
Creates a new attribute store.
Definition attributes.h:785
Stores an array of elements of a given type, and notifies a set of AttributeStoreObservers each time ...
Definition attributes.h:608
void scale_item(index_t to, double s) override
Scales an item.
Definition attributes.h:692
TypedAttributeStore(index_t dim=1)
Creates a new empty attribute store.
Definition attributes.h:617
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:710
void clear(bool keep_memory=false) override
Resizes this AttributeStore to 0.
Definition attributes.h:642
AttributeStore * clone() const override
Creates a new AttributeStore that is a carbon copy of this AttributeStore.
Definition attributes.h:680
void resize(index_t new_size) override
Resizes this AttributeStore.
Definition attributes.h:621
std::string element_typeid_name() const override
Gets the typeid name of the element type stored in this AttributeStore.
Definition attributes.h:676
void reserve(index_t new_capacity) override
Reserves memory.
Definition attributes.h:630
bool elements_type_matches(const std::string &type_name) const override
Tests whether this AttributeStore stores elements of a given type.
Definition attributes.h:672
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:699
void redim(index_t dim) override
Sets the dimension.
Definition attributes.h:652
Helper class to register new attribute types.
Definition attributes.h:796
geo_register_attribute_type(const std::string &type_name)
geo_register_attribute_type constructor
Definition attributes.h:807
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...
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: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:205
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.