Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

configurable zoom max and min #497

Closed
hironoriyh opened this issue Aug 9, 2018 · 10 comments
Closed

configurable zoom max and min #497

hironoriyh opened this issue Aug 9, 2018 · 10 comments
Labels

Comments

@hironoriyh
Copy link

Currently the visualizer has the max and min zoom. This results in objects vanishing in the view when the object pose is set outside of the max-min zoom range.

Would it be possible to make the zoom range configurable?

@qianyizh
Copy link
Collaborator

qianyizh commented Aug 9, 2018

Can you provide an example of it? Would be nice to attach the view status (you can do it by control+C to take a snapshot, and paste it here).

@JeremyBYU
Copy link

JeremyBYU commented Jun 18, 2019

I am running into the same issue. It seems to be related to this: #803

The basic idea is that the objects in the environment (large) are not being drawn because the far clipping plane is too near: https://github.com/intel-isl/Open3D/blob/fab6441b763b4964ef898cbb3fae8d10ef98442f/src/Visualization/Visualizer/ViewControl.cpp#L69

A simple change to allow this to work would be able to have a parameter to increase the max zoom, which is hard coded to 2.0. https://github.com/intel-isl/Open3D/blob/fab6441b763b4964ef898cbb3fae8d10ef98442f/src/Visualization/Visualizer/ViewControl.cpp#L43

In my case I have point clouds that are translating dynamically through the environment. I need to be able to zoom out for them to be drawn in the window, but I can not because I am limited to how much I can zoom out.

@JeremyBYU
Copy link

A not so great workaround that I have implemented. Basically you press the key 'C' to recenter the bounding box of the point cloud.

def center_view(vis):
    vis.reset_view_point(True)


vis = o3d.visualization.VisualizerWithKeyCallback()
vis.create_window()
vis.register_key_callback(ord("C"), center_view)
# Your Code
# Loop
while True:
    # Update your geometries, possibly large translations
    vis.update_geometry()
    vis.poll_events()
    vis.update_renderer()
    time.sleep(1/60)

@germanros1987
Copy link
Contributor

This is done in the new visualizer.

@ghost
Copy link

ghost commented Aug 25, 2021

any solution to this? I have pointcloud from a small room and I want to be able to visualize it by zooming in

@javrtg
Copy link

javrtg commented Dec 7, 2022

When using Visualizer and its extensions (VisualizerWithEditing, VisualizerWithKeyCallback, VisualizerWithVertexSelection), I think there is a somewhat dirty solution to the issue that @hironoriyh mentioned.

To add some context, the workaround proposed @JeremyBYU has the advantage that, by calling vis.reset_view_point(True), the bounding box of what needs to be rendered is also reset:

/// Function to reset view point.
void ResetViewPoint(bool reset_bounding_box = false);

This also allows to avoid the depth-range clipping problem mentioned in #803 without the need of moving to the O3DVisualizer (I am finding it more difficult to work with, in a non-blocking way).

However, by only calling vis.reset_view_point(True), interaction with the viewer is barely allowed (see example below) because of the corresponding reset.

This is resolved by saving the viewpoint before the reset and loading it afterwards:

cam = vis.get_view_control().convert_to_pinhole_camera_parameters()
vis.reset_view_point(True)
vis.get_view_control().convert_from_pinhole_camera_parameters(cam)

As suggested by @qianyizh, below I post a (toy) example for each case.

[code to reproduce (Open3D version: 0.16)]
import open3d as o3d
import numpy as np
import time

if __name__ == "__main__":
    vis = o3d.visualization.Visualizer()
    vis.create_window(height=480, width=640)

    sphere1 = o3d.geometry.TriangleMesh.create_sphere(0.5)
    sphere1.paint_uniform_color((0.8, 0.0, 0.0))
    vis.add_geometry(sphere1)

    sphere2 = o3d.geometry.TriangleMesh.create_sphere(0.5)
    sphere2.paint_uniform_color((0.8, 0.0, 0.0))
    vis.add_geometry(sphere2)

    dt = 0.2
    s = time.time()

    # run non-blocking visualization.
    keep_running = True
    while keep_running:

        if time.time() - s > dt:
            s = time.time()
            sphere2.translate(np.array([0.1, 0.0, 0.0]))
            vis.update_geometry(sphere2)

            # workaround.
            # 1) Comment the 3 lines for the original behavior.
            # 2) Only comment the 1st and 3rd lines for reset only.
            # 3) Uncomment the 3 lines for the complete workaround.
            cam = vis.get_view_control().convert_to_pinhole_camera_parameters()
            vis.reset_view_point(True)
            vis.get_view_control().convert_from_pinhole_camera_parameters(cam)

        keep_running = vis.poll_events()
        vis.update_renderer()

    vis.destroy_window()
original behavior vis.reset_view_point(True) previous block-code
orig reset full
Solve depth clipping ✔️ ✔️
Relax zoom restriction ✔️ ✔️
Allow full interaction ✔️ ✔️

