Open SamTov opened 2 years ago
We fixed a couple of memory leak issues after 0.14.1. I want to confirm, have you tried the latest development version of Open3D available here?
Yep, it still failed using '0.14.1+19635ef'
on MacOS with Python 3.8
The code snippet is high level and hard to track the issue. Could you please dig into your code base and see what might be the minimal reproducible example that is directly related to Open3D?
Yes I can do this, sorry I did not provide it previously. I have printed below how Open3D is used in the visualizer.
Here is the code for updating of a particle state, i.e. position and rotation
def _draw_particles(self, visualizer=None, initial: bool = False):
"""
Draw the particles on the visualizer.
Parameters
----------
initial : bool (default = True)
If true, no particles are removed.
Returns
-------
updates the information in the visualizer.
Notes
-----
TODO: Use of initial is a dirty fix. It can be removed when support for
transforming multiple geometry objects is added to open3d.
"""
if visualizer is None:
visualizer = self.vis
if initial:
for item in self.particles:
for particle in item.mesh_dict:
visualizer.add_geometry(particle, item.mesh_dict[particle])
else:
for item in self.particles:
for particle in item.mesh_dict:
visualizer.remove_geometry(particle)
visualizer.add_geometry(particle, item.mesh_dict[particle])
The mesh dict in this case is a dictionary full of mesh objects, e.g. spheres. These are Open3D TriangleMesh
objects.
The following method updates the particles in the visualizer window:
def _update_particles(self, visualizer=None, step: int = None):
"""
Update the positions of the particles.
Parameters
----------
step : int
Step to update to.
Returns
-------
Updates the positions of the particles in the box.
"""
if visualizer is None:
visualizer = self.vis
if step is None:
if self.counter == self.number_of_steps - 1:
self.counter = 0
else:
self.counter += 1
step = self.counter
for particle in self.particles:
particle.update_position_data(step)
self._draw_particles(visualizer=visualizer) # draw the particles.
visualizer.post_redraw() # re-draw the window.
Finally, the following two methods (one is just a thread opening linked to a button) uses a callback to run the simulation is the visualizer window:
def _continuous_trajectory(self, vis):
"""
Button command for running the simulation in the visualizer.
Parameters
----------
vis : visualizer
Object passed during the callback.
"""
threading.Thread(target=self._run_trajectory).start()
def _run_trajectory(self):
"""
Callback method for running the trajectory smoothly.
Returns
-------
Runs through the trajectory.
"""
while self.counter < self.number_of_steps:
time.sleep(1 / self.frame_rate)
o3d.visualization.gui.Application.instance.post_to_main_thread(
self.vis, self._update_particles
)
if self.interrupt == 1:
break
self.interrupt = 0
In terms of updating the position and rotation data of a mesh it is done in the following code:
def update_position_data(self, step: int):
"""
Update the positions of each particle.
Parameters
----------
step : int
Step to update to.
Returns
-------
Updates the position of the mesh in the mesh_dict
Notes
-----
TODO: Allow for no position data.
"""
for i, item in enumerate(self.mesh_dict):
self.mesh_dict[item].translate(self.position[step][i], relative=False)
if self.director is not None:
if step == 0:
current = self.director[-1][i]
matrix = rotation_matrix(current, self.director[step][i])
self.mesh_dict[item].rotate(matrix)
else:
current = self.director[step - 1][i]
matrix = rotation_matrix(current, self.director[step][i])
self.mesh_dict[item].rotate(matrix)
Please let me know if I can provide more information about any part of the code.
@theNded and @errissa have you have any ideas on this recently?
I encountered the same problem as you. Finally, I found that the system would crash after calling the function post_redraw many times. The post_redraw function may have some vulnerabilities. It may crash or not respond to mouse operations after multiple calls.
I encountered the same problem as you. Finally, I found that the system would crash after calling the function post_redraw many times. The post_redraw function may have some vulnerabilities. It may crash or not respond to mouse operations after multiple calls.
I am having similar issues with the post_redraw, is there anything on the issue or how to bypass the crashes? currently trying to debug and find the issue with gdb.
The code here will recreate the crashes: https://github.com/isl-org/Open3D/issues/5243
Unfortunately, I have not solved this problem. Two weeks have been delayed on this issue, resulting in the inability to realize animation. The asynchronous method can be used to refresh in a short time by using the python threading.Thread, and problems will occur again after several times. Or use the regular visualizer as open3d.visualization.Visualizer, as you reply in the issue 5245.
Hey, after how many calls does it crash approximately? The code I liked above can be called thousands of times until It crashes currently. The repo is https://github.com/zincware/ZnVis
open3d 0.16 is out and it seems like the crashes stopped accuring for me. try and check it out if it solves this issue @SamTov
I still get a segmentation fault with the new version. The issue persists when I use a smaller number of spheres for a larger number of updates or more spheres for less updates so I guess it is really the post_redraw operation being called many times still.
I can confirm that the issue still persists. It crashes on exactly the 65520th call to add geometry. Basic example code to reproduce the crash:
import open3d as o3d
import open3d.visualization.gui as gui
import open3d.visualization.rendering as rendering
import time
import threading
class Window3D:
def __init__(self):
self.window = gui.Application.instance.create_window("Test", 1800, 700)
self.window.set_on_close(self._on_close)
self.widget3d = gui.SceneWidget()
self.widget3d.scene = rendering.Open3DScene(self.window.renderer)
self.window.add_child(self.widget3d)
self.lit = rendering.MaterialRecord()
self.lit.shader = "defaultUnlit"
self.elems = []
for i in range(20):
wall = o3d.geometry.TriangleMesh.create_box(width=0.01, height=0.01, depth=0.01, create_uv_map=False, map_texture_to_each_face=False)
wall.translate([i*0.1, 0, 0])
self.elems.append(wall)
self.widget3d.scene.add_geometry("wall" + str(i), wall, self.lit)
bounds = self.widget3d.scene.bounding_box
self.widget3d.setup_camera(60.0, bounds, bounds.get_center())
self.counter = 0;
self.is_done = False
threading.Thread(target=self._update_thread).start()
def _on_close(self):
self.is_done = True
return True
def _update_thread(self):
while not self.is_done:
time.sleep(0.01)
def update():
self.counter +=1
print(self.counter)
print("remove_geometry")
for i in range(len(self.elems)):
# print("remove_geometry")
self.widget3d.scene.remove_geometry('wall' + str(i))
print("add_geometry")
for i in range(len(self.elems)):
self.widget3d.scene.add_geometry('wall' + str(i), self.elems[i], self.lit)
if not self.is_done:
gui.Application.instance.post_to_main_thread(self.window, update)
def main():
app = o3d.visualization.gui.Application.instance
app.initialize()
win = Window3D()
app.run()
if __name__ == "__main__":
main()
Having the same issue as @jen-co . I am trying to implement SLAM pipeline with 1.16.0 and drawing camera frustum (line sets) at video frame rate but always fails with this segmentation fault at some point.
@muskie82 I don' think there is a simple solution to this particular bug on the Python level as it is usually a Segmentation fault. This would suggest one needs to look into the c++ side to resolve it.
Same issue here. Interesting thing is that my application running in an event loop by iteratively calling instance.run_one_tick() crashes as well with a segfault after a certain amount of calls. post_redraw() is not actively called. Maybe run_one_tick() calls this function or parts of it as well.
did the issue got fixed in 0.17?
@MeyerBuaharonAssuming the 0.17 version is on PyPi not from my side. I have however moved my software over to combining all meshes into one large mesh which means I delay this fault for many time steps which is a temporary workable solution.
I'm using the v0.17 release in C++ and I seem to be having the same problem. Does anyone know if the issue is fixed in the current latest commit on the master branch?
+1, similar issue here with the latest 0.17
release too.
The issue persists in v0.18
Checklist
master
branch).Describe the issue
I wrote a package for visualising particle simulations/trajectories built on top of Open3D. Code is available here. However, during the visualisation, if many frames (~>1000) or a larger number of particles (~>300) are being visualised, the program will eventually segfault.
It seems that there is some trade-off between number of particles and length of the simulation run and therefore I thought it could be associated with the update of the mesh position at each time step. I do so as follows:
It seem that for a large number of these updates there are memory issues. I have checked the raw memory usage and found that there is NO proliferation of memory use before the crash, i.e, there is plenty of memory left on the machine before the program segfaults and crashes. The memory usage is in fact very constant after initialisation as no new data is added after this point.
Steps to reproduce the bug
Error message
In the terminal one receives the standard: ``bash zsh: segmentation fault
Expected behavior
It should be able to run for as many meshes and as many time steps as required. Seeing as the memory use in constant, I do not see why it should fail at any point.
Open3D, Python and System information
Additional information
No response