ed
rendering.cpp
Go to the documentation of this file.
1 // ROS
2 #include <ros/console.h>
3 
4 // TU/e Robotics
6 #include <geolib/Mesh.h>
7 #include <geolib/Box.h>
8 #include <tue/config/reader.h>
9 
10 // ED
11 #include "ed/entity.h"
12 #include "ed/rendering.h"
13 #include "ed/world_model.h"
14 
15 namespace ed {
16 
17 
18 float COLORS[27][3] = { { 0.6, 0.6, 0.6}, { 0.6, 0.6, 0.4}, { 0.6, 0.6, 0.2},
19  { 0.6, 0.4, 0.6}, { 0.6, 0.4, 0.4}, { 0.6, 0.4, 0.2},
20  { 0.6, 0.2, 0.6}, { 0.6, 0.2, 0.4}, { 0.6, 0.2, 0.2},
21  { 0.4, 0.6, 0.6}, { 0.4, 0.6, 0.4}, { 0.4, 0.6, 0.2},
22  { 0.4, 0.4, 0.6}, { 0.4, 0.4, 0.4}, { 0.4, 0.4, 0.2},
23  { 0.4, 0.2, 0.6}, { 0.4, 0.2, 0.4}, { 0.4, 0.2, 0.2},
24  { 0.2, 0.6, 0.6}, { 0.2, 0.6, 0.4}, { 0.2, 0.6, 0.2},
25  { 0.2, 0.4, 0.6}, { 0.2, 0.4, 0.4}, { 0.2, 0.4, 0.2},
26  { 0.2, 0.2, 0.6}, { 0.2, 0.2, 0.4}, { 0.2, 0.2, 0.2} };
27 
28 
30 {
31 
32 public:
33 
34  SampleRenderResult(cv::Mat& z_buffer, cv::Mat& image)
35  : geo::RenderResult(z_buffer.cols, z_buffer.rows), z_buffer_(z_buffer), image_(image)
36  {
37  }
38 
39  void setMesh(const geo::Mesh* mesh)
40  {
41  mesh_ = mesh;
42  vals_.resize(mesh_->getTriangleIs().size());
43  vals_.assign(mesh_->getTriangleIs().size(), -1);
44  }
45 
46  inline void setColor(const cv::Vec3b& color) { color_ = color; }
47 
48  void renderPixel(int x, int y, float depth, int i_triangle)
49  {
50  float old_depth = z_buffer_.at<float>(y, x);
51  if (old_depth == 0. || depth < old_depth)
52  {
53  z_buffer_.at<float>(y, x) = depth;
54 
55  if (vals_[i_triangle] < 0)
56  {
57  geo::Vec3 n = mesh_->getTriangleNormal(i_triangle);
58 
59  // Small color difference between surfaces
60  vals_[i_triangle] = (1 + n.dot(geo::Vec3(0, 0.3, -1).normalized())) / 2;
61  }
62 
63  image_.at<cv::Vec3b>(y, x) = vals_[i_triangle] * color_;
64  }
65  }
66 
67 protected:
68 
69  cv::Mat& z_buffer_;
70  cv::Mat& image_;
71  const geo::Mesh* mesh_;
72  cv::Vec3b color_;
74 
75 };
76 
77 
78 unsigned int djb2(const std::string& str)
79 {
80  int hash = 5381;
81  for(unsigned int i = 0; i < str.size(); ++i)
82  hash = ((hash << 5) + hash) + str[i]; /* hash * 33 + c */
83 
84  if (hash < 0)
85  hash = -hash;
86 
87  return hash;
88 }
89 
99 void renderMesh(const geo::DepthCamera& cam, const geo::Pose3D& pose, const geo::Mesh& mesh, const cv::Vec3b& color, SampleRenderResult& res, bool flatten = false)
100 {
101  geo::RenderOptions opt;
102  res.setColor(color);
103  geo::Mesh mesh_flat;
104  if (!flatten)
105  {
106  res.setMesh(&mesh);
107  opt.setMesh(mesh, pose);
108  }
109  else
110  {
111  for (auto point : mesh.getPoints())
112  {
113  point.z = 0;
114  mesh_flat.addPoint(point);
115  }
116  for (auto triangle_indexes : mesh.getTriangleIs())
117  {
118  mesh_flat.addTriangle(triangle_indexes.i1_, triangle_indexes.i2_, triangle_indexes.i3_);
119  }
120  res.setMesh(&mesh_flat);
121  opt.setMesh(mesh_flat, pose);
122  }
123 
124  cam.render(opt, res);
125 }
126 
127 // Might it be nicer to separate rendering of the colored image and the depth image?
128 bool renderWorldModel(const ed::WorldModel& world_model, const enum ShowVolumes show_volumes,
129  const geo::DepthCamera& cam, const geo::Pose3D& cam_pose_inv,
130  cv::Mat& depth_image, cv::Mat& image, bool flatten)
131 {
132 
133  if (depth_image.rows != image.rows || depth_image.cols != image.cols)
134  {
135  throw std::invalid_argument("Depth image and image must be of the same size");
136  }
137 
139  geo::RenderOptions opt;
140 
141  // Draw axis
142 
143  constexpr double al = 0.25; // axis length (m)
144  constexpr double at = 0.01; // axis thickness (m)
145 
146  geo::Mesh x_box = geo::Box(geo::Vector3(0, -at, -at), geo::Vector3(al, at, at)).getMesh();
147  geo::Mesh y_box = geo::Box(geo::Vector3(-at, 0, -at), geo::Vector3(at, al, at)).getMesh();
148  geo::Mesh z_box = geo::Box(geo::Vector3(-at, -at, 0), geo::Vector3(at, at, al)).getMesh();
149 
150  renderMesh(cam, cam_pose_inv, x_box, cv::Vec3b(0, 0, 255), res, flatten);
151  renderMesh(cam, cam_pose_inv, y_box, cv::Vec3b(0, 255, 0), res, flatten);
152  renderMesh(cam, cam_pose_inv, z_box, cv::Vec3b(255, 0, 0), res, flatten);
153 
154  for(ed::WorldModel::const_iterator it = world_model.begin(); it != world_model.end(); ++it)
155  {
156  const ed::EntityConstPtr& e = *it;
157  const std::string& id = e->id().str();
158 
159  if (e->visual() && e->has_pose() && !e->hasFlag("self") && (id.size() < 5 || id.substr(id.size() - 5) != "floor")) // Filter ground plane
160  {
161 
162  if (show_volumes == RoomVolumes && (id.size() < 4 || id.substr(0, 4) != "wall")) continue;
163 
164  cv::Vec3b color;
165 
166  tue::config::Reader config(e->data());
167  if (config.readGroup("color"))
168  {
169  double r, g, b;
170  if (config.value("red", r) && config.value("green", g) && config.value("blue", b))
171  color = cv::Vec3b(255 * b, 255 * g, 255 * r);
172  config.endGroup();
173  }
174  else
175  {
176  int i_color = djb2(id) % 27;
177  color = cv::Vec3b(255 * COLORS[i_color][2], 255 * COLORS[i_color][1], 255 * COLORS[i_color][0]);
178  }
179 
180  geo::Pose3D pose = cam_pose_inv * e->pose();
181  renderMesh(cam, pose, e->visual()->getMesh(), color, res, flatten);
182 
183  // Render volumes
184  if (show_volumes == ModelVolumes && !e->volumes().empty())
185  {
186  for (std::map<std::string, geo::ShapeConstPtr>::const_iterator it = e->volumes().begin(); it != e->volumes().end(); ++it)
187  {
188  renderMesh(cam, pose, it->second->getMesh(), cv::Vec3b(0, 0, 255), res, flatten); // Red
189  }
190  }
191  }
192  else if (show_volumes == RoomVolumes && e->types().find("room") != e->types().end())
193  {
194  geo::Pose3D pose = cam_pose_inv * e->pose();
195  for (std::map<std::string, geo::ShapeConstPtr>::const_iterator it = e->volumes().begin(); it != e->volumes().end(); ++it)
196  {
197  renderMesh(cam, pose, it->second->getMesh(), cv::Vec3b(0, 0, 255), res, flatten); // Red
198  }
199  }
200 
201  }
202  return true;
203 }
204 
205 }
std::vector::resize
T resize(T... args)
ed::WorldModel
Definition: world_model.h:21
std::string
ed::SampleRenderResult::vals_
std::vector< double > vals_
Definition: rendering.cpp:73
DepthCamera.h
geo::RenderOptions::setMesh
void setMesh(const geo::Mesh &mesh, const geo::Pose3D &pose=geo::Pose3D::identity())
ed::renderMesh
void renderMesh(const geo::DepthCamera &cam, const geo::Pose3D &pose, const geo::Mesh &mesh, const cv::Vec3b &color, SampleRenderResult &res, bool flatten=false)
Render a mesh.
Definition: rendering.cpp:99
geo::Mesh::getTriangleNormal
const geo::Vector3 getTriangleNormal(unsigned int index) const
geo
geo::Mesh::getTriangleIs
const std::vector< TriangleI > & getTriangleIs() const
entity.h
std::vector< double >
std::string::size
T size(T... args)
hash
int hash(const char *str, int max_val)
Definition: gui_plugin.cpp:90
geo::Box
cam
geo::DepthCamera cam
Definition: view_model.cpp:28
geo::Vec3T
ed::renderWorldModel
bool renderWorldModel(const ed::WorldModel &world_model, const enum ShowVolumes show_volumes, const geo::DepthCamera &cam, const geo::Pose3D &cam_pose_inv, cv::Mat &depth_image, cv::Mat &image, bool flatten=false)
renderWorldModel renders a world model on a depth image and a colored (3D) image
Definition: rendering.cpp:128
reader.h
geo::DepthCamera::render
void render(const RenderOptions &opt, RenderResult &res) const
ed::SampleRenderResult::renderPixel
void renderPixel(int x, int y, float depth, int i_triangle)
Definition: rendering.cpp:48
ed::SampleRenderResult::color_
cv::Vec3b color_
Definition: rendering.cpp:72
geo::Transform3T
rendering.h
geo::Shape::getMesh
virtual const Mesh & getMesh() const
ed::ShowVolumes
ShowVolumes
The ShowVolumes enum indicates which volumes to render.
Definition: rendering.h:23
ed::WorldModel::begin
const_iterator begin() const
Definition: world_model.h:68
ed::COLORS
float COLORS[27][3]
Definition: rendering.cpp:18
ed::EntityConstPtr
shared_ptr< const Entity > EntityConstPtr
Definition: types.h:37
ed::WorldModel::end
const_iterator end() const
Definition: world_model.h:70
ed::SampleRenderResult::SampleRenderResult
SampleRenderResult(cv::Mat &z_buffer, cv::Mat &image)
Definition: rendering.cpp:34
image
cv::Mat image
Definition: view_model.cpp:42
geo::Mesh::getPoints
const std::vector< geo::Vector3 > & getPoints() const
geo::RenderResult
geo::RenderOptions
tue::config::Reader
tue::config::ReaderWriter::endGroup
bool endGroup()
ed::djb2
unsigned int djb2(const std::string &str)
Definition: rendering.cpp:78
std::invalid_argument
geo::Vector3
std::map
ed::WorldModel::EntityIterator
Definition: world_model.h:26
ed::SampleRenderResult
Definition: rendering.cpp:29
Mesh.h
b
void b()
tue::config::ReaderWriter::value
bool value(const std::string &name, T &value, RequiredOrOptional opt=REQUIRED)
std::map::begin
T begin(T... args)
geo::Vec3T::normalized
Vec3T normalized() const
tue::config::ReaderWriter::readGroup
bool readGroup(const std::string &name, const RequiredOrOptional opt=OPTIONAL)
geo::Mesh::addTriangle
void addTriangle(unsigned int i1, unsigned int i2, unsigned int i3)
std::vector::assign
T assign(T... args)
geo::DepthCamera
ed
Definition: convex_hull.h:8
geo::Vec3T::dot
T dot(const Vec3T &v) const
Box.h
ed::SampleRenderResult::setMesh
void setMesh(const geo::Mesh *mesh)
Definition: rendering.cpp:39
ed::ModelVolumes
@ ModelVolumes
Definition: rendering.h:26
ed::SampleRenderResult::z_buffer_
cv::Mat & z_buffer_
Definition: rendering.cpp:69
ed::SampleRenderResult::image_
cv::Mat & image_
Definition: rendering.cpp:70
geo::RenderResult::RenderResult
RenderResult(int width, int height)
geo::Mesh
depth_image
cv::Mat depth_image
Definition: view_model.cpp:41
geo::Mesh::addPoint
unsigned int addPoint(const geo::Vector3 &p)
ed::SampleRenderResult::setColor
void setColor(const cv::Vec3b &color)
Definition: rendering.cpp:46
ed::SampleRenderResult::mesh_
const geo::Mesh * mesh_
Definition: rendering.cpp:71
config
tue::config::ReaderWriter config
world_model.h
ed::RoomVolumes
@ RoomVolumes
Definition: rendering.h:27