Open3D
Open3D copied to clipboard
Changing view point in C++
Hi everybody, I want to change the view point of the visualizer in C++, but it does not work and I am running out of ideas why that is. No matter what I set front_, lookat_ or up_ to, it doesn’t change the view in the visualizer window. Here is a minimal toy example:
// Create Visualizer and point cloud
open3d::visualization::Visualizer vis;
vis.CreateVisualizerWindow("Open3D");
std::vector<Eigen::Vector3d> points = std::vector<Eigen::Vector3d>();
for (int i = 0; i < 1000; i++)
{
auto tmp = Eigen::Vector3d(rand() % 100, rand() % 100, rand() % 100);
points.push_back(tmp);
}
open3d::geometry::PointCloud point_cloud = open3d::geometry::PointCloud(points);
std::shared_ptr<open3d::geometry::PointCloud> cloud_ptr = std::make_shared<open3d::geometry::PointCloud>(point_cloud);
vis.AddGeometry(cloud_ptr);
// Change view
open3d::visualization::ViewControl view_control = vis.GetViewControl();
auto view_params = open3d::visualization::ViewParameters();
view_control.ConvertToViewParameters(view_params);
view_params.front_ = Eigen::Vector3d(15, 30, 0);
view_params.lookat_ = Eigen::Vector3d(2, 5, -0.3);
view_params.up_ = Eigen::Vector3d(4, -1, 0);
view_control.ConvertFromViewParameters(view_params);
while (true)
{
vis.UpdateGeometry();
vis.UpdateRender();
vis.PollEvents();
}
I can not find any examples of this, so any advice would be greatly appreciated.
best regards!
With the old viewer, use the allow_arbitrary argument. Related PR: https://github.com/intel-isl/Open3D/pull/2564
Here there is an example but in python: https://github.com/pablospe/open3D_depthmap_example
I think for the new viewer, you can take a look to this example: https://github.com/intel-isl/Open3D/blob/master/examples/python/gui/render-to-image.py
Also check the comments about the new version 0.12.0:
- Support for arbitrary camera intrinsic matrices: A small step for the Camera class; a very anticipated step by the Open3D community
Camera::SetProjection(const Eigen::Matrix3d& intrinsics,
double near,
double far,
double width,
double height)
Thanks for your answer, the python example works but it doesn't work in C++.
Here is my adapted code:
open3d::visualization::Visualizer vis;
vis.CreateVisualizerWindow("Open3D");
vis.PollEvents();
vis.UpdateRender();
auto point_cloud = open3d::geometry::PointCloud();
open3d::io::ReadPointCloud("fragment.ply", point_cloud);
auto cloud_ptr = std::make_shared<open3d::geometry::PointCloud>(point_cloud);
vis.AddGeometry(cloud_ptr);
auto param = open3d::camera::PinholeCameraParameters();
open3d::io::ReadIJsonConvertible("view_point.json", param);
auto intrinsic = param.intrinsic_.intrinsic_matrix_;
auto extrinsic = param.extrinsic_;
auto view_control = vis.GetViewControl();
param = open3d::camera::PinholeCameraParameters();
param.intrinsic_ = open3d::camera::PinholeCameraIntrinsic();
param.intrinsic_.intrinsic_matrix_ = intrinsic;
param.extrinsic_ = extrinsic;
view_control.ConvertFromPinholeCameraParameters(param, true);
vis.UpdateRender();
vis.Run();
This looks like a bug that is related to #2874
The python code is calling the C++ code in the end, so it should be a way to call C++ to do the same as python. What is the actual problem?
I thought so too and I also confirmed in PyBind that I use the correct C++ functions as in your example, but it doesn't work. I have no clue why, can you perhaps check my example?
Not sure if I will be able have time to test this soon, but I will definitely give a try at some point.
Some questions. Why do you do twice param = open3d::camera::PinholeCameraParameters()? Shouldn't the following code be equivalent?
open3d::visualization::Visualizer vis;
vis.CreateVisualizerWindow("Open3D");
auto point_cloud = open3d::geometry::PointCloud();
open3d::io::ReadPointCloud("fragment.ply", point_cloud);
auto cloud_ptr = std::make_shared<open3d::geometry::PointCloud>(point_cloud);
vis.AddGeometry(cloud_ptr);
auto param = open3d::camera::PinholeCameraParameters();
open3d::io::ReadIJsonConvertible("view_point.json", param);
auto view_control = vis.GetViewControl();
view_control.ConvertFromPinholeCameraParameters(param, true);
vis.PollEvents();
vis.UpdateRender();
vis.Run();
vis.Destroy();
Maybe, instead of displaying it (with Run()) you could save the image with, using capture_screen_image or capture_depth_float_buffer for depth. Like in this example (python again, sorry):
http://www.open3d.org/docs/release/tutorial/visualization/non_blocking_visualization.html?highlight=capture_screen_image
Yes, your code is equivalent, but doesn't make a difference. Same with CaptureScreenImage.
Thanks for looking into it!
@Constantin771 So how did you run open3d on visual studio?
@Constantin771 So how did you run open3d on visual studio?
I could not solve the issue sadly.
Not sure if I will be able have time to test this soon, but I will definitely give a try at some point.
Some questions. Why do you do twice
param = open3d::camera::PinholeCameraParameters()? Shouldn't the following code be equivalent?open3d::visualization::Visualizer vis; vis.CreateVisualizerWindow("Open3D"); auto point_cloud = open3d::geometry::PointCloud(); open3d::io::ReadPointCloud("fragment.ply", point_cloud); auto cloud_ptr = std::make_shared<open3d::geometry::PointCloud>(point_cloud); vis.AddGeometry(cloud_ptr); auto param = open3d::camera::PinholeCameraParameters(); open3d::io::ReadIJsonConvertible("view_point.json", param); auto view_control = vis.GetViewControl(); view_control.ConvertFromPinholeCameraParameters(param, true); vis.PollEvents(); vis.UpdateRender(); vis.Run(); vis.Destroy();Maybe, instead of displaying it (with
Run()) you could save the image with, usingcapture_screen_imageorcapture_depth_float_bufferfor depth. Like in this example (python again, sorry): http://www.open3d.org/docs/release/tutorial/visualization/non_blocking_visualization.html?highlight=capture_screen_image
This still does not work for me. I would really appreciate it if someone could try this example too and confirm that it does not work.
Thanks :)
I just came across the same problem, you need to do auto &view_control = vis.GetViewControl(); meaning you must have & to do a proper reference
I just came across the same problem, you need to do
auto &view_control = vis.GetViewControl();meaning you must have&to do a proper reference
Yes, this fixed it for me.