Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.28
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Attribs.hpp
1#pragma once
2#include <Core/Containers/VectorArray.hpp>
3#include <Core/CoreMacros.hpp>
4#include <Core/RaCore.hpp>
5#include <Core/Utils/ContainerIntrospectionInterface.hpp>
6#include <Core/Utils/Index.hpp>
7#include <Core/Utils/Observable.hpp>
8#include <Eigen/Core>
9#include <iterator>
10#include <map>
11#include <memory>
12#include <stddef.h>
13#include <string>
14#include <type_traits>
15#include <utility>
16#include <vector>
17
18namespace Ra {
19namespace Core {
20
21namespace Geometry {
22// need forward declarations for friend classes outside of Utils namespace
23class TopologicalMesh;
24} // namespace Geometry
25
26namespace Utils {
27
28template <typename T>
29class Attrib;
30
34class RA_CORE_API AttribBase : public ObservableVoid, public ContainerIntrospectionInterface
35{
36 public:
37 inline explicit AttribBase( const std::string& name );
38 virtual ~AttribBase();
39 AttribBase( const AttribBase& ) = delete;
40 AttribBase& operator=( const AttribBase& ) = delete;
41
43 inline std::string getName() const;
44
46 inline void setName( const std::string& name );
47
49 virtual void resize( size_t s ) = 0;
50
52 bool inline operator==( const AttribBase& rhs );
53
55 template <typename T>
56 inline Attrib<T>& cast();
57
59 template <typename T>
60 inline const Attrib<T>& cast() const;
61
63 virtual bool isFloat() const = 0;
64
66 virtual bool isVector2() const = 0;
67
69 virtual bool isVector3() const = 0;
70
72 virtual bool isVector4() const = 0;
73
77 bool inline isLocked() const;
78
80 void inline unlock();
81
82 virtual std::unique_ptr<AttribBase> clone() = 0;
83
84 protected:
85 void inline lock( bool isLocked = true );
86
87 private:
89 std::string m_name;
90
92 bool m_isLocked { false };
93};
94
98template <typename T>
99class Attrib : public AttribBase
100{
101 public:
102 using value_type = T;
104
105 explicit Attrib( const std::string& name );
106 virtual ~Attrib();
107
109 void resize( size_t s ) override;
110
113 inline Container& getDataWithLock();
114
117 size_t getSize() const override;
118 size_t getNumberOfComponents() const override;
119 int getStride() const override;
120 size_t getBufferSize() const override;
121 const void* dataPtr() const override;
123
126 void setData( const Container& data );
127 void setData( Container&& data );
129
131 inline const Container& data() const;
132 bool isFloat() const override;
133 bool isVector2() const override;
134 bool isVector3() const override;
135 bool isVector4() const override;
136
138 template <typename U>
139 bool isType();
140
141 std::unique_ptr<AttribBase> clone() override {
142 auto ptr = std::make_unique<Attrib<T>>( getName() );
143 ptr->m_data = m_data;
144 return ptr;
145 }
146
147 private:
148 Container m_data;
149};
150
152template <typename T>
154{
155 public:
156 using value_type = T;
157 using AttribType = Attrib<T>;
158 using Container = typename Attrib<T>::Container;
161 template <typename U>
162 bool operator==( const AttribHandle<U>& lhs ) const {
163 return std::is_same<T, U>::value && m_idx == lhs.idx();
164 }
165
167 Index idx() const { return m_idx; }
168
171 std::string attribName() const { return m_name; }
172
173 private:
174 Index m_idx = Index::Invalid();
175 std::string m_name = "";
176
177 friend class AttribManager;
178};
179
211class RA_CORE_API AttribManager : public Observable<const std::string&>
212{
213 public:
214 using value_type = AttribBase;
215 using pointer_type = value_type*;
218
219 inline AttribManager();
220
222 AttribManager( const AttribManager& m ) = delete;
223 AttribManager& operator=( const AttribManager& m ) = delete;
224
225 inline AttribManager( AttribManager&& m );
226
227 inline AttribManager& operator=( AttribManager&& m );
228 ~AttribManager() override;
229
231 inline void copyAttributes( const AttribManager& m );
232
236 template <class T, class... Handle>
237 void copyAttributes( const AttribManager& m, const AttribHandle<T>& attr, Handle... attribs );
238
242 void copyAllAttributes( const AttribManager& m );
243
245 void clear();
246
248 template <typename T>
249 bool isValid( const AttribHandle<T>& h ) const;
250
257 inline bool contains( const std::string& name ) const;
258
266 template <typename T>
267 inline AttribHandle<T> findAttrib( const std::string& name ) const;
268
275 template <typename T>
276 typename Attrib<T>::Container& getDataWithLock( const AttribHandle<T>& h );
277
284 template <typename T>
285 const typename Attrib<T>::Container& getData( const AttribHandle<T>& h );
286
292 template <typename T>
293 void unlock( const AttribHandle<T>& h );
294
301 template <typename T>
302 inline Attrib<T>& getAttrib( const AttribHandle<T>& h );
303 template <typename T>
304 inline const Attrib<T>& getAttrib( const AttribHandle<T>& h ) const;
305 template <typename T>
306 inline Attrib<T>* getAttribPtr( const AttribHandle<T>& h );
307 template <typename T>
308 inline const Attrib<T>* getAttribPtr( const AttribHandle<T>& h ) const;
310
316 template <typename T>
317 inline Attrib<T>& getAttrib( const std::string& name );
318 template <typename T>
319 inline const Attrib<T>& getAttrib( const std::string& name ) const;
321
326 inline AttribBase* getAttribBase( const std::string& name );
327 inline const AttribBase* getAttribBase( const std::string& name ) const;
328 inline AttribBase* getAttribBase( const Index& idx );
329 inline const AttribBase* getAttribBase( const Index& idx ) const;
331
335 template <typename T>
336 inline void setAttrib( const AttribHandle<T>& h,
337 const typename AttribHandle<T>::Container& data );
338
340 template <typename T>
341 inline void setAttrib( const AttribHandle<T>& h, typename AttribHandle<T>::Container&& data );
343
349 template <typename T>
350 AttribHandle<T> addAttrib( const std::string& name );
351
357 template <typename T>
358 void removeAttrib( AttribHandle<T>& h );
362 bool hasSameAttribs( const AttribManager& other );
363
366 // This is needed by the user to avoid caring about removed attributes (nullptr)
367 // \todo reimplement as range for
368 template <typename F>
369 void for_each_attrib( const F& func ) const;
370
371 // \todo keep non const version private
372 template <typename F>
373 void for_each_attrib( const F& func );
375
377 inline int getNumAttribs() const;
378
411 {
412 public:
418 a->for_each_attrib( [this]( const auto& attr ) {
419 return ( v.push_back( std::make_pair( attr, attr->isLocked() ) ) );
420 } );
421 }
427 for ( auto& p : v ) {
428 if ( !p.second && p.first->isLocked() ) { p.first->unlock(); }
429 }
430 }
431
432 private:
434 };
435
438
439 private:
441 Container m_attribs;
442
445 std::map<std::string, Index> m_attribsIndex;
446
447 // Ease wrapper
448 friend class ::Ra::Core::Geometry::TopologicalMesh;
449
451 int m_numAttribs { 0 };
452};
453
454AttribBase::AttribBase( const std::string& name ) : m_name { name } {}
455
457 return m_name;
458}
459
460void AttribBase::setName( const std::string& name ) {
461 m_name = name;
462}
463
464bool inline AttribBase::operator==( const AttribBase& rhs ) {
465 return m_name == rhs.getName();
466}
467
468template <typename T>
470 return static_cast<Attrib<T>&>( *this );
471}
472
473template <typename T>
475 return static_cast<const Attrib<T>&>( *this );
476}
477
479 return m_isLocked;
480}
481
483 lock( false );
484}
485
486void AttribBase::lock( bool isLocked ) {
487 CORE_ASSERT( isLocked != m_isLocked, "double (un)lock" );
488 m_isLocked = isLocked;
489 if ( !m_isLocked ) notify();
490}
491
493
494template <typename T>
495Attrib<T>::Attrib( const std::string& name ) : AttribBase( name ) {}
496
497template <typename T>
498
500 m_data.clear();
501}
502template <typename T>
503void Attrib<T>::resize( size_t s ) {
504 m_data.resize( s );
505}
506template <typename T>
508 lock();
509 return m_data;
510}
511
512template <typename T>
513const void* Attrib<T>::dataPtr() const {
514 return m_data.dataPtr();
515}
516
517template <typename T>
518void Attrib<T>::setData( const Container& data ) {
519 CORE_ASSERT( !isLocked(), "try to set onto locked data" );
520 m_data = data;
521 notify();
522}
523
524template <typename T>
525void Attrib<T>::setData( Container&& data ) {
526 CORE_ASSERT( !isLocked(), "try to set onto locked data" );
527 m_data = std::move( data );
528 notify();
529}
530
531template <typename T>
532const typename Attrib<T>::Container& Attrib<T>::data() const {
533 return m_data;
534}
535
536template <typename T>
537size_t Attrib<T>::getSize() const {
538 return m_data.getSize();
539}
540
541template <typename T>
543 return m_data.getStride();
544}
545
546template <typename T>
548 return m_data.getBufferSize();
549}
550
551template <typename T>
555
556template <typename T>
559}
560
561template <typename T>
564}
565
566template <typename T>
569}
570
571template <typename T>
572template <typename U>
576
577// Defer computation to VectorArrayTypeHelper
578template <typename T>
580 return m_data.getNumberOfComponents();
581}
582
584
585AttribManager::AttribManager() {}
586
587AttribManager::AttribManager( AttribManager&& m ) :
588 m_attribs( std::move( m.m_attribs ) ),
589 m_attribsIndex( std::move( m.m_attribsIndex ) ),
590 m_numAttribs( std::move( m.m_numAttribs ) ) {}
591
592AttribManager& AttribManager::operator=( AttribManager&& m ) {
593 m_attribs = std::move( m.m_attribs );
594 m_attribsIndex = std::move( m.m_attribsIndex );
595 m_numAttribs = std::move( m.m_numAttribs );
596 return *this;
597}
598
600 m_numAttribs = m.m_numAttribs;
601}
602
603template <class T, class... Handle>
605 const AttribHandle<T>& attr,
606 Handle... attribs ) {
607 if ( m.isValid( attr ) ) {
608 // get attrib to copy
609 auto& a = m.getAttrib( attr );
610 // add new attrib
611 auto h = addAttrib<T>( a.getName() );
612 // copy attrib data
613 getAttrib( h ).setData( a.data() );
614 }
615 // deal with other attribs
616 copyAttributes( m, attribs... );
617}
618
619template <typename T>
621 auto itr = m_attribsIndex.find( h.attribName() );
622 return h.m_idx != Index::Invalid() && itr != m_attribsIndex.end() && itr->second == h.m_idx;
623}
624
625inline bool AttribManager::contains( const std::string& name ) const {
626 return m_attribsIndex.find( name ) != m_attribsIndex.end();
627}
628
629template <typename T>
631 auto c = m_attribsIndex.find( name );
632 AttribHandle<T> handle;
633 if ( c != m_attribsIndex.end() ) {
634 handle.m_idx = c->second;
635 handle.m_name = c->first;
636 }
637 return handle;
638}
639
640template <typename T>
642 return static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() )->getDataWithLock();
643}
644
645template <typename T>
647 return static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() )->data();
648}
649
650template <typename T>
652 static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() )->unlock();
653}
654
655template <typename T>
657 return *static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() );
658}
659
660template <typename T>
661inline const Attrib<T>& AttribManager::getAttrib( const AttribHandle<T>& h ) const {
662 return *static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() );
663}
664template <typename T>
666 return getAttrib( findAttrib<T>( name ) );
667}
668
669template <typename T>
670inline const Attrib<T>& AttribManager::getAttrib( const std::string& name ) const {
671 return getAttrib( findAttrib<T>( name ) );
672}
673
674template <typename T>
675inline Attrib<T>* AttribManager::getAttribPtr( const AttribHandle<T>& h ) {
676 return static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() );
677}
678
679template <typename T>
680inline const Attrib<T>* AttribManager::getAttribPtr( const AttribHandle<T>& h ) const {
681 return static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() );
682}
683
684template <typename T>
686 const typename AttribHandle<T>::Container& data ) {
687 static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() )->setData( data );
688}
689
690template <typename T>
692 typename AttribHandle<T>::Container&& data ) {
693 static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() )->setData( data );
694}
695
697 auto c = m_attribsIndex.find( name );
698 if ( c != m_attribsIndex.end() ) return m_attribs[c->second].get();
699 return nullptr;
700}
701
702inline const AttribBase* AttribManager::getAttribBase( const std::string& name ) const {
703 auto c = m_attribsIndex.find( name );
704 if ( c != m_attribsIndex.end() ) return m_attribs[c->second].get();
705 return nullptr;
706}
707
708inline AttribBase* AttribManager::getAttribBase( const Index& idx ) {
709 if ( idx.isValid() ) return m_attribs[idx].get();
710 return nullptr;
711}
712
713inline const AttribBase* AttribManager::getAttribBase( const Index& idx ) const {
714 if ( idx.isValid() ) return m_attribs[idx].get();
715 return nullptr;
716}
717
718template <typename T>
720 // does the attrib already exist?
721 AttribHandle<T> h = findAttrib<T>( name );
722 if ( isValid( h ) ) return h;
723
724 // create the attrib
725 smart_pointer_type attrib = std::make_unique<Attrib<T>>( name );
726
727 // look for a free slot
728 auto it = std::find_if(
729 m_attribs.begin(), m_attribs.end(), []( const auto& attr ) { return !attr; } );
730 if ( it != m_attribs.end() ) {
731 it->swap( attrib );
732 h.m_idx = std::distance( m_attribs.begin(), it );
733 }
734 else {
735 m_attribs.push_back( std::move( attrib ) );
736 h.m_idx = m_attribs.size() - 1;
737 }
738 m_attribsIndex[name] = h.m_idx;
739 h.m_name = name;
740 ++m_numAttribs;
741
742 notify( name );
743 return h;
744}
745
746template <typename T>
748 auto c = m_attribsIndex.find( h.m_name );
749 if ( c != m_attribsIndex.end() ) {
750 Index idx = c->second;
751 m_attribs[idx].reset( nullptr );
752 m_attribsIndex.erase( c );
753 }
754 h.m_idx = Index::Invalid(); // invalidate whatever!
755 auto name = h.m_name;
756 h.m_name = ""; // invalidate whatever!
757 --m_numAttribs;
758 notify( name );
759}
760
761template <typename F>
762void AttribManager::for_each_attrib( const F& func ) const {
763 for ( const auto& attr : m_attribs )
764 if ( attr != nullptr ) func( attr.get() );
765}
766
767template <typename F>
768void AttribManager::for_each_attrib( const F& func ) {
769 for ( auto& attr : m_attribs )
770 if ( attr != nullptr ) func( attr.get() );
771}
772
774 return m_numAttribs;
775}
776
777} // namespace Utils
778} // namespace Core
779} // namespace Ra
T at(T... args)
T begin(T... args)
virtual bool isFloat() const =0
Return true if the attribute content is of Scalar type, false otherwise.
virtual bool isVector3() const =0
Return true if the attribute content is of Vector3 type, false otherwise.
virtual bool isVector4() const =0
Return true if the attribute content is of Vector4 type, false otherwise.
virtual bool isVector2() const =0
Return true if the attribute content is of Vector2 type, false otherwise.
virtual void resize(size_t s)=0
Resize the attribute's array.
void unlock()
Unlock data so another one can gain write access.
Definition Attribs.hpp:482
Attrib< T > & cast()
Downcast from AttribBase to Attrib<T>.
Definition Attribs.hpp:469
bool operator==(const AttribBase &rhs)
Return true if *this and rhs have the same name.
Definition Attribs.hpp:464
std::string getName() const
Return the attribute's name.
Definition Attribs.hpp:456
void setName(const std::string &name)
Set the attribute's name.
Definition Attribs.hpp:460
An attrib handle basically store an Index and a name.
Definition Attribs.hpp:154
std::string attribName() const
Definition Attribs.hpp:171
bool operator==(const AttribHandle< U > &lhs) const
Definition Attribs.hpp:162
Index idx() const
return the index of the attrib.
Definition Attribs.hpp:167
Scope lock state management for attributes.
Definition Attribs.hpp:411
ScopedLockState(AttribManager *a)
Constructor, save lock state of all attribs from attribManager.
Definition Attribs.hpp:417
~ScopedLockState()
Destructor, unlock all attribs whose have been locked after the initialization of the Unlocker.
Definition Attribs.hpp:426
The AttribManager provides attributes management by handles.
Definition Attribs.hpp:212
void setAttrib(const AttribHandle< T > &h, const typename AttribHandle< T >::Container &data)
Definition Attribs.hpp:685
AttribBase * getAttribBase(const std::string &name)
Definition Attribs.hpp:696
int getNumAttribs() const
Return the number of attributes.
Definition Attribs.hpp:773
ScopedLockState getScopedLockState()
Returns a scope unlocker for managed attribs.
Definition Attribs.hpp:437
AttribManager(const AttribManager &m)=delete
Copy constructor and assignment operator are forbidden.
Attrib< T >::Container & getDataWithLock(const AttribHandle< T > &h)
Get the locked data container from the attrib handle.
Definition Attribs.hpp:641
void unlock(const AttribHandle< T > &h)
Unlock the handle data.
Definition Attribs.hpp:651
AttribHandle< T > addAttrib(const std::string &name)
Definition Attribs.hpp:719
void copyAttributes(const AttribManager &m)
Base copy, does nothing.
Definition Attribs.hpp:599
bool contains(const std::string &name) const
contains Check if an attribute with the given name exists.
Definition Attribs.hpp:625
Attrib< T > & getAttrib(const AttribHandle< T > &h)
Definition Attribs.hpp:656
bool isValid(const AttribHandle< T > &h) const
Return true if h correspond to an existing attribute in *this.
Definition Attribs.hpp:620
void removeAttrib(AttribHandle< T > &h)
Definition Attribs.hpp:747
void for_each_attrib(const F &func) const
Definition Attribs.hpp:762
const Attrib< T >::Container & getData(const AttribHandle< T > &h)
Get read access to the data container from the attrib handle.
Definition Attribs.hpp:646
AttribHandle< T > findAttrib(const std::string &name) const
findAttrib Grab an attribute handler by name.
Definition Attribs.hpp:630
size_t getSize() const override
Definition Attribs.hpp:537
void setData(const Container &data)
Definition Attribs.hpp:518
size_t getNumberOfComponents() const override
Definition Attribs.hpp:579
bool isType()
check if attrib is a given type, as in attr.isType<MyMatrix>()
Definition Attribs.hpp:573
bool isVector4() const override
Return true if the attribute content is of Vector4 type, false otherwise.
Definition Attribs.hpp:567
const void * dataPtr() const override
Definition Attribs.hpp:513
Container & getDataWithLock()
Definition Attribs.hpp:507
const Container & data() const
Read-only acccess to the attribute content.
Definition Attribs.hpp:532
bool isVector2() const override
Return true if the attribute content is of Vector2 type, false otherwise.
Definition Attribs.hpp:557
bool isVector3() const override
Return true if the attribute content is of Vector3 type, false otherwise.
Definition Attribs.hpp:562
size_t getBufferSize() const override
Definition Attribs.hpp:547
int getStride() const override
Definition Attribs.hpp:542
void resize(size_t s) override
Resize the container (value_type must have a default ctor).
Definition Attribs.hpp:503
bool isFloat() const override
Return true if the attribute content is of Scalar type, false otherwise.
Definition Attribs.hpp:552
This class defines the introspection interface a container need to implement.
void notify(Args... p) const
T distance(T... args)
T end(T... args)
T erase(T... args)
T find(T... args)
T get(T... args)
T make_pair(T... args)
T move(T... args)
@ Geometry
"Geometry" render objects are those loaded using Radium::IO and generated by GeometrySystem
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:4
STL namespace.
T push_back(T... args)
T size(T... args)