Open3D
Open3D copied to clipboard
Open3D crashes when adding and removing geometries around 65500 times
Checklist
- [x] I have searched for similar issues.
- [x] For Python issues, I have tested with the latest development wheel.
- [x] I have checked the release documentation and the latest documentation (for
mainbranch).
Describe the issue
I want to update a pointcloud very often with the Open3D GUI API. In this example you can see that the program crashes every time after about the same number of frames, it is looking like the value of a UInt16. So I assume it has to do with this.
This could be a similar issue: https://github.com/isl-org/Open3D/issues/7129
It would be nice if we could run the program for a long time.
Please note: This program is only written to reproduce the ERROR very quickly. The displayed point cloud bar moves to indicate that the program is running.
Steps to reproduce the bug
import faulthandler
import numpy as np
import open3d as o3d
import open3d.visualization.gui as gui
import open3d.visualization.rendering as rendering
import threading
CLOUD_NAME = 'points'
class Open3DTest:
def __init__(self):
# the open3d pointcloud
self.pcd = o3d.geometry.PointCloud()
# counter for pointcloud actualizations
self.pcd_actualize_counter = 0
# lock
self.pcd_lock = threading.Lock()
# crate application
self.app = gui.Application.instance
# initialize application
self.app.initialize()
# create window
self.window_name = 'Open3D_Overflow_Test'
self.window = self.app.create_window(self.window_name, 800, 500)
# add a scene and setup camera
self.widget3d = gui.SceneWidget()
self.widget3d.scene = rendering.Open3DScene(self.window.renderer)
self.setup_scene_camera()
self.widget3d.scene.show_ground_plane(True, rendering.Scene.GroundPlane.XY)
self.window.add_child(self.widget3d)
# prepare thread
self.ui_update_thread = threading.Thread(target=self.ui_update_thread)
def setup_scene_camera(self):
bounds = o3d.geometry.AxisAlignedBoundingBox()
bounds.max_bound = [30, 10, 10]
bounds.min_bound = [-10, -10, -10]
self.widget3d.setup_camera(43, bounds, [0, 0, 0])
def ui_update_thread(self):
def calc_colors_from_reflectivity(pcd_reflectivity):
pcd_reflectivity_size = pcd_reflectivity.size
pcd_colors = np.zeros(shape=(pcd_reflectivity_size, 3), dtype=np.float64)
pcd_colors[:, 0] = (pcd_reflectivity[:] / 255) # r
pcd_colors[:, 1] = (pcd_reflectivity[:] / 255) # g
pcd_colors[:, 2] = 1 - (pcd_reflectivity[:] / 255) # b
o3d_pcd_colors = o3d.utility.Vector3dVector(pcd_colors)
return o3d_pcd_colors
def create_numpy_pcd(intensity_offset):
pcd_colortest = np.zeros(shape=(256, 4), dtype=np.float64)
i = 0
while i < 256:
pcd_colortest[i, 0] = i * 0.1 # x
intensity = i + intensity_offset
intensity = intensity % 256
pcd_colortest[i, 3] = intensity
i += 1
return pcd_colortest
def update_open3d_pcd_colortest():
pcd_colortest = create_numpy_pcd(self.pcd_actualize_counter)
with self.pcd_lock:
self.pcd.points = o3d.utility.Vector3dVector(pcd_colortest[:, 0:3])
self.pcd.colors = calc_colors_from_reflectivity(pcd_colortest[:, 3])
def add_first_cloud():
pcd_colortest = create_numpy_pcd(self.pcd_actualize_counter)
with self.pcd_lock:
self.pcd.points = o3d.utility.Vector3dVector(pcd_colortest[:, 0:3])
self.pcd.colors = calc_colors_from_reflectivity(pcd_colortest[:, 3])
mat = o3d.visualization.rendering.MaterialRecord()
mat.shader = 'defaultUnlit'
mat.point_size = 10
self.widget3d.scene.add_geometry(CLOUD_NAME, self.pcd, mat)
del mat
def update_cloud():
# clear old geometries
self.widget3d.scene.clear_geometry()
mat = o3d.visualization.rendering.MaterialRecord()
mat.shader = 'defaultUnlit'
mat.point_size = 10
# add the new cloud
with self.pcd_lock:
self.widget3d.scene.add_geometry(CLOUD_NAME, self.pcd, mat)
del mat
# count counter and make checks for displaying the counter
self.pcd_actualize_counter += 1
if self.pcd_actualize_counter < 100 or self.pcd_actualize_counter > 65500:
print(self.pcd_actualize_counter)
elif self.pcd_actualize_counter % 10000 == 0:
print(self.pcd_actualize_counter)
# _____ Thread Start _____
gui.Application.instance.post_to_main_thread(self.window, add_first_cloud)
# Thread Loop
while True:
update_open3d_pcd_colortest()
gui.Application.instance.post_to_main_thread(self.window, update_cloud)
def run(self):
# Start the update thread for ui
self.ui_update_thread.start()
# Start the Application
self.app.run()
if __name__ == '__main__':
faulthandler.enable()
# Start the Main UI thread
win = Open3DTest()
win.run()
Error message
Windows fatal exception: access violation
Thread 0x000046d4 (most recent call first): File "C:...\open3d_overflow_test.py", line 113 in ui_update_thread File "C:...\Lib\threading.py", line 1012 in run File "C:...\Lib\threading.py", line 1075 in _bootstrap_inner File "C:...\Lib\threading.py", line 1032 in _bootstrap
Thread 0x0000812c (most recent call first):
File "C:...\open3d_overflow_test.py", line 95 in update_cloud
File "C:...\open3d_overflow_test.py", line 120 in run
File "C:...\open3d_overflow_test.py", line 126 in
Expected behavior
The program should not crash.
Open3D, Python and System information
- Operating system: Windows 11 64-bit
- Python version: Python 3.12.9 / output from `import sys; print(sys.version)`
- Open3D version: output from python: `0.19.0`
- System architecture: x64
- Is this a remote workstation?: no
- How did you install Open3D?: pip
Additional information
No response