isl-org / Open3D

Open3D: A Modern Library for 3D Data Processing
http://www.open3d.org
Other
11.56k stars 2.32k forks source link

How to set orthographic projection in camera #4862

Open rowanG077 opened 2 years ago

rowanG077 commented 2 years ago

Checklist

My Question

I want to have an orthographic projection view in my gui and I can't get it to work. There is a way according to the doc to setup orthographic projection but I can't get it to work right.

The object is stretched in the view however. In addition I can't zoom in or out. Is there any way to get a "normal" orthographic perspective?

Currently I use this code to setup orthographic projection:

self._scene.setup_camera(0, bounds, bounds.get_center())
proj = rendering.Camera.Projection.Ortho
mins = bounds.get_min_bound()
maxs = bounds.get_max_bound()
self._scene.scene.camera.set_projection(
    proj,
    mins[0],
    maxs[0],
    mins[1],
    maxs[1],
    mins[2],
    maxs[2]
)
rowanG077 commented 2 years ago

Is there another way to do this? In my app it's important that the view is orthographic.

solarjoe commented 2 years ago

I would also like to have an easy way to do this, similar to setting views in other tools.

Mayavi fig.scene.parallel_projection = True

PyVista pl.view_isometric()

lambertwx commented 1 year ago

Adding my vote for this. I too have an application that needs orthographic views. My code is very similar to @rowanG077's above.

import open3d.visualization.gui as gui
import open3d.visualization.rendering as rendering

gui.Application.instance.initialize()
window = gui.Application.instance.create_window("scenewidget", 1024, 1024)
widget = gui.SceneWidget()
widget.scene = rendering.Open3DScene(window.renderer)
bbox = open3d.geometry.AxisAlignedBoundingBox([-10, -10, -10],
                                                   [10, 10, 10])
fov_degs = 60
widget.setup_camera(fov_degs, bbox, [0, 0, 0])
widget.scene.camera.look_at([0,0,0],
                                [0, 50, 50],
                                [0, -1, 0])
widget.scene.camera.set_projection(rendering.Camera.Projection.Ortho, -10, 10, -10, 10, 1, 10)

Running open3d 0.16.1 on MacOS Big Sur 11.7.4, I get the error in void filament::FCamera::setProjection(Camera::Projection, double, double, double, double, double, double):100 reason: Camera preconditions not met. Using default projection. and the projection remains perspective.

lambertwx commented 1 year ago

Hmm... looking further I'm starting to think this might be a simple typo in the python -> cpp -> filament call chain. By searching the github filament code base, I see that the error is raising from FCamera::setProjection() at https://github.com/google/filament/blob/a171e75e70c3631f7a43636e213943e4376f7768/filament/src/details/Camera.cpp#L100

Inspecting the conditional that logs the error, it's pretty simple - it tests just a few conditions on the left, right, bottom, top, far, near params.

if (UTILS_UNLIKELY(left == right ||
                       bottom == top ||
                       (projection == Projection::PERSPECTIVE && (near <= 0 || far <= near)) ||
                       (projection == Projection::ORTHO && (near == far)))) {
        PANIC_LOG("Camera preconditions not met. Using default projection.");

Looking at the args I'm passing in to set_projection, it seems like they do not meet any of these conditions that would trigger the PANIC_LOG.

Which leads me to conclude that something is going wrong in the call chain that eventually invokes this filament routine.

Unfortunately, I'm not familiar with how python to cpp bindings work. If someone with more experience tracking through the python -> cpp > filament chain could take a look, this might be an easy fix!

lambertwx commented 1 year ago

@rowanG077 It might be helpful if you changed the label on this to "bug" instead of "question".

rowanG077 commented 1 year ago

@lambertwx Unfortunately I can't change the labels (anymore?).

ajktym94 commented 1 year ago

Is there any update regarding this? I wanted to use this function to visualize in orthographic projection.

yes89929 commented 10 months ago

I would also like to have an easy way to do this, similar to setting views in other tools.

Mayavi fig.scene.parallel_projection = True

PyVista pl.view_isometric()

In PyVista, use pl.camera.parallel_projection = True not pl.view_isometric(). pl.view_isometric() just changes the viewpoint.

0i0i0i commented 7 months ago

mee too has this issue. Any workaround is acceptable.

xiebei commented 6 months ago

+1

stasgold commented 2 weeks ago

import open3d as o3d import open3d.visualization as vis

def set_camera_to_orthographic(vis):

Get current camera settings

ctr = vis.get_view_control()
param = ctr.convert_to_pinhole_camera_parameters()
# Modify the intrinsic parameters to achieve orthographic projection
param.intrinsic.set_intrinsics(
    width=1920,
    height=1080,
    fx=1.0,  # Set a small value to simulate an orthographic projection
    fy=1.0,
    cx=960,
    cy=540
)
ctr.convert_from_pinhole_camera_parameters(param)

Draw geometries and apply orthographic camera settings

vis.draw(geoms, on_animation_frame=set_camera_to_orthographic)

works like a charm :)