Geogram Version 1.9.9
A programming library of geometric algorithms
Loading...
Searching...
No Matches
attributes.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40
41#ifndef GEOGRAM_BASIC_ATTRIBUTES
42#define GEOGRAM_BASIC_ATTRIBUTES
43
51
52#include <map>
53#include <typeinfo>
54#include <set>
55#include <type_traits>
56
62namespace GEO {
63
64 class AttributeStore;
65
70 class GEOGRAM_API AttributeStoreObserver {
71 public:
72
77 base_addr_(nullptr), size_(0), dimension_(0),
78 disconnected_(false) {
79 }
80
88 void notify(
89 Memory::pointer base_addr, index_t size, index_t dim
90 ) {
91 base_addr_ = base_addr;
92 size_ = size;
93 dimension_ = dim;
94 }
95
100 index_t size() const {
101 return size_;
102 }
103
109 return dimension_;
110 }
111
119 return size_ * dimension_;
120 }
121
127 return base_addr_;
128 }
129
135
141
149 void disconnect() {
150 base_addr_ = nullptr;
151 size_ = 0;
152 dimension_ = 0;
153 disconnected_ = true;
154 }
155
162 bool disconnected() const {
163 return disconnected_;
164 }
165
166 protected:
167 Memory::pointer base_addr_;
168 index_t size_;
169 index_t dimension_;
170 bool disconnected_;
171 };
172
173
174 /*********************************************************************/
175
176
181 class GEOGRAM_API AttributeStoreCreator : public Counted {
182 public:
183
188
195
203 virtual bool elements_are_trivially_copyable() const = 0;
204
205 private:
206 std::string element_type_name_;
207 std::string element_typeid_name_;
208 };
209
215
221 class GEOGRAM_API AttributeStore {
222 public:
232 AttributeStore(size_t elemsize, index_t dim=1);
233
238
239
250 const std::string& type_name
251 ) const = 0;
252
258 virtual std::string element_typeid_name() const = 0;
259
264 index_t size() const {
265 return cached_size_;
266 }
267
274 return cached_capacity_;
275 }
276
281 virtual void resize(index_t new_size) = 0;
282
288 virtual void reserve(index_t new_capacity) = 0;
289
295 virtual void clear(bool keep_memory = false) = 0;
296
302 bool has_observers() const {
303 return !observers_.empty();
304 }
305
312 return dimension_;
313 }
314
324 virtual void redim(index_t dim) = 0;
325
326
342 virtual void apply_permutation(
343 const vector<index_t>& permutation
344 );
345
346
362 virtual void compress(const vector<index_t>& old2new);
363
368 virtual void zero();
369
375 virtual AttributeStore* clone() const = 0;
376
377
383 void copy_item(index_t to, index_t from) {
384 geo_debug_assert(from < cached_size_);
385 geo_debug_assert(to < cached_size_);
386 size_t item_size = element_size_ * dimension_;
387 if(lifecycle_.is_null()) {
388 Memory::copy(
389 cached_base_addr_+to*item_size,
390 cached_base_addr_+from*item_size,
391 item_size
392 );
393 } else {
394 lifecycle_->assign(
395 cached_base_addr_+to*item_size,
396 cached_base_addr_+from*item_size
397 );
398 }
399 }
400
406 geo_debug_assert(to < cached_size_);
407 size_t item_size = element_size_ * dimension_;
408 if(lifecycle_.is_null()) {
409 Memory::clear(
410 cached_base_addr_+to*item_size,
411 item_size
412 );
413 } else {
414 lifecycle_->reset(cached_base_addr_+to*item_size);
415 }
416 }
417
425 virtual void scale_item(index_t to, double s);
426
435 virtual void madd_item(index_t to, double s, index_t from);
436
442
447 void* data() {
448 return cached_base_addr_;
449 }
450
455 const void* data() const {
456 return cached_base_addr_;
457 }
458
463 size_t element_size() const {
464 return element_size_;
465 }
466
476 const std::string& element_type_name
477 ) {
478 return (
479 type_name_to_creator_.find(element_type_name) !=
480 type_name_to_creator_.end()
481 );
482 }
483
493 const std::string& element_typeid_name
494 ) {
495 return (
496 typeid_name_to_type_name_.find(element_typeid_name) !=
497 typeid_name_to_type_name_.end()
498 );
499 }
500
511 const std::string& element_type_name
512 ) {
513 geo_debug_assert(element_type_name_is_known(element_type_name));
514 return (
515 type_name_to_creator_[
516 element_type_name
517 ]->elements_are_trivially_copyable()
518 );
519 }
520
531 const std::string& element_typeid_name
532 ) {
533 geo_debug_assert(element_typeid_name_is_known(element_typeid_name));
534 std::string element_type_name =
535 typeid_name_to_type_name_[element_typeid_name];
536 return element_by_type_name_is_trivially_copyable(element_type_name);
537 }
538
546 const std::string& element_type_name,
547 index_t dimension
548 ) {
549 geo_assert(element_type_name_is_known(element_type_name));
550 return type_name_to_creator_[element_type_name]->
551 create_attribute_store(dimension);
552 }
553
562 const std::string& element_typeid_name
563 ) {
564 geo_assert(element_typeid_name_is_known(element_typeid_name));
565 return typeid_name_to_type_name_[element_typeid_name];
566 }
567
577 const std::string& element_type_name
578 ) {
579 geo_assert(element_type_name_is_known(element_type_name));
580 return type_name_to_typeid_name_[element_type_name];
581 }
582
594 AttributeStoreCreator* creator,
595 const std::string& element_type_name,
596 const std::string& element_typeid_name
597 );
598
607 return lifecycle_;
608 }
609
610 protected:
611
618 const vector<index_t>& permutation
619 );
620
629 virtual void notify(
630 Memory::pointer base_addr, index_t size, index_t dim
631 );
632
642
651
652
653 protected:
654 size_t element_size_;
655 index_t dimension_;
656 Memory::pointer cached_base_addr_;
657 index_t cached_size_;
658 index_t cached_capacity_;
659 LifeCycle_var lifecycle_;
660 std::set<AttributeStoreObserver*> observers_;
661 Process::spinlock lock_;
662
663 static std::map<std::string, AttributeStoreCreator_var>
664 type_name_to_creator_;
665
666 static std::map<std::string, std::string>
667 typeid_name_to_type_name_;
668
669 static std::map<std::string, std::string>
670 type_name_to_typeid_name_;
671
672 friend class AttributeStoreObserver;
673 };
674
675 /*********************************************************************/
676
682 template <class T> class TypedAttributeStore : public AttributeStore {
683 public:
684
692 AttributeStore(sizeof(T),dim) {
693 if(!std::is_trivially_copyable<T>::value) {
694 lifecycle_ = new GenericLifeCycle<T>();
695 }
696 }
697
698 void resize(index_t new_size) override {
699 store_.resize(new_size*dimension_);
700 notify(
701 store_.empty() ? nullptr : Memory::pointer(store_.data()),
702 new_size,
703 dimension_
704 );
705 }
706
707 void reserve(index_t new_capacity) override {
708 if(new_capacity > capacity()) {
709 store_.reserve(new_capacity*dimension_);
710 cached_capacity_ = new_capacity;
711 notify(
712 store_.empty() ? nullptr : Memory::pointer(store_.data()),
713 size(),
714 dimension_
715 );
716 }
717 }
718
719 void clear(bool keep_memory=false) override {
720 if(keep_memory) {
721 store_.resize(0);
722 } else {
723 store_.clear();
724 }
725 notify(nullptr, 0, dimension_);
726 }
727
728 void redim(index_t dim) override {
729 if(dim == dimension()) {
730 return;
731 }
732 vector<T> new_store(size()*dim);
733 new_store.reserve(capacity()*dim);
734 index_t copy_dim = std::min(dim, dimension());
735 for(index_t i = 0; i < size(); ++i) {
736 for(index_t c = 0; c < copy_dim; ++c) {
737 new_store[dim * i + c] = store_[dimension_ * i + c];
738 }
739 }
740 store_.swap(new_store);
741 notify(
742 store_.empty() ? nullptr : Memory::pointer(store_.data()),
743 size(),
744 dim
745 );
746 }
747
748 bool elements_type_matches(const std::string& type_name) const override {
749 return type_name == typeid(T).name();
750 }
751
752 std::string element_typeid_name() const override {
753 return typeid(T).name();
754 }
755
756 AttributeStore* clone() const override {
757 TypedAttributeStore<T>* result =
759 result->resize(size());
760 result->store_ = store_;
761 result->lifecycle_ = lifecycle_;
762 return result;
763 }
764
765 vector<T>& get_vector() {
766 return store_;
767 }
768
769 void scale_item(index_t to, double s) override {
770 geo_assert(to < size());
771 for(index_t i=0; i<dimension_; ++i) {
772 scale_value(store_[to*dimension_+i], s);
773 }
774 }
775
776 void madd_item(index_t to, double s, index_t from) override {
777 geo_assert(from < size());
778 geo_assert(to < size());
779 for(index_t i=0; i<dimension_; ++i) {
780 madd_value(
781 store_[to*dimension_+i], s, store_[from*dimension_+i]
782 );
783 }
784 }
785
786 protected:
787 void notify(
788 Memory::pointer base_addr, index_t size, index_t dim
789 ) override {
790 AttributeStore::notify(base_addr, size, dim);
791 geo_assert(size*dim <= store_.size());
792 }
793
794 template<class TT> static void scale_value(TT& to, double s) {
795 geo_argused(to);
796 geo_argused(s);
797 }
798
799 static void scale_value(uint8_t& to, double s) {
800 to = uint8_t(double(to)*s != 0.0);
801 }
802
803 static void scale_value(int32_t& to, double s) {
804 to = int32_t(double(to)*s);
805 }
806
807 static void scale_value(uint32_t& to, double s) {
808 to = uint32_t(double(to)*s);
809 }
810
811 static void scale_value(float& to, double s) {
812 to = float(double(to)*s);
813 }
814
815 static void scale_value(double& to, double s) {
816 to *= s;
817 }
818
819 template<class TT> static void madd_value(TT& to, double s, TT& from) {
820 geo_argused(to);
821 geo_argused(s);
822 geo_argused(from);
823 }
824
825 static void madd_value(uint8_t& to, double s, uint8_t& from) {
826 to = uint8_t(double(to) + s*double(from) != 0.0);
827 }
828
829 static void madd_value(int32_t& to, double s, int32_t& from) {
830 to = int32_t(double(to) + s*double(from));
831 }
832
833 static void madd_value(uint32_t& to, double s, uint32_t& from) {
834 to = uint32_t(double(to) + s*double(from));
835 }
836
837 static void madd_value(float& to, double s, float& from) {
838 to = float(double(to) + s*double(from));
839 }
840
841 static void madd_value(double& to, double s, double& from) {
842 to += s*from;
843 }
844
845
846 private:
847 vector<T> store_;
848 };
849
850 /*********************************************************************/
851
856 template <class T>
858 public:
863 return new TypedAttributeStore<T>(dim);
864 }
865
869 bool elements_are_trivially_copyable() const override {
870 return(std::is_trivially_copyable<T>::value);
871 }
872 };
873
874 /*********************************************************************/
875
880 template <class T> class geo_register_attribute_type {
881 public:
891 geo_register_attribute_type(const std::string& type_name) {
893 new TypedAttributeStoreCreator<T>, type_name, typeid(T).name()
894 );
895 if(type_name == "bool") {
897 type_name,
900 );
901 } else {
903 type_name,
904 read_ascii_attribute<T>,
905 write_ascii_attribute<T>
906 );
907 }
908 }
909 };
910
911 /*********************************************************************/
912
917 class GEOGRAM_API AttributesManager {
918 public:
923
924
929
935 index_t nb() const {
936 return index_t(attributes_.size());
937 }
938
945
952 index_t size() const {
953 return size_;
954 }
955
962 return capacity_;
963 }
964
971 void resize(index_t new_size);
972
979 void reserve(index_t new_capacity);
980
989 void clear(bool keep_attributes, bool keep_memory = false);
990
991
995 void zero();
996
1005 void bind_attribute_store(const std::string& name, AttributeStore* as);
1006
1013 AttributeStore* find_attribute_store(const std::string& name);
1014
1022 const std::string& name
1023 ) const;
1024
1025
1032 bool is_defined(const std::string& name) const {
1033 return (find_attribute_store(name) != nullptr);
1034 }
1035
1041 void delete_attribute_store(const std::string& name);
1042
1049
1066 const vector<index_t>& permutation
1067 );
1068
1084 void compress(const vector<index_t>& old2new);
1085
1090 void copy(const AttributesManager& rhs);
1091
1092
1099 void copy_item(index_t to, index_t from);
1100
1107
1108
1114
1122 void scale_item(index_t to, double s);
1123
1132 void madd_item(index_t to, double s, index_t from);
1133
1143 const std::string& name, const std::string& new_name
1144 );
1145
1155 const std::string& old_name, const std::string& new_name
1156 );
1157
1158 private:
1166 AttributesManager(const AttributesManager& rhs) = delete;
1167
1175 const AttributesManager& operator=(const AttributesManager& rhs) = delete;
1176
1177 private:
1178 index_t size_;
1179 index_t capacity_;
1180 std::map<std::string, AttributeStore*> attributes_;
1181 } ;
1182
1183
1184 /*********************************************************************/
1185
1186
1191 template <class T> class AttributeBase : public AttributeStoreObserver {
1192 public:
1193
1198 manager_(nullptr),
1199 store_(nullptr),
1200 existed_already_(false) {
1201 }
1202
1212 AttributeBase(AttributesManager& manager, const std::string& name) :
1213 manager_(nullptr),
1214 store_(nullptr),
1215 existed_already_(false) {
1216 bind(manager, name);
1217 }
1218
1224 bool is_bound() const {
1225 return (store_ != nullptr && !disconnected_);
1226 }
1227
1235 bool existed_already() const {
1236 return existed_already_;
1237 }
1238
1243 void unbind() {
1245 // If the AttributesManager was destroyed before, do not
1246 // do anything. This can occur in Lua scripting when using
1247 // Attribute wrapper objects.
1248 if(!disconnected_) {
1249 unregister_me(store_);
1250 }
1251 manager_ = nullptr;
1252 store_ = nullptr;
1253 existed_already_ = false;
1254 }
1255
1265 void bind(AttributesManager& manager, const std::string& name) {
1266 geo_assert(!is_bound());
1267 manager_ = &manager;
1268 store_ = manager_->find_attribute_store(name);
1269 if(store_ == nullptr) {
1270 store_ = new TypedAttributeStore<T>();
1271 manager_->bind_attribute_store(name,store_);
1272 existed_already_ = false;
1273 } else {
1274 geo_assert(store_->elements_type_matches(typeid(T).name()));
1275 existed_already_ = true;
1276 }
1277 register_me(store_);
1278 }
1279
1280
1290 AttributesManager& manager, const std::string& name
1291 ) {
1292 geo_assert(!is_bound());
1293 manager_ = &manager;
1294 store_ = manager_->find_attribute_store(name);
1295 if(store_ != nullptr) {
1296 geo_assert(store_->elements_type_matches(typeid(T).name()));
1297 register_me(store_);
1298 existed_already_ = true;
1299 return true;
1300 }
1301 existed_already_ = false;
1302 return false;
1303 }
1304
1314 AttributesManager& manager, const std::string& name
1315 ) {
1316 if( is_bound() ) {
1317 unbind();
1318 }
1319 store_ = manager.find_attribute_store(name);
1320 if(store_ != nullptr) {
1321 existed_already_ = true;
1322 if( !store_->elements_type_matches(typeid(T).name()) ) {
1323 store_ = nullptr;
1324 return false;
1325 }
1326 manager_ = &manager;
1327 register_me(store_);
1328 return true;
1329 }
1330 existed_already_ = false;
1331 return false;
1332 }
1333
1342 const std::string& name,
1344 ) {
1345 geo_assert(!is_bound());
1346 manager_ = &manager;
1347 geo_assert(manager_->find_attribute_store(name) == nullptr);
1348 store_ = new TypedAttributeStore<T>(dimension);
1349 manager_->bind_attribute_store(name,store_);
1350 register_me(store_);
1351 }
1352
1359 void destroy() {
1361 unregister_me(store_);
1362 manager_->delete_attribute_store(store_);
1363 store_ = nullptr;
1364 manager_ = nullptr;
1365 }
1366
1376 void redim(index_t new_dim) {
1378 store_->redim(new_dim);
1379 }
1380
1389 if(is_bound()) {
1390 unbind();
1391 }
1392 }
1393
1394
1402 static bool is_defined(
1403 AttributesManager& manager, const std::string& name,
1404 index_t dim = 0
1405 ) {
1407 return (
1408 store != nullptr &&
1409 store->elements_type_matches(typeid(T).name()) &&
1410 ((dim == 0) || (store->dimension() == dim))
1411 );
1412 }
1413
1418 index_t size() const {
1419 return size_;
1420 }
1421
1426 void zero() {
1428 store_->zero();
1429 }
1430
1441 return(
1442 dynamic_cast<TypedAttributeStore<T>*>(store_) != nullptr
1443 );
1444 }
1445
1457 TypedAttributeStore<T>* typed_store =
1458 dynamic_cast<TypedAttributeStore<T>*>(store_);
1459 geo_assert(typed_store != nullptr);
1460 return typed_store->get_vector();
1461 }
1462
1469 const vector<T>& get_vector() const {
1470 TypedAttributeStore<T>* typed_store =
1471 dynamic_cast<TypedAttributeStore<T>*>(store_);
1472 geo_assert(typed_store != nullptr);
1473 return typed_store->get_vector();
1474 }
1475
1481 return manager_;
1482 }
1483
1484 protected:
1485 AttributesManager* manager_;
1486 AttributeStore* store_;
1487 bool existed_already_;
1488 } ;
1489
1490 /*********************************************************************/
1491
1498 template <class T> class Attribute : public AttributeBase<T> {
1499 public:
1501
1506 }
1507
1517 Attribute(AttributesManager& manager, const std::string& name) :
1518 superclass(manager, name) {
1519 }
1520
1529 return ((T*)(void*)superclass::base_addr_)[i];
1530 }
1531
1537 const T& operator[](index_t i) const {
1540 return ((const T*)(void*)superclass::base_addr_)[i];
1541 }
1542
1548 void fill(const T& val) {
1550 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1551 (*this)[i] = val;
1552 }
1553 }
1554
1561 void copy(const Attribute<T>& rhs) {
1562 geo_assert(rhs.size() == superclass::size());
1564 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1565 (*this)[i] = rhs[i];
1566 }
1567 }
1568
1573 T* data() {
1574 return (T*)AttributeStoreObserver::base_addr_;
1575 }
1576
1581 const T* data() const {
1582 return (const T*)AttributeStoreObserver::base_addr_;
1583 }
1584
1585
1586 private:
1590 Attribute(const Attribute<T>& rhs) = delete;
1594 Attribute<T>& operator=(const Attribute<T>& rhs) = delete;
1595 };
1596
1597 /*********************************************************************/
1598
1607 template <> class Attribute<bool> : public AttributeBase<Numeric::uint8> {
1608 public:
1610
1611 Attribute() : superclass() {
1612 }
1613
1614 Attribute(AttributesManager& manager, const std::string& name) :
1615 superclass(manager,name) {
1616 }
1617
1618 class BoolAttributeAccessor;
1619
1620
1625 class ConstBoolAttributeAccessor {
1626 public:
1631 const Attribute<bool>& attribute,
1632 index_t index
1633 ) :
1634 attribute_(&attribute),
1635 index_(index) {
1636 }
1637
1642 operator bool() const {
1643 return (attribute_->element(index_) != 0);
1644 }
1645
1646 private:
1647 const Attribute<bool>* attribute_;
1648 index_t index_;
1649
1650 friend class BoolAttributeAccessor;
1651 };
1652
1657 class BoolAttributeAccessor {
1658 public:
1663 Attribute<bool>& attribute,
1664 index_t index
1665 ) :
1666 attribute_(&attribute),
1667 index_(index) {
1668 }
1669
1674 operator bool() const {
1675 return (attribute_->element(index_) != 0);
1676 }
1677
1683 BoolAttributeAccessor(const BoolAttributeAccessor& rhs) {
1684 attribute_ = rhs.attribute_;
1685 index_ = rhs.index_;
1686 }
1687
1692 BoolAttributeAccessor& operator=(bool x) {
1693 attribute_->element(index_) = Numeric::uint8(x);
1694 return *this;
1695 }
1696
1702 BoolAttributeAccessor& operator=(
1703 const BoolAttributeAccessor& rhs
1704 ) {
1705 if(&rhs != this) {
1706 attribute_->element(index_) =
1707 rhs.attribute_->element(rhs.index_);
1708 }
1709 return *this;
1710 }
1711
1717 BoolAttributeAccessor& operator=(
1718 const ConstBoolAttributeAccessor& rhs
1719 ) {
1720 attribute_->element(index_) =
1721 rhs.attribute_->element(rhs.index_);
1722 return *this;
1723 }
1724
1725 private:
1726 Attribute<bool>* attribute_;
1727 index_t index_;
1728 };
1729
1730
1731 BoolAttributeAccessor operator[](index_t i) {
1732 return BoolAttributeAccessor(*this,i);
1733 }
1734
1735 ConstBoolAttributeAccessor operator[](index_t i) const {
1736 return ConstBoolAttributeAccessor(*this,i);
1737 }
1738
1744 void fill(bool val) {
1745 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1746 element(i) = Numeric::uint8(val);
1747 }
1748 }
1749
1756 void copy(const Attribute<bool>& rhs) {
1757 geo_assert(rhs.size() == superclass::size());
1759 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1760 element(i) = rhs.element(i);
1761 }
1762 }
1763
1764 protected:
1765
1766 friend class BoolAttributeAccessor;
1767 friend class ConstBoolAttributeAccessor;
1768
1776 return ((Numeric::uint8*)superclass::base_addr_)[i];
1777 }
1778
1786 return ((const Numeric::uint8*)superclass::base_addr_)[i];
1787 }
1788
1789 private:
1793 Attribute(const Attribute<bool>& rhs) = delete;
1797 Attribute<bool>& operator=(const Attribute<bool>& rhs) = delete;
1798 } ;
1799
1800 /***********************************************************/
1801
1806 class GEOGRAM_API ScalarAttributeAdapterBase :
1807 public AttributeStoreObserver {
1808
1809 public:
1814 ET_NONE=0,
1815 ET_UINT8=1,
1816 ET_INT8=2,
1817 ET_UINT32=3,
1818 ET_INT32=4,
1819 ET_FLOAT32=5,
1820 ET_FLOAT64=6,
1821 ET_VEC2=7,
1822 ET_VEC3=8
1823 };
1824
1825
1830 class Accessor {
1831 public:
1832 Accessor(
1833 ScalarAttributeAdapterBase& attribute,
1834 index_t index
1835 ) : attribute_(attribute), index_(index) {
1836 }
1837
1838 operator double() const {
1839 return attribute_.get_element_as_double(index_);
1840 }
1841
1842 void operator=(double x) {
1843 attribute_.set_element_as_double(index_, x);
1844 }
1845
1846 private:
1847 ScalarAttributeAdapterBase& attribute_;
1848 index_t index_;
1849 };
1850
1856 public:
1858 const ScalarAttributeAdapterBase& attribute,
1859 index_t index
1860 ) : attribute_(attribute), index_(index) {
1861 }
1862
1863 operator double() const {
1864 return attribute_.get_element_as_double(index_);
1865 }
1866
1867 private:
1868 const ScalarAttributeAdapterBase& attribute_;
1869 index_t index_;
1870 };
1871
1876 manager_(nullptr),
1877 store_(nullptr),
1878 element_type_(ET_NONE),
1879 element_index_(index_t(-1)) {
1880 }
1881
1892 const AttributesManager& manager, const std::string& name
1893 ) :
1894 manager_(nullptr),
1895 store_(nullptr) {
1896 bind_if_is_defined(manager, name);
1897 }
1898
1904 bool is_bound() const {
1905 return (store_ != nullptr);
1906 }
1907
1912 void unbind() {
1913 geo_assert(is_bound());
1914 unregister_me(const_cast<AttributeStore*>(store_));
1915 manager_ = nullptr;
1916 store_ = nullptr;
1917 element_type_ = ET_NONE;
1918 element_index_ = index_t(-1);
1919 }
1920
1931 const AttributesManager& manager, const std::string& name
1932 );
1933
1942 if(is_bound()) {
1943 unbind();
1944 }
1945 }
1946
1956 static bool is_defined(
1957 const AttributesManager& manager, const std::string& name
1958 );
1959
1964 index_t size() const {
1965 return (store_ == nullptr) ? 0 : store_->size();
1966 }
1967
1976 return element_type_;
1977 }
1978
1986 return element_index_;
1987 }
1988
1994 return store_;
1995 }
1996
1997
2005 static bool can_be_bound_to(const AttributeStore* store) {
2006 return element_type(store) != ET_NONE;
2007 }
2008
2017
2018 protected:
2027 static std::string attribute_base_name(const std::string& name);
2028
2037 static index_t attribute_element_index(const std::string& name);
2038
2047
2056 double result = 0.0;
2057 switch(element_type()) {
2058 case ET_UINT8:
2059 result = double(get_element<Numeric::uint8>(i));
2060 break;
2061 case ET_INT8:
2062 result = double(get_element<Numeric::int8>(i));
2063 break;
2064 case ET_UINT32:
2065 result = double(get_element<Numeric::uint32>(i));
2066 break;
2067 case ET_INT32:
2068 result = double(get_element<Numeric::int32>(i));
2069 break;
2070 case ET_FLOAT32:
2071 result = double(get_element<Numeric::float32>(i));
2072 break;
2073 case ET_FLOAT64:
2074 result = double(get_element<Numeric::float64>(i));
2075 break;
2076 case ET_VEC2:
2077 result = double(get_element<Numeric::float64>(i,2));
2078 break;
2079 case ET_VEC3:
2080 result = double(get_element<Numeric::float64>(i,3));
2081 break;
2082 case ET_NONE:
2084 }
2085 return result;
2086 }
2087
2096 template <class T> T get_element(index_t i,index_t multiplier=1) const {
2097 geo_debug_assert(is_bound());
2098 geo_debug_assert(i < size());
2099 return static_cast<const T*>(store_->data())[
2100 (i * store_->dimension() * multiplier) +
2101 element_index_
2102 ];
2103 }
2104
2111 double set_element_as_double(index_t i, double value) {
2112 double result = 0.0;
2113 switch(element_type()) {
2114 case ET_UINT8:
2115 set_element<Numeric::uint8>(Numeric::uint8(value), i);
2116 break;
2117 case ET_INT8:
2118 set_element<Numeric::int8>(Numeric::int8(value),i);
2119 break;
2120 case ET_UINT32:
2121 set_element<Numeric::uint32>(Numeric::uint32(value),i);
2122 break;
2123 case ET_INT32:
2124 set_element<Numeric::int32>(Numeric::int32(value),i);
2125 break;
2126 case ET_FLOAT32:
2127 set_element<Numeric::float32>(Numeric::float32(value),i);
2128 break;
2129 case ET_FLOAT64:
2130 set_element<Numeric::float64>(Numeric::float64(value),i);
2131 break;
2132 case ET_VEC2:
2133 set_element<Numeric::float64>(Numeric::float64(value),i,2);
2134 break;
2135 case ET_VEC3:
2136 set_element<Numeric::float64>(Numeric::float64(value),i,3);
2137 break;
2138 case ET_NONE:
2140 }
2141 return result;
2142 }
2143
2153 template <class T> void set_element(
2154 T value, index_t i, index_t multiplier=1
2155 ) const {
2156 geo_debug_assert(is_bound());
2157 geo_debug_assert(i < size());
2158 const_cast<T*>(static_cast<const T*>(store_->data()))[
2159 (i * store_->dimension() * multiplier) +
2160 element_index_
2161 ] = value;
2162 }
2163
2164 protected:
2165 const AttributesManager* manager_;
2166 const AttributeStore* store_;
2167 ElementType element_type_;
2168 index_t element_index_;
2169 };
2170
2171 /***********************************************************/
2172
2178 public:
2180 }
2181
2183 const AttributesManager& manager, const std::string& name
2184 ) : ScalarAttributeAdapterBase(manager, name) {
2185 }
2186
2195 return get_element_as_double(i);
2196 }
2197 };
2198
2199 /***********************************************************/
2200
2206 public:
2208 }
2209
2211 const AttributesManager& manager, const std::string& name
2212 ) : ScalarAttributeAdapterBase(manager, name) {
2213 }
2214
2215 Accessor operator[](index_t i) {
2216 return Accessor(*this, i);
2217 }
2218
2219 ConstAccessor operator[](index_t i) const {
2220 return ConstAccessor(*this, i);
2221 }
2222
2223 protected:
2224 };
2225
2226
2227}
2228
2229#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.
bool existed_already() const
Tests whether the latest bound attribute existed already.
void bind(AttributesManager &manager, const std::string &name)
Binds this Attribute to an AttributesManager.
bool bind_if_is_defined(AttributesManager &manager, const std::string &name)
Binds this Attribute to an AttributesManager if it already exists in the AttributesManager.
Internal class for creating an AttributeStore from the type name of its elements.
Definition attributes.h:181
~AttributeStoreCreator() override
AttributeStoreCreator destructor.
virtual bool elements_are_trivially_copyable() const =0
Tests whether elements of this attribute can be trivially copyable.
virtual AttributeStore * create_attribute_store(index_t dimension)=0
Creates a new attribute store.
Base class for attributes. They are notified whenever the AttributeStore is modified.
Definition attributes.h:70
AttributeStoreObserver()
Creates a new uninitialied AttributeStore.
Definition attributes.h:76
void register_me(AttributeStore *store)
Registers this observer to an AttributeStore.
index_t size() const
Gets the size.
Definition attributes.h:100
void notify(Memory::pointer base_addr, index_t size, index_t dim)
Callback function, called by the AttributeStore whenever it is modified.
Definition attributes.h:88
index_t nb_elements() const
Gets the total number of elements.
Definition attributes.h:118
bool disconnected() const
Tests whether this AttributeStoreObserver was disconnected.
Definition attributes.h:162
void disconnect()
Disconnects this AttributeStoreObserver from its AttributeStore.
Definition attributes.h:149
void unregister_me(AttributeStore *store)
Unregisters this observer from an AttributeStore.
index_t dimension() const
Gets the dimension.
Definition attributes.h:108
Memory::pointer base_addr() const
Gets a pointer to the storage.
Definition attributes.h:126
Notifies a set of AttributeStoreObservers each time the stored array changes size and/or base address...
Definition attributes.h:221
void * data()
Gets a pointer to the stored data.
Definition attributes.h:447
static AttributeStore * create_attribute_store_by_element_type_name(const std::string &element_type_name, index_t dimension)
Creates an attribute store of a given type.
Definition attributes.h:545
bool has_observers() const
Tests whether observers listen to this AttributeStore.
Definition attributes.h:302
void zero_item(index_t to)
Sets an item to zero.
Definition attributes.h:405
virtual ~AttributeStore()
AttributeStore destructor.
static std::string element_typeid_name_by_element_type_name(const std::string &element_type_name)
Gets an element mangled type name from its C++ name.
Definition attributes.h:576
static void register_attribute_creator(AttributeStoreCreator *creator, const std::string &element_type_name, const std::string &element_typeid_name)
Registers a new element type.
index_t size() const
Gets the size.
Definition attributes.h:264
const void * data() const
Gets a pointer to the stored data.
Definition attributes.h:455
virtual void clear(bool keep_memory=false)=0
Resizes this AttributeStore to 0.
virtual void notify(Memory::pointer base_addr, index_t size, index_t dim)
If size or base address differ from the cached values, notify all the observers, and update the cache...
AttributeStore(size_t elemsize, index_t dim=1)
AttributeStore constructor.
index_t capacity() const
Gets the capacity.
Definition attributes.h:273
virtual void madd_item(index_t to, double s, index_t from)
Adds a scaled item to another item \detais item[to] += s * item[from].
static bool element_by_typeid_name_is_trivially_copyable(const std::string &element_typeid_name)
Tests whether an element type is trivially copyable.
Definition attributes.h:530
static bool element_type_name_is_known(const std::string &element_type_name)
Tests whether a given element type is registered in the system.
Definition attributes.h:475
void apply_permutation_with_lifecycle(const vector< index_t > &permutation)
implementation of apply_permutation() used when there is a lifecycle, that is, when attribute type is...
virtual void compress(const vector< index_t > &old2new)
Compresses the stored attributes, by applying an index mapping that fills-in the gaps.
LifeCycle * lifecycle() const
Gets the LifeCycle.
Definition attributes.h:606
virtual std::string element_typeid_name() const =0
Gets the typeid name of the element type stored in this AttributeStore.
void copy_item(index_t to, index_t from)
Copies an item.
Definition attributes.h:383
virtual AttributeStore * clone() const =0
Creates a new AttributeStore that is a carbon copy of this AttributeStore.
static bool element_typeid_name_is_known(const std::string &element_typeid_name)
Tests whether a given element type is registered in the system.
Definition attributes.h:492
void register_observer(AttributeStoreObserver *observer)
Registers an observer.
virtual void apply_permutation(const vector< index_t > &permutation)
Applies a permutation to the stored attributes.
virtual void resize(index_t new_size)=0
Resizes this AttributeStore.
virtual void scale_item(index_t to, double s)
Scales an item.
void unregister_observer(AttributeStoreObserver *observer)
Unregisters an observer.
virtual void redim(index_t dim)=0
Sets the dimension.
index_t dimension() const
Gets the dimension.
Definition attributes.h:311
static std::string element_type_name_by_element_typeid_name(const std::string &element_typeid_name)
Gets an element type name from its mangled name.
Definition attributes.h:561
virtual bool elements_type_matches(const std::string &type_name) const =0
Tests whether this AttributeStore stores elements of a given type.
void swap_items(index_t i, index_t j)
Swaps two items.
static bool element_by_type_name_is_trivially_copyable(const std::string &element_type_name)
Tests whether an element type is trivially copyable.
Definition attributes.h:510
size_t element_size() const
Gets the element size.
Definition attributes.h:463
virtual void reserve(index_t new_capacity)=0
Reserves memory.
virtual void zero()
Zeroes all the memory associated with this AttributeStore.
BoolAttributeAccessor(Attribute< bool > &attribute, index_t index)
BoolAttributeAccessor constructor.
BoolAttributeAccessor & operator=(const BoolAttributeAccessor &rhs)
Copies a bool from another attribute.
BoolAttributeAccessor & operator=(const ConstBoolAttributeAccessor &rhs)
Copies a bool from another attribute.
BoolAttributeAccessor & operator=(bool x)
Assigns a bool to a BoolAttributeAccessor.
BoolAttributeAccessor(const BoolAttributeAccessor &rhs)
Copy-constructor.
ConstBoolAttributeAccessor(const Attribute< bool > &attribute, index_t index)
ConstBoolAttributeAccessor constructor.
Numeric::uint8 & element(index_t i)
Gets a modifiable element by index.
void fill(bool val)
Sets all the elements in this attribute to a specified value.
const Numeric::uint8 & element(index_t i) const
Gets an element by index.
void copy(const Attribute< bool > &rhs)
Copies all the values from another attribute.
Manages an attribute attached to a set of object.
Attribute(AttributesManager &manager, const std::string &name)
Creates or retrieves a persistent attribute attached to a given AttributesManager.
const T & operator[](index_t i) const
Gets an element by index.
Attribute()
Creates an uninitialized (unbound) Attribute.
T * data()
Gets the pointer to the data.
void fill(const T &val)
Sets all the elements in this attribute to a specified value.
const T * data() const
Gets the pointer to the data.
T & operator[](index_t i)
Gets a modifiable element by index.
void copy(const Attribute< T > &rhs)
Copies all the values from another attribute.
Managers a set of attributes attached to an object.
Definition attributes.h:917
void delete_attribute_store(AttributeStore *as)
Deletes an AttributeStore.
void compress(const vector< index_t > &old2new)
Compresses the stored attributes, by applying an index mapping that fills-in the gaps.
void zero_item(index_t to)
Sets an item to zero.
void copy(const AttributesManager &rhs)
Copies all the attributes from another AttributesManager.
AttributesManager()
Constructs a new empty AttributesManager.
index_t nb() const
Gets the number of attributes.
Definition attributes.h:935
bool rename_attribute(const std::string &old_name, const std::string &new_name)
Renames an attribute.
void scale_item(index_t to, double s)
Scales an item.
const AttributeStore * find_attribute_store(const std::string &name) const
Finds an AttributeStore by name.
void apply_permutation(const vector< index_t > &permutation)
Applies a permutation to the stored attributes.
AttributeStore * find_attribute_store(const std::string &name)
Finds an AttributeStore by name.
void bind_attribute_store(const std::string &name, AttributeStore *as)
Binds an AttributeStore with the specified name. Ownership of this AttributeStore is transferred to t...
void list_attribute_names(vector< std::string > &names) const
Gets the names of all the attributes in this AttributeStore.
~AttributesManager()
AttributesManager destructor.
void copy_item(index_t to, index_t from)
Copies all the attributes of an item into another one.
void madd_item(index_t to, double s, index_t from)
Adds a scaled item to another item \detais item[to] += s * item[from].
bool is_defined(const std::string &name) const
Tests whether an attribute is defined.
void swap_items(index_t i, index_t j)
Swaps all the attributes of two items.
index_t size() const
Gets the size.
Definition attributes.h:952
void clear(bool keep_attributes, bool keep_memory=false)
Clears this AttributesManager.
index_t capacity() const
Gets the capacity.
Definition attributes.h:961
void delete_attribute_store(const std::string &name)
Deletes an AttributeStore by name.
bool copy_attribute(const std::string &name, const std::string &new_name)
Copies an attribute.
void zero()
Zeroes all the attributes.
void reserve(index_t new_capacity)
Pre-allocates memory for a number of items.
void resize(index_t new_size)
Resizes all the attributes managed by this AttributesManager.
Base class for reference-counted objects.
Definition counted.h:71
Concrete implementation of LifeCycle.
Definition life_cycle.h:252
static void register_ascii_attribute_serializer(const std::string &type_name, AsciiAttributeReadSerializer read, AsciiAttributeWriteSerializer write)
Declares a new attribute type that can be read from and written to ascii files.
Manages the life cycle of an object.
Definition life_cycle.h:66
Readonly access to an attribute as a double regardless its type.
double operator[](index_t i)
Gets a property value.
Readwrite access to an attribute as a double regardless its type.
Accessor class used by ScalarAttributeAdapter to implement indexing operator.
Accessor class used by ScalarAttributeAdapter to implement indexing operator (const version).
Access to an attribute as a double regardless its type.
index_t element_index() const
Gets the element index.
T get_element(index_t i, index_t multiplier=1) const
Gets an element.
ElementType
Internal representation of the attribute.
static std::string attribute_base_name(const std::string &name)
Gets the base attribute name from a compound name.
void bind_if_is_defined(const AttributesManager &manager, const std::string &name)
Binds this Attribute to an AttributesManager if it already exists in the AttributesManager.
bool is_bound() const
Tests whether an Attribute is bound.
static index_t nb_scalar_elements_per_item(const AttributeStore *store)
Gets the number of scalar components per item in an AttributeStore.
double get_element_as_double(index_t i) const
Gets an attribute value.
~ScalarAttributeAdapterBase()
ReadonlyScalarAttributeAdapterBase destructor.
static ElementType element_type(const AttributeStore *store)
Gets the element type stored in an AttributeStore.
const AttributeStore * attribute_store() const
Gets the AttributeStore.
ScalarAttributeAdapterBase()
ScalarAttributeAdapterBase constructor.
static bool can_be_bound_to(const AttributeStore *store)
Tests whether a ScalarAttributeAdapterBase can be bound to a given attribute store.
void unbind()
Unbinds this Attribute.
static bool is_defined(const AttributesManager &manager, const std::string &name)
Tests whether an attribute with the specified name and with a type that can be converted to double ex...
ScalarAttributeAdapterBase(const AttributesManager &manager, const std::string &name)
ScalarAttributeAdapterBase constructor.
double set_element_as_double(index_t i, double value)
Sets an attribute value.
void set_element(T value, index_t i, index_t multiplier=1) const
Sets an element.
static index_t attribute_element_index(const std::string &name)
Gets the base attribute name from a compound name.
index_t size() const
Gets the size.
ElementType element_type() const
Gets the internal representation of the elements.
A smart pointer with reference-counted copy semantics.
Implementation of AttributeStoreCreator for a specific type.
Definition attributes.h:857
AttributeStore * create_attribute_store(index_t dim) override
Creates a new attribute store.
Definition attributes.h:862
bool elements_are_trivially_copyable() const override
Tests whether elements of this attribute can be trivially copyable.
Definition attributes.h:869
Stores an array of elements of a given type, and notifies a set of AttributeStoreObservers each time ...
Definition attributes.h:682
void scale_item(index_t to, double s) override
Scales an item.
Definition attributes.h:769
TypedAttributeStore(index_t dim=1)
Creates a new empty attribute store.
Definition attributes.h:691
void notify(Memory::pointer base_addr, index_t size, index_t dim) override
If size or base address differ from the cached values, notify all the observers, and update the cache...
Definition attributes.h:787
void clear(bool keep_memory=false) override
Resizes this AttributeStore to 0.
Definition attributes.h:719
AttributeStore * clone() const override
Creates a new AttributeStore that is a carbon copy of this AttributeStore.
Definition attributes.h:756
void resize(index_t new_size) override
Resizes this AttributeStore.
Definition attributes.h:698
std::string element_typeid_name() const override
Gets the typeid name of the element type stored in this AttributeStore.
Definition attributes.h:752
void reserve(index_t new_capacity) override
Reserves memory.
Definition attributes.h:707
bool elements_type_matches(const std::string &type_name) const override
Tests whether this AttributeStore stores elements of a given type.
Definition attributes.h:748
void madd_item(index_t to, double s, index_t from) override
Adds a scaled item to another item \detais item[to] += s * item[from].
Definition attributes.h:776
void redim(index_t dim) override
Sets the dimension.
Definition attributes.h:728
Helper class to register new attribute types.
Definition attributes.h:880
geo_register_attribute_type(const std::string &type_name)
geo_register_attribute_type constructor
Definition attributes.h:891
Vector with aligned memory allocation.
Definition memory.h:710
Functions to read and write structured files.
Common include file, providing basic definitions. Should be included before anything else by all head...
Implementation of generic object lifecycle service.
Generic logging mechanism.
Types and functions for memory manipulation.
byte * pointer
Pointer to unsigned byte(s)
Definition memory.h:104
float float32
Definition numeric.h:148
uint8_t uint8
Definition numeric.h:136
int8_t int8
Definition numeric.h:124
double float64
Definition numeric.h:151
int32_t int32
Definition numeric.h:130
uint32_t uint32
Definition numeric.h:142
std::atomic_flag spinlock
A lightweight synchronization structure.
Global Vorpaline namespace.
Definition basic.h:55
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:330
SmartPointer< AttributeStoreCreator > AttributeStoreCreator_var
An automatic reference-counted pointer to an AttributeStoreCreator.
Definition attributes.h:214
bool read_ascii_attribute< bool >(FILE *file, Memory::pointer base_addr, index_t nb_elements)
Reads an ASCII attribute from a file.
Definition geofile.h:208
bool write_ascii_attribute< bool >(FILE *file, Memory::const_pointer base_addr, index_t nb_elements)
Writes an ASCII attribute to a file.
Definition geofile.h:232
Types and functions for numbers manipulation.
Function and classes for process manipulation.