Developer Documentation

SplatCloudT_impl.hh
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42
43
44 //================================================================
45 //
46 // CLASS SplatCloud - TEMPLATE IMPLEMENTATION
47 //
48 //================================================================
49
50
51 #define SPLATCLOUDT_CC
52
53
54 //== INCLUDES ====================================================
55
56
57 #include "SplatCloud.hh"
58
59
60 //== IMPLEMENTATION ==============================================
61
62
63 template <typename T>
64 unsigned int SplatCloud::eraseSplatsByIndex( const T &_indices )
65 {
66 int maxIdx = numSplats_ - 1;
67
68 // create vector of flags indicating which elements to delete (initialized to false)
69 std::vector<bool> flags( numSplats_, false );
70
71 // set flags given by indices
72 typename T::const_iterator idxIter;
73 for( idxIter = _indices.begin(); idxIter != _indices.end(); ++idxIter )
74 {
75 // convert index to int
76 int idx = static_cast<int>( *idxIter );
77
78 // if index is valid, set flag
79 if( (idx >= 0) && (idx <= maxIdx) )
80 flags[ idx ] = true;
81 }
82
83 // delete elements and return number of deleted elements
84 return eraseSplatsByFlag( flags );
85 }
86
87
88 //----------------------------------------------------------------
89
90
91 template <typename T>
92 unsigned int SplatCloud::eraseSplatsByFlag( const std::vector<T> &_flags )
93 {
94 // check for right size of flags vector
95 if( _flags.size() != numSplats_ )
96 return 0; // error; no elements have been deleted so return 0
97
98 // create index vector indicating which elements to keep
99 std::vector<int> indices;
100
101 // reserve enough memory
102 indices.reserve( numSplats_ );
103
104 // fill index vector
105 unsigned int i;
106 for( i=0; i<numSplats_; ++i )
107 {
108 if( !_flags[i] )
109 indices.push_back( i );
110 }
111
112 // calculate number of elements to delete
113 unsigned int numDelete = numSplats_ - indices.size();
114
115 // check if something has to be deleted
116 if( numDelete != 0 )
117 {
118 // keep only elements with given indices in data vector of all splat-properties
119 SplatPropertyMap::const_iterator splatPropertyIter;
120 for( splatPropertyIter = splatProperties_.begin(); splatPropertyIter != splatProperties_.end(); ++splatPropertyIter )
121 splatPropertyIter->second.property_->crop( indices );
122
123 // update number of splats
124 numSplats_ = indices.size();
125 }
126
127 // return number of deleted elements
128 return numDelete;
129 }
130
131
132 //----------------------------------------------------------------
133
134
135 template <typename T>
136 void SplatCloud::cropSplats( const T &_indices )
137 {
138 int maxIdx = numSplats_ - 1;
139
140 // create vector of valid indices
141 std::vector<int> validIndices;
142 validIndices.reserve( _indices.size() );
143
144 // set valid indices
145 typename T::const_iterator idxIter;
146 for( idxIter = _indices.begin(); idxIter != _indices.end(); ++idxIter )
147 {
148 // convert index to int
149 int idx = static_cast<int>( *idxIter );
150
151 // if index is valid, add index to valid indices
152 if( (idx >= 0) && (idx <= maxIdx) )
153 validIndices.push_back( idx );
154 }
155
156 // keep only elements with given indices in data vector of all splat-properties
157 SplatPropertyMap::const_iterator splatPropertyIter;
158 for( splatPropertyIter = splatProperties_.begin(); splatPropertyIter != splatProperties_.end(); ++splatPropertyIter )
159 splatPropertyIter->second.property_->crop( validIndices );
160
161 // update number of splats
162 numSplats_ = validIndices.size();
163 }
164
165
166 //----------------------------------------------------------------
167
168
169 template <typename T>
170 /*virtual*/ void SplatCloud::SplatPropertyT<T>::crop( const std::vector<int> &_indices )
171 {
172 // create new data vector
173 std::vector<T> newData;
174 newData.reserve( _indices.size() );
175
176 // fill new data vector by inserting elements of old data vector with given indices
177 std::vector<int>::const_iterator idxIter;
178 for( idxIter = _indices.begin(); idxIter != _indices.end(); ++idxIter )
179 newData.push_back( data_[ *idxIter ] );
180
181 // set old data vector to new one (swap and discard old vector)
182 data_.swap( newData );
183 }
184
185
186 //----------------------------------------------------------------
187
188
189 template <typename T>
190 SplatCloud::SplatPropertyT<T> *SplatCloud::requestSplatProperty( const SplatCloud::PropertyHandleT<T> &_handle )
191 {
192 // try to find property map entry
193 SplatPropertyMap::iterator iter = splatProperties_.find( _handle );
194
195 // check if a property with the same name is already present
196 if( iter != splatProperties_.end() )
197 {
198 // try to cast
199 SplatPropertyT<T> *oldProp = dynamic_cast<SplatPropertyT<T> *>( iter->second.property_ );
200
201 // if found property is of the right type, increase number of requests
202 if( oldProp != 0 )
203 ++iter->second.numRequests_;
204
205 // return pointer to old property
206 return oldProp;
207 }
208
209 // create new property
210 SplatPropertyT<T> *newProp = new SplatPropertyT<T>( _handle, numSplats_ );
211
212 // if creation went wrong, free memory and reset pointer
213 if( newProp->data_.size() != numSplats_ )
214 {
215 delete newProp;
216 newProp = 0;
217 }
218
219 // if pointer is valid, insert new property map entry
220 if( newProp != 0 )
221 splatProperties_[ _handle ] = SplatPropertyMapEntry( newProp, 1 );
222
223 // return pointer to new property
224 return newProp;
225 }
226
227
228 //----------------------------------------------------------------
229
230
231 template <typename T>
232 SplatCloud::CloudPropertyT<T> *SplatCloud::requestCloudProperty( const SplatCloud::PropertyHandleT<T> &_handle )
233 {
234 // try to find property map entry
235 CloudPropertyMap::iterator iter = cloudProperties_.find( _handle );
236
237 // check if a property with the same name is already present
238 if( iter != cloudProperties_.end() )
239 {
240 // try to cast
241 CloudPropertyT<T> *oldProp = dynamic_cast<CloudPropertyT<T> *>( iter->second.property_ );
242
243 // if found property is of the right type, increase number of requests
244 if( oldProp != 0 )
245 ++iter->second.numRequests_;
246
247 // return pointer to old property
248 return oldProp;
249 }
250
251 // create new property
252 CloudPropertyT<T> *newProp = new CloudPropertyT<T>( _handle );
253
254 // if pointer is valid, insert new property map entry
255 if( newProp != 0 )
256 cloudProperties_[ _handle ] = CloudPropertyMapEntry( newProp, 1 );
257
258 // return pointer to new property
259 return newProp;
260 }
261
262
263 //----------------------------------------------------------------
264
265
266 template <typename T>
267 SplatCloud::SplatPropertyT<T> *SplatCloud::releaseSplatProperty( const SplatCloud::PropertyHandleT<T> &_handle )
268 {
269 // try to find property map entry
270 SplatPropertyMap::iterator iter = splatProperties_.find( _handle );
271
272 // if *not* found, abort
273 if( iter == splatProperties_.end() )
274 return 0;
275
276 // try to cast
277 SplatPropertyT<T> *prop = dynamic_cast<SplatPropertyT<T> *>( iter->second.property_ );
278
279 // check if found property is of the right type
280 if( prop != 0 )
281 {
282 // decrease number of request
283 --iter->second.numRequests_;
284
285 // check if property should be removed now
286 if( iter->second.numRequests_ == 0 )
287 {
288 // free memory of property and reset pointer
289 delete prop;
290 prop = 0;
291
292 // remove property map entry
293 splatProperties_.erase( iter );
294 }
295 }
296
297 // return pointer to property
298 return prop;
299 }
300
301
302 //----------------------------------------------------------------
303
304
305 template <typename T>
306 SplatCloud::CloudPropertyT<T> *SplatCloud::releaseCloudProperty( const SplatCloud::PropertyHandleT<T> &_handle )
307 {
308 // try to find property map entry
309 CloudPropertyMap::iterator iter = cloudProperties_.find( _handle );
310
311 // if *not* found, abort
312 if( iter == cloudProperties_.end() )
313 return 0;
314
315 // try to cast
316 CloudPropertyT<T> *prop = dynamic_cast<CloudPropertyT<T> *>( iter->second.property_ );
317
318 // check if found property is of the right type
319 if( prop != 0 )
320 {
321 // decrease number of request
322 --iter->second.numRequests_;
323
324 // check if property should be removed now
325 if( iter->second.numRequests_ == 0 )
326 {
327 // free memory of property and reset pointer
328 delete prop;
329 prop = 0;
330
331 // remove property map entry
332 cloudProperties_.erase( iter );
333 }
334 }
335
336 // return pointer to property
337 return prop;
338 }
339
340
341 //----------------------------------------------------------------
342
343
344 template <typename T>
345 SplatCloud::SplatPropertyT<T> *SplatCloud::getSplatProperty( const SplatCloud::PropertyHandleT<T> &_handle )
346 {
347 // try to find property map entry
348 SplatPropertyMap::const_iterator iter = splatProperties_.find( _handle );
349
350 // if *not* found or cast fails return 0, otherwise return a valid pointer
351 return (iter == splatProperties_.end()) ? 0 : dynamic_cast<SplatPropertyT<T> *>( iter->second.property_ );
352 }
353
354
355 //----------------------------------------------------------------
356
357
358 template <typename T>
359 const SplatCloud::SplatPropertyT<T> *SplatCloud::getSplatProperty( const SplatCloud::PropertyHandleT<T> &_handle ) const
360 {
361 // try to find property map entry
362 SplatPropertyMap::const_iterator iter = splatProperties_.find( _handle );
363
364 // if *not* found or cast fails return 0, otherwise return a valid pointer
365 return (iter == splatProperties_.end()) ? 0 : dynamic_cast<const SplatPropertyT<T> *>( iter->second.property_ );
366 }
367
368
369 //----------------------------------------------------------------
370
371
372 template <typename T>
373 SplatCloud::CloudPropertyT<T> *SplatCloud::getCloudProperty( const SplatCloud::PropertyHandleT<T> &_handle )
374 {
375 // try to find property map entry
376 CloudPropertyMap::const_iterator iter = cloudProperties_.find( _handle );
377
378 // if *not* found or cast fails return 0, otherwise return a valid pointer
379 return (iter == cloudProperties_.end()) ? 0 : dynamic_cast<CloudPropertyT<T> *>( iter->second.property_ );
380 }
381
382
383 //----------------------------------------------------------------
384
385
386 template <typename T>
387 const SplatCloud::CloudPropertyT<T> *SplatCloud::getCloudProperty( const SplatCloud::PropertyHandleT<T> &_handle ) const
388 {
389 // try to find property map entry
390 CloudPropertyMap::const_iterator iter = cloudProperties_.find( _handle );
391
392 // if *not* found or cast fails return 0, otherwise return a valid pointer
393 return (iter == cloudProperties_.end()) ? 0 : dynamic_cast<const CloudPropertyT<T> *>( iter->second.property_ );
394 }
SplatCloud::requestSplatProperty
SplatPropertyT< T > * requestSplatProperty(const PropertyHandleT< T > &_handle)
Request a new property.
Definition: SplatCloudT_impl.hh:190
SplatCloud::PropertyHandleT
Definition: SplatCloud.hh:283
SplatCloud::SplatPropertyT
Definition: SplatCloud.hh:293
SplatCloud::SplatPropertyT::crop
virtual void crop(const std::vector< int > &_indices) override
Keep only the elements with given indices in the data vector. The indices have to be valid...
Definition: SplatCloudT_impl.hh:170
SplatCloud::SplatPropertyT::data_
std::vector< T > data_
The actual stored data (one element per splat)
Definition: SplatCloud.hh:317
SplatCloud::cloudProperties_
CloudPropertyMap cloudProperties_
Cloud-property map.
Definition: SplatCloud.hh:479
SplatCloud.hh
SplatCloud::requestCloudProperty
CloudPropertyT< T > * requestCloudProperty(const PropertyHandleT< T > &_handle)
Request a new property.
Definition: SplatCloudT_impl.hh:232
SplatCloud::releaseSplatProperty
SplatPropertyT< T > * releaseSplatProperty(const PropertyHandleT< T > &_handle)
Release a property.
Definition: SplatCloudT_impl.hh:267
SplatCloud::CloudPropertyMapEntry
Definition: SplatCloud.hh:257
SplatCloud::SplatPropertyMapEntry
Definition: SplatCloud.hh:244
SplatCloud::splatProperties_
SplatPropertyMap splatProperties_
Splat-property map.
Definition: SplatCloud.hh:476
SplatCloud::cropSplats
void cropSplats(const T &_indices)
Keep only the elements with given indices in the data vector of all splat-properties. The splats will be rearranged depending on the order of the indices.
Definition: SplatCloudT_impl.hh:136
SplatCloud::getCloudProperty
CloudPropertyT< T > * getCloudProperty(const PropertyHandleT< T > &_handle)
Get a pointer to a property.
Definition: SplatCloudT_impl.hh:373
SplatCloud::numSplats_
unsigned int numSplats_
Number of splats.
Definition: SplatCloud.hh:186
SplatCloud::eraseSplatsByIndex
unsigned int eraseSplatsByIndex(const T &_indices)
Delete the elements with given indices from the data vector of all splat-properties.
Definition: SplatCloudT_impl.hh:64
SplatCloud::eraseSplatsByFlag
unsigned int eraseSplatsByFlag(const std::vector< T > &_flags)
Delete the elements with flag != 0 from the data vector of all splat-properties.
Definition: SplatCloudT_impl.hh:92
SplatCloud::getSplatProperty
SplatPropertyT< T > * getSplatProperty(const PropertyHandleT< T > &_handle)
Get a pointer to a property.
Definition: SplatCloudT_impl.hh:345
SplatCloud::CloudPropertyT
Definition: SplatCloud.hh:324
SplatCloud::releaseCloudProperty
CloudPropertyT< T > * releaseCloudProperty(const PropertyHandleT< T > &_handle)
Release a property.
Definition: SplatCloudT_impl.hh:306
SplatCloud::indices
Index & indices(int _idx)
Get a reference of the predefined property&#39;s value.
Definition: SplatCloud.hh:639