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

Calling draw_geometries() while in a non-blocking drawing loop breaks the non-blocking drawing #599

Closed
martinakos opened this issue Oct 4, 2018 · 4 comments

Comments

@martinakos
Copy link

martinakos commented Oct 4, 2018

Consider the non_blocking_visualisation.py example.
If we call

draw_geometries([source_raw]) 

any time after

    vis = Visualizer()
    vis.create_window()

then after exiting draw_geometries, when we try to use vis it prints the following error:

GLFW Error: The GLFW library is not initialized

and nothing shows up in the vis window after that point.

I find myself in this scenario in an app I'm making which displays point clouds in a non-blocking way. But as I'm debugging it I often call draw_geometries() from the ipython interpreter to display some intermediate results. The problem is that, at the moment, if I do this I can't continue with the app, as the non-blocking visualization stops working. I have to restart the app to see the non-blocking visualization again.

Is there anything that can be done to avoid this?

@syncle
Copy link
Contributor

syncle commented Oct 4, 2018

Hi @martinakos. draw_geometries is high level function - it create a window and add geometries. If you put draw_geometries inside the lop, this will make many windows simultaneously and may cause problem.

The workaround is to define Visualizer() class and use internal functions. Let me take an example using non_blocking_visualisation.py:

    vis = Visualizer()
    vis.create_window()
    vis.add_geometry(source)
    vis.add_geometry(target)
    threshold = 0.05
    icp_iteration = 100
    save_image = False
   
    ##################
    # this is to display the second example
    vis2 = Visualizer()
    vis2.create_window()
    vis2.add_geometry(source) # replace your geometry
    ##################

    for i in range(icp_iteration):
        reg_p2l = registration_icp(source, target, threshold,
                np.identity(4), TransformationEstimationPointToPlane(),
                ICPConvergenceCriteria(max_iteration = 1))
        source.transform(reg_p2l.transformation)
        vis.update_geometry()
        vis.poll_events()
        vis.update_renderer()

        ##################
        # this is to display the second example
        vis2.update_geometry()
        vis2.poll_events()
        vis2.update_renderer()
        ##################

        if save_image:
            vis.capture_screen_image("temp_%04d.jpg" % i)
    vis.destroy_window()
    vis2.destroy_window()

This script will show two screens without glitch.

@martinakos
Copy link
Author

martinakos commented Oct 5, 2018

Sorry, I think I wasn't very clear. I only call draw_geometries() from the interactive prompt, for debugging purposes. It allows me to verify and interactively inspect that my intermediate operations work as I intend while stopped at a breakpoint. I've wrapped draw_geometries() with a function that creates a number of point clouds from numpy arrays and allows me to add some markers. It's very handy for interactive debugging. The problem is that if I use this function my non-blocking visualisation breaks.

Thanks for the example. I see in this example that I can interact with both windows. This is good.
So I've repacked the code to my use case and created the test below:

from open3d import *
import numpy as np
import copy


def show_drawings(source):

    vis2 = Visualizer()
    vis2.create_window(window_name='window2',width=640, height=480)
    vis2.add_geometry(source) # replace your geometry
    e = True
    while e:        
        vis2.update_geometry()
        e = vis2.poll_events()
        vis2.update_renderer()
    #vis2.destroy_window()                        
    return

if __name__ == "__main__":
    set_verbosity_level(VerbosityLevel.Debug)
    source_raw = read_point_cloud("../../TestData/ICP/cloud_bin_0.pcd")
    target_raw = read_point_cloud("../../TestData/ICP/cloud_bin_1.pcd")
    source = voxel_down_sample(source_raw, voxel_size = 0.02)
    target = voxel_down_sample(target_raw, voxel_size = 0.02)
    trans = [[0.862, 0.011, -0.507,  0.0],
            [-0.139, 0.967, -0.215,  0.7],
            [0.487, 0.255,  0.835, -1.4],
            [0.0, 0.0, 0.0, 1.0]]
    source.transform(trans)

    flip_transform = [[1, 0, 0, 0],
            [0, -1, 0, 0],
            [0, 0, -1, 0],
            [0, 0, 0, 1]]
    source.transform(flip_transform)
    target.transform(flip_transform)



    vis = Visualizer()
    vis.create_window(window_name='window1',width=640, height=480)                         
    vis.add_geometry(source)
    vis.add_geometry(target)
    threshold = 0.05
    icp_iteration = 100
    save_image = False    
  
    for i in range(icp_iteration):
        reg_p2l = registration_icp(source, target, threshold,
                np.identity(4), TransformationEstimationPointToPlane(),
                ICPConvergenceCriteria(max_iteration = 1))
        source.transform(reg_p2l.transformation)
        vis.update_geometry()
        vis.poll_events()
        vis.update_renderer()

        #At some point, while running, set a breakpoint here 
        #and in the interactive prompt call: show_drawings(source)
        #after inspecting, press ESC to close the window, 
        #and continue with the script.

        if save_image:
            vis.capture_screen_image("temp_%04d.jpg" % i)
    vis.destroy_window()

What I was hopping for is that I could stop the code at a breakpoint at the line "if save_image"; then as explained in the comment above this line, call my show_drawings(source) in an interactive prompt; inspect the pointcloud; close the window by pressing ESC; and then carry on with the execution of the script. However, for some reason, when closing window2, by pressing ESC, window1 is closed too! and the next time window1 is used the "GLFW Error: The GLFW library is not initialized" will appear again.

Any idea how to do what I intend?

@syncle
Copy link
Contributor

syncle commented Oct 8, 2018

I see the same symptom. It seems glfw window close event is being broad-casted to the every windows, but I couldn't find how to fix this yet.

@syncle syncle added the bug label Oct 12, 2018
@tornadomeet
Copy link

add del vis like this:

vis.destroy_window()
del vis

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

No branches or pull requests

4 participants