Radium Engine  1.5.20
Loading...
Searching...
No Matches
IndexedGeometry.hpp
1#pragma once
2
3#include <Core/Containers/VectorArray.hpp>
4#include <Core/Geometry/TriangleMesh.hpp>
5#include <Core/Utils/ContainerIntrospectionInterface.hpp>
6#include <Core/Utils/ObjectWithSemantic.hpp>
8
9#include <memory>
10#include <unordered_map>
11
12namespace Ra {
13namespace Core {
14namespace Geometry {
15
17class RA_CORE_API GeometryIndexLayerBase : public Utils::ObservableVoid,
20{
21 public:
24 inline explicit GeometryIndexLayerBase( const GeometryIndexLayerBase& other );
27 inline GeometryIndexLayerBase& operator=( const GeometryIndexLayerBase& other );
30 inline GeometryIndexLayerBase& operator=( GeometryIndexLayerBase&& other );
32
35
38 virtual bool append( const GeometryIndexLayerBase& other ) = 0;
39
41 virtual inline bool operator==( const GeometryIndexLayerBase& other ) const;
42
43 protected:
46 template <class... SemanticNames>
47 inline GeometryIndexLayerBase( SemanticNames... names ) : ObjectWithSemantic( names... ) {}
48};
49
51template <typename T>
53 using IndexType = T;
55
56 inline IndexContainerType& collection();
57 const IndexContainerType& collection() const;
58
59 inline bool append( const GeometryIndexLayerBase& other ) final;
60
62 inline bool operator==( const GeometryIndexLayerBase& other ) const final;
63
64 inline size_t getSize() const override final;
65
66 inline std::unique_ptr<GeometryIndexLayerBase> clone() override final;
67
68 inline size_t getNumberOfComponents() const override final;
69
70 inline size_t getBufferSize() const override final;
71
74 inline int getStride() const override final;
75
76 inline const void* dataPtr() const override final;
77
78 protected:
79 template <class... SemanticNames>
80 inline GeometryIndexLayer( SemanticNames... names ) : GeometryIndexLayerBase( names... ) {}
81
82 private:
83 IndexContainerType m_collection;
84};
85
131class RA_CORE_API MultiIndexedGeometry : public AttribArrayGeometry, public Utils::ObservableVoid
132{
133 public:
137
144
145 inline MultiIndexedGeometry() = default;
146 explicit MultiIndexedGeometry( const MultiIndexedGeometry& other );
147 explicit MultiIndexedGeometry( MultiIndexedGeometry&& other );
148 explicit MultiIndexedGeometry( const AttribArrayGeometry& other );
149 explicit MultiIndexedGeometry( AttribArrayGeometry&& other );
150 MultiIndexedGeometry& operator=( const MultiIndexedGeometry& other );
151 MultiIndexedGeometry& operator=( MultiIndexedGeometry&& other );
152
153 virtual inline ~MultiIndexedGeometry();
154 void clear() override;
155
158 void copy( const MultiIndexedGeometry& other );
159
162 void checkConsistency() const;
163
167 bool append( const MultiIndexedGeometry& other );
168
171
175 inline bool containsLayer( const LayerKeyType& layerKey ) const;
176
183 inline bool containsLayer( const LayerSemanticCollection& semantics,
184 const std::string& layerName ) const;
185
191 bool containsLayer( const LayerSemanticCollection& semantics ) const;
192
198 bool containsLayer( const LayerSemantic& semanticName ) const;
199
202
206 inline size_t countLayers( const LayerKeyType& layerKey ) const;
207
214 inline size_t countLayers( const LayerSemanticCollection& semantics,
215 const std::string& layerName ) const;
216
222 size_t countLayers( const LayerSemanticCollection& semantics ) const;
223
229 size_t countLayers( const LayerSemantic& semanticName ) const;
230
233
238 inline const GeometryIndexLayerBase& getLayer( const LayerKeyType& layerKey ) const;
239
248 const std::string& layerName ) const;
257 getFirstLayerOccurrence( const LayerSemanticCollection& semantics ) const;
258
267 getFirstLayerOccurrence( const LayerSemantic& semanticName ) const;
268
271
280 GeometryIndexLayerBase& getLayerWithLock( const LayerKeyType& layerKey );
281
290 inline GeometryIndexLayerBase& getLayerWithLock( const LayerSemanticCollection& semantics,
291 const std::string& layerName );
292
302 getFirstLayerOccurrenceWithLock( const LayerSemanticCollection& semantics );
303
313 getFirstLayerOccurrenceWithLock( const LayerSemantic& semanticName );
314
317
324 void unlockLayer( const LayerKeyType& layerKey );
325
334 inline void unlockLayer( const LayerSemanticCollection& semantics,
335 const std::string& layerName );
336
337 // The following methods are only mean to be used by PredifinedIndexGeometry and should not be
338 // part of the final API
339 protected:
347 void unlockFirstLayerOccurrence( const LayerSemanticCollection& semantics );
348
356 void unlockFirstLayerOccurrence( const LayerSemantic& semanticName );
357
360 public:
370 const bool withLock = false,
371 const std::string& layerName = "" );
372
377 [[nodiscard]] inline auto layerKeys() const;
378
379 private:
381 void deepCopy( const MultiIndexedGeometry& other );
382
384 void deepClear();
385
387
388 struct RA_CORE_API KeyHash {
389 std::size_t operator()( const LayerKeyType& k ) const;
390 };
391
398};
399
403
405struct RA_CORE_API PointCloudIndexLayer : public GeometryIndexLayer<Vector1ui> {
407 inline PointCloudIndexLayer();
408
411 inline explicit PointCloudIndexLayer( size_t n );
412
414 void linearIndices( const AttribArrayGeometry& attr );
415
416 static constexpr const char* staticSemanticName = "PointCloud";
417
418 protected:
419 template <class... SemanticNames>
420 inline PointCloudIndexLayer( SemanticNames... names );
421};
422
425struct RA_CORE_API TriangleIndexLayer : public GeometryIndexLayer<Vector3ui> {
426 inline TriangleIndexLayer();
427 static constexpr const char* staticSemanticName = "TriangleMesh";
428
429 protected:
430 template <class... SemanticNames>
431 inline explicit TriangleIndexLayer( SemanticNames... names );
432};
433
436struct RA_CORE_API QuadIndexLayer : public GeometryIndexLayer<Vector4ui> {
437 inline QuadIndexLayer();
438 static constexpr const char* staticSemanticName = "QuadMesh";
439
440 protected:
441 template <class... SemanticNames>
442 inline explicit QuadIndexLayer( SemanticNames... names );
443};
444
448struct RA_CORE_API PolyIndexLayer : public GeometryIndexLayer<VectorNui> {
449 inline PolyIndexLayer();
450 static constexpr const char* staticSemanticName = "PolyMesh";
451
452 protected:
453 template <class... SemanticNames>
454 inline explicit PolyIndexLayer( SemanticNames... names );
455};
456
459struct RA_CORE_API LineIndexLayer : public GeometryIndexLayer<Vector2ui> {
460 inline LineIndexLayer();
461 static constexpr const char* staticSemanticName = "LineMesh";
462
463 protected:
464 template <class... SemanticNames>
465 inline explicit LineIndexLayer( SemanticNames... names );
466};
467
469
472namespace IndexLayerType {
473template <class IndexT>
474struct getType {};
475
476template <>
477struct getType<Vector2ui> {
479};
480
481template <>
482struct getType<Vector3ui> {
484};
485
486template <>
487struct getType<Vector4ui> {
489};
490
491template <>
492struct getType<VectorNui> {
494};
495
496template <>
497struct getType<Vector1ui> {
499};
500
501} // namespace IndexLayerType
502
513template <typename T>
515{
516 public:
517 using IndexType = T;
519
520 private:
521 using DefaultLayerType = typename IndexLayerType::getType<IndexType>::Type;
522
523 public:
524 inline IndexedGeometry();
525
526 inline const IndexContainerType& getIndices() const;
531
533 inline void indicesUnlock();
537 inline void setIndices( IndexContainerType&& indices );
538 inline void setIndices( const IndexContainerType& indices );
539 inline const LayerKeyType& getLayerKey() const;
540
541 private:
542 LayerKeyType m_mainIndexLayerKey;
543};
544
545class RA_CORE_API IndexedPointCloud : public IndexedGeometry<Vector1ui>
546{};
547
548class RA_CORE_API TriangleMesh : public IndexedGeometry<Vector3ui>
549{};
550
551class RA_CORE_API QuadMesh : public IndexedGeometry<Vector4ui>
552{};
553
554class RA_CORE_API PolyMesh : public IndexedGeometry<VectorNui>
555{};
556
557class RA_CORE_API LineMesh : public IndexedGeometry<Vector2ui>
558{};
559
560// GeometryIndexLayerBase
563
566 CORE_UNUSED( other );
567 CORE_ASSERT( semantics() == other.semantics(),
568 "Try to assign object with different semantics" );
569 return *this;
570}
571
573 CORE_UNUSED( other );
574 CORE_ASSERT( semantics() == other.semantics(),
575 "Try to assign GeometryIndexLayer of different type" );
576 return *this;
577}
578
579inline GeometryIndexLayerBase::~GeometryIndexLayerBase() {}
580
582 return false;
583}
584
585// GeometryIndexLayer
586
587template <typename T>
589 return m_collection;
590}
591
592template <typename T>
595 return m_collection;
596}
597
598template <typename T>
600 if ( shareSemantic( other ) ) {
601 const auto& othercasted = static_cast<const GeometryIndexLayer<T>&>( other );
602 m_collection.insert(
603 m_collection.end(), othercasted.collection().begin(), othercasted.collection().end() );
604 return true;
605 }
606 return false;
607}
608
609template <typename T>
611 if ( shareSemantic( other ) ) {
612 const auto& othercasted = static_cast<const GeometryIndexLayer<T>&>( other );
613 return othercasted.collection() == m_collection;
614 }
615 return false;
616}
617
618template <typename T>
619inline size_t GeometryIndexLayer<T>::getSize() const {
620 return m_collection.size();
621}
622
623template <typename T>
625 return IndexType::RowsAtCompileTime;
626}
627
628template <typename T>
630 return m_collection.size() * sizeof( IndexType );
631}
632
633template <typename T>
635 return sizeof( IndexType );
636}
637
638template <typename T>
639inline const void* GeometryIndexLayer<T>::dataPtr() const {
640 return m_collection.data();
641}
642
643template <typename T>
645 auto copy = std::make_unique<GeometryIndexLayer<T>>( *this );
646 copy->m_collection = m_collection;
647 return copy;
648}
649
650// MultiIndexedGeometry
651inline MultiIndexedGeometry::~MultiIndexedGeometry() {
652 detachAll();
653 clear();
654}
655
656inline bool
658 return m_indices.find( layerKey ) != m_indices.end();
659}
660
661inline bool
663 const std::string& layerName ) const {
664 return containsLayer( { semantics, layerName } );
665}
666
667inline size_t
669 return m_indices.count( layerKey );
670}
671
672inline size_t
674 const std::string& layerName ) const {
675 return countLayers( { semantics, layerName } );
676}
677
678inline const GeometryIndexLayerBase&
680 return *( m_indices.at( layerKey ).second.get() );
681}
682
685 const std::string& layerName ) {
686 return getLayerWithLock( { semantics, layerName } );
687}
688
689inline void
691 const std::string& layerName ) {
692 unlockLayer( { semantics, layerName } );
693}
694
695[[nodiscard]] inline auto MultiIndexedGeometry::layerKeys() const {
696 return Utils::map_keys( m_indices );
697}
698
699// PointCloudIndexLayer
703 GeometryIndexLayer( PointCloudIndexLayer::staticSemanticName ) {
704 collection().resize( n );
705 collection().getMap() = IndexContainerType::Matrix::LinSpaced( n, 0, n - 1 );
706}
707template <class... SemanticNames>
708inline PointCloudIndexLayer::PointCloudIndexLayer( SemanticNames... names ) :
709 GeometryIndexLayer( PointCloudIndexLayer::staticSemanticName, names... ) {}
710// TriangleIndexLayer
711inline TriangleIndexLayer::TriangleIndexLayer() :
712 GeometryIndexLayer( TriangleIndexLayer::staticSemanticName ) {}
713template <class... SemanticNames>
714inline TriangleIndexLayer::TriangleIndexLayer( SemanticNames... names ) :
715 GeometryIndexLayer( TriangleIndexLayer::staticSemanticName, names... ) {}
716// QuadIndexLayer
717inline QuadIndexLayer::QuadIndexLayer() :
718 GeometryIndexLayer( QuadIndexLayer::staticSemanticName ) {}
719template <class... SemanticNames>
720inline QuadIndexLayer::QuadIndexLayer( SemanticNames... names ) :
721 GeometryIndexLayer( QuadIndexLayer::staticSemanticName, names... ) {}
722// PolyIndexLayer
723inline PolyIndexLayer::PolyIndexLayer() :
724 GeometryIndexLayer( PolyIndexLayer::staticSemanticName ) {}
725template <class... SemanticNames>
726inline PolyIndexLayer::PolyIndexLayer( SemanticNames... names ) :
727 GeometryIndexLayer( PolyIndexLayer::staticSemanticName, names... ) {}
728// LineIndexLayer
729inline LineIndexLayer::LineIndexLayer() :
730 GeometryIndexLayer( LineIndexLayer::staticSemanticName ) {}
731template <class... SemanticNames>
732inline LineIndexLayer::LineIndexLayer( SemanticNames... names ) :
733 GeometryIndexLayer( LineIndexLayer::staticSemanticName, names... ) {}
734// IndexedGeometry
735template <typename T>
736inline IndexedGeometry<T>::IndexedGeometry() {
737 auto layer = std::make_unique<DefaultLayerType>();
738 m_mainIndexLayerKey = { layer->semantics(), "" };
739 addLayer( std::move( layer ) );
740}
741
742template <typename T>
743
744inline const typename IndexedGeometry<T>::IndexContainerType&
745IndexedGeometry<T>::getIndices() const {
746 const auto& abstractLayer = getLayer( m_mainIndexLayerKey );
747 return static_cast<const IndexedGeometry<T>::DefaultLayerType&>( abstractLayer ).collection();
748}
749template <typename T>
751 auto& abstractLayer = getLayerWithLock( m_mainIndexLayerKey );
752 return static_cast<IndexedGeometry<T>::DefaultLayerType&>( abstractLayer ).collection();
753}
754
755template <typename T>
757 unlockLayer( m_mainIndexLayerKey );
758}
759
760template <typename T>
762 auto& abstractLayer = getLayerWithLock( m_mainIndexLayerKey );
763 static_cast<IndexedGeometry<T>::DefaultLayerType&>( abstractLayer ).collection() =
764 std::move( indices );
765 notify();
766}
767
768template <typename T>
769inline void IndexedGeometry<T>::setIndices( const IndexContainerType& indices ) {
770 auto& abstractLayer = getLayerWithLock( m_mainIndexLayerKey );
771 static_cast<IndexedGeometry<T>::DefaultLayerType&>( abstractLayer ).collection() = indices;
772 notify();
773}
774
775template <typename T>
777 return m_mainIndexLayerKey;
778}
779
780} // namespace Geometry
781} // namespace Core
782} // namespace Ra
This class represents vertex + attributes per vertex. Toplogy is handled in MultiIndexedGeometry subc...
Base class for index collections stored in MultiIndexedGeometry.
GeometryIndexLayerBase(SemanticNames... names)
Hidden constructor that must be called by inheriting classes to define the object semantics.
virtual bool append(const GeometryIndexLayerBase &other)=0
Append content from another layer.
virtual std::unique_ptr< GeometryIndexLayerBase > clone()=0
Create new layer with duplicated content.
virtual bool operator==(const GeometryIndexLayerBase &other) const
Compare if two layers have the same content.
GeometryIndexLayerBase(const GeometryIndexLayerBase &other)
Copy constructor.
GeometryIndexLayerBase & operator=(const GeometryIndexLayerBase &other)
Assignment operator.
A single layer MultiIndexedGeometry.
IndexContainerType & getIndicesWithLock()
void indicesUnlock()
unlock previously read write acces, notify observers of the update.
void setIndices(IndexContainerType &&indices)
AbstractGeometry with per-vertex attributes and layers of indices. Each layer represents a different ...
const GeometryIndexLayerBase & getLayer(const LayerKeyType &layerKey) const
Read-only access to a layer.
const GeometryIndexLayerBase & getLayer(const LayerSemanticCollection &semantics, const std::string &layerName) const
Read-only access to a layer.
auto layerKeys() const
Range on layer keys (read-only)
size_t countLayers(const LayerKeyType &layerKey) const
Count the number of layer matching the input parameters.
bool containsLayer(const LayerKeyType &layerKey) const
Check if at least one layer with such properties exists.
GeometryIndexLayerBase & getLayerWithLock(const LayerKeyType &layerKey)
Write access to a layer.
void clear() override
Erases all data, making the AttribArrayGeometry empty.
void unlockLayer(const LayerKeyType &layerKey)
Unlock layer with write acces, notify observers of the update.
This class defines the introspection interface a container need to implement.
Object associated with one or multiple semantic names.
std::enable_if_t<(N > 0), MatrixMap > getMap()
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:3
STL namespace.
T resize(T... args)
bool append(const GeometryIndexLayerBase &other) final
Append content from another layer.
size_t getSize() const override final
const void * dataPtr() const override final
size_t getBufferSize() const override final
size_t getNumberOfComponents() const override final
bool operator==(const GeometryIndexLayerBase &other) const final
std::unique_ptr< GeometryIndexLayerBase > clone() override final
Create new layer with duplicated content.
PointCloudIndexLayer()
Constructor of an empty layer.
Index layer for polygonal mesh.
Index layer for quadrilateral mesh.
Index layer for triangle mesh.
Generate a range to iterate over the keys of a map.