00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <pcl/visualization/point_cloud_handlers.h>
00039 #include <pcl/console/time.h>
00040 #include <pcl/pcl_macros.h>
00041 #include <pcl/common/io.h>
00042
00044 void
00045 pcl::visualization::PointCloudColorHandlerCustom<sensor_msgs::PointCloud2>::getColor (vtkSmartPointer<vtkDataArray> &scalars) const
00046 {
00047 if (!capable_)
00048 return;
00049
00050 if (!scalars)
00051 scalars = vtkSmartPointer<vtkUnsignedCharArray>::New ();
00052 scalars->SetNumberOfComponents (3);
00053
00054 vtkIdType nr_points = cloud_->width * cloud_->height;
00055 reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->SetNumberOfTuples (nr_points);
00056
00057
00058 unsigned char* colors = new unsigned char[nr_points * 3];
00059
00060
00061 for (vtkIdType cp = 0; cp < nr_points; ++cp)
00062 {
00063 colors[cp * 3 + 0] = r_;
00064 colors[cp * 3 + 1] = g_;
00065 colors[cp * 3 + 2] = b_;
00066 }
00067 reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->SetArray (colors, 3 * nr_points, 0);
00068 }
00069
00071 void
00072 pcl::visualization::PointCloudColorHandlerRandom<sensor_msgs::PointCloud2>::getColor (vtkSmartPointer<vtkDataArray> &scalars) const
00073 {
00074 if (!capable_)
00075 return;
00076
00077 if (!scalars)
00078 scalars = vtkSmartPointer<vtkUnsignedCharArray>::New ();
00079 scalars->SetNumberOfComponents (3);
00080
00081 vtkIdType nr_points = cloud_->width * cloud_->height;
00082 reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->SetNumberOfTuples (nr_points);
00083
00084
00085 unsigned char* colors = new unsigned char[nr_points * 3];
00086 double r, g, b;
00087 pcl::visualization::getRandomColors (r, g, b);
00088
00089 int r_ = pcl_lrint (r * 255.0), g_ = pcl_lrint (g * 255.0), b_ = pcl_lrint (b * 255.0);
00090
00091
00092 for (vtkIdType cp = 0; cp < nr_points; ++cp)
00093 {
00094 colors[cp * 3 + 0] = r_;
00095 colors[cp * 3 + 1] = g_;
00096 colors[cp * 3 + 2] = b_;
00097 }
00098 reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->SetArray (colors, 3 * nr_points, 0);
00099 }
00100
00102 pcl::visualization::PointCloudColorHandlerRGBField<sensor_msgs::PointCloud2>::PointCloudColorHandlerRGBField (
00103 const pcl::visualization::PointCloudColorHandler<sensor_msgs::PointCloud2>::PointCloudConstPtr &cloud) :
00104 pcl::visualization::PointCloudColorHandler<sensor_msgs::PointCloud2>::PointCloudColorHandler (cloud)
00105 {
00106
00107 field_idx_ = pcl::getFieldIndex (*cloud, "rgb");
00108 if (field_idx_ != -1)
00109 {
00110 capable_ = true;
00111 return;
00112 }
00113 else
00114 {
00115 field_idx_ = pcl::getFieldIndex (*cloud, "rgba");
00116 if (field_idx_ != -1)
00117 capable_ = true;
00118 else
00119 capable_ = false;
00120 }
00121 }
00122
00124 void
00125 pcl::visualization::PointCloudColorHandlerRGBField<sensor_msgs::PointCloud2>::getColor (vtkSmartPointer<vtkDataArray> &scalars) const
00126 {
00127 if (!capable_)
00128 return;
00129
00130 if (!scalars)
00131 scalars = vtkSmartPointer<vtkUnsignedCharArray>::New ();
00132 scalars->SetNumberOfComponents (3);
00133
00134 vtkIdType nr_points = cloud_->width * cloud_->height;
00135 reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->SetNumberOfTuples (nr_points);
00136
00137 unsigned char* colors = new unsigned char[nr_points * 3];
00138
00139 float rgb_data;
00140 int point_offset = cloud_->fields[field_idx_].offset;
00141 int j = 0;
00142
00143
00144 int x_idx = pcl::getFieldIndex (*cloud_, "x");
00145 if (x_idx != -1)
00146 {
00147 float x_data, y_data, z_data;
00148 int x_point_offset = cloud_->fields[x_idx].offset;
00149
00150
00151 for (vtkIdType cp = 0; cp < nr_points; ++cp,
00152 point_offset += cloud_->point_step,
00153 x_point_offset += cloud_->point_step)
00154 {
00155
00156 memcpy (&rgb_data, &cloud_->data[point_offset], sizeof (float));
00157
00158 if (!pcl_isfinite (rgb_data))
00159 continue;
00160
00161 memcpy (&x_data, &cloud_->data[x_point_offset], sizeof (float));
00162 memcpy (&y_data, &cloud_->data[x_point_offset + sizeof (float)], sizeof (float));
00163 memcpy (&z_data, &cloud_->data[x_point_offset + 2 * sizeof (float)], sizeof (float));
00164
00165 if (!pcl_isfinite (x_data) || !pcl_isfinite (y_data) || !pcl_isfinite (z_data))
00166 continue;
00167
00168 int rgb = *reinterpret_cast<int*>(&rgb_data);
00169 colors[j * 3 + 0] = static_cast<unsigned char> ((rgb >> 16) & 0xff);
00170 colors[j * 3 + 1] = static_cast<unsigned char> ((rgb >> 8) & 0xff);
00171 colors[j * 3 + 2] = static_cast<unsigned char> (rgb & 0xff);
00172 j++;
00173 }
00174 }
00175
00176 else
00177 {
00178
00179 for (vtkIdType cp = 0; cp < nr_points; ++cp, point_offset += cloud_->point_step)
00180 {
00181
00182 memcpy (&rgb_data, &cloud_->data[point_offset], sizeof (float));
00183
00184 if (!pcl_isfinite (rgb_data))
00185 continue;
00186
00187 int rgb = *reinterpret_cast<int*>(&rgb_data);
00188 colors[j * 3 + 0] = static_cast<unsigned char> ((rgb >> 16) & 0xff);
00189 colors[j * 3 + 1] = static_cast<unsigned char> ((rgb >> 8) & 0xff);
00190 colors[j * 3 + 2] = static_cast<unsigned char> (rgb & 0xff);
00191 j++;
00192 }
00193 }
00194 reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->SetArray (colors, 3 * j, 0);
00195
00196 }
00197
00199 pcl::visualization::PointCloudColorHandlerHSVField<sensor_msgs::PointCloud2>::PointCloudColorHandlerHSVField (
00200 const pcl::visualization::PointCloudColorHandler<sensor_msgs::PointCloud2>::PointCloudConstPtr &cloud) :
00201 pcl::visualization::PointCloudColorHandler<sensor_msgs::PointCloud2>::PointCloudColorHandler (cloud),
00202 s_field_idx_ (-1), v_field_idx_ (-1)
00203 {
00204
00205 field_idx_ = pcl::getFieldIndex (*cloud, "h");
00206 if (field_idx_ == -1)
00207 {
00208 capable_ = false;
00209 return;
00210 }
00211
00212
00213 s_field_idx_ = pcl::getFieldIndex (*cloud, "s");
00214 if (s_field_idx_ == -1)
00215 {
00216 capable_ = false;
00217 return;
00218 }
00219
00220
00221 v_field_idx_ = pcl::getFieldIndex (*cloud, "v");
00222 if (v_field_idx_ == -1)
00223 {
00224 capable_ = false;
00225 return;
00226 }
00227 capable_ = true;
00228 }
00229
00231 void
00232 pcl::visualization::PointCloudColorHandlerHSVField<sensor_msgs::PointCloud2>::getColor (vtkSmartPointer<vtkDataArray> &scalars) const
00233 {
00234 if (!capable_)
00235 return;
00236
00237 if (!scalars)
00238 scalars = vtkSmartPointer<vtkUnsignedCharArray>::New ();
00239 scalars->SetNumberOfComponents (3);
00240
00241 vtkIdType nr_points = cloud_->width * cloud_->height;
00242 reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->SetNumberOfTuples (nr_points);
00243
00244
00245
00246 unsigned char* colors = new unsigned char[nr_points * 3];
00247
00248 float h_data;
00249 float v_data;
00250 float s_data;
00251 int point_offset = cloud_->fields[field_idx_].offset;
00252 int j = 0;
00253
00254
00255 int x_idx = pcl::getFieldIndex (*cloud_, "x");
00256 if (x_idx != -1)
00257 {
00258 float x_data, y_data, z_data;
00259 int x_point_offset = cloud_->fields[x_idx].offset;
00260
00261
00262 for (vtkIdType cp = 0; cp < nr_points; ++cp,
00263 point_offset += cloud_->point_step,
00264 x_point_offset += cloud_->point_step)
00265 {
00266
00267 memcpy (&h_data, &cloud_->data[point_offset], sizeof (float));
00268 memcpy (&s_data, &cloud_->data[point_offset + sizeof (float)], sizeof (float));
00269 memcpy (&v_data, &cloud_->data[point_offset + 2 * sizeof (float)], sizeof (float));
00270
00271 if (!pcl_isfinite (h_data) || !pcl_isfinite (s_data) || !pcl_isfinite (v_data))
00272 continue;
00273
00274 memcpy (&x_data, &cloud_->data[x_point_offset], sizeof (float));
00275 memcpy (&y_data, &cloud_->data[x_point_offset + sizeof (float)], sizeof (float));
00276 memcpy (&z_data, &cloud_->data[x_point_offset + 2 * sizeof (float)], sizeof (float));
00277
00278 if (!pcl_isfinite (x_data) || !pcl_isfinite (y_data) || !pcl_isfinite (z_data))
00279 continue;
00280
00281 int idx = j * 3;
00282
00283 if (s_data == 0)
00284 {
00285 colors[idx] = colors[idx+1] = colors[idx+2] = v_data;
00286 return;
00287 }
00288 float a = h_data / 60;
00289 int i = floor (a);
00290 float f = a - i;
00291 float p = v_data * (1 - s_data);
00292 float q = v_data * (1 - s_data * f);
00293 float t = v_data * (1 - s_data * (1 - f));
00294
00295 switch (i)
00296 {
00297 case 0:
00298 {
00299 colors[idx] = static_cast<unsigned char> (v_data);
00300 colors[idx+1] = static_cast<unsigned char> (t);
00301 colors[idx+2] = static_cast<unsigned char> (p);
00302 break;
00303 }
00304 case 1:
00305 {
00306 colors[idx] = static_cast<unsigned char> (q);
00307 colors[idx+1] = static_cast<unsigned char> (v_data);
00308 colors[idx+2] = static_cast<unsigned char> (p);
00309 break;
00310 }
00311 case 2:
00312 {
00313 colors[idx] = static_cast<unsigned char> (p);
00314 colors[idx+1] = static_cast<unsigned char> (v_data);
00315 colors[idx+2] = static_cast<unsigned char> (t);
00316 break;
00317 }
00318 case 3:
00319 {
00320 colors[idx] = static_cast<unsigned char> (p);
00321 colors[idx+1] = static_cast<unsigned char> (q);
00322 colors[idx+2] = static_cast<unsigned char> (v_data);
00323 break;
00324 }
00325 case 4:
00326 {
00327 colors[idx] = static_cast<unsigned char> (t);
00328 colors[idx+1] = static_cast<unsigned char> (p);
00329 colors[idx+2] = static_cast<unsigned char> (v_data);
00330 break;
00331 }
00332 default:
00333 {
00334 colors[idx] = static_cast<unsigned char> (v_data);
00335 colors[idx+1] = static_cast<unsigned char> (p);
00336 colors[idx+2] = static_cast<unsigned char> (q);
00337 break;
00338 }
00339 }
00340 j++;
00341 }
00342 }
00343
00344 else
00345 {
00346
00347 for (vtkIdType cp = 0; cp < nr_points; ++cp, point_offset += cloud_->point_step)
00348 {
00349
00350 memcpy (&h_data, &cloud_->data[point_offset], sizeof (float));
00351 memcpy (&s_data, &cloud_->data[point_offset + sizeof (float)], sizeof (float));
00352 memcpy (&v_data, &cloud_->data[point_offset + 2 * sizeof (float)], sizeof (float));
00353
00354 if (!pcl_isfinite (h_data) || !pcl_isfinite (s_data) || !pcl_isfinite (v_data))
00355 continue;
00356
00357 int idx = j * 3;
00358
00359 if (s_data == 0)
00360 {
00361 colors[idx] = colors[idx+1] = colors[idx+2] = v_data;
00362 return;
00363 }
00364 float a = h_data / 60;
00365 int i = floor (a);
00366 float f = a - i;
00367 float p = v_data * (1 - s_data);
00368 float q = v_data * (1 - s_data * f);
00369 float t = v_data * (1 - s_data * (1 - f));
00370
00371 switch (i)
00372 {
00373 case 0:
00374 {
00375 colors[idx] = static_cast<unsigned char> (v_data);
00376 colors[idx+1] = static_cast<unsigned char> (t);
00377 colors[idx+2] = static_cast<unsigned char> (p);
00378 break;
00379 }
00380 case 1:
00381 {
00382 colors[idx] = static_cast<unsigned char> (q);
00383 colors[idx+1] = static_cast<unsigned char> (v_data);
00384 colors[idx+2] = static_cast<unsigned char> (p);
00385 break;
00386 }
00387 case 2:
00388 {
00389 colors[idx] = static_cast<unsigned char> (p);
00390 colors[idx+1] = static_cast<unsigned char> (v_data);
00391 colors[idx+2] = static_cast<unsigned char> (t);
00392 break;
00393 }
00394 case 3:
00395 {
00396 colors[idx] = static_cast<unsigned char> (p);
00397 colors[idx+1] = static_cast<unsigned char> (q);
00398 colors[idx+2] = static_cast<unsigned char> (v_data);
00399 break;
00400 }
00401 case 4:
00402 {
00403 colors[idx] = static_cast<unsigned char> (t);
00404 colors[idx+1] = static_cast<unsigned char> (p);
00405 colors[idx+2] = static_cast<unsigned char> (v_data);
00406 break;
00407 }
00408 default:
00409 {
00410 colors[idx] = static_cast<unsigned char> (v_data);
00411 colors[idx+1] = static_cast<unsigned char> (p);
00412 colors[idx+2] = static_cast<unsigned char> (q);
00413 break;
00414 }
00415 }
00416 j++;
00417 }
00418 }
00419 reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->SetArray (colors, 3 * j, 0);
00420
00421 }
00422
00424 pcl::visualization::PointCloudColorHandlerGenericField<sensor_msgs::PointCloud2>::PointCloudColorHandlerGenericField (
00425 const pcl::visualization::PointCloudColorHandler<sensor_msgs::PointCloud2>::PointCloudConstPtr &cloud,
00426 const std::string &field_name) :
00427 pcl::visualization::PointCloudColorHandler<sensor_msgs::PointCloud2>::PointCloudColorHandler (cloud),
00428 field_name_ (field_name)
00429 {
00430 field_idx_ = pcl::getFieldIndex (*cloud, field_name);
00431 if (field_idx_ != -1)
00432 capable_ = true;
00433 else
00434 capable_ = false;
00435 }
00436
00438 void
00439 pcl::visualization::PointCloudColorHandlerGenericField<sensor_msgs::PointCloud2>::getColor (vtkSmartPointer<vtkDataArray> &scalars) const
00440 {
00441 if (!capable_)
00442 return;
00443
00444 if (!scalars)
00445 scalars = vtkSmartPointer<vtkFloatArray>::New ();
00446 scalars->SetNumberOfComponents (1);
00447
00448 vtkIdType nr_points = cloud_->width * cloud_->height;
00449 reinterpret_cast<vtkFloatArray*>(&(*scalars))->SetNumberOfTuples (nr_points);
00450
00451 float* colors = new float[nr_points];
00452 float field_data;
00453 int j = 0;
00454 int point_offset = cloud_->fields[field_idx_].offset;
00455
00456
00457 int x_idx = pcl::getFieldIndex (*cloud_, "x");
00458 if (x_idx != -1)
00459 {
00460 float x_data, y_data, z_data;
00461 int x_point_offset = cloud_->fields[x_idx].offset;
00462
00463
00464 for (vtkIdType cp = 0; cp < nr_points; ++cp,
00465 point_offset += cloud_->point_step,
00466 x_point_offset += cloud_->point_step)
00467 {
00468 memcpy (&x_data, &cloud_->data[x_point_offset], sizeof (float));
00469 memcpy (&y_data, &cloud_->data[x_point_offset + sizeof (float)], sizeof (float));
00470 memcpy (&z_data, &cloud_->data[x_point_offset + 2 * sizeof (float)], sizeof (float));
00471 if (!pcl_isfinite (x_data) || !pcl_isfinite (y_data) || !pcl_isfinite (z_data))
00472 continue;
00473
00474
00475 memcpy (&field_data, &cloud_->data[point_offset], pcl::getFieldSize (cloud_->fields[field_idx_].datatype));
00476 colors[j] = field_data;
00477 j++;
00478 }
00479 }
00480
00481 else
00482 {
00483
00484 for (vtkIdType cp = 0; cp < nr_points; ++cp, point_offset += cloud_->point_step)
00485 {
00486
00487
00488 memcpy (&field_data, &cloud_->data[point_offset], pcl::getFieldSize (cloud_->fields[field_idx_].datatype));
00489
00490 if (!pcl_isfinite (field_data))
00491 continue;
00492 colors[j] = field_data;
00493 j++;
00494 }
00495 }
00496 reinterpret_cast<vtkFloatArray*>(&(*scalars))->SetArray (colors, j, 0);
00497 }
00498
00500 void
00501 pcl::visualization::PointCloudGeometryHandler<sensor_msgs::PointCloud2>::getGeometry (vtkSmartPointer<vtkPoints> &points) const
00502 {
00503 if (!capable_)
00504 return;
00505
00506 if (!points)
00507 points = vtkSmartPointer<vtkPoints>::New ();
00508 points->SetDataTypeToFloat ();
00509
00510 vtkSmartPointer<vtkFloatArray> data = vtkSmartPointer<vtkFloatArray>::New ();
00511 data->SetNumberOfComponents (3);
00512 vtkIdType nr_points = cloud_->width * cloud_->height;
00513
00514
00515 float dim;
00516 vtkIdType j = 0;
00517 float* pts = static_cast<float*> (malloc (nr_points * 3 * sizeof (float)));
00518 int point_offset = 0;
00519
00520
00521 if (cloud_->is_dense)
00522 {
00523 for (vtkIdType i = 0; i < nr_points; ++i, point_offset+=cloud_->point_step)
00524 {
00525
00526 memcpy (&dim, &cloud_->data[point_offset + cloud_->fields[field_x_idx_].offset], sizeof (float));
00527 pts[i * 3 + 0] = dim;
00528
00529 memcpy (&dim, &cloud_->data[point_offset + cloud_->fields[field_y_idx_].offset], sizeof (float));
00530 pts[i * 3 + 1] = dim;
00531
00532 memcpy (&dim, &cloud_->data[point_offset + cloud_->fields[field_z_idx_].offset], sizeof (float));
00533 pts[i * 3 + 2] = dim;
00534 }
00535 data->SetArray (&pts[0], nr_points * 3, 0);
00536 points->SetData (data);
00537 }
00538 else
00539 {
00540 for (vtkIdType i = 0; i < nr_points; ++i, point_offset+=cloud_->point_step)
00541 {
00542
00543 memcpy (&dim, &cloud_->data[point_offset + cloud_->fields[field_x_idx_].offset], sizeof (float));
00544 if (!pcl_isfinite (dim))
00545 continue;
00546 pts[j * 3 + 0] = dim;
00547
00548 memcpy (&dim, &cloud_->data[point_offset + cloud_->fields[field_y_idx_].offset], sizeof (float));
00549 if (!pcl_isfinite (dim))
00550 continue;
00551 pts[j * 3 + 1] = dim;
00552
00553 memcpy (&dim, &cloud_->data[point_offset + cloud_->fields[field_z_idx_].offset], sizeof (float));
00554 if (!pcl_isfinite (dim))
00555 continue;
00556 pts[j * 3 + 2] = dim;
00557
00558
00559 j++;
00560 }
00561 data->SetArray (&pts[0], j * 3, 0);
00562 points->SetData (data);
00563 }
00564 }
00565
00567 pcl::visualization::PointCloudGeometryHandlerXYZ<sensor_msgs::PointCloud2>::PointCloudGeometryHandlerXYZ (const PointCloudConstPtr &cloud)
00568 : pcl::visualization::PointCloudGeometryHandler<sensor_msgs::PointCloud2>::PointCloudGeometryHandler (cloud)
00569 {
00570 field_x_idx_ = pcl::getFieldIndex (*cloud, "x");
00571 if (field_x_idx_ == -1)
00572 return;
00573 field_y_idx_ = pcl::getFieldIndex (*cloud, "y");
00574 if (field_y_idx_ == -1)
00575 return;
00576 field_z_idx_ = pcl::getFieldIndex (*cloud, "z");
00577 if (field_z_idx_ == -1)
00578 return;
00579 capable_ = true;
00580 }
00581
00582
00583
00585 pcl::visualization::PointCloudGeometryHandlerSurfaceNormal<sensor_msgs::PointCloud2>::PointCloudGeometryHandlerSurfaceNormal (const PointCloudConstPtr &cloud)
00586 : pcl::visualization::PointCloudGeometryHandler<sensor_msgs::PointCloud2>::PointCloudGeometryHandler (cloud)
00587 {
00588 field_x_idx_ = pcl::getFieldIndex (*cloud, "normal_x");
00589 if (field_x_idx_ == -1)
00590 return;
00591 field_y_idx_ = pcl::getFieldIndex (*cloud, "normal_y");
00592 if (field_y_idx_ == -1)
00593 return;
00594 field_z_idx_ = pcl::getFieldIndex (*cloud, "normal_z");
00595 if (field_z_idx_ == -1)
00596 return;
00597 capable_ = true;
00598 }
00599
00601 pcl::visualization::PointCloudGeometryHandlerCustom<sensor_msgs::PointCloud2>::PointCloudGeometryHandlerCustom (
00602 const PointCloudConstPtr &cloud, const std::string &x_field_name, const std::string &y_field_name, const std::string &z_field_name)
00603 : pcl::visualization::PointCloudGeometryHandler<sensor_msgs::PointCloud2>::PointCloudGeometryHandler (cloud), field_name_ ()
00604 {
00605 field_x_idx_ = pcl::getFieldIndex (*cloud, x_field_name);
00606 if (field_x_idx_ == -1)
00607 return;
00608 field_y_idx_ = pcl::getFieldIndex (*cloud, y_field_name);
00609 if (field_y_idx_ == -1)
00610 return;
00611 field_z_idx_ = pcl::getFieldIndex (*cloud, z_field_name);
00612 if (field_z_idx_ == -1)
00613 return;
00614 field_name_ = x_field_name + y_field_name + z_field_name;
00615 capable_ = true;
00616 }
00617