@richardrl
Copy link

When using Visualizer and its extensions (VisualizerWithEditing, VisualizerWithKeyCallback, VisualizerWithVertexSelection), I think there is a somewhat dirty solution to the issue that @hironoriyh mentioned.

To add some context, the workaround proposed @JeremyBYU has the advantage that, by calling vis.reset_view_point(True), the bounding box of what needs to be rendered is also reset:

/// Function to reset view point.
void ResetViewPoint(bool reset_bounding_box = false);

This also allows to avoid the depth-range clipping problem mentioned in #803 without the need of moving to the O3DVisualizer (I am finding it more difficult to work with, in a non-blocking way).

However, by only calling vis.reset_view_point(True), interaction with the viewer is barely allowed (see example below) because of the corresponding reset.

This is resolved by saving the viewpoint before the reset and loading it afterwards:

cam = vis.get_view_control().convert_to_pinhole_camera_parameters()
vis.reset_view_point(True)
vis.get_view_control().convert_from_pinhole_camera_parameters(cam)

As suggested by @qianyizh, below I post a (toy) example for each case.

[code to reproduce (Open3D version: 0.16)]

import open3d as o3d
import numpy as np
import time

if __name__ == "__main__":
    vis = o3d.visualization.Visualizer()
    vis.create_window(height=480, width=640)

    sphere1 = o3d.geometry.TriangleMesh.create_sphere(0.5)
    sphere1.paint_uniform_color((0.8, 0.0, 0.0))
    vis.add_geometry(sphere1)

    sphere2 = o3d.geometry.TriangleMesh.create_sphere(0.5)
    sphere2.paint_uniform_color((0.8, 0.0, 0.0))
    vis.add_geometry(sphere2)

    dt = 0.2
    s = time.time()

    # run non-blocking visualization.
    keep_running = True
    while keep_running:

        if time.time() - s > dt:
            s = time.time()
            sphere2.translate(np.array([0.1, 0.0, 0.0]))
            vis.update_geometry(sphere2)

            # workaround.
            # 1) Comment the 3 lines for the original behavior.
            # 2) Only comment the 1st and 3rd lines for reset only.
            # 3) Uncomment the 3 lines for the complete workaround.
            cam = vis.get_view_control().convert_to_pinhole_camera_parameters()
            vis.reset_view_point(True)
            vis.get_view_control().convert_from_pinhole_camera_parameters(cam)

        keep_running = vis.poll_events()
        vis.update_renderer()

    vis.destroy_window()

original behavior vis.reset_view_point(True) previous block-code
orig reset full
Solve depth clipping ❌ ✔️ ✔️
Relax zoom restriction ❌ ✔️ ✔️
Allow full interaction ✔️ ❌ ✔️

Great post, but I got this error when using the last line in your code snippet:

[Open3D WARNING] [ViewControl] ConvertFromPinholeCameraParameters() failed because window height and width do not match.

vis.get_view_control().convert_from_pinhole_camera_parameters(cam)

@javrtg
Copy link

javrtg commented Jun 9, 2024

Hi @richardrl , I can reproduce the error you are having, and I believe it is caused by the bug mentioned in #6666.

This bug has been fixed in #6711. However, the latest pypi release of Open3D (0.18.0) still contains the bug.

The reason this error shouldn't occur is that the convert_from_pinhole_camera_parameters method does the following checks:

constexpr double threshold = 1.e-6;
if (!allow_arbitrary &&
(window_height_ <= 0 || window_width_ <= 0 ||
window_height_ != intrinsic.height_ ||
window_width_ != intrinsic.width_ ||
std::abs(intrinsic.intrinsic_matrix_(0, 2) -
((double)window_width_ / 2.0 - 0.5)) > threshold ||
std::abs(intrinsic.intrinsic_matrix_(1, 2) -
((double)window_height_ / 2.0 - 0.5)) > threshold)) {
utility::LogWarning(
"[ViewControl] ConvertFromPinholeCameraParameters() failed "
"because window height and width do not match.");

These checks ensure that the dimensions (height and width) of the viewer match those of the camera being set. Since we are keeping the dimensions unchanged, there shouldn't be any error.

As a workaround to avoid being affected by the bug, you can set the optional argument allow_arbitrary, to True, like so:

# change this line:
vis.get_view_control().convert_from_pinhole_camera_parameters(cam)
# to this line:
vis.get_view_control().convert_from_pinhole_camera_parameters(cam, allow_arbitrary=True)

@richardrl
Copy link

@javrtg Thanks for your response. However, the allow_arbitrary code seems to do something weird to the camera. I can't really translate it with CTRL + ALT + left drag anymore.

@javrtg
Copy link

javrtg commented Jun 9, 2024

@richardrl I find that a bit strange because (at least with open3d 0.18.0) I can still translate the camera using either of:

  • CTRL + ALT + left drag
  • Wheel button + drag

Maybe something else is causing the visualizer to block?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants