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>
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>
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>
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>
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>
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>
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>
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>
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 }
unsigned int eraseSplatsByFlag(const std::vector< T > &_flags)
Delete the elements with flag != 0 from the data vector of all splat-properties.
CloudPropertyT< T > * getCloudProperty(const PropertyHandleT< T > &_handle)
Get a pointer to a property.
CloudPropertyT< T > * requestCloudProperty(const PropertyHandleT< T > &_handle)
Request a new property.
CloudPropertyMap cloudProperties_
Cloud-property map.
Definition: SplatCloud.hh:479
Index & indices(int _idx)
Get a reference of the predefined property&#39;s value.
Definition: SplatCloud.hh:639
SplatPropertyT< T > * releaseSplatProperty(const PropertyHandleT< T > &_handle)
Release a property.
unsigned int numSplats_
Number of splats.
Definition: SplatCloud.hh:186
SplatPropertyT< T > * requestSplatProperty(const PropertyHandleT< T > &_handle)
Request a new property.
CloudPropertyT< T > * releaseCloudProperty(const PropertyHandleT< T > &_handle)
Release a property.
std::vector< T > data_
The actual stored data (one element per splat)
Definition: SplatCloud.hh:317
unsigned int eraseSplatsByIndex(const T &_indices)
Delete the elements with given indices from the data vector of all splat-properties.
virtual void crop(const std::vector< int > &_indices)
Keep only the elements with given indices in the data vector. The indices have to be valid...
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.
SplatPropertyMap splatProperties_
Splat-property map.
Definition: SplatCloud.hh:476
SplatPropertyT< T > * getSplatProperty(const PropertyHandleT< T > &_handle)
Get a pointer to a property.