Radium Engine  1.5.20
Loading...
Searching...
No Matches
IndexedGeometry.cpp
1#include <Core/Geometry/IndexedGeometry.hpp>
2#include <iterator>
3
4namespace Ra {
5namespace Core {
6namespace Geometry {
7
8MultiIndexedGeometry::MultiIndexedGeometry( const MultiIndexedGeometry& other ) :
9 AttribArrayGeometry( other ) {
10 deepCopy( other );
11}
12
13MultiIndexedGeometry::MultiIndexedGeometry( MultiIndexedGeometry&& other ) :
14 AttribArrayGeometry( std::move( other ) ), m_indices( std::move( other.m_indices ) ) {}
15
16MultiIndexedGeometry::MultiIndexedGeometry( const AttribArrayGeometry& other ) :
17 AttribArrayGeometry( other ) {}
18
19MultiIndexedGeometry::MultiIndexedGeometry( AttribArrayGeometry&& other ) :
20 AttribArrayGeometry( std::move( other ) ) {}
21
22MultiIndexedGeometry& MultiIndexedGeometry::operator=( const MultiIndexedGeometry& other ) {
23 invalidateAabb();
24 AttribArrayGeometry::operator=( other );
25 deepCopy( other );
26 notify();
27 return *this;
28}
29
30MultiIndexedGeometry& MultiIndexedGeometry::operator=( MultiIndexedGeometry&& other ) {
31 invalidateAabb();
32 AttribArrayGeometry::operator=( std::move( other ) );
33 m_indices = std::move( other.m_indices );
34 notify();
35 return *this;
36}
37
38void MultiIndexedGeometry::clear() {
39 invalidateAabb();
40 AttribArrayGeometry::clear();
41 deepClear();
42 notify();
43}
44
45void MultiIndexedGeometry::copy( const MultiIndexedGeometry& other ) {
46 invalidateAabb();
47 AttribArrayGeometry::copyBaseGeometry( other );
48 deepCopy( other );
49 notify();
50}
51
53void MultiIndexedGeometry::checkConsistency() const {
54#ifdef CORE_DEBUG
55#endif
56}
57
58bool MultiIndexedGeometry::append( const MultiIndexedGeometry& other ) {
59 bool dataHasBeenCopied = false;
60 for ( const auto& [key, value] : other.m_indices ) {
61 auto it = m_indices.find( key );
62 if ( it == m_indices.end() ) // copy entire layer
63 {
64 m_indices[key] = std::make_pair(
65 value.first, std::unique_ptr<GeometryIndexLayerBase> { value.second->clone() } );
66
67 dataHasBeenCopied = true;
68 }
69 else {
70 // try to append to an existing layer: should always work
71 if ( it->second.second->append( *( value.second ) ) ) { dataHasBeenCopied = true; }
72 else {
73 CORE_ASSERT( false,
74 "Inconsistency: layers with different semantics shares the same key" );
75 }
76 }
77 }
78
79 if ( dataHasBeenCopied ) {
80 invalidateAabb();
81 notify();
82 }
83 return true;
84}
85
88
89bool MultiIndexedGeometry::containsLayer( const LayerSemantic& semanticName ) const {
90 for ( const auto& [key, value] : m_indices ) {
91 if ( key.first.find( semanticName ) != key.first.end() ) return true;
92 }
93 return false;
94}
95
96bool MultiIndexedGeometry::containsLayer( const LayerSemanticCollection& semantics ) const {
97 for ( const auto& [key, value] : m_indices ) {
98 if ( key.first == semantics ) return true;
99 }
100 return false;
101}
102
105
106size_t MultiIndexedGeometry::countLayers( const LayerSemantic& semanticName ) const {
107 size_t c = 0;
108 for ( const auto& [key, value] : m_indices ) {
109 if ( key.first.find( semanticName ) != key.first.end() ) ++c;
110 }
111 return c;
112}
113
114size_t MultiIndexedGeometry::countLayers( const LayerSemanticCollection& semantics ) const {
115 size_t c = 0;
116 for ( const auto& [key, value] : m_indices ) {
117 if ( key.first == semantics ) ++c;
118 }
119 return c;
120}
121
124
126MultiIndexedGeometry::getFirstLayerOccurrence( const LayerSemantic& semanticName ) const {
127 for ( const auto& [key, value] : m_indices ) {
128 if ( key.first.find( semanticName ) != key.first.end() )
129 return { key, *( value.second.get() ) };
130 }
131 throw std::out_of_range( "Layer entry not found" );
132}
133
135MultiIndexedGeometry::getFirstLayerOccurrence( const LayerSemanticCollection& semantics ) const {
136 for ( const auto& [key, value] : m_indices ) {
137 if ( key.first == semantics ) return { key, *( value.second.get() ) };
138 }
139 throw std::out_of_range( "Layer entry not found" );
140}
141
144
146MultiIndexedGeometry::getFirstLayerOccurrenceWithLock( const LayerSemantic& semanticName ) {
147 for ( auto& [key, value] : m_indices ) {
148 if ( key.first.find( semanticName ) != key.first.end() ) {
149 CORE_ASSERT( !value.first, "try to get already locked layer" );
150 value.first = true;
151 return { key, *( value.second.get() ) };
152 }
153 }
154 throw std::out_of_range( "Layer entry not found" );
155}
156
158MultiIndexedGeometry::getFirstLayerOccurrenceWithLock( const LayerSemanticCollection& semantics ) {
159 for ( auto& [key, value] : m_indices ) {
160 if ( key.first == semantics ) {
161 CORE_ASSERT( !value.first, "try to get already locked layer" );
162 value.first = true;
163 return { key, *( value.second.get() ) };
164 }
165 }
166 throw std::out_of_range( "Layer entry not found" );
167}
168
169GeometryIndexLayerBase& MultiIndexedGeometry::getLayerWithLock( const LayerKeyType& layerKey ) {
170 auto& p = m_indices.at( layerKey );
171 CORE_ASSERT( !p.first, "try to get already locked layer" );
172 p.first = true;
173 return *( p.second.get() );
174}
175
178
179void MultiIndexedGeometry::unlockFirstLayerOccurrence( const LayerSemantic& semanticName ) {
180 for ( auto& [key, value] : m_indices ) {
181 if ( key.first.find( semanticName ) != key.first.end() ) {
182 CORE_ASSERT( value.first, "try to release unlocked layer" );
183 value.first = false;
184 notify();
185 return;
186 }
187 }
188 throw std::out_of_range( "Layer entry not found" );
189}
190
191void MultiIndexedGeometry::unlockFirstLayerOccurrence( const LayerSemanticCollection& semantics ) {
192 for ( auto& [key, value] : m_indices ) {
193 if ( key.first == semantics ) {
194 CORE_ASSERT( value.first, "try to release unlocked layer" );
195 value.first = false;
196 notify();
197 return;
198 }
199 }
200 throw std::out_of_range( "Layer entry not found" );
201}
202
203void MultiIndexedGeometry::unlockLayer( const LayerKeyType& layerKey ) {
204 auto& p = m_indices.at( layerKey );
205 CORE_ASSERT( p.first, "try to release unlocked layer" );
206 p.first = false;
207 notify();
208}
209
212
214MultiIndexedGeometry::addLayer( std::unique_ptr<GeometryIndexLayerBase>&& layer,
215 const bool withLock,
216 const std::string& layerName ) {
217 LayerKeyType key { layer->semantics(), layerName };
218 std::pair<LayerKeyType, EntryType> elt { key, std::make_pair( false, std::move( layer ) ) };
219 auto [pos, inserted] = m_indices.insert( std::move( elt ) );
220 notify();
221
222 if ( withLock ) {
223 CORE_ASSERT( !pos->second.first, "try to get already locked layer" );
224 pos->second.first = true;
225 }
228
229 return { inserted, *( pos->second.second ) };
230}
233
234void MultiIndexedGeometry::deepCopy( const MultiIndexedGeometry& other ) {
235 for ( const auto& [key, value] : other.m_indices ) {
236 m_indices[key] = std::make_pair(
237 value.first, std::unique_ptr<GeometryIndexLayerBase> { value.second->clone() } );
238 }
239}
240
241void MultiIndexedGeometry::deepClear() {
242 m_indices.clear();
243}
244
247
248std::size_t MultiIndexedGeometry::KeyHash::operator()( const LayerKeyType& k ) const {
249 // Mix semantic collection into a single identifier string
250 std::ostringstream stream;
251 std::copy( k.first.begin(), k.first.end(), std::ostream_iterator<std::string>( stream, "" ) );
252 std::string result = stream.str();
253 std::sort( result.begin(), result.end() );
254
255 // Combine with layer name hash
256 return std::hash<std::string> {}( result ) ^ ( std::hash<std::string> {}( k.second ) << 1 );
257}
258
261
262void PointCloudIndexLayer::linearIndices( const AttribArrayGeometry& attr ) {
263 auto nbVert = attr.vertices().size();
264 collection().resize( nbVert );
265 collection().getMap() = IndexContainerType::Matrix::LinSpaced( nbVert, 0, nbVert - 1 );
266}
267
268} // namespace Geometry
269} // namespace Core
270} // namespace Ra
T begin(T... args)
This class represents vertex + attributes per vertex. Toplogy is handled in MultiIndexedGeometry subc...
const PointAttribHandle::Container & vertices() const
Access the vertices positions.
Base class for index collections stored in MultiIndexedGeometry.
AbstractGeometry with per-vertex attributes and layers of indices. Each layer represents a different ...
T copy(T... args)
T end(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:3
STL namespace.
T sort(T... args)
T str(T... args)