MeVisLab Toolbox Reference
mlPCLInventorTools.h
Go to the documentation of this file.
1// Copyright (c) Fraunhofer MEVIS, Germany. All rights reserved.
2// **InsertLicense** code author="Wolf Spindler"
3//----------------------------------------------------------------------------------
5
12//----------------------------------------------------------------------------------
13#pragma once
14
16#include <mlPCLTypes.h>
17#include <mlPCLSupportTools.h>
18#include <mlErrorMacros.h>
19#include <mlRangeCasts.h>
21#include <Inventor/nodes/SoVertexProperty.h>
23
24// Forwards to internally used classes.
25class SoVertexProperty;
26class SoMFInt32;
27
28ML_START_NAMESPACE
29
31namespace PCLInventorTools {
32
33//----------------------------------------------------------------------------------
34// DESTINATION: SbVec2f
35//----------------------------------------------------------------------------------
36
37//----------------------------------------------------------------------------------
41//----------------------------------------------------------------------------------
42inline void setOneMFVecFieldValue(SbVec2f *dstVal, const float data[4])
43{
44 dstVal->setValue(data[0], data[1]);
45}
46
47//----------------------------------------------------------------------------------
52//----------------------------------------------------------------------------------
53inline void setOneMFVecFieldValue(SbVec2f *dstVal, const unsigned int * /*rgbaVal*/)
54{
55 dstVal->setValue(0.f, 0.f);
56}
57
58//----------------------------------------------------------------------------------
62//----------------------------------------------------------------------------------
63inline void setOneMFVecFieldValue(SbVec2f *dstVal, float data)
64{
65 dstVal->setValue(data, data);
66}
67
68
69//----------------------------------------------------------------------------------
70// DESTINATION: SbVec3f
71//----------------------------------------------------------------------------------
72
73//----------------------------------------------------------------------------------
77//----------------------------------------------------------------------------------
78inline void setOneMFVecFieldValue(SbVec3f *dstVal, const float data[4])
79{
80 dstVal->setValue(data[0], data[1], data[2]);
81}
82
83//----------------------------------------------------------------------------------
88//----------------------------------------------------------------------------------
89inline void setOneMFVecFieldValue(SbVec3f *dstVal, const unsigned int * /*rgbaVal*/)
90{
91 dstVal->setValue(0.f, 0.f, 0.f);
92}
93
94//----------------------------------------------------------------------------------
98//----------------------------------------------------------------------------------
99inline void setOneMFVecFieldValue(SbVec3f *dstVal, float data)
100{
101 dstVal->setValue(data, data, data);
102}
103
104
105
106//----------------------------------------------------------------------------------
107// DESTINATION: MLuint32
108//----------------------------------------------------------------------------------
109
110//----------------------------------------------------------------------------------
115//----------------------------------------------------------------------------------
116inline void setOneMFVecFieldValue(MLuint32 *dstVal, const float data)
117{
118 const MLuint32 byteVal = static_cast<MLuint32>(data);
119 *dstVal = (byteVal | (byteVal << 8) | (byteVal << 16) | (byteVal << 24));
120}
121
122//----------------------------------------------------------------------------------
127//----------------------------------------------------------------------------------
128inline void setOneMFVecFieldValue(MLuint32 *dstVal, const float data[4])
129{
130 *dstVal = ((static_cast<MLuint32>(data[3]) ) |
131 (static_cast<MLuint32>(data[2]) << 8) |
132 (static_cast<MLuint32>(data[1]) << 16) |
133 (static_cast<MLuint32>(data[0]) << 24) );
134}
135
136//----------------------------------------------------------------------------------
138//----------------------------------------------------------------------------------
139inline void setOneMFVecFieldValue(MLuint32 *dstVal, const unsigned int *rgbaVal)
140{
141 *dstVal = ( (( (*rgbaVal) >> 24) & 0x000000ff) |
142 (( (*rgbaVal) >> 8) & 0x0000ff00) |
143 (( (*rgbaVal) << 8) & 0x00ff0000) |
144 (( (*rgbaVal) << 24) & 0xff000000) );
145}
146
147//----------------------------------------------------------------------------------
152//----------------------------------------------------------------------------------
153#if defined(_MSC_VER) && !defined(_WIN64) && ((_MSC_VER == 1600) || (_MSC_VER == 1900))
154#define SpecializedPCLPointXYZ EIGEN_WORKAROUND_MSVC_STL_SUPPORT(pcl::PointXYZ)
155#else
156#define SpecializedPCLPointXYZ pcl::PointXYZ
157#endif
158
159//----------------------------------------------------------------------------------
162//----------------------------------------------------------------------------------
163template <typename DST_VAL_TYPE>
164inline void setOneMFVecFieldValueFromPoint(DST_VAL_TYPE *dstVal, const SpecializedPCLPointXYZ &pnt, bool useData_n)
165{
166 const float zeroData_n[4] = {0.f, 0.f, 0.f, 0.f};
167 setOneMFVecFieldValue(dstVal, useData_n ? zeroData_n : pnt.data);
168}
169
170//----------------------------------------------------------------------------------
172//----------------------------------------------------------------------------------
173template <typename POINT_TYPE, typename DST_VAL_TYPE>
174inline void setOneMFVecFieldValueFromPoint(DST_VAL_TYPE *dstVal, const POINT_TYPE &pnt, bool useData_n)
175{
176 setOneMFVecFieldValue(dstVal, useData_n ? pnt.data_n : pnt.data);
177}
178
179//----------------------------------------------------------------------------------
181//----------------------------------------------------------------------------------
182template <typename DST_VAL_TYPE>
183inline void setTwoMFVecFieldValuesFromPoint(DST_VAL_TYPE *dstVal, const SpecializedPCLPointXYZ &pnt)
184{
185 setOneMFVecFieldValue(dstVal , pnt.data);
186 setOneMFVecFieldValue(dstVal+1, pnt.data);
187}
188
189//----------------------------------------------------------------------------------
191//----------------------------------------------------------------------------------
192template <typename POINT_TYPE, typename DST_VAL_TYPE>
193inline void setTwoMFVecFieldValuesFromPoint(DST_VAL_TYPE *dstVal, const POINT_TYPE &pnt)
194{
195 setOneMFVecFieldValue(dstVal , pnt.data );
196 setOneMFVecFieldValue(dstVal+1, pnt.data_n);
197 dstVal[1] += dstVal[0];
198}
199
200//----------------------------------------------------------------------------------
203//----------------------------------------------------------------------------------
220
221//----------------------------------------------------------------------------------
225//----------------------------------------------------------------------------------
226MLPCL_InventorAdapters_EXPORT void getRainbowRGB_From0_to_1(float intensity, float retRGB[3]);
227
228//----------------------------------------------------------------------------------
253//----------------------------------------------------------------------------------
254template <typename POINT_CLOUD_TYPE, typename SM_MF_VEC_FIELD_TYPE>
255inline size_t setMFVecFromPointCloud(const POINT_CLOUD_TYPE &pointCloud,
256 SM_MF_VEC_FIELD_TYPE &mfvecField,
257 PCLMFVecStorageTypes storageType,
258 bool duplicateColors=false,
259 bool mapToRainbow=false,
260 bool useCurvatureForColor=false,
261 bool scaleFromInputRange=false,
262 float inRangeMin=0.f,
263 float inRangeMax=1.f)
264{
265 // Ensure default scaling if scaleFromInputRange is false.
266 if (!scaleFromInputRange){
267 inRangeMin=0.f;
268 inRangeMax=1.f;
269 }
270 // Precalculate time critical calculations by inverting divisor safely.
271 const float scaleWidth = fabs(inRangeMax-inRangeMin) < 10e-6f ? 10e-6f : inRangeMax-inRangeMin;
272 const float scaleWidthInv = 1.f/scaleWidth;
273
274 bool isSet = false;
275 const size_t numPoints = pointCloud.points.size();
276 if ((numPoints * (CopyDataAndData_n == storageType ? 2 : 1)) <= ML_NAMESPACE::PCLSupportTools::getSigned32BitMaximumLimit()){
277 const unsigned int numPointsAsUInt = mlrange_cast<unsigned int>(numPoints);
278 if ((CopyFromData == storageType) ||
280 mfvecField.setNum(mlrange_cast<int>(numPoints));
281
282 // Enable fast direct pointer array editing on the inventor field data.
283 auto dataPtr = mfvecField.startEditing();
284 const bool copyFromData_n = (CopyFromData_n == storageType);
285 for (unsigned int c=0; c < numPointsAsUInt; ++c){
286 // Note: No scaling, because it is not very useful on RGB[A] data, it is needed only for incoming scalar colour scaling.
288 }
289 mfvecField.finishEditing();
290 isSet = true;
291 }
292 else if (UseOnlyRGBA == storageType){
293 // Enable fast direct pointer array editing on the inventor field data.
294 mfvecField.setNum(mlrange_cast<int>(numPoints * (duplicateColors ? 2u:1u)));
295 auto dataPtr = mfvecField.startEditing();
296 // Use direct copying of .rgba to uint32 inventor data values.
297 for (unsigned int c=0; c < numPointsAsUInt; ++c){
298 const unsigned int rgbaVal = ML_NAMESPACE::PCLSupportTools::getPointRGBA(pointCloud.points[c]);
299 // Note: No scaling, because it is not very useful on RGB[A] data, it is needed only for incoming scalar colour scaling.
300 if (duplicateColors){
301 setOneMFVecFieldValue(dataPtr+c*2 , &rgbaVal);
302 setOneMFVecFieldValue(dataPtr+c*2+1, &rgbaVal);
303 }
304 else{
305 setOneMFVecFieldValue(dataPtr+c , &rgbaVal);
306 }
307 }
308 mfvecField.finishEditing();
309 isSet = true;
310 }
313 // Enable fast direct pointer array editing on the inventor field data.
314 mfvecField.setNum(mlrange_cast<int>(numPoints * (duplicateColors ? 2u:1u)));
315 auto dataPtr = mfvecField.startEditing();
316 // Use assignment of any value usable as intensity to RGBA voxels as grey values
317 // where the intensity value is used as an rgb triple or - if requested - as rgba quadrupel.
318 float data[4]={0,0,0,255.9f};
320
321 // An often used mode is that intensity and transparency are the same value; then we can
322 // assign the value more effectively.
324
325 float curvatureVal = 0.f;
326 for (unsigned int c=0; c < numPointsAsUInt; ++c){
327 float dataVal = ML_NAMESPACE::PCLSupportTools::getIntensityReplacement(pointCloud.points[c]);
329 else if (dataVal > inRangeMax){ dataVal = inRangeMax; }
332 }
333 // If dataVal is the same four RGBA values then use optimized version below.
335 // Channels differ, the four RGBA channels come from different sources.
336 float intensityVal = dataVal; // -> color RGB
337 float alphaVal = dataVal; // -> transparency
338
339 // What is used as intensity (i.e. for RGB channels)?
341 // Use curvature instead
342 curvatureVal = ML_NAMESPACE::PCLSupportTools::getCurvature(pointCloud.points[c]);
347 }
349 }
350
351 // Translate intensity to a rainbow color table (especially interesting for curvature values).
352 if (mapToRainbow){
353 float retRGB[3]={0.f, 0.f, 0.f};
355 data[0] = retRGB[0]*255.999f;
356 data[1] = retRGB[1]*255.999f;
357 data[2] = retRGB[2]*255.999f;
358 }
359 else{
360 // Use the same value for R, G, and B.
361 data[0] = data[1] = data[2] = intensityVal*255.999f;
362 }
363
364 if (isRGBAAssignment){
365 // Opacity is related to dataVal.
366 data[3] = alphaVal*255.999f;
367 }
368 else{
369 // Opacity shall always be dense.
370 data[3] = 255.999f;
371 }
372 if (duplicateColors){
373 setOneMFVecFieldValue(dataPtr+c*2 , data);
374 setOneMFVecFieldValue(dataPtr+c*2+1, data);
375 }
376 else{
377 setOneMFVecFieldValue(dataPtr+c, data);
378 }
379 }
380 else{
381 dataVal*=255.999f;
382 // Use optimized version with a single float for all components.
383 if (duplicateColors){
384 setOneMFVecFieldValue(dataPtr+c*2 , dataVal);
385 setOneMFVecFieldValue(dataPtr+c*2+1, dataVal);
386 }
387 else{
388 setOneMFVecFieldValue(dataPtr+c, dataVal);
389 }
390 }
391 }
392 mfvecField.finishEditing();
393 isSet = true;
394 }
395 else if (CopyDataAndData_n == storageType){
396 // Enable fast direct pointer array editing on the inventor field data.
397 mfvecField.setNum(mlrange_cast<int>(numPoints*2u));
398 auto dataPtr = mfvecField.startEditing();
399 for (unsigned int c=0; c < numPointsAsUInt; ++c){
400 // Note: No scaling, because it is not very useful on vector data, it is needed only for incoming scalar colour scaling.
401 setTwoMFVecFieldValuesFromPoint(dataPtr+(c*2u), pointCloud.points[c]);
402 }
403 mfvecField.finishEditing();
404 isSet = true;
405 }
406 else{
407 ML_PRINT_ERROR("mlPCLInventorTools.h: setMFVecFromPointCloud", ML_BAD_PARAMETER,
408 "Bad enumerator value passed. Not setting any MField values.");
409 }
410 }
411 else{
412 ML_PRINT_ERROR("mlPCLInventorTools.h: setMFVecFromPointCloud", ML_BAD_PARAMETER,
413 "Inventor cannot handle field sets with more than ML_INT32_MAX points which, "
414 "however, are required for the current input data conversion. Not setting the MField values.");
415 }
416 if (!isSet){
417 mfvecField.deleteValues(0);
418 }
419 return isSet ? numPoints : 0u;
420}
421
422
423
424//----------------------------------------------------------------------------------
430//----------------------------------------------------------------------------------
431MLPCL_InventorAdapters_EXPORT void setVertices(const std::vector<pcl::Vertices> &verticesVector,
434
435};
436
Project global and OS specific declarations.
#define MLPCL_InventorAdapters_EXPORT
If included by external modules, exported symbols are declared as import symbols.
Disables warnings from PCL headers which otherwise cannot be avoided.
Restores disabled warnings from PCL headers which otherwise cannot be avoided.
#define ML_BAD_PARAMETER
A bad/invalid parameter (or even an inappropriate image) has been passed to a module or an algorithm;...
Definition mlTypeDefs.h:823
#define ML_PRINT_ERROR(FUNC_NAME, REASON, HANDLING)
Like ML_PRINT_ERROR_DUMP(FUNC_NAME, REASON, HANDLING, RT_OBJ) without a runtime object to be dumped.
#define SpecializedPCLPointXYZ
Eigen makes strange stuff with some types on some windows platforms which makes some specializations ...
A collection of tool functions used in MLPCLSupport.
Basic types used in the MeVislab binding of the Point Cloud Library(PCL).
Target mlrange_cast(Source arg)
Generic version of checked ML casts.
unsigned int MLuint32
Definition mlTypeDefs.h:185
MLPCL_InventorAdapters_EXPORT void getRainbowRGB_From0_to_1(float intensity, float retRGB[3])
Maps an intensity value from [0,1] to an RGB rainbow value where 0 is mapped to red increasing to gre...
void setOneMFVecFieldValueFromPoint(DST_VAL_TYPE *dstVal, const SpecializedPCLPointXYZ &pnt, bool useData_n)
Explicit case for PointXYZ (which does not have data_n members) to copy pnt.data[0-2] or pnt....
void setOneMFVecFieldValue(SbVec2f *dstVal, const float data[4])
Writes data[0] and data[1] to dstVal; data[2] and data[3] are ignored.
size_t setMFVecFromPointCloud(const POINT_CLOUD_TYPE &pointCloud, SM_MF_VEC_FIELD_TYPE &mfvecField, PCLMFVecStorageTypes storageType, bool duplicateColors=false, bool mapToRainbow=false, bool useCurvatureForColor=false, bool scaleFromInputRange=false, float inRangeMin=0.f, float inRangeMax=1.f)
Converts the point cloud to an Inventor SoMFVec2f, SoMFVec3f, or SoMFUInt32 field; it does not necess...
MLPCL_InventorAdapters_EXPORT void setVertices(const std::vector< pcl::Vertices > &verticesVector, SoMFInt32 &mfIntField, bool terminateWithMinusOne)
For each entry of verticesVector all indexes of are appended mfIntField and - if terminateWithMinusOn...
void setTwoMFVecFieldValuesFromPoint(DST_VAL_TYPE *dstVal, const SpecializedPCLPointXYZ &pnt)
Explicit case for pclPointXYZ which copies pnt.data[0-2] to dstVal and dstVal+1.
PCLMFVecStorageTypes
Describes the way how data combinations of a point cloud are stored in an OpenInventor MFVec field.
@ CopyFromData
The data vector of the points are copied to the MFVec.
@ StoreIntensitReplacementAsRGB
Store the member values of the points, which is considered as an intensity replacement,...
@ UseOnlyRGBA
If the point is of an RGBA type the rgba member is used for the SoVertexProperty.rgba settings,...
@ CopyFromData_n
If available then the point values describing the vector are copied, if not then nullptr vectors are ...
@ CopyDataAndData_n
From each point the point given by point.data followed by another coordinate, which is the result fro...
@ StoreIntensitReplacementAsRGBA
Store the member values of the points, which is considered as an intensity replacement,...