point_cloud_transformers.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include <OgreColourValue.h>
00031 #include <OgreMatrix4.h>
00032 #include <OgreVector3.h>
00033 
00034 #include "rviz/properties/bool_property.h"
00035 #include "rviz/properties/color_property.h"
00036 #include "rviz/properties/editable_enum_property.h"
00037 #include "rviz/properties/enum_property.h"
00038 #include "rviz/properties/float_property.h"
00039 #include "rviz/validate_floats.h"
00040 
00041 #include "point_cloud_transformers.h"
00042 
00043 namespace rviz
00044 {
00045 
00046 static void getRainbowColor(float value, Ogre::ColourValue& color)
00047 {
00048   // this is HSV color palette with hue values going only from 0.0 to 0.833333.
00049   
00050   value = std::min(value, 1.0f);
00051   value = std::max(value, 0.0f);
00052 
00053   float h = value * 5.0f + 1.0f;
00054   int i = floor(h);
00055   float f = h - i;
00056   if ( !(i&1) ) f = 1 - f; // if i is even
00057   float n = 1 - f;
00058 
00059   if      (i <= 1) color[0] = n, color[1] = 0, color[2] = 1;
00060   else if (i == 2) color[0] = 0, color[1] = n, color[2] = 1;
00061   else if (i == 3) color[0] = 0, color[1] = 1, color[2] = n;
00062   else if (i == 4) color[0] = n, color[1] = 1, color[2] = 0;
00063   else if (i >= 5) color[0] = 1, color[1] = n, color[2] = 0;
00064 }
00065 
00066 uint8_t IntensityPCTransformer::supports(const sensor_msgs::PointCloud2ConstPtr& cloud)
00067 {
00068   updateChannels(cloud);
00069   return Support_Color;
00070 }
00071 
00072 uint8_t IntensityPCTransformer::score(const sensor_msgs::PointCloud2ConstPtr& cloud)
00073 {
00074   return 255;
00075 }
00076 
00077 bool IntensityPCTransformer::transform( const sensor_msgs::PointCloud2ConstPtr& cloud,
00078                                         uint32_t mask,
00079                                         const Ogre::Matrix4& transform,
00080                                         V_PointCloudPoint& points_out )
00081 {
00082   if( !( mask & Support_Color ))
00083   {
00084     return false;
00085   }
00086 
00087   int32_t index = findChannelIndex( cloud, channel_name_property_->getStdString() );
00088 
00089   if( index == -1 )
00090   {
00091     if( channel_name_property_->getStdString() == "intensity" )
00092     {
00093       index = findChannelIndex( cloud, "intensities" );
00094       if( index == -1 )
00095       {
00096         return false;
00097       }
00098     }
00099     else
00100     {
00101       return false;
00102     }
00103   }
00104 
00105   const uint32_t offset = cloud->fields[index].offset;
00106   const uint8_t type = cloud->fields[index].datatype;
00107   const uint32_t point_step = cloud->point_step;
00108   const uint32_t num_points = cloud->width * cloud->height;
00109 
00110   float min_intensity = 999999.0f;
00111   float max_intensity = -999999.0f;
00112   if( auto_compute_intensity_bounds_property_->getBool() )
00113   {
00114     for( uint32_t i = 0; i < num_points; ++i )
00115     {
00116       float val = valueFromCloud<float>(cloud, offset, type, point_step, i);
00117       min_intensity = std::min(val, min_intensity);
00118       max_intensity = std::max(val, max_intensity);
00119     }
00120 
00121     min_intensity = std::max(-999999.0f, min_intensity);
00122     max_intensity = std::min(999999.0f, max_intensity);
00123     min_intensity_property_->setFloat( min_intensity );
00124     max_intensity_property_->setFloat( max_intensity );
00125   }
00126   else
00127   {
00128     min_intensity = min_intensity_property_->getFloat();
00129     max_intensity = max_intensity_property_->getFloat();
00130   }
00131   float diff_intensity = max_intensity - min_intensity;
00132   if( diff_intensity == 0 )
00133   {
00134     // If min and max are equal, set the diff to something huge so
00135     // when we divide by it, we effectively get zero.  That way the
00136     // point cloud coloring will be predictably uniform when min and
00137     // max are equal.
00138     diff_intensity = 1e20;
00139   }
00140   Ogre::ColourValue max_color = max_color_property_->getOgreColor();
00141   Ogre::ColourValue min_color = min_color_property_->getOgreColor();
00142 
00143   if( use_rainbow_property_->getBool() )
00144   {
00145     for (uint32_t i = 0; i < num_points; ++i)
00146     {
00147       float val = valueFromCloud<float>(cloud, offset, type, point_step, i);
00148       float value = 1.0 - (val - min_intensity)/diff_intensity;
00149       if(invert_rainbow_property_->getBool() ){
00150         value = 1.0 - value;
00151       }
00152       getRainbowColor(value, points_out[i].color);
00153     }
00154   }
00155   else
00156   {
00157     for (uint32_t i = 0; i < num_points; ++i)
00158     {
00159       float val = valueFromCloud<float>(cloud, offset, type, point_step, i);
00160       float normalized_intensity = ( val - min_intensity ) / diff_intensity;
00161       normalized_intensity = std::min(1.0f, std::max(0.0f, normalized_intensity));
00162       points_out[i].color.r = max_color.r * normalized_intensity + min_color.r * (1.0f - normalized_intensity);
00163       points_out[i].color.g = max_color.g * normalized_intensity + min_color.g * (1.0f - normalized_intensity);
00164       points_out[i].color.b = max_color.b * normalized_intensity + min_color.b * (1.0f - normalized_intensity);
00165     }
00166   }
00167 
00168   return true;
00169 }
00170 
00171 void IntensityPCTransformer::createProperties( Property* parent_property, uint32_t mask, QList<Property*>& out_props )
00172 {
00173   if( mask & Support_Color )
00174   {
00175     channel_name_property_ = new EditableEnumProperty( "Channel Name", "intensity",
00176                                                        "Select the channel to use to compute the intensity",
00177                                                        parent_property, SIGNAL( needRetransform() ), this );
00178 
00179     use_rainbow_property_ = new BoolProperty( "Use rainbow", true,
00180                                               "Whether to use a rainbow of colors or interpolate between two",
00181                                               parent_property, SLOT( updateUseRainbow() ), this );
00182     invert_rainbow_property_ = new BoolProperty( "Invert Rainbow", false,
00183                                               "Whether to invert rainbow colors",
00184                                               parent_property, SLOT( updateUseRainbow() ), this );
00185 
00186     min_color_property_ = new ColorProperty( "Min Color", Qt::black,
00187                                              "Color to assign the points with the minimum intensity.  "
00188                                              "Actual color is interpolated between this and Max Color.",
00189                                              parent_property, SIGNAL( needRetransform() ), this );
00190 
00191     max_color_property_ = new ColorProperty( "Max Color", Qt::white,
00192                                              "Color to assign the points with the maximum intensity.  "
00193                                              "Actual color is interpolated between this and Min Color.",
00194                                              parent_property, SIGNAL( needRetransform() ), this );
00195 
00196     auto_compute_intensity_bounds_property_ = new BoolProperty( "Autocompute Intensity Bounds", true,
00197                                                                 "Whether to automatically compute the intensity min/max values.",
00198                                                                 parent_property, SLOT( updateAutoComputeIntensityBounds() ), this );
00199 
00200     min_intensity_property_ = new FloatProperty( "Min Intensity", 0,
00201                                                  "Minimum possible intensity value, used to interpolate from Min Color to Max Color for a point.",
00202                                                  parent_property );
00203 
00204     max_intensity_property_ = new FloatProperty( "Max Intensity", 4096,
00205                                                  "Maximum possible intensity value, used to interpolate from Min Color to Max Color for a point.",
00206                                                  parent_property );
00207 
00208     out_props.push_back( channel_name_property_ );
00209     out_props.push_back( use_rainbow_property_ );
00210     out_props.push_back( invert_rainbow_property_ );
00211     out_props.push_back( min_color_property_ );
00212     out_props.push_back( max_color_property_ );
00213     out_props.push_back( auto_compute_intensity_bounds_property_ );
00214     out_props.push_back( min_intensity_property_ );
00215     out_props.push_back( max_intensity_property_ );
00216 
00217     updateUseRainbow();
00218     updateAutoComputeIntensityBounds();
00219   }
00220 }
00221 
00222 void IntensityPCTransformer::updateChannels( const sensor_msgs::PointCloud2ConstPtr& cloud )
00223 {
00224   V_string channels;
00225   for(size_t i = 0; i < cloud->fields.size(); ++i )
00226   {
00227     channels.push_back(cloud->fields[i].name );
00228   }
00229   std::sort(channels.begin(), channels.end());
00230 
00231   if( channels != available_channels_ )
00232   {
00233     channel_name_property_->clearOptions();
00234     for( V_string::const_iterator it = channels.begin(); it != channels.end(); ++it )
00235     {
00236       const std::string& channel = *it;
00237       if( channel.empty() )
00238       {
00239         continue;
00240       }
00241       channel_name_property_->addOptionStd( channel );
00242     }
00243     available_channels_ = channels;
00244   }
00245 }
00246 
00247 void IntensityPCTransformer::updateAutoComputeIntensityBounds()
00248 {
00249   bool auto_compute = auto_compute_intensity_bounds_property_->getBool();
00250   min_intensity_property_->setHidden( auto_compute );
00251   max_intensity_property_->setHidden( auto_compute );
00252   if( auto_compute )
00253   {
00254     disconnect( min_intensity_property_, SIGNAL( changed() ), this, SIGNAL( needRetransform() ));
00255     disconnect( max_intensity_property_, SIGNAL( changed() ), this, SIGNAL( needRetransform() ));
00256   }
00257   else
00258   {
00259     connect( min_intensity_property_, SIGNAL( changed() ), this, SIGNAL( needRetransform() ));
00260     connect( max_intensity_property_, SIGNAL( changed() ), this, SIGNAL( needRetransform() ));
00261   }
00262   Q_EMIT needRetransform();
00263 }
00264 
00265 void IntensityPCTransformer::updateUseRainbow()
00266 {
00267   bool use_rainbow = use_rainbow_property_->getBool();
00268   invert_rainbow_property_->setHidden( !use_rainbow );
00269   min_color_property_->setHidden( use_rainbow );
00270   max_color_property_->setHidden( use_rainbow );
00271   Q_EMIT needRetransform();
00272 }
00273 
00274 uint8_t XYZPCTransformer::supports(const sensor_msgs::PointCloud2ConstPtr& cloud)
00275 {
00276   int32_t xi = findChannelIndex(cloud, "x");
00277   int32_t yi = findChannelIndex(cloud, "y");
00278   int32_t zi = findChannelIndex(cloud, "z");
00279 
00280   if (xi == -1 || yi == -1 || zi == -1)
00281   {
00282     return Support_None;
00283   }
00284 
00285   if (cloud->fields[xi].datatype == sensor_msgs::PointField::FLOAT32)
00286   {
00287     return Support_XYZ;
00288   }
00289 
00290   return Support_None;
00291 }
00292 
00293 bool XYZPCTransformer::transform(const sensor_msgs::PointCloud2ConstPtr& cloud, uint32_t mask, const Ogre::Matrix4& transform, V_PointCloudPoint& points_out)
00294 {
00295   if (!(mask & Support_XYZ))
00296   {
00297     return false;
00298   }
00299 
00300   int32_t xi = findChannelIndex(cloud, "x");
00301   int32_t yi = findChannelIndex(cloud, "y");
00302   int32_t zi = findChannelIndex(cloud, "z");
00303 
00304   const uint32_t xoff = cloud->fields[xi].offset;
00305   const uint32_t yoff = cloud->fields[yi].offset;
00306   const uint32_t zoff = cloud->fields[zi].offset;
00307   const uint32_t point_step = cloud->point_step;
00308   const uint32_t num_points = cloud->width * cloud->height;
00309   uint8_t const* point_x = &cloud->data.front() + xoff;
00310   uint8_t const* point_y = &cloud->data.front() + yoff;
00311   uint8_t const* point_z = &cloud->data.front() + zoff;
00312   for (V_PointCloudPoint::iterator iter = points_out.begin(); iter != points_out.end(); ++iter, point_x += point_step,
00313     point_y += point_step, point_z += point_step)
00314   {
00315     iter->position.x = *reinterpret_cast<const float*>(point_x);
00316     iter->position.y = *reinterpret_cast<const float*>(point_y);
00317     iter->position.z = *reinterpret_cast<const float*>(point_z);
00318   }
00319 
00320   return true;
00321 }
00322 
00323 uint8_t RGB8PCTransformer::supports(const sensor_msgs::PointCloud2ConstPtr& cloud)
00324 {
00325   int32_t index = std::max(findChannelIndex(cloud, "rgb"), findChannelIndex(cloud, "rgba"));
00326   if (index == -1)
00327   {
00328     return Support_None;
00329   }
00330 
00331   if (cloud->fields[index].datatype == sensor_msgs::PointField::INT32 ||
00332       cloud->fields[index].datatype == sensor_msgs::PointField::UINT32 ||
00333       cloud->fields[index].datatype == sensor_msgs::PointField::FLOAT32)
00334   {
00335     return Support_Color;
00336   }
00337 
00338   return Support_None;
00339 }
00340 
00341 bool RGB8PCTransformer::transform(const sensor_msgs::PointCloud2ConstPtr& cloud, uint32_t mask, const Ogre::Matrix4& transform, V_PointCloudPoint& points_out)
00342 {
00343   if (!(mask & Support_Color))
00344   {
00345     return false;
00346   }
00347 
00348   const int32_t rgb  = findChannelIndex(cloud, "rgb");
00349   const int32_t rgba = findChannelIndex(cloud, "rgba");
00350   const int32_t index = std::max(rgb, rgba);
00351 
00352   const uint32_t off = cloud->fields[index].offset;
00353   uint8_t const* rgb_ptr = &cloud->data.front() + off;
00354   const uint32_t point_step = cloud->point_step;
00355 
00356   // Create a look-up table for colors
00357   float rgb_lut[256];
00358   for(int i = 0; i < 256; ++i)
00359   {
00360     rgb_lut[i] = float(i)/255.0f;
00361   }
00362   if (rgb != -1) // rgb
00363   {
00364     for (V_PointCloudPoint::iterator iter = points_out.begin(); iter != points_out.end(); ++iter, rgb_ptr += point_step)
00365     {
00366       uint32_t rgb = *reinterpret_cast<const uint32_t*>(rgb_ptr);
00367       iter->color.r = rgb_lut[(rgb >> 16) & 0xff];
00368       iter->color.g = rgb_lut[(rgb >> 8) & 0xff];
00369       iter->color.b = rgb_lut[rgb & 0xff];
00370       iter->color.a = 1.0f;
00371     }
00372   }
00373   else // rgba
00374   {
00375     for (V_PointCloudPoint::iterator iter = points_out.begin(); iter != points_out.end(); ++iter, rgb_ptr += point_step)
00376     {
00377       uint32_t rgb = *reinterpret_cast<const uint32_t*>(rgb_ptr);
00378       iter->color.r = rgb_lut[(rgb >> 16) & 0xff];
00379       iter->color.g = rgb_lut[(rgb >> 8) & 0xff];
00380       iter->color.b = rgb_lut[rgb & 0xff];
00381       iter->color.a = rgb_lut[rgb >> 24];
00382     }
00383   }
00384 
00385   return true;
00386 }
00387 
00388 uint8_t RGBF32PCTransformer::supports(const sensor_msgs::PointCloud2ConstPtr& cloud)
00389 {
00390   int32_t ri = findChannelIndex(cloud, "r");
00391   int32_t gi = findChannelIndex(cloud, "g");
00392   int32_t bi = findChannelIndex(cloud, "b");
00393   if (ri == -1 || gi == -1 || bi == -1)
00394   {
00395     return Support_None;
00396   }
00397 
00398   if (cloud->fields[ri].datatype == sensor_msgs::PointField::FLOAT32)
00399   {
00400     return Support_Color;
00401   }
00402 
00403   return Support_None;
00404 }
00405 
00406 bool RGBF32PCTransformer::transform(const sensor_msgs::PointCloud2ConstPtr& cloud, uint32_t mask, const Ogre::Matrix4& transform, V_PointCloudPoint& points_out)
00407 {
00408   if (!(mask & Support_Color))
00409   {
00410     return false;
00411   }
00412 
00413   int32_t ri = findChannelIndex(cloud, "r");
00414   int32_t gi = findChannelIndex(cloud, "g");
00415   int32_t bi = findChannelIndex(cloud, "b");
00416 
00417   const uint32_t roff = cloud->fields[ri].offset;
00418   const uint32_t goff = cloud->fields[gi].offset;
00419   const uint32_t boff = cloud->fields[bi].offset;
00420   const uint32_t point_step = cloud->point_step;
00421   const uint32_t num_points = cloud->width * cloud->height;
00422   uint8_t const* point = &cloud->data.front();
00423   for (uint32_t i = 0; i < num_points; ++i, point += point_step)
00424   {
00425     float r = *reinterpret_cast<const float*>(point + roff);
00426     float g = *reinterpret_cast<const float*>(point + goff);
00427     float b = *reinterpret_cast<const float*>(point + boff);
00428     points_out[i].color = Ogre::ColourValue(r, g, b);
00429   }
00430 
00431   return true;
00432 }
00433 
00434 uint8_t FlatColorPCTransformer::supports(const sensor_msgs::PointCloud2ConstPtr& cloud)
00435 {
00436   return Support_Color;
00437 }
00438 
00439 uint8_t FlatColorPCTransformer::score(const sensor_msgs::PointCloud2ConstPtr& cloud)
00440 {
00441   return 0;
00442 }
00443 
00444 bool FlatColorPCTransformer::transform( const sensor_msgs::PointCloud2ConstPtr& cloud,
00445                                         uint32_t mask,
00446                                         const Ogre::Matrix4& transform,
00447                                         V_PointCloudPoint& points_out )
00448 {
00449   if( !( mask & Support_Color ))
00450   {
00451     return false;
00452   }
00453 
00454   Ogre::ColourValue color = color_property_->getOgreColor();
00455 
00456   const uint32_t num_points = cloud->width * cloud->height;
00457   for( uint32_t i = 0; i < num_points; ++i )
00458   {
00459     points_out[i].color = color;
00460   }
00461 
00462   return true;
00463 }
00464 
00465 void FlatColorPCTransformer::createProperties( Property* parent_property, uint32_t mask, QList<Property*>& out_props )
00466 {
00467   if( mask & Support_Color )
00468   {
00469     color_property_ = new ColorProperty( "Color", Qt::white,
00470                                          "Color to assign to every point.",
00471                                          parent_property, SIGNAL( needRetransform() ), this );
00472     out_props.push_back( color_property_ );
00473   }
00474 }
00475 
00476 uint8_t AxisColorPCTransformer::supports(const sensor_msgs::PointCloud2ConstPtr& cloud)
00477 {
00478   return Support_Color;
00479 }
00480 
00481 uint8_t AxisColorPCTransformer::score(const sensor_msgs::PointCloud2ConstPtr& cloud)
00482 {
00483   return 255;
00484 }
00485 
00486 bool AxisColorPCTransformer::transform( const sensor_msgs::PointCloud2ConstPtr& cloud,
00487                                         uint32_t mask,
00488                                         const Ogre::Matrix4& transform,
00489                                         V_PointCloudPoint& points_out )
00490 {
00491   if( !( mask & Support_Color ))
00492   {
00493     return false;
00494   }
00495 
00496   int32_t xi = findChannelIndex( cloud, "x" );
00497   int32_t yi = findChannelIndex( cloud, "y" );
00498   int32_t zi = findChannelIndex( cloud, "z" );
00499 
00500   const uint32_t xoff = cloud->fields[xi].offset;
00501   const uint32_t yoff = cloud->fields[yi].offset;
00502   const uint32_t zoff = cloud->fields[zi].offset;
00503   const uint32_t point_step = cloud->point_step;
00504   const uint32_t num_points = cloud->width * cloud->height;
00505   uint8_t const* point = &cloud->data.front();
00506 
00507   // Fill a vector of floats with values based on the chosen axis.
00508   int axis = axis_property_->getOptionInt();
00509   std::vector<float> values;
00510   values.reserve( num_points );
00511   Ogre::Vector3 pos;
00512   if( use_fixed_frame_property_->getBool() )
00513   {
00514     for (uint32_t i = 0; i < num_points; ++i, point += point_step)
00515     {
00516       // TODO: optimize this by only doing the multiplication needed
00517       // for the desired output value, instead of doing all of them
00518       // and then throwing most away.
00519       pos.x = *reinterpret_cast<const float*>(point + xoff);
00520       pos.y = *reinterpret_cast<const float*>(point + yoff);
00521       pos.z = *reinterpret_cast<const float*>(point + zoff);
00522 
00523       pos = transform * pos;
00524       values.push_back( pos[ axis ]);
00525     }
00526   }
00527   else
00528   {
00529     const uint32_t offsets[ 3 ] = { xoff, yoff, zoff };
00530     const uint32_t off = offsets[ axis ];
00531     for (uint32_t i = 0; i < num_points; ++i, point += point_step)
00532     {
00533       values.push_back( *reinterpret_cast<const float*>( point + off ));
00534     }
00535   }
00536   float min_value_current = 9999.0f;
00537   float max_value_current = -9999.0f;
00538   if( auto_compute_bounds_property_->getBool() )
00539   {
00540     for( uint32_t i = 0; i < num_points; i++ )
00541     {
00542       float val = values[ i ];
00543       min_value_current = std::min( min_value_current, val );
00544       max_value_current = std::max( max_value_current, val );
00545     }
00546     min_value_property_->setFloat( min_value_current );
00547     max_value_property_->setFloat( max_value_current );
00548   }
00549   else
00550   {
00551     min_value_current = min_value_property_->getFloat();
00552     max_value_current = max_value_property_->getFloat();
00553   }
00554 
00555   float range = max_value_current - min_value_current;
00556   if( range == 0 )
00557   {
00558     range = 0.001f;
00559   }
00560   for( uint32_t i = 0; i < num_points; ++i )
00561   {
00562     float value = 1.0 - ( values[ i ] - min_value_current ) / range;
00563     getRainbowColor( value, points_out[i].color );
00564   }
00565 
00566   return true;
00567 }
00568 
00569 void AxisColorPCTransformer::createProperties( Property* parent_property, uint32_t mask, QList<Property*>& out_props )
00570 {
00571   if( mask & Support_Color )
00572   {
00573     axis_property_ = new EnumProperty( "Axis", "Z",
00574                                        "The axis to interpolate the color along.",
00575                                        parent_property, SIGNAL( needRetransform() ), this );
00576     axis_property_->addOption( "X", AXIS_X );
00577     axis_property_->addOption( "Y", AXIS_Y );
00578     axis_property_->addOption( "Z", AXIS_Z );
00579 
00580     auto_compute_bounds_property_ = new BoolProperty( "Autocompute Value Bounds", true,
00581                                                       "Whether to automatically compute the value min/max values.",
00582                                                       parent_property, SLOT( updateAutoComputeBounds() ), this );
00583 
00584     min_value_property_ = new FloatProperty( "Min Value", -10,
00585                                              "Minimum value value, used to interpolate the color of a point.",
00586                                              auto_compute_bounds_property_ );
00587 
00588     max_value_property_ = new FloatProperty( "Max Value", 10,
00589                                              "Maximum value value, used to interpolate the color of a point.",
00590                                              auto_compute_bounds_property_ );
00591 
00592     use_fixed_frame_property_ = new BoolProperty( "Use Fixed Frame", true,
00593                                                   "Whether to color the cloud based on its fixed frame position or its local frame position.",
00594                                                   parent_property, SIGNAL( needRetransform() ), this );
00595 
00596     out_props.push_back( axis_property_ );
00597     out_props.push_back( auto_compute_bounds_property_ );
00598     out_props.push_back( use_fixed_frame_property_ );
00599 
00600     updateAutoComputeBounds();
00601   }
00602 }
00603 
00604 void AxisColorPCTransformer::updateAutoComputeBounds()
00605 {
00606   bool auto_compute = auto_compute_bounds_property_->getBool();
00607   min_value_property_->setHidden( auto_compute );
00608   max_value_property_->setHidden( auto_compute );
00609   if( auto_compute )
00610   {
00611     disconnect( min_value_property_, SIGNAL( changed() ), this, SIGNAL( needRetransform() ));
00612     disconnect( max_value_property_, SIGNAL( changed() ), this, SIGNAL( needRetransform() ));
00613   }
00614   else
00615   {
00616     connect( min_value_property_, SIGNAL( changed() ), this, SIGNAL( needRetransform() ));
00617     connect( max_value_property_, SIGNAL( changed() ), this, SIGNAL( needRetransform() ));
00618     auto_compute_bounds_property_->expand();
00619   }
00620   Q_EMIT needRetransform();
00621 }
00622 
00623 } // end namespace rviz
00624 
00625 #include <pluginlib/class_list_macros.h>
00626 PLUGINLIB_EXPORT_CLASS( rviz::AxisColorPCTransformer, rviz::PointCloudTransformer )
00627 PLUGINLIB_EXPORT_CLASS( rviz::FlatColorPCTransformer, rviz::PointCloudTransformer )
00628 PLUGINLIB_EXPORT_CLASS( rviz::IntensityPCTransformer, rviz::PointCloudTransformer )
00629 PLUGINLIB_EXPORT_CLASS(      rviz::RGB8PCTransformer,      rviz::PointCloudTransformer )
00630 PLUGINLIB_EXPORT_CLASS(    rviz::RGBF32PCTransformer,    rviz::PointCloudTransformer )
00631 PLUGINLIB_EXPORT_CLASS(       rviz::XYZPCTransformer,       rviz::PointCloudTransformer )


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Tue Oct 3 2017 03:19:31