-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
render_engine_vtk.h
222 lines (178 loc) · 8.49 KB
/
render_engine_vtk.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#pragma once
#include <array>
#include <memory>
#include <string>
#include <vector>
#include <vtkActor.h>
#include <vtkAutoInit.h>
#include <vtkCommand.h>
#include <vtkImageExport.h>
#include <vtkNew.h>
#include <vtkPolyDataAlgorithm.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkShaderProgram.h>
#include <vtkSmartPointer.h>
#include <vtkWindowToImageFilter.h>
#include "drake/common/drake_copyable.h"
#include "drake/geometry/dev/render/render_engine.h"
#include "drake/geometry/dev/render/render_label.h"
#include "drake/systems/sensors/color_palette.h"
#ifndef DRAKE_DOXYGEN_CXX
// This, and the ModuleInitVtkRenderingOpenGL2, provide the basis for enabling
// VTK's OpenGL2 infrastructure.
VTK_AUTOINIT_DECLARE(vtkRenderingOpenGL2)
#endif
namespace drake {
namespace geometry {
namespace dev {
namespace render {
#ifndef DRAKE_DOXYGEN_CXX
namespace detail {
struct ModuleInitVtkRenderingOpenGL2 {
ModuleInitVtkRenderingOpenGL2(){
VTK_AUTOINIT_CONSTRUCT(vtkRenderingOpenGL2)
}
};
// A callback class for setting uniform variables used in shader programs,
// namely z_near and z_far, when vtkCommand::UpdateShaderEvent is caught.
// See also shaders::kDepthFS, this is where the variables are used.
// For the detail of VTK's callback mechanism, please refer to:
// https://www.vtk.org/doc/nightly/html/classvtkCommand.html#details
class ShaderCallback : public vtkCommand {
public:
DRAKE_DEFAULT_COPY_AND_MOVE_AND_ASSIGN(ShaderCallback);
ShaderCallback();
static ShaderCallback* New() { return new ShaderCallback; }
// NOLINTNEXTLINE(runtime/int): To match pre-existing APIs.
void Execute(vtkObject*, unsigned long, void* callback_object) VTK_OVERRIDE {
vtkShaderProgram* program =
reinterpret_cast<vtkShaderProgram*>(callback_object);
program->SetUniformf("z_near", z_near_);
program->SetUniformf("z_far", z_far_);
}
void set_z_near(float z_near) {
z_near_ = z_near;
}
void set_z_far(float z_far) {
z_far_ = z_far;
}
private:
float z_near_{0.f};
float z_far_{0.f};
};
} // namespace detail
#endif
/** Implementation of the RenderEngine using the VTK OpenGL renderer.
@anchor render_engine_vtk_properties
<h2>Low-fidelity geometry perception properties</h2>
RGB images
| Group name | Required | Property Name | Property Type | Property Description |
| :--------: | :------: | :-----------: | :-------------: | :------------------- |
| phong | no | diffuse | Eigen::Vector4d | The rgba value of the object surface |
| phong | no | diffuse_map | std::string | The path to a texture to apply to the geometry. If none is given, or the file cannot be read, the diffuse RGB value is used. |
Depth images - no specific properties required.
Label images
| Group name | Required | Property Name | Property Type | Property Description |
| :--------: | :------: | :-----------: | :-------------: | :------------------- |
| label | no | id | RenderLabel | The label to render into the image |
If no label is provided, it uses the terrain label.
*/
class RenderEngineVtk final : public RenderEngine,
private detail::ModuleInitVtkRenderingOpenGL2 {
public:
DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN(RenderEngineVtk);
RenderEngineVtk();
std::unique_ptr<RenderEngine> Clone() const override;
/** Inherits RenderEngine::AddFlatTerrain(). */
void AddFlatTerrain() override;
/** Inherits RenderEngine::RegisterVisual(). */
RenderIndex RegisterVisual(const Shape& shape,
const PerceptionProperties& properties,
const Isometry3<double>& X_FG) override;
// TODO(SeanCurtis-TRI): I need a super-secret RegisterVisual in which the
// index is specified.
/** Inherits RenderEngine::RegisterVisual(). */
void UpdateVisualPose(const Eigen::Isometry3d& X_WG,
RenderIndex index) const override;
/** Inherits RenderEngine::UpdateViewpoint(). */
void UpdateViewpoint(const Eigen::Isometry3d& X_WR) const override;
/** Inherits RenderEngine::RenderColorImage(). */
void RenderColorImage(const CameraProperties& camera,
systems::sensors::ImageRgba8U* color_image_out,
bool show_window) const override;
/** Inherits RenderEngine::RenderDepthImage(). */
void RenderDepthImage(
const DepthCameraProperties& camera,
systems::sensors::ImageDepth32F* depth_image_out) const override;
/** Inherits RenderEngine::RenderLabelImage(). */
void RenderLabelImage(const CameraProperties& camera,
systems::sensors::ImageLabel16I* label_image_out,
bool show_window) const override;
/** @name Shape reification */
//@{
void ImplementGeometry(const Sphere& sphere, void* user_data) override;
void ImplementGeometry(const Cylinder& cylinder, void* user_data) override;
void ImplementGeometry(const HalfSpace& half_space, void* user_data) override;
void ImplementGeometry(const Box& box, void* user_data) override;
void ImplementGeometry(const Mesh& mesh, void* user_data) override;
void ImplementGeometry(const Convex& convex, void* user_data) override;
//@}
/** Returns the sky's color in an RGB image. */
const systems::sensors::ColorI& get_sky_color() const;
/** Returns flat terrain's color in an RGB image. */
const systems::sensors::ColorI& get_flat_terrain_color() const;
private:
// Common interface for loading an obj file -- used for both mesh and convex
// shapes.
void ImplementObj(const std::string& file_name, double scale,
void* user_data);
// Performs the common setup for all shape types.
void ImplementGeometry(vtkPolyDataAlgorithm* source, void* user_data);
// TODO(SeanCurtis-TRI): Do away with this color palette; RenderLabel values
// should be mangled into an rgb color and then the rgb color should be
// mangled back into a 16-bit int without doing lookups. The labels can be
// mapped to human-distinguishable colors as a post-processing operation.
const systems::sensors::ColorPalette<RenderLabel> color_palette_;
// The rendering pipeline for a single image type (color, depth, or label).
struct RenderingPipeline {
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> window;
vtkNew<vtkWindowToImageFilter> filter;
vtkNew<vtkImageExport> exporter;
};
// Updates VTK rendering related objects including vtkRenderWindow,
// vtkWindowToImageFilter and vtkImageExporter, so that VTK reflects
// vtkActors' pose update for rendering.
static void PerformVTKUpdate(const RenderingPipeline& p);
// This actually modifies internal state; the pointer to a const pipeline
// allows mutation via the contained vtkNew pointers.
void UpdateWindow(const CameraProperties& camera, bool show_window,
const RenderingPipeline* p, const char* name) const;
// Modifies the camera for the special case of the depth camera.
void UpdateWindow(const DepthCameraProperties& camera,
const RenderingPipeline* p) const;
std::array<std::unique_ptr<RenderingPipeline>, 3> pipelines_;
// By design, all of the geometry is shared across clones of the render
// engine. This is predicated upon the idea that the geometry is *not*
// deformable and does *not* depend on the system's pose information.
// (If there is deformable geometry, it will have to be handled differently.)
// Having "shared geometry" means having shared vtkPolyDataAlgorithm and
// vtkOpenGLPolyDataMapper instances. The shader callback gets registered to
// the *mapper* instances, so they all, implicitly, share the same callback.
// Making this member static facilitates that but it does preclude the
// possibility of simultaneous renderings with different uniform parameters.
// Currently, this doesn't happen because drake isn't particularly thread safe
// (or executed in such a context). However, this renderer will need some
// formal thread safe mechanism so that it doesn't rely on that in the future.
// TODO(SeanCurtis-TRI): Add thread safety mechanisms to the renderings to
// preclude collisions if this code is executed in a multi-thread context.
static vtkNew<detail::ShaderCallback> uniform_setting_callback_;
// The collection of per-geometry actors (one actor per pipeline (color,
// depth, and label) indexed by the geometry's RenderIndex.
std::vector<std::array<vtkSmartPointer<vtkActor>, 3>> actors_;
};
} // namespace render
} // namespace dev
} // namespace geometry
} // namespace drake