ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
rendering.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 #include <pybind11/functional.h>
10 
11 #include "pybind/docstring.h"
14 #include "t/geometry/Geometry.h"
15 #include "t/geometry/PointCloud.h"
26 
27 namespace cloudViewer {
28 namespace visualization {
29 namespace rendering {
30 
32 public:
34  int height,
35  const std::string &resource_path) {
36  gui::InitializeForPython(resource_path, true);
37  width_ = width;
38  height_ = height;
39  // NOTE: OffscreenRenderer now always uses headless so that a window
40  // system is never required
43  height,
45  scene_ = new CloudViewerScene(*renderer_);
46  }
47 
49  delete scene_;
50  delete renderer_;
51  // Destroy Filament Engine here so OffscreenRenderer can be reused
53  }
54 
55  CloudViewerScene *GetScene() { return scene_; }
56 
57  std::shared_ptr<geometry::Image> RenderToImage() {
58  return gui::RenderToImageWithoutWindow(scene_, width_, height_);
59  }
60 
61  std::shared_ptr<geometry::Image> RenderToDepthImage(
62  bool z_in_view_space = false) {
63  return gui::RenderToDepthImageWithoutWindow(scene_, width_, height_,
64  z_in_view_space);
65  }
66 
68  const Eigen::Matrix4d &extrinsic) {
69  SetupCamera(intrinsic.intrinsic_matrix_, extrinsic, intrinsic.width_,
70  intrinsic.height_);
71  }
72 
73  void SetupCamera(const Eigen::Matrix3d &intrinsic,
74  const Eigen::Matrix4d &extrinsic,
75  int intrinsic_width_px,
76  int intrinsic_height_px) {
78  *scene_->GetCamera(), intrinsic, extrinsic, intrinsic_width_px,
79  intrinsic_height_px, scene_->GetBoundingBox());
80  }
81 
82  void SetupCamera(float verticalFoV,
83  const Eigen::Vector3f &center,
84  const Eigen::Vector3f &eye,
85  const Eigen::Vector3f &up,
86  float nearClip = -1.0f,
87  float farClip = -1.0f) {
88  float aspect = 1.0f;
89  if (height_ > 0) {
90  aspect = float(width_) / float(height_);
91  }
92  auto *camera = scene_->GetCamera();
93  auto far_plane = farClip > 0.0
94  ? farClip
96  *camera, scene_->GetBoundingBox());
97  camera->SetProjection(
98  verticalFoV, aspect,
99  nearClip > 0.0 ? nearClip : Camera::CalcNearPlane(), far_plane,
101  camera->LookAt(center, eye, up);
102  }
103 
104 private:
105  int width_;
106  int height_;
107  FilamentRenderer *renderer_;
108  // The offscreen renderer owns the scene so that it can clean it up
109  // in the right order (otherwise we will crash).
110  CloudViewerScene *scene_;
111 };
112 
113 void pybind_rendering_classes(py::module &m_rendering) {
114  py::class_<TextureHandle> texture_handle(m_rendering, "TextureHandle",
115  "Handle to a texture");
116  py::class_<Renderer> renderer(
117  m_rendering, "Renderer",
118  "Renderer class that manages 3D resources. Get from gui.Window.");
119  renderer.def("set_clear_color", &Renderer::SetClearColor,
120  "Sets the background color for the renderer, [r, g, b, a]. "
121  "Applies to everything being rendered, so it essentially acts "
122  "as the background color of the window")
123  .def("add_texture",
124  (TextureHandle(Renderer::*)(
125  const std::shared_ptr<geometry::Image>, bool)) &
127  "image"_a, "is_sRGB"_a = false,
128  "Adds a texture. The first parameter is the image, the second "
129  "parameter is optional and is True if the image is in the "
130  "sRGB colorspace and False otherwise")
131  .def("update_texture",
132  (bool(Renderer::*)(TextureHandle,
133  const std::shared_ptr<geometry::Image>,
134  bool)) &
136  "texture"_a, "image"_a, "is_sRGB"_a = false,
137  "Updates the contents of the texture to be the new image, or "
138  "returns False and does nothing if the image is a different "
139  "size. It is more efficient to call update_texture() rather "
140  "than removing and adding a new texture, especially when "
141  "changes happen frequently, such as when implementing video. "
142  "add_texture(geometry.Image, bool). The first parameter is "
143  "the image, the second parameter is optional and is True "
144  "if the image is in the sRGB colorspace and False otherwise")
145  .def("remove_texture", &Renderer::RemoveTexture, "texture"_a,
146  "Deletes the texture. This does not remove the texture from "
147  "any existing materials or GUI widgets, and must be done "
148  "prior to this call.");
149 
150  // It would be nice to have this inherit from Renderer, but the problem is
151  // that Python needs to own this class and Python needs to not own Renderer,
152  // and pybind does not let us mix the two styles of ownership.
153  py::class_<PyOffscreenRenderer, std::shared_ptr<PyOffscreenRenderer>>
154  offscreen(m_rendering, "OffscreenRenderer",
155  "Renderer instance that can be used for rendering to an "
156  "image");
157  offscreen
158  .def(py::init([](int w, int h, const std::string &resource_path) {
159  return std::make_shared<PyOffscreenRenderer>(
160  w, h, resource_path);
161  }),
162  "width"_a, "height"_a, "resource_path"_a = "",
163  "Takes width, height and optionally a resource_path. "
164  " If unspecified, resource_path will use the resource path "
165  "from "
166  "the installed CloudViewer library.")
167  .def_property_readonly(
169  "Returns the CloudViewerScene for this renderer. This "
170  "scene is "
171  "destroyed when the renderer is destroyed and should not "
172  "be accessed after that point.")
173  .def("setup_camera",
174  py::overload_cast<float, const Eigen::Vector3f &,
175  const Eigen::Vector3f &,
176  const Eigen::Vector3f &, float, float>(
178  "vertical_field_of_view"_a, "center"_a, "eye"_a, "up"_a,
179  "near_clip"_a = -1.0f, "far_clip"_a = -1.0f,
180  "Sets camera view using bounding box of current geometry if "
181  "the near_clip and far_clip parameters are not set")
182  .def("setup_camera",
183  py::overload_cast<const camera::PinholeCameraIntrinsic &,
184  const Eigen::Matrix4d &>(
186  "intrinsics"_a, "extrinsic_matrix"_a,
187  "Sets the camera view using bounding box of current geometry")
188  .def("setup_camera",
189  py::overload_cast<const Eigen::Matrix3d &,
190  const Eigen::Matrix4d &, int, int>(
192  "intrinsic_matrix"_a, "extrinsic_matrix"_a,
193  "intrinsic_width_px"_a, "intrinsic_height_px"_a,
194  "Sets the camera view using bounding box of current geometry")
195  .def("render_to_image", &PyOffscreenRenderer::RenderToImage,
196  "Renders scene to an image, blocking until the image is "
197  "returned")
198  .def("render_to_depth_image",
200  "z_in_view_space"_a = false,
201  "Renders scene depth buffer to a float image, blocking until "
202  "the image is returned. Pixels range from 0 (near plane) to "
203  "1 (far plane). If z_in_view_space is set to True then pixels "
204  "are pre-transformed into view space (i.e., distance from "
205  "camera).");
206 
207  // ---- Camera ----
208  py::class_<Camera, std::shared_ptr<Camera>> cam(m_rendering, "Camera",
209  "Camera object");
210  py::native_enum<Camera::FovType>(
211  cam, "FovType", "enum.Enum",
212  "Enum class for Camera field of view types.")
213  .value("Vertical", Camera::FovType::Vertical)
214  .value("Horizontal", Camera::FovType::Horizontal)
215  .export_values()
216  .finalize();
217 
218  py::native_enum<Camera::Projection>(
219  cam, "Projection", "enum.Enum",
220  "Enum class for Camera projection types.")
221  .value("Perspective", Camera::Projection::Perspective)
222  .value("Ortho", Camera::Projection::Ortho)
223  .export_values()
224  .finalize();
225 
226  cam.def("set_projection",
227  (void(Camera::*)(double, double, double, double, Camera::FovType)) &
229  "field_of_view"_a, "aspect_ratio"_a, "near_plane"_a, "far_plane"_a,
230  "field_of_view_type"_a, "Sets a perspective projection.")
231  .def("set_projection",
232  (void(Camera::*)(Camera::Projection, double, double, double,
233  double, double, double)) &
235  "projection_type"_a, "left"_a, "right"_a, "bottom"_a, "top"_a,
236  "near"_a, "far"_a,
237  "Sets the camera projection via a viewing frustum. ")
238  .def("set_projection",
239  (void(Camera::*)(const Eigen::Matrix3d &, double, double,
240  double, double)) &
242  "intrinsics"_a, "near_plane"_a, "far_plane"_a, "image_width"_a,
243  "image_height"_a,
244  "Sets the camera projection via intrinsics matrix.")
245  .def("look_at", &Camera::LookAt, "center"_a, "eye"_a, "up"_a,
246  "Sets the position and orientation of the camera: ")
247  .def("unproject", &Camera::Unproject, "x"_a, "y"_a, "z"_a,
248  "view_width"_a, "view_height"_a,
249  "Takes the (x, y, z) location in the view, where x, y are the "
250  "number of pixels from the upper left of the view, and z is "
251  "the depth value. Returns the world coordinate (x', y', z').")
252  .def("copy_from", &Camera::CopyFrom, "camera"_a,
253  "Copies the settings from the camera passed as the argument "
254  "into this camera")
255  .def("get_near", &Camera::GetNear,
256  "Returns the distance from the camera to the near plane")
257  .def("get_far", &Camera::GetFar,
258  "Returns the distance from the camera to the far plane")
259  .def("get_field_of_view", &Camera::GetFieldOfView,
260  "Returns the field of view of camera, in degrees. Only valid "
261  "if it was passed to set_projection().")
262  .def("get_field_of_view_type", &Camera::GetFieldOfViewType,
263  "Returns the field of view type. Only valid if it was passed "
264  "to set_projection().")
265  .def(
266  "get_projection_matrix",
267  [](const Camera &cam) -> Eigen::Matrix4f {
268  // GetProjectionMatrix() returns Eigen::Transform which
269  // doesn't have a conversion to a Python object
270  return cam.GetProjectionMatrix().matrix();
271  },
272  "Returns the projection matrix of the camera")
273  .def(
274  "get_view_matrix",
275  [](const Camera &cam) -> Eigen::Matrix4f {
276  return cam.GetViewMatrix().matrix();
277  },
278  "Returns the view matrix of the camera")
279  .def(
280  "get_model_matrix",
281  [](const Camera &cam) -> Eigen::Matrix4f {
282  return cam.GetModelMatrix().matrix();
283  },
284  "Returns the model matrix of the camera");
285 
286  // ---- Gradient ----
287  py::class_<Gradient, std::shared_ptr<Gradient>> gradient(
288  m_rendering, "Gradient",
289  "Manages a gradient for the unlitGradient shader."
290  "In gradient mode, the array of points specifies points along "
291  "the gradient, from 0 to 1 (inclusive). These do need to be "
292  "evenly spaced."
293  "Simple greyscale:"
294  " [ ( 0.0, black ),"
295  " ( 1.0, white ) ]"
296  "Rainbow (note the gaps around green):"
297  " [ ( 0.000, blue ),"
298  " ( 0.125, cornflower blue ),"
299  " ( 0.250, cyan ),"
300  " ( 0.500, green ),"
301  " ( 0.750, yellow ),"
302  " ( 0.875, orange ),"
303  " ( 1.000, red ) ]"
304  "The gradient will generate a largish texture, so it should "
305  "be fairly smooth, but the boundaries may not be exactly as "
306  "specified due to quantization imposed by the fixed size of "
307  "the texture."
308  " The points *must* be sorted from the smallest value to the "
309  "largest. The values must be in the range [0, 1].");
310 
311  py::native_enum<Gradient::Mode>(gradient, "Mode", "enum.Enum")
312  .value("GRADIENT", Gradient::Mode::kGradient)
313  .value("LUT", Gradient::Mode::kLUT)
314  .export_values()
315  .finalize();
316  py::class_<Gradient::Point> gpt(gradient, "Point");
317  gpt.def(py::init<float, const Eigen::Vector4f>())
318  .def("__repr__",
319  [](const Gradient::Point &p) {
320  std::stringstream s;
321  s << "Gradient.Point[" << p.value << ", (" << p.color[0]
322  << ", " << p.color[1] << ", " << p.color[2] << ", "
323  << p.color[3] << ")]";
324  return s.str();
325  })
326  .def_readwrite("value", &Gradient::Point::value,
327  "Must be within 0.0 and 1.0")
328  .def_readwrite("color", &Gradient::Point::color,
329  "[R, G, B, A]. Color values must be in [0.0, 1.0]");
330  gradient.def(py::init<>())
331  .def(py::init<std::vector<Gradient::Point>>())
332  .def_property("points", &Gradient::GetPoints, &Gradient::SetPoints)
333  .def_property("mode", &Gradient::GetMode, &Gradient::SetMode);
334 
335  // ---- MaterialRecord ----
336  py::class_<MaterialRecord> mat(
337  m_rendering, "MaterialRecord",
338  "Describes the real-world, physically based (PBR) "
339  "material used to render a geometry");
340  mat.def(py::init<>())
341  .def_readwrite("has_alpha", &MaterialRecord::has_alpha)
342  .def_readwrite("base_color", &MaterialRecord::base_color)
343  .def_readwrite("base_metallic", &MaterialRecord::base_metallic)
344  .def_readwrite("base_roughness", &MaterialRecord::base_roughness)
345  .def_readwrite("base_reflectance",
347  .def_readwrite("base_clearcoat", &MaterialRecord::base_clearcoat)
348  .def_readwrite("base_clearcoat_roughness",
350  .def_readwrite("base_anisotropy", &MaterialRecord::base_anisotropy)
351  .def_readwrite("emissive_color", &MaterialRecord::emissive_color)
352  .def_readwrite("thickness", &MaterialRecord::thickness)
353  .def_readwrite("transmission", &MaterialRecord::transmission)
354  .def_readwrite("absorption_color",
356  .def_readwrite("absorption_distance",
358  .def_readwrite("point_size", &MaterialRecord::point_size)
359  .def_readwrite("line_width", &MaterialRecord::line_width,
360  "Requires 'shader' to be 'unlitLine'")
361  .def_readwrite("albedo_img", &MaterialRecord::albedo_img)
362  .def_readwrite("normal_img", &MaterialRecord::normal_img)
363  .def_readwrite("ao_img", &MaterialRecord::ao_img)
364  .def_readwrite("metallic_img", &MaterialRecord::metallic_img)
365  .def_readwrite("roughness_img", &MaterialRecord::roughness_img)
366  .def_readwrite("reflectance_img", &MaterialRecord::reflectance_img)
367  .def_readwrite("clearcoat_img", &MaterialRecord::clearcoat_img)
368  .def_readwrite("clearcoat_roughness_img",
370  .def_readwrite("anisotropy_img", &MaterialRecord::anisotropy_img)
371  .def_readwrite("ao_rough_metal_img",
373  .def_readwrite("generic_params", &MaterialRecord::generic_params)
374  .def_readwrite("generic_imgs", &MaterialRecord::generic_imgs)
375  .def_readwrite("gradient", &MaterialRecord::gradient)
376  .def_readwrite("scalar_min", &MaterialRecord::scalar_min)
377  .def_readwrite("scalar_max", &MaterialRecord::scalar_max)
378  .def_readwrite("sRGB_color", &MaterialRecord::sRGB_color)
379  .def_readwrite("aspect_ratio", &MaterialRecord::aspect_ratio)
380  .def_readwrite("ground_plane_axis",
382  .def_readwrite("shader", &MaterialRecord::shader);
383 
384  // ---- TriangleMeshModel ----
385  py::class_<TriangleMeshModel, std::shared_ptr<TriangleMeshModel>> tri_model(
386  m_rendering, "TriangleMeshModel",
387  "A list of geometry.TriangleMesh and MaterialRecord that can "
388  "describe a "
389  "complex model with multiple meshes, such as might be stored in an "
390  "FBX, OBJ, or GLTF file");
391  py::class_<TriangleMeshModel::MeshInfo> tri_model_info(tri_model,
392  "MeshInfo", "");
393  tri_model_info
394  .def(py::init([](std::shared_ptr<ccMesh> mesh,
395  const std::string &name,
396  unsigned int material_idx) {
397  return TriangleMeshModel::MeshInfo{mesh, name, material_idx};
398  }))
399  .def_readwrite("mesh", &TriangleMeshModel::MeshInfo::mesh)
400  .def_readwrite("mesh_name", &TriangleMeshModel::MeshInfo::mesh_name)
401  .def_readwrite("material_idx",
403  tri_model.def(py::init<>())
404  .def_readwrite("meshes", &TriangleMeshModel::meshes_)
405  .def_readwrite("materials", &TriangleMeshModel::materials_);
406 
407  // ---- ColorGradingParams ---
408  py::class_<ColorGradingParams> color_grading(
409  m_rendering, "ColorGrading",
410  "Parameters to control color grading options");
411 
412  py::native_enum<ColorGradingParams::Quality>(
413  color_grading, "Quality", "enum.Enum",
414  "Quality level of color grading operations")
415  .value("LOW", ColorGradingParams::Quality::kLow)
416  .value("MEDIUM", ColorGradingParams::Quality::kMedium)
417  .value("HIGH", ColorGradingParams::Quality::kHigh)
418  .value("ULTRA", ColorGradingParams::Quality::kUltra)
419  .finalize();
420  py::native_enum<ColorGradingParams::ToneMapping>(
421  color_grading, "ToneMapping", "enum.Enum",
422  "Specifies the tone-mapping algorithm")
424  .value("ACES_LEGACY", ColorGradingParams::ToneMapping::kAcesLegacy)
429  .value("DISPLAY_RANGE",
431  .finalize();
432 
433  color_grading
434  .def(py::init([](ColorGradingParams::Quality q,
436  return ColorGradingParams(q, algorithm);
437  }))
438  .def_property("quality", &ColorGradingParams::GetQuality,
440  "Quality of color grading operations. High quality "
441  "is more accurate but slower")
442  .def_property("tone_mapping", &ColorGradingParams::GetToneMapping,
444  "The tone mapping algorithm to apply. Must be one of "
445  "Linear, AcesLegacy, Aces, Filmic, Uchimura, "
446  "Rienhard, Display Range(for debug)")
447  .def_property("temperature", &ColorGradingParams::GetTemperature,
449  "White balance color temperature")
450  .def_property(
453  "Tint on the green/magenta axis. Ranges from -1.0 to 1.0.");
454 
455  // ---- View ----
456  py::class_<View, UnownedPointer<View>> view(m_rendering, "View",
457  "Low-level view class");
458  py::native_enum<View::ShadowType>(
459  view, "ShadowType", "enum.Enum",
460  "Available shadow mapping algorithm options")
461  .value("PCF", View::ShadowType::kPCF)
462  .value("VSM", View::ShadowType::kVSM)
463  .finalize();
464  view.def("set_color_grading", &View::SetColorGrading,
465  "Sets the parameters to be used for the color grading algorithms")
466  .def("set_post_processing", &View::SetPostProcessing,
467  "True to enable, False to disable post processing. Post "
468  "processing effects include: color grading, ambient occlusion "
469  "(and other screen space effects), and anti-aliasing.")
470  .def("set_ambient_occlusion", &View::SetAmbientOcclusion,
471  "enabled"_a, "ssct_enabled"_a = false,
472  "True to enable, False to disable ambient occlusion. "
473  "Optionally, screen-space cone tracing may be enabled with "
474  "ssct_enabled=True.")
475  .def("set_antialiasing", &View::SetAntiAliasing, "enabled"_a,
476  "temporal"_a = false,
477  "True to enable, False to disable anti-aliasing. Note that "
478  "this only impacts anti-aliasing post-processing. MSAA is "
479  "controlled separately by `set_sample_count`. Temporal "
480  "anti-aliasing may be optionally enabled with temporal=True.")
481  .def("set_sample_count", &View::SetSampleCount,
482  "Sets the sample count for MSAA. Set to 1 to disable MSAA. "
483  "Typical values are 2, 4 or 8. The maximum possible value "
484  "depends on the underlying GPU and OpenGL driver.")
485  .def("set_shadowing", &View::SetShadowing, "enabled"_a,
486  py::arg_v("type", View::ShadowType::kPCF,
487  "cloudViewer.visualization.rendering.View."
488  "ShadowType.PCF"),
489  "True to enable, false to enable all shadow mapping when "
490  "rendering this View. When enabling shadow mapping you may "
491  "also specify one of two shadow mapping algorithms: PCF "
492  "(default) or VSM. Note: shadowing is enabled by default with "
493  "PCF shadow mapping.")
494  .def("get_camera", &View::GetCamera,
495  "Returns the Camera associated with this View.");
496 
497  // ---- Scene ----
498  py::class_<Scene, UnownedPointer<Scene>> scene(m_rendering, "Scene",
499  "Low-level rendering scene");
500  py::native_enum<Scene::GroundPlane>(
501  scene, "GroundPlane", "enum.Enum",
502  "Plane on which to show ground plane: XZ, XY, or YZ")
503  .value("XZ", Scene::GroundPlane::XZ)
504  .value("XY", Scene::GroundPlane::XY)
505  .value("YZ", Scene::GroundPlane::YZ)
506  .export_values()
507  .finalize();
508  scene.def("add_camera", &Scene::AddCamera, "name"_a, "camera"_a,
509  "Adds a camera to the scene")
510  .def("remove_camera", &Scene::RemoveCamera, "name"_a,
511  "Removes the camera with the given name")
512  .def("set_active_camera", &Scene::SetActiveCamera, "name"_a,
513  "Sets the camera with the given name as the active camera for "
514  "the scene")
515  .def("add_geometry",
516  (bool(Scene::*)(const std::string &, const ccHObject &,
517  const MaterialRecord &, const std::string &,
518  size_t)) &
520  "name"_a, "geometry"_a, "material"_a,
521  "downsampled_name"_a = "", "downsample_threshold"_a = SIZE_MAX,
522  "Adds a Geometry with a material to the scene")
523  .def("add_geometry",
524  (bool(Scene::*)(
525  const std::string &, const t::geometry::Geometry &,
526  const MaterialRecord &, const std::string &, size_t)) &
528  "name"_a, "geometry"_a, "material"_a,
529  "downsampled_name"_a = "", "downsample_threshold"_a = SIZE_MAX,
530  "Adds a Geometry with a material to the scene")
531  .def("has_geometry", &Scene::HasGeometry, "name"_a,
532  "Returns True if a geometry with the provided name exists in "
533  "the scene.")
534  .def("update_geometry", &Scene::UpdateGeometry, "name"_a,
535  "point_cloud"_a, "update_flag"_a,
536  "Updates the flagged arrays from the tgeometry.PointCloud. "
537  "The flags should be ORed from Scene.UPDATE_POINTS_FLAG, "
538  "Scene.UPDATE_NORMALS_FLAG, Scene.UPDATE_COLORS_FLAG, and "
539  "Scene.UPDATE_UV0_FLAG")
540  .def("remove_geometry", &Scene::RemoveGeometry, "name"_a,
541  "Removes the named geometry from the scene.")
542  .def("show_geometry", &Scene::ShowGeometry, "name"_a, "show"_a,
543  "Show or hide the named geometry.")
544  .def("geometry_is_visible", &Scene::GeometryIsVisible, "name"_a,
545  "Returns false if the geometry is hidden, True otherwise. "
546  "Note: this is different from whether or not the geometry is "
547  "in view.")
548  .def("geometry_shadows", &Scene::GeometryShadows, "name"_a,
549  "cast_shadows"_a, "receive_shadows"_a,
550  "Controls whether an object casts and/or receives shadows: "
551  "geometry_shadows(name, cast_shadows, receieve_shadows)")
552  .def("set_geometry_culling", &Scene::SetGeometryCulling, "name"_a,
553  "enable"_a,
554  "Enable/disable view frustum culling on the named object. "
555  "Culling is enabled by default.")
556  .def("set_geometry_priority", &Scene::SetGeometryPriority, "name"_a,
557  "priority"_a,
558  "Set sorting priority for named object. Objects with higher "
559  "priority will be rendering on top of overlapping geometry "
560  "with lower priority.")
561  .def("enable_indirect_light", &Scene::EnableIndirectLight,
562  "enable"_a, "Enables or disables indirect lighting")
563  .def("set_indirect_light", &Scene::SetIndirectLight, "name"_a,
564  "Loads the indirect light. The name parameter is the name of "
565  "the file to load")
566  .def("set_indirect_light_intensity",
567  &Scene::SetIndirectLightIntensity, "intensity"_a,
568  "Sets the brightness of the indirect light")
569  .def("enable_sun_light", &Scene::EnableSunLight, "enable"_a)
570  .def("set_sun_light", &Scene::SetSunLight, "direction"_a, "color"_a,
571  "intensity"_a,
572  "Sets the parameters of the sun light direction, "
573  "color, intensity")
574  .def("add_point_light", &Scene::AddPointLight, "name"_a, "color"_a,
575  "position"_a, "intensity"_a, "falloff"_a, "cast_shadows"_a,
576  "Adds a point light to the scene.")
577  .def("add_spot_light", &Scene::AddSpotLight, "name"_a, "color"_a,
578  "position"_a, "direction"_a, "intensity"_a, "falloff"_a,
579  "inner_cone_angle"_a, "outer_cone_angle"_a, "cast_shadows"_a,
580  "Adds a spot light to the scene.")
581  .def("add_directional_light", &Scene::AddDirectionalLight, "name"_a,
582  "color"_a, "direction"_a, "intensity"_a, "cast_shadows"_a,
583  "Adds a directional light to the scene")
584  .def("remove_light", &Scene::RemoveLight, "name"_a,
585  "Removes the named light from the scene.")
586  .def("update_light_color", &Scene::UpdateLightColor, "name"_a,
587  "color"_a,
588  "Changes a point, spot, or directional light's color")
589  .def("update_light_position", &Scene::UpdateLightPosition, "name"_a,
590  "position"_a, "Changes a point or spot light's position.")
591  .def("update_light_direction", &Scene::UpdateLightDirection,
592  "name"_a, "direction"_a,
593  "Changes a spot or directional light's direction.")
594  .def("update_light_intensity", &Scene::UpdateLightIntensity,
595  "name"_a, "intensity"_a,
596  "Changes a point, spot or directional light's intensity.")
597  .def("update_light_falloff", &Scene::UpdateLightFalloff, "name"_a,
598  "falloff"_a, "Changes a point or spot light's falloff.")
599  .def("update_light_cone_angles", &Scene::UpdateLightConeAngles,
600  "name"_a, "inner_cone_angle"_a, "outer_cone_angle"_a,
601  "Changes a spot light's inner and outer cone angles.")
602  .def("enable_light_shadow", &Scene::EnableLightShadow, "name"_a,
603  "can_cast_shadows"_a,
604  "Changes whether a point, spot, or directional light can "
605  "cast shadows.")
606  .def("render_to_image", &Scene::RenderToImage,
607  "Renders the scene to an image. This can only be used in a "
608  "GUI app. To render without a window, use "
609  "``Application.render_to_image``.")
610  .def("render_to_depth_image", &Scene::RenderToDepthImage,
611  "Renders the scene to a depth image. This can only be used in "
612  "GUI app. To render without a window, use "
613  "``Application.render_to_depth_image``. Pixels range from "
614  "0.0 (near plane) to 1.0 (far plane)");
615 
616  scene.attr("UPDATE_POINTS_FLAG") = py::int_(Scene::kUpdatePointsFlag);
617  scene.attr("UPDATE_NORMALS_FLAG") = py::int_(Scene::kUpdateNormalsFlag);
618  scene.attr("UPDATE_COLORS_FLAG") = py::int_(Scene::kUpdateColorsFlag);
619  scene.attr("UPDATE_UV0_FLAG") = py::int_(Scene::kUpdateUv0Flag);
620 
621  // ---- CloudViewerScene ----
622  py::class_<CloudViewerScene, UnownedPointer<CloudViewerScene>> o3dscene(
623  m_rendering, "CloudViewerScene", "High-level scene for rending");
624  py::native_enum<CloudViewerScene::LightingProfile>(
625  o3dscene, "LightingProfile", "enum.Enum",
626  "Enum for conveniently setting lighting")
627  .value("HARD_SHADOWS",
629  .value("DARK_SHADOWS",
631  .value("MED_SHADOWS",
633  .value("SOFT_SHADOWS",
636  .export_values()
637  .finalize();
638 
639  o3dscene.def(py::init<Renderer &>())
640  .def("show_skybox", &CloudViewerScene::ShowSkybox, "enable"_a,
641  "Toggles display of the skybox")
642  .def("show_axes", &CloudViewerScene::ShowAxes, "enable"_a,
643  "Toggles display of xyz axes")
644  .def("show_ground_plane", &CloudViewerScene::ShowGroundPlane,
645  "enable"_a, "plane"_a, "Toggles display of ground plane")
646  .def("set_lighting", &CloudViewerScene::SetLighting, "profile"_a,
647  "sun_dir"_a,
648  "Sets a simple lighting model. The default value is "
649  "set_lighting(CloudViewerScene.LightingProfile.MED_SHADOWS, "
650  "(0.577, -0.577, -0.577))")
651  .def(
652  "set_background_color",
653  [](CloudViewerScene &scene, const Eigen::Vector4f &color) {
655  "visualization.rendering.CloudViewerScene.set_"
656  "background_color()\nhas been deprecated. "
657  "Please use set_background() instead.");
658  scene.SetBackground(color, nullptr);
659  },
660  "This function has been deprecated. Please use "
661  "set_background() instead.")
662  .def("set_background", &CloudViewerScene::SetBackground, "color"_a,
663  "image"_a = nullptr,
664  "set_background([r, g, b, a], image=None). Sets the "
665  "background color and (optionally) image of the scene. ")
666  .def("clear_geometry", &CloudViewerScene::ClearGeometry)
667  .def("add_geometry",
668  py::overload_cast<const std::string &, const ccHObject *,
669  const MaterialRecord &, bool>(
671  "name"_a, "geometry"_a, "material"_a,
672  "add_downsampled_copy_for_fast_rendering"_a = true,
673  "Adds a geometry with the specified name. Default visible is "
674  "true.")
675  .def("add_geometry",
676  py::overload_cast<const std::string &,
677  const t::geometry::Geometry *,
678  const MaterialRecord &, bool>(
680  "name"_a, "geometry"_a, "material"_a,
681  "add_downsampled_copy_for_fast_rendering"_a = true,
682  "Adds a geometry with the specified name. Default visible is "
683  "true.")
684  .def("add_model", &CloudViewerScene::AddModel, "name"_a, "model"_a,
685  "Adds TriangleMeshModel to the scene.")
686  .def("has_geometry", &CloudViewerScene::HasGeometry, "name"_a,
687  "Returns True if the geometry has been added to the scene, "
688  "False otherwise")
689  .def("remove_geometry", &CloudViewerScene::RemoveGeometry, "name"_a,
690  "Removes the geometry with the given name")
691  .def("geometry_is_visible", &CloudViewerScene::GeometryIsVisible,
692  "name"_a, "Returns True if the geometry name is visible")
693  .def("set_geometry_transform",
695  "transform"_a,
696  "sets the pose of the geometry name to transform")
697  .def("get_geometry_transform",
699  "Returns the pose of the geometry name in the scene")
700  .def("modify_geometry_material",
702  "material"_a,
703  "Modifies the material of the specified geometry")
704  .def("show_geometry", &CloudViewerScene::ShowGeometry, "name"_a,
705  "show"_a, "Shows or hides the geometry with the given name")
706  .def("update_material", &CloudViewerScene::UpdateMaterial,
707  "material"_a,
708  "Applies the passed material to all the geometries")
709  .def(
710  "set_view_size",
711  [](CloudViewerScene *scene, int width, int height) {
712  scene->GetView()->SetViewport(0, 0, width, height);
713  },
714  "width"_a, "height"_a,
715  "Sets the view size. This should not be used except for "
716  "rendering to an image")
717  .def_property_readonly("scene", &CloudViewerScene::GetScene,
718  "The low-level rendering scene object "
719  "(read-only)")
720  .def_property_readonly("camera", &CloudViewerScene::GetCamera,
721  "The camera object (read-only)")
722  .def_property_readonly("bounding_box",
724  "The bounding box of all the items in the "
725  "scene, visible and invisible")
726  .def_property_readonly(
727  "view", &CloudViewerScene::GetView,
728  "The low level view associated with the scene")
729  .def_property_readonly("background_color",
731  "The background color (read-only)")
732  .def_property("downsample_threshold",
735  "Minimum number of points before downsampled point "
736  "clouds are created and used when rendering speed "
737  "is important");
738 }
739 
740 void pybind_rendering(py::module &m) {
741  py::module m_rendering = m.def_submodule("rendering");
742  pybind_rendering_classes(m_rendering);
743 }
744 
745 } // namespace rendering
746 } // namespace visualization
747 } // namespace cloudViewer
int width
std::string name
int height
math::float4 color
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
Contains the pinhole camera intrinsic parameters.
The base geometry class.
Definition: Geometry.h:23
virtual Eigen::Vector3f Unproject(float x, float y, float z, float view_width, float view_height) const =0
virtual void CopyFrom(const Camera *camera)=0
virtual double GetFieldOfView() const =0
only valid if fov was passed to SetProjection()
virtual FovType GetFieldOfViewType() const =0
only valid if fov was passed to SetProjection()
static void SetupCameraAsPinholeCamera(rendering::Camera &camera, const Eigen::Matrix3d &intrinsic, const Eigen::Matrix4d &extrinsic, int intrinsic_width_px, int intrinsic_height_px, const ccBBox &scene_bounds)
Definition: Camera.cpp:35
static float CalcNearPlane()
Returns a good value for the near plane.
Definition: Camera.cpp:47
virtual void SetProjection(double fov, double aspect, double near, double far, FovType fov_type)=0
static float CalcFarPlane(const rendering::Camera &camera, const ccBBox &scene_bounds)
Definition: Camera.cpp:49
virtual void LookAt(const Eigen::Vector3f &center, const Eigen::Vector3f &eye, const Eigen::Vector3f &up)=0
Eigen::Matrix4d GetGeometryTransform(const std::string &name)
void ShowGeometry(const std::string &name, bool show)
Shows or hides the geometry with the specified name.
void ModifyGeometryMaterial(const std::string &name, const MaterialRecord &mat)
void SetBackground(const Eigen::Vector4f &color, std::shared_ptr< geometry::Image > image=nullptr)
void SetGeometryTransform(const std::string &name, const Eigen::Matrix4d &transform)
void ShowGroundPlane(bool enable, Scene::GroundPlane plane)
void UpdateMaterial(const MaterialRecord &mat)
Updates all geometries to use this material.
void SetLighting(LightingProfile profile, const Eigen::Vector3f &sun_dir)
void AddGeometry(const std::string &name, const ccHObject *geom, const MaterialRecord &mat, bool add_downsampled_copy_for_fast_rendering=true)
Adds a geometry with the specified name. Default visible is true.
void AddModel(const std::string &name, const TriangleMeshModel &model)
Quality
Quality level of color grading operations.
Definition: ColorGrading.h:21
static FilamentResourceManager & GetResourceManager()
const std::vector< Gradient::Point > & GetPoints() const
Definition: Gradient.cpp:43
void SetPoints(const std::vector< Gradient::Point > &points)
Definition: Gradient.cpp:47
PyOffscreenRenderer(int width, int height, const std::string &resource_path)
Definition: rendering.cpp:33
std::shared_ptr< geometry::Image > RenderToDepthImage(bool z_in_view_space=false)
Definition: rendering.cpp:61
void SetupCamera(float verticalFoV, const Eigen::Vector3f &center, const Eigen::Vector3f &eye, const Eigen::Vector3f &up, float nearClip=-1.0f, float farClip=-1.0f)
Definition: rendering.cpp:82
void SetupCamera(const Eigen::Matrix3d &intrinsic, const Eigen::Matrix4d &extrinsic, int intrinsic_width_px, int intrinsic_height_px)
Definition: rendering.cpp:73
void SetupCamera(const camera::PinholeCameraIntrinsic &intrinsic, const Eigen::Matrix4d &extrinsic)
Definition: rendering.cpp:67
std::shared_ptr< geometry::Image > RenderToImage()
Definition: rendering.cpp:57
virtual bool UpdateTexture(TextureHandle texture, const std::shared_ptr< geometry::Image > image, bool srgb)=0
virtual void SetClearColor(const Eigen::Vector4f &color)=0
virtual TextureHandle AddTexture(const ResourceLoadRequest &request, bool srgb=false)=0
virtual void RemoveTexture(const TextureHandle &id)=0
virtual void SetGeometryPriority(const std::string &object_name, uint8_t priority)=0
virtual void RenderToDepthImage(std::function< void(std::shared_ptr< geometry::Image >)> callback)=0
Size of image is the size of the window.
virtual void UpdateLightIntensity(const std::string &light_name, float intensity)=0
virtual bool AddPointLight(const std::string &light_name, const Eigen::Vector3f &color, const Eigen::Vector3f &position, float intensity, float falloff, bool cast_shadows)=0
virtual bool AddDirectionalLight(const std::string &light_name, const Eigen::Vector3f &color, const Eigen::Vector3f &direction, float intensity, bool cast_shadows)=0
virtual void UpdateLightFalloff(const std::string &light_name, float falloff)=0
virtual bool GeometryIsVisible(const std::string &object_name)=0
virtual void UpdateLightDirection(const std::string &light_name, const Eigen::Vector3f &direction)=0
virtual void GeometryShadows(const std::string &object_name, bool cast_shadows, bool receive_shadows)=0
virtual void RemoveCamera(const std::string &camera_name)=0
static const uint32_t kUpdateNormalsFlag
Definition: Scene.h:47
virtual void SetActiveCamera(const std::string &camera_name)=0
virtual void RemoveGeometry(const std::string &object_name)=0
static const uint32_t kUpdatePointsFlag
Definition: Scene.h:46
virtual void EnableSunLight(bool enable)=0
virtual void RemoveLight(const std::string &light_name)=0
virtual void EnableLightShadow(const std::string &light_name, bool cast_shadows)=0
virtual void UpdateGeometry(const std::string &object_name, const t::geometry::PointCloud &point_cloud, uint32_t update_flags)=0
virtual bool AddGeometry(const std::string &object_name, const ccHObject &geometry, const MaterialRecord &material, const std::string &downsampled_name="", size_t downsample_threshold=SIZE_MAX)=0
virtual void SetSunLight(const Eigen::Vector3f &direction, const Eigen::Vector3f &color, float intensity)=0
virtual void SetIndirectLightIntensity(float intensity)=0
virtual void UpdateLightColor(const std::string &light_name, const Eigen::Vector3f &color)=0
virtual bool SetIndirectLight(const std::string &ibl_name)=0
static const uint32_t kUpdateColorsFlag
Definition: Scene.h:48
virtual void SetGeometryCulling(const std::string &object_name, bool enable)=0
virtual void RenderToImage(std::function< void(std::shared_ptr< geometry::Image >)> callback)=0
Size of image is the size of the window.
virtual bool HasGeometry(const std::string &object_name) const =0
virtual void UpdateLightConeAngles(const std::string &light_name, float inner_cone_angle, float outer_cone_angle)=0
static const uint32_t kUpdateUv0Flag
Definition: Scene.h:49
virtual void UpdateLightPosition(const std::string &light_name, const Eigen::Vector3f &position)=0
virtual void AddCamera(const std::string &camera_name, std::shared_ptr< Camera > cam)=0
virtual bool AddSpotLight(const std::string &light_name, const Eigen::Vector3f &color, const Eigen::Vector3f &position, const Eigen::Vector3f &direction, float intensity, float falloff, float inner_cone_angle, float outer_cone_angle, bool cast_shadows)=0
virtual void ShowGeometry(const std::string &object_name, bool show)=0
virtual void EnableIndirectLight(bool enable)=0
virtual void SetColorGrading(const ColorGradingParams &color_grading)=0
virtual Camera * GetCamera() const =0
virtual void SetShadowing(bool enabled, ShadowType type)=0
virtual void SetAmbientOcclusion(bool enabled, bool ssct_enabled=false)=0
virtual void SetPostProcessing(bool enabled)=0
virtual void SetAntiAliasing(bool enabled, bool temporal=false)=0
#define LogWarning(...)
Definition: Logging.h:72
#define SIZE_MAX
std::shared_ptr< geometry::Image > RenderToImageWithoutWindow(rendering::CloudViewerScene *scene, int width, int height)
Definition: gui.cpp:158
std::shared_ptr< geometry::Image > RenderToDepthImageWithoutWindow(rendering::CloudViewerScene *scene, int width, int height, bool z_in_view_space)
Definition: gui.cpp:165
void InitializeForPython(std::string resource_path, bool headless)
Definition: gui.cpp:136
REHandle< EntityType::Texture > TextureHandle
void pybind_rendering(py::module &m)
Definition: rendering.cpp:740
void pybind_rendering_classes(py::module &m_rendering)
Definition: rendering.cpp:113
Generic file read and write utility for python interface.
std::unordered_map< std::string, geometry::Image > generic_imgs
std::shared_ptr< geometry::Image > normal_img
std::shared_ptr< geometry::Image > clearcoat_roughness_img
std::shared_ptr< geometry::Image > clearcoat_img
std::shared_ptr< geometry::Image > albedo_img
std::shared_ptr< geometry::Image > ao_rough_metal_img
std::unordered_map< std::string, Eigen::Vector4f > generic_params
std::shared_ptr< geometry::Image > metallic_img
std::shared_ptr< geometry::Image > roughness_img
std::shared_ptr< geometry::Image > anisotropy_img
std::shared_ptr< geometry::Image > reflectance_img
std::vector< visualization::rendering::MaterialRecord > materials_
Definition: Model.h:26