polygon_array_display.cpp
Go to the documentation of this file.
00001 #include "polygon_array_display.h"
00002 #include "rviz/properties/parse_color.h"
00003 #include <rviz/validate_floats.h>
00004 #include <jsk_topic_tools/color_utils.h>
00005 #include <jsk_pcl_ros/geo_util.h>
00006 
00007 namespace jsk_rviz_plugin
00008 {
00009   PolygonArrayDisplay::PolygonArrayDisplay()
00010   {
00011     auto_coloring_property_ = new rviz::BoolProperty("auto color", true,
00012                                                       "automatically change the color of the polygons",
00013                                                       this, SLOT(updateAutoColoring()));
00014     color_property_ = new rviz::ColorProperty( "Color", QColor( 25, 255, 0 ),
00015                                                "Color to draw the polygons.",
00016                                                this, SLOT( queueRender() ));
00017     alpha_property_ = new rviz::FloatProperty( "Alpha", 1.0,
00018                                                "Amount of transparency to apply to the polygon.",
00019                                                this, SLOT( queueRender() ));
00020     only_border_property_ = new rviz::BoolProperty("only border", true,
00021                                                    "only shows the borders of polygons",
00022                                                    this, SLOT(updateOnlyBorder()));
00023     //only_border_ = true;
00024     alpha_property_->setMin( 0 );
00025     alpha_property_->setMax( 1 );
00026   }
00027   
00028   PolygonArrayDisplay::~PolygonArrayDisplay()
00029   {
00030     delete alpha_property_;
00031     delete color_property_;
00032     //delete only_border_property_;
00033     delete auto_coloring_property_;
00034 
00035     for (size_t i = 0; i < lines_.size(); i++) {
00036       delete lines_[i];
00037     }
00038     
00039     for (size_t i = 0; i < materials_.size(); i++) {
00040       materials_[i]->unload();
00041       Ogre::MaterialManager::getSingleton().remove(materials_[i]->getName());
00042     }
00043     
00044     for (size_t i = 0; i < manual_objects_.size(); i++) {
00045       scene_manager_->destroyManualObject(manual_objects_[i]);
00046       scene_manager_->destroySceneNode(scene_nodes_[i]);
00047     }
00048   }
00049   
00050   void PolygonArrayDisplay::onInitialize()
00051   {
00052     MFDClass::onInitialize();
00053     updateOnlyBorder();
00054     updateAutoColoring();
00055   }
00056 
00057   void PolygonArrayDisplay::allocateMaterials(int num)
00058   {
00059     if (only_border_) {
00060       return;
00061     }
00062     static uint32_t count = 0;
00063     
00064     if (num > materials_.size()) {
00065       for (size_t i = materials_.size(); num > i; i++) {
00066         std::stringstream ss;
00067         ss << "PolygonArrayMaterial" << count++;
00068         Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create(ss.str(), "rviz");
00069         material->setReceiveShadows(false);
00070         material->getTechnique(0)->setLightingEnabled(true);
00071         material->getTechnique(0)->setAmbient( 0.5, 0.5, 0.5 );
00072         materials_.push_back(material);
00073       }
00074     }
00075   }
00076   
00077   bool validateFloats( const jsk_pcl_ros::PolygonArray& msg)
00078   {
00079     for (size_t i = 0; i < msg.polygons.size(); i++) {
00080       if (!rviz::validateFloats(msg.polygons[i].polygon.points))
00081         return false;
00082     }
00083     return true;
00084   }
00085   
00086   void PolygonArrayDisplay::reset()
00087   {
00088     MFDClass::reset();
00089     for (size_t i = 0; i < manual_objects_.size(); i++) {
00090       manual_objects_[i]->clear();
00091     }
00092   }
00093 
00094   void PolygonArrayDisplay::updateSceneNodes(const jsk_pcl_ros::PolygonArray::ConstPtr& msg)
00095   {
00096     int scale_factor = 2;
00097     if (only_border_) {
00098       scale_factor = 1;
00099     }
00100     if (msg->polygons.size() * scale_factor > manual_objects_.size()) {
00101       for (size_t i = manual_objects_.size(); i < msg->polygons.size() * scale_factor; i++) {
00102         Ogre::SceneNode* scene_node = scene_node_->createChildSceneNode();
00103         Ogre::ManualObject* manual_object = scene_manager_->createManualObject();
00104         manual_object->setDynamic( true );
00105         scene_node->attachObject( manual_object );
00106         manual_objects_.push_back(manual_object);
00107         scene_nodes_.push_back(scene_node);
00108       }
00109     }
00110     else if (msg->polygons.size() * scale_factor < manual_objects_.size()) {
00111       for (size_t i = msg->polygons.size() * scale_factor; i < manual_objects_.size(); i++) {
00112         manual_objects_[i]->setVisible(false);
00113       }
00114     }
00115   }
00116 
00117   void PolygonArrayDisplay::updateLines(int num)
00118   {
00119     if (num > lines_.size()) {
00120       for (size_t i = lines_.size(); i < num; i++) {
00121         rviz::BillboardLine* line = new rviz::BillboardLine(context_->getSceneManager(), scene_nodes_[i]);
00122         line->setLineWidth(0.01);
00123         line->setNumLines(1);
00124         lines_.push_back(line);
00125       }
00126     }
00127     for (size_t i = 0; i < lines_.size(); i++) {
00128       lines_[i]->clear();
00129     }
00130   }
00131   
00132   void PolygonArrayDisplay::processMessage(const jsk_pcl_ros::PolygonArray::ConstPtr& msg)
00133   {
00134     if (!validateFloats(*msg)) {
00135       setStatus( rviz::StatusProperty::Error, "Topic", "Message contained invalid floating point values (nans or infs)" );
00136       return;
00137     }
00138     // create nodes and manual objects
00139     updateSceneNodes(msg);
00140     allocateMaterials(msg->polygons.size());
00141     updateLines(msg->polygons.size());
00142     
00143     if (only_border_) {
00144       // use line_
00145       for (size_t i = 0; i < manual_objects_.size(); i++) {
00146         manual_objects_[i]->setVisible(false);
00147       }
00148       for (size_t i = 0; i < msg->polygons.size(); i++) {
00149         geometry_msgs::PolygonStamped polygon = msg->polygons[i];
00150         if (polygon.polygon.points.size() >= 3) {
00151           Ogre::SceneNode* scene_node = scene_nodes_[i];
00152           //Ogre::ManualObject* manual_object = manual_objects_[i];
00153           Ogre::Vector3 position;
00154           Ogre::Quaternion orientation;
00155           if( !context_->getFrameManager()->getTransform(
00156                 polygon.header, position, orientation )) {
00157             ROS_DEBUG( "Error transforming from frame '%s' to frame '%s'",
00158                        polygon.header.frame_id.c_str(), qPrintable( fixed_frame_ ));
00159           }
00160           scene_node->setPosition( position );
00161           scene_node->setOrientation( orientation );
00162           rviz::BillboardLine* line = lines_[i];
00163           line->clear();
00164           line->setMaxPointsPerLine(polygon.polygon.points.size() + 1);
00165         
00166           Ogre::ColourValue color;
00167           if (auto_coloring_) {
00168             std_msgs::ColorRGBA ros_color = jsk_topic_tools::colorCategory20(i);
00169             color.r = ros_color.r;
00170             color.g = ros_color.g;
00171             color.b = ros_color.b;
00172             color.a = ros_color.a;
00173           }
00174           else {
00175             color = rviz::qtToOgre( color_property_->getColor() );
00176           }
00177           color.a = alpha_property_->getFloat();
00178           line->setColor(color.r, color.g, color.b, color.a);
00179 
00180           for (size_t i = 0; i < polygon.polygon.points.size(); ++i) {
00181             Ogre::Vector3 step_position;
00182             step_position.x = polygon.polygon.points[i].x;
00183             step_position.y = polygon.polygon.points[i].y;
00184             step_position.z = polygon.polygon.points[i].z;
00185             line->addPoint(step_position);
00186           }
00187           Ogre::Vector3 step_position;
00188           step_position.x = polygon.polygon.points[0].x;
00189           step_position.y = polygon.polygon.points[0].y;
00190           step_position.z = polygon.polygon.points[0].z;
00191           line->addPoint(step_position);
00192         }
00193       }
00194     }
00195     else {
00196       for (size_t i = 0; i < msg->polygons.size(); i++) {
00197         Ogre::ColourValue color;
00198         if (auto_coloring_) {
00199           std_msgs::ColorRGBA ros_color = jsk_topic_tools::colorCategory20(i);
00200           color.r = ros_color.r;
00201           color.g = ros_color.g;
00202           color.b = ros_color.b;
00203           color.a = ros_color.a;
00204         }
00205         else {
00206           color = rviz::qtToOgre( color_property_->getColor() );
00207         }
00208         color.a = alpha_property_->getFloat();
00209         materials_[i]->getTechnique(0)->setAmbient( color * 0.5 );
00210         materials_[i]->getTechnique(0)->setDiffuse( color );
00211         if ( color.a < 0.9998 )
00212         {
00213           materials_[i]->getTechnique(0)->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );
00214           materials_[i]->getTechnique(0)->setDepthWriteEnabled( false );
00215         }
00216         else
00217         {
00218           materials_[i]->getTechnique(0)->setSceneBlending( Ogre::SBT_REPLACE );
00219           materials_[i]->getTechnique(0)->setDepthWriteEnabled( true );
00220         }
00221       
00222         materials_[i]->getTechnique(0)->setAmbient( color * 0.5 );
00223         materials_[i]->getTechnique(0)->setDiffuse( color );
00224       }
00225       
00226       for (size_t i = 0; i < msg->polygons.size(); i++) {
00227         geometry_msgs::PolygonStamped polygon = msg->polygons[i];
00228         Ogre::SceneNode* scene_node = scene_nodes_[i * 2];
00229         Ogre::ManualObject* manual_object = manual_objects_[i * 2];
00230         Ogre::Vector3 position;
00231         Ogre::Quaternion orientation;
00232         if(!context_->getFrameManager()->getTransform(
00233              polygon.header, position, orientation)) {
00234           ROS_DEBUG( "Error transforming from frame '%s' to frame '%s'",
00235                      polygon.header.frame_id.c_str(), qPrintable(fixed_frame_));
00236         }
00237         scene_node->setPosition( position );
00238         scene_node->setOrientation( orientation );
00239         manual_object->clear();
00240         manual_object->setVisible(true);
00241 
00242         jsk_pcl_ros::Polygon geo_polygon
00243           = jsk_pcl_ros::Polygon::fromROSMsg(polygon.polygon);
00244         // if (!geo_polygon.isConvex()) {
00245         //   ROS_WARN("non convex polygon is not supported");
00246         // }
00247         std::vector<jsk_pcl_ros::Polygon::Ptr>
00248           triangles = geo_polygon.decomposeToTriangles();
00249         
00250         //uint32_t num_points = polygon.polygon.points.size();
00251         uint32_t num_points = 0;
00252         for (size_t j = 0; j < triangles.size(); j++) {
00253           num_points += triangles[j]->getNumVertices();
00254         }
00255         if( num_points > 0 ) {
00256           manual_object->estimateVertexCount(num_points * 2);
00257           manual_object->begin(
00258             materials_[i]->getName(), Ogre::RenderOperation::OT_TRIANGLE_LIST);
00259           for (size_t ii = 0; ii < triangles.size(); ii++) {
00260             jsk_pcl_ros::Polygon::Ptr triangle = triangles[ii];
00261             size_t num_vertices = triangle->getNumVertices();
00262             for (size_t j = 0; j < num_vertices; j++) {
00263               Eigen::Vector3f v = triangle->getVertex(j);
00264               manual_object->position(v[0], v[1], v[2]);
00265             }
00266             for (int j = num_vertices - 1; j >= 0; j--) {
00267               Eigen::Vector3f v = triangle->getVertex(j);
00268               manual_object->position(v[0], v[1], v[2]);
00269             }
00270           }
00271           // for( uint32_t i = 0; i < num_points + 1; ++i )
00272           // {
00273           //   const geometry_msgs::Point32& msg_point = polygon.polygon.points[ i % num_points ];
00274           //   manual_object->position( msg_point.x, msg_point.y, msg_point.z );
00275           // }
00276           manual_object->end();
00277         }
00278       }
00279       //     reverse order
00280       for (size_t i = 0; i < msg->polygons.size(); i++) {
00281         geometry_msgs::PolygonStamped polygon = msg->polygons[i];
00282         Ogre::SceneNode* scene_node = scene_nodes_[i * 2 + 1];
00283         Ogre::ManualObject* manual_object = manual_objects_[i * 2 + 1];
00284         Ogre::Vector3 position;
00285         Ogre::Quaternion orientation;
00286         if( !context_->getFrameManager()->getTransform( polygon.header, position, orientation )) {
00287           ROS_DEBUG( "Error transforming from frame '%s' to frame '%s'",
00288                      polygon.header.frame_id.c_str(), qPrintable( fixed_frame_ ));
00289         }
00290         scene_node->setPosition( position );
00291         scene_node->setOrientation( orientation );
00292         manual_object->setVisible(false);
00293         manual_object->clear();
00294         
00295         uint32_t num_points = polygon.polygon.points.size();
00296         if( num_points > 0 )
00297         {
00298           manual_object->estimateVertexCount( num_points );
00299           manual_object->begin(materials_[i]->getName(), Ogre::RenderOperation::OT_TRIANGLE_FAN );
00300           for( uint32_t i = num_points; i > 0; --i )
00301           {
00302             const geometry_msgs::Point32& msg_point = polygon.polygon.points[ i % num_points ];
00303             manual_object->position( msg_point.x, msg_point.y, msg_point.z );
00304           }
00305           manual_object->end();
00306         }
00307       }
00308 
00309     }
00310     
00311     
00312   }
00313 
00314   void PolygonArrayDisplay::updateAutoColoring()
00315   {
00316     auto_coloring_ = auto_coloring_property_->getBool();
00317   }
00318   void PolygonArrayDisplay::updateOnlyBorder()
00319   {
00320     only_border_ = only_border_property_->getBool();
00321   }
00322   
00323 }
00324 
00325 #include <pluginlib/class_list_macros.h>
00326 PLUGINLIB_EXPORT_CLASS( jsk_rviz_plugin::PolygonArrayDisplay, rviz::Display )


jsk_rviz_plugins
Author(s): Kei Okada , Yohei Kakiuchi , Shohei Fujii , Ryohei Ueda
autogenerated on Mon Oct 6 2014 01:18:44