polygon_parts.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2020, Locus Robotics
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
36 #include <nav_2d_utils/polygons.h>
38 #include <string>
39 #include <vector>
40 
41 namespace robot_nav_rviz_plugins
42 {
43 std_msgs::ColorRGBA getColor(rviz::ColorProperty* color_property, rviz::FloatProperty* alpha_property)
44 {
45  const QColor& qcolor = color_property->getColor();
46  std_msgs::ColorRGBA color;
47  color.r = qcolor.redF();
48  color.g = qcolor.greenF();
49  color.b = qcolor.blueF();
50  color.a = (alpha_property == nullptr) ? 1.0 : alpha_property->getFloat();
51  return color;
52 }
53 
54 PolygonOutline::PolygonOutline(Ogre::SceneManager& scene_manager, Ogre::SceneNode& scene_node)
55  : scene_manager_(scene_manager), scene_node_(scene_node)
56 {
57  manual_object_ = scene_manager_.createManualObject();
58  manual_object_->setDynamic(true);
59  scene_node_.attachObject(manual_object_);
60 }
61 
63 {
64  scene_manager_.destroyManualObject(manual_object_);
65 }
66 
68 {
69  manual_object_->clear();
70 }
71 
72 void PolygonOutline::setPolygon(const nav_2d_msgs::Polygon2D& polygon, const Ogre::ColourValue& color, double z_offset)
73 {
74  manual_object_->estimateVertexCount(polygon.points.size());
75  manual_object_->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_STRIP);
76  for (const nav_2d_msgs::Point2D& msg_point : polygon.points)
77  {
78  manual_object_->position(msg_point.x, msg_point.y, z_offset);
79  manual_object_->colour(color);
80  }
81  manual_object_->end();
82 }
83 
84 PolygonFill::PolygonFill(Ogre::SceneManager& scene_manager, Ogre::SceneNode& scene_node,
85  const std::string& material_name)
86  : scene_manager_(scene_manager), scene_node_(scene_node), material_name_(material_name)
87 {
88  manual_object_ = scene_manager_.createManualObject();
89  manual_object_->setDynamic(true);
90  scene_node_.attachObject(manual_object_);
91 }
92 
94 {
95  scene_manager_.destroyManualObject(manual_object_);
96 }
97 
99 {
100  manual_object_->clear();
101  last_vertex_count_ = 0;
102 }
103 
104 
105 void PolygonFill::setPolygon(const nav_2d_msgs::Polygon2D& polygon, const std_msgs::ColorRGBA& color, double z_offset)
106 {
107  nav_2d_msgs::ComplexPolygon2D complex;
108  complex.outer = polygon;
109  setPolygon(complex, color, z_offset);
110 }
111 
112 void PolygonFill::setPolygon(const nav_2d_msgs::ComplexPolygon2D& polygon, const std_msgs::ColorRGBA& color,
113  double z_offset)
114 {
115  std::vector<nav_2d_msgs::Point2D> vertices = nav_2d_utils::triangulate(polygon);
116  if (vertices.empty())
117  {
118  return;
119  }
120  unsigned int vertex_count = vertices.size();
121 
122  // Based on https://github.com/ros-visualization/rviz/blob/6bf59755eb213afa575e219feb152c0efd8b3209/src/rviz/default_plugin/markers/triangle_list_marker.cpp#L113
123  // If we have the same number of tris as previously, just update the object
124  if (vertex_count == last_vertex_count_)
125  {
126  manual_object_->beginUpdate(0);
127  }
128  else // Otherwise clear it and begin anew
129  {
130  manual_object_->clear();
131  manual_object_->estimateVertexCount(vertex_count);
132  manual_object_->begin(material_name_, Ogre::RenderOperation::OT_TRIANGLE_LIST);
133  last_vertex_count_ = vertex_count;
134  }
135 
136  for (unsigned int i = 0; i < vertex_count; i += 3)
137  {
138  std::vector<Ogre::Vector3> corners(3);
139  for (size_t c = 0; c < 3; c++)
140  {
141  corners[c] = Ogre::Vector3(vertices[i + c].x, vertices[i + c].y, z_offset);
142  }
143  Ogre::Vector3 normal = (corners[1] - corners[0]).crossProduct(corners[2] - corners[0]);
144  normal.normalise();
145 
146  for (size_t c = 0; c < 3; c++)
147  {
148  manual_object_->position(corners[c]);
149  manual_object_->normal(normal);
150  manual_object_->colour(color.r, color.g, color.b, color.a);
151  }
152  }
153  manual_object_->end();
154 }
155 
157 {
158  static uint32_t count = 0;
160  ss << "PolygonMaterial" << count++;
161  name_ = ss.str();
162  material_ = Ogre::MaterialManager::getSingleton().create(name_, "rviz");
163  material_->setReceiveShadows(false);
164  material_->setCullingMode(Ogre::CULL_NONE);
165 
166  Ogre::Technique* technique = material_->getTechnique(0);
167  technique->setLightingEnabled(false);
168  technique->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
169  technique->setDepthWriteEnabled(false);
170 }
171 
173 {
174  material_->unload();
175  Ogre::MaterialManager::getSingleton().remove(name_);
176 }
177 
179 {
180  property_ = new rviz::EnumProperty("Display Mode", "Filled Outline",
181  "Draw the outline, the filled-in polygon, or both", parent, changed_slot);
182  property_->addOption("Outline", static_cast<int>(DisplayMode::OUTLINE));
183  property_->addOption("Filled", static_cast<int>(DisplayMode::FILLED));
184  property_->addOption("Filled Outline", static_cast<int>(DisplayMode::FILLED_OUTLINE));
185 }
186 
187 
188 } // namespace robot_nav_rviz_plugins
virtual QColor getColor() const
void setPolygon(const nav_2d_msgs::Polygon2D &polygon, const Ogre::ColourValue &color, double z_offset)
Set the object to display the outline of the given polygon, in a specific color, possibly offset in z...
Ogre::SceneManager & scene_manager_
std::vector< nav_2d_msgs::Point2D > triangulate(const nav_2d_msgs::ComplexPolygon2D &polygon)
PolygonOutline(Ogre::SceneManager &scene_manager, Ogre::SceneNode &scene_node)
virtual float getFloat() const
TFSIMD_FORCE_INLINE const tfScalar & y() const
std_msgs::ColorRGBA getColor(rviz::ColorProperty *color_property, rviz::FloatProperty *alpha_property=nullptr)
Given a Color Property and an optional Float property, return a ROS Color message.
Ogre::ManualObject * manual_object_
Several reusable pieces for displaying polygons.
PolygonDisplayModeProperty(rviz::Property *parent, const char *changed_slot=0)
TFSIMD_FORCE_INLINE const tfScalar & x() const
void setPolygon(const nav_2d_msgs::Polygon2D &polygon, const std_msgs::ColorRGBA &color, double z_offset)
Set the object to display the area of the given polygon, in a specific color, possibly offset in z...
PolygonFill(Ogre::SceneManager &scene_manager, Ogre::SceneNode &scene_node, const std::string &material_name)


robot_nav_rviz_plugins
Author(s):
autogenerated on Sun Jan 10 2021 04:08:58