polygon_array_display.cpp
Go to the documentation of this file.
1 // -*- mode: c++ -*-
2 /*********************************************************************
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2015, JSK Lab
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/o2r other materials provided
17  * with the distribution.
18  * * Neither the name of the JSK Lab nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *********************************************************************/
35 
36 #define BOOST_PARAMETER_MAX_ARITY 7
37 
38 #include "polygon_array_display.h"
40 #include <rviz/validate_floats.h>
43 
44 namespace jsk_rviz_plugins
45 {
47  {
49  "coloring", "Auto",
50  "coloring method",
51  this, SLOT(updateColoring()));
52  coloring_property_->addOption("Auto", 0);
53  coloring_property_->addOption("Flat color", 1);
54  coloring_property_->addOption("Liekelihood", 2);
55  coloring_property_->addOption("Label", 3);
57  "Color", QColor(25, 255, 0),
58  "Color to draw the polygons.",
59  this, SLOT(queueRender()));
61  "Alpha", 1.0,
62  "Amount of transparency to apply to the polygon.",
63  this, SLOT(queueRender()));
65  "only border", true,
66  "only shows the borders of polygons",
67  this, SLOT(updateOnlyBorder()));
69  "show normal", true,
70  "show normal direction",
71  this, SLOT(updateShowNormal()));
73  "enable lighting", true,
74  "enable lighting",
75  this, SLOT(updateEnableLighting()));
77  "normal length", 0.1,
78  "normal length",
79  this, SLOT(updateNormalLength()));
81  //only_border_ = true;
84  }
85 
87  {
88  delete alpha_property_;
89  delete color_property_;
90  delete only_border_property_;
91  delete coloring_property_;
92  delete show_normal_property_;
94  for (size_t i = 0; i < lines_.size(); i++) {
95  delete lines_[i];
96  }
97 
98  for (size_t i = 0; i < materials_.size(); i++) {
99  materials_[i]->unload();
100  Ogre::MaterialManager::getSingleton().remove(materials_[i]->getName());
101  }
102 
103  for (size_t i = 0; i < manual_objects_.size(); i++) {
104  scene_manager_->destroyManualObject(manual_objects_[i]);
105  scene_manager_->destroySceneNode(scene_nodes_[i]);
106  }
107  }
108 
110  {
113  updateColoring();
116  }
117 
119  {
120  if (only_border_) {
121  return;
122  }
123  static uint32_t count = 0;
124 
125  if (num > materials_.size()) {
126  for (size_t i = materials_.size(); num > i; i++) {
127  std::stringstream ss;
128  ss << "PolygonArrayMaterial" << count++;
129  Ogre::MaterialPtr material
130  = Ogre::MaterialManager::getSingleton().create(ss.str(), "rviz");
131  material->setReceiveShadows(false);
132  material->getTechnique(0)->setLightingEnabled(enable_lighting_);
133  material->getTechnique(0)->setAmbient(0.5, 0.5, 0.5);
134 
135  //material->setCullingMode(Ogre::CULL_NONE);
136  materials_.push_back(material);
137  }
138  }
139  }
140 
141  bool validateFloats(const jsk_recognition_msgs::PolygonArray& msg)
142  {
143  for (size_t i = 0; i < msg.polygons.size(); i++) {
144  if (!rviz::validateFloats(msg.polygons[i].polygon.points))
145  return false;
146  }
147  return true;
148  }
149 
151  {
152  MFDClass::reset();
153  for (size_t i = 0; i < manual_objects_.size(); i++) {
154  manual_objects_[i]->clear();
155  }
156  }
157 
159  const jsk_recognition_msgs::PolygonArray::ConstPtr& msg)
160  {
161  int scale_factor = 2;
162  if (only_border_) {
163  scale_factor = 1;
164  }
165  if (msg->polygons.size() * scale_factor > manual_objects_.size()) {
166  for (size_t i = manual_objects_.size();
167  i < msg->polygons.size() * scale_factor;
168  i++) {
169  Ogre::SceneNode* scene_node
170  = scene_node_->createChildSceneNode();
171  Ogre::ManualObject* manual_object
172  = scene_manager_->createManualObject();
173  manual_object->setDynamic(true);
174  scene_node->attachObject(manual_object);
175  manual_objects_.push_back(manual_object);
176  scene_nodes_.push_back(scene_node);
177  }
178  }
179  else if (msg->polygons.size() * scale_factor < manual_objects_.size()) {
180  for (size_t i = msg->polygons.size() * scale_factor;
181  i < manual_objects_.size(); i++) {
182  manual_objects_[i]->setVisible(false);
183  }
184  }
185  // arrow nodes
186  if (msg->polygons.size() > arrow_objects_.size()) {
187  for (size_t i = arrow_objects_.size(); i < msg->polygons.size(); i++) {
188  Ogre::SceneNode* scene_node = scene_node_->createChildSceneNode();
189  ArrowPtr arrow (new rviz::Arrow(scene_manager_, scene_node));
190  scene_node->setVisible(false);
191  arrow_objects_.push_back(arrow);
192  arrow_nodes_.push_back(scene_node);
193  }
194  }
195  else if (msg->polygons.size() < manual_objects_.size()) {
196  for (size_t i = msg->polygons.size(); i < arrow_nodes_.size(); i++) {
197  //arrow_objects_[i]->setVisible(false);
198  arrow_nodes_[i]->setVisible(false);
199  }
200  }
201  }
202 
204  {
205  if (num > lines_.size()) {
206  for (size_t i = lines_.size(); i < num; i++) {
207  rviz::BillboardLine* line
209  scene_nodes_[i]);
210  line->setLineWidth(0.01);
211  line->setNumLines(1);
212  lines_.push_back(line);
213  }
214  }
215  for (size_t i = 0; i < lines_.size(); i++) {
216  lines_[i]->clear();
217  }
218  }
219 
220  Ogre::ColourValue PolygonArrayDisplay::getColor(size_t index)
221  {
222  Ogre::ColourValue color;
223  if (coloring_method_ == "auto") {
224  std_msgs::ColorRGBA ros_color = jsk_topic_tools::colorCategory20(index);
225  color.r = ros_color.r;
226  color.g = ros_color.g;
227  color.b = ros_color.b;
228  color.a = ros_color.a;
229  }
230  else if (coloring_method_ == "flat") {
232  }
233  else if (coloring_method_ == "likelihood") {
234  if (latest_msg_->likelihood.size() == 0 ||
235  latest_msg_->likelihood.size() < index) {
237  "Topic",
238  "Message does not have lieklihood fields");
239  }
240  else {
241  std_msgs::ColorRGBA ros_color
242  = jsk_topic_tools::heatColor(latest_msg_->likelihood[index]);
243  color.r = ros_color.r;
244  color.g = ros_color.g;
245  color.b = ros_color.b;
246  color.a = ros_color.a;
247  }
248  }
249  else if (coloring_method_ == "label") {
250  if (latest_msg_->labels.size() == 0 ||
251  latest_msg_->labels.size() < index) {
253  "Topic",
254  "Message does not have lebels fields");
255  }
256  else {
257  std_msgs::ColorRGBA ros_color
259  color.r = ros_color.r;
260  color.g = ros_color.g;
261  color.b = ros_color.b;
262  color.a = ros_color.a;
263  }
264  }
265  color.a = alpha_property_->getFloat();
266  return color;
267  }
268 
270  const size_t i,
271  const geometry_msgs::PolygonStamped& polygon)
272  {
273  Ogre::SceneNode* scene_node = scene_nodes_[i];
274  //Ogre::ManualObject* manual_object = manual_objects_[i];
275  Ogre::Vector3 position;
276  Ogre::Quaternion orientation;
277  if (!getTransform(polygon.header, position, orientation))
278  return;
279  scene_node->setPosition(position);
280  scene_node->setOrientation(orientation);
281  rviz::BillboardLine* line = lines_[i];
282  line->clear();
283  line->setMaxPointsPerLine(polygon.polygon.points.size() + 1);
284 
285  Ogre::ColourValue color = getColor(i);
286  line->setColor(color.r, color.g, color.b, color.a);
287 
288  for (size_t i = 0; i < polygon.polygon.points.size(); ++i) {
289  Ogre::Vector3 step_position;
290  step_position.x = polygon.polygon.points[i].x;
291  step_position.y = polygon.polygon.points[i].y;
292  step_position.z = polygon.polygon.points[i].z;
293  line->addPoint(step_position);
294  }
295  Ogre::Vector3 step_position;
296  step_position.x = polygon.polygon.points[0].x;
297  step_position.y = polygon.polygon.points[0].y;
298  step_position.z = polygon.polygon.points[0].z;
299  line->addPoint(step_position);
300  }
301 
303  {
304  Ogre::ColourValue color = getColor(i);
305  materials_[i]->getTechnique(0)->setLightingEnabled(enable_lighting_);
306  materials_[i]->getTechnique(0)->setAmbient(color * 0.5);
307  materials_[i]->getTechnique(0)->setDiffuse(color);
308  if (color.a < 0.9998) {
309  materials_[i]->getTechnique(0)->setSceneBlending(
310  Ogre::SBT_TRANSPARENT_ALPHA);
311  materials_[i]->getTechnique(0)->setDepthWriteEnabled(false);
312  }
313  else {
314  materials_[i]->getTechnique(0)->setSceneBlending(Ogre::SBT_REPLACE);
315  materials_[i]->getTechnique(0)->setDepthWriteEnabled(true);
316  }
317 
318  materials_[i]->getTechnique(0)->setAmbient(color * 0.5);
319  materials_[i]->getTechnique(0)->setDiffuse(color);
320  }
321 
323  const size_t i, const geometry_msgs::PolygonStamped& polygon)
324  {
325  Ogre::Vector3 position;
326  Ogre::Quaternion orientation;
327  if (!getTransform(polygon.header, position, orientation))
328  return;
329 
330  {
331  Ogre::SceneNode* scene_node = scene_nodes_[i * 2];
332  Ogre::ManualObject* manual_object = manual_objects_[i * 2];
333  Ogre::ColourValue color = getColor(i);
334  scene_node->setPosition(position);
335  scene_node->setOrientation(orientation);
336  manual_object->clear();
337  manual_object->setVisible(true);
338 
341  std::vector<jsk_recognition_utils::Polygon::Ptr>
342  triangles = geo_polygon.decomposeToTriangles();
343 
344  uint32_t num_points = 0;
345  for (size_t j = 0; j < triangles.size(); j++) {
346  num_points += triangles[j]->getNumVertices();
347  }
348  if(num_points > 0) {
349  manual_object->estimateVertexCount(num_points * 2);
350  manual_object->begin(
351  materials_[i]->getName(), Ogre::RenderOperation::OT_TRIANGLE_LIST);
352  for (size_t ii = 0; ii < triangles.size(); ii++) {
353  jsk_recognition_utils::Polygon::Ptr triangle = triangles[ii];
354  size_t num_vertices = triangle->getNumVertices();
355  for (size_t j = 0; j < num_vertices; j++) {
356  Eigen::Vector3f v = triangle->getVertex(j);
357  manual_object->position(v[0], v[1], v[2]);
358  manual_object->colour(color.r, color.g, color.b, color.a);
359  }
360  for (int j = num_vertices - 1; j >= 0; j--) {
361  Eigen::Vector3f v = triangle->getVertex(j);
362  manual_object->position(v[0], v[1], v[2]);
363  manual_object->colour(color.r, color.g, color.b, color.a);
364  }
365  }
366  manual_object->end();
367  }
368  }
369  }
370 
372  const size_t i, const geometry_msgs::PolygonStamped& polygon)
373  {
374  Ogre::SceneNode* scene_node = arrow_nodes_[i];
375  scene_node->setVisible(true);
376  ArrowPtr arrow = arrow_objects_[i];
377  Ogre::Vector3 position;
378  Ogre::Quaternion orientation;
379  if (!getTransform(polygon.header, position, orientation))
380  return;
381  scene_node->setPosition(position);
382  scene_node->setOrientation(orientation); // scene node is at frame pose
386  = geo_polygon.getVertices();
387  Eigen::Vector3f centroid(0, 0, 0); // should be replaced by centroid method
388  if (vertices.size() == 0) {
389  ROS_ERROR("the size of vertices is 0");
390  }
391  else {
392  for (size_t j = 0; j < vertices.size(); j++) {
393  centroid = vertices[j] + centroid;
394  }
395  centroid = centroid / vertices.size();
396  }
397  Ogre::Vector3 pos(centroid[0], centroid[1], centroid[2]);
398  Eigen::Vector3f normal = geo_polygon.getNormal();
399  Ogre::Vector3 direction(normal[0], normal[1], normal[2]);
400  if (std::isnan(direction[0]) || std::isnan(direction[1]) || std::isnan(direction[2])) {
401  ROS_ERROR("failed to compute normal direction");
402  Ogre::Vector3 zeroscale(0, 0, 0);
403  arrow->setScale(zeroscale);
404  return;
405  }
407  arrow->setPosition(pos);
408  arrow->setDirection(direction);
409 
410  arrow->setScale(scale);
411  arrow->setColor(getColor(i));
412  }
413 
415  const jsk_recognition_msgs::PolygonArray::ConstPtr& msg)
416  {
417  if (!validateFloats(*msg)) {
419  "Topic",
420  "Message contained invalid floating point values"
421  "(nans or infs)");
422  return;
423  }
425  "Topic",
426  "ok");
427  latest_msg_ = msg;
428  // create nodes and manual objects
429  updateSceneNodes(msg);
430  allocateMaterials(msg->polygons.size());
431  updateLines(msg->polygons.size());
432  if (only_border_) {
433  // use line_
434  for (size_t i = 0; i < manual_objects_.size(); i++) {
435  manual_objects_[i]->setVisible(false);
436  }
437  for (size_t i = 0; i < msg->polygons.size(); i++) {
438  geometry_msgs::PolygonStamped polygon = msg->polygons[i];
439  if (polygon.polygon.points.size() >= 3) {
440  processLine(i, polygon);
441  }
442  }
443  }
444  else {
445  for (size_t i = 0; i < msg->polygons.size(); i++) {
447  }
448 
449  for (size_t i = 0; i < msg->polygons.size(); i++) {
450  geometry_msgs::PolygonStamped polygon = msg->polygons[i];
451  processPolygon(i, polygon);
452  }
453  }
454 
455  if (show_normal_) {
456  for (size_t i = 0; i < msg->polygons.size(); i++) {
457  geometry_msgs::PolygonStamped polygon = msg->polygons[i];
458  if (polygon.polygon.points.size() >= 3) {
459  processNormal(i, polygon);
460  }
461  }
462  }
463  }
464 
466  const std_msgs::Header &header,
467  Ogre::Vector3 &position, Ogre::Quaternion &orientation)
468  {
469  bool ok = context_->getFrameManager()->getTransform(
470  header.frame_id, header.stamp,
471  position, orientation);
472  if (!ok) {
473  std::ostringstream oss;
474  oss << "Error transforming from frame '";
475  oss << header.frame_id << "' to frame '";
476  oss << qPrintable(fixed_frame_) << "'";
477  ROS_DEBUG_STREAM(oss.str());
479  "Transform", QString::fromStdString(oss.str()));
480  }
481  return ok;
482  }
483 
485  {
486  if (coloring_property_->getOptionInt() == 0) {
487  coloring_method_ = "auto";
489  }
490  else if (coloring_property_->getOptionInt() == 1) {
491  coloring_method_ = "flat";
493  }
494  else if (coloring_property_->getOptionInt() == 2) {
495  coloring_method_ = "likelihood";
497  }
498  else if (coloring_property_->getOptionInt() == 3) {
499  coloring_method_ = "label";
501  }
502  }
503 
505  {
507  }
508 
510  {
512  if (show_normal_) {
514  }
515  else {
517  for (size_t i = 0; i < arrow_nodes_.size(); i++) {
518  arrow_nodes_[i]->setVisible(false);
519  }
520  }
521  }
522 
524  {
526  }
527 
529  {
531  }
532 }
533 
virtual QColor getColor() const
std_msgs::ColorRGBA heatColor(double v)
void setMin(float min)
virtual bool getTransform(const std_msgs::Header &header, Ogre::Vector3 &position, Ogre::Quaternion &orientation)
std::vector< Ogre::SceneNode * > arrow_nodes_
void setMax(float max)
virtual void processMessage(const jsk_recognition_msgs::PolygonArray::ConstPtr &msg)
pos
void addPoint(const Ogre::Vector3 &point)
PLUGINLIB_EXPORT_CLASS(jsk_rviz_plugins::PictogramArrayDisplay, rviz::Display)
DisplayContext * context_
virtual void processLine(const size_t i, const geometry_msgs::PolygonStamped &polygon)
virtual Vertices getVertices()
virtual float getFloat() const
static Polygon fromROSMsg(const geometry_msgs::Polygon &polygon)
Ogre::SceneNode * scene_node_
jsk_recognition_msgs::PolygonArray::ConstPtr latest_msg_
virtual void setColor(float r, float g, float b, float a)
virtual void processPolygonMaterial(const size_t i)
Ogre::ColourValue qtToOgre(const QColor &c)
virtual bool getBool() const
QString fixed_frame_
virtual void processPolygon(const size_t i, const geometry_msgs::PolygonStamped &polygon)
virtual void processNormal(const size_t i, const geometry_msgs::PolygonStamped &polygon)
virtual void addOption(const QString &option, int value=0)
virtual void updateSceneNodes(const jsk_recognition_msgs::PolygonArray::ConstPtr &msg)
std::vector< Ogre::SceneNode * > scene_nodes_
bool validateFloats(const sensor_msgs::CameraInfo &msg)
void queueRender()
virtual FrameManager * getFrameManager() const =0
bool validateFloats(const visualization_msgs::InteractiveMarker &msg)
void setNumLines(uint32_t num)
#define ROS_DEBUG_STREAM(args)
void setMaxPointsPerLine(uint32_t max)
Ogre::SceneManager * scene_manager_
std::vector< Eigen::Vector3f, Eigen::aligned_allocator< Eigen::Vector3f > > Vertices
virtual Ogre::SceneManager * getSceneManager() const =0
std::vector< rviz::BillboardLine * > lines_
std_msgs::ColorRGBA colorCategory20(int i)
std::vector< Ogre::MaterialPtr > materials_
bool getTransform(const Header &header, Ogre::Vector3 &position, Ogre::Quaternion &orientation)
std::vector< Ogre::ManualObject * > manual_objects_
virtual Ogre::ColourValue getColor(size_t index)
virtual int getOptionInt()
#define ROS_ERROR(...)
virtual void setStatus(StatusProperty::Level level, const QString &name, const QString &text)
virtual QString getName() const
virtual std::vector< Polygon::Ptr > decomposeToTriangles()
virtual Eigen::Vector3f getNormal()
void setLineWidth(float width)


jsk_rviz_plugins
Author(s): Kei Okada , Yohei Kakiuchi , Shohei Fujii , Ryohei Ueda
autogenerated on Sat Mar 20 2021 03:03:18