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