I am currently working on the next release of an interactive 3D display for neutrino events and the main new feature is the ability to interact with the scene from the Julia REPL. Modifying existing objects (colouring and size of the mesh scatter elements which represent PMT hits) works really nicely and in real-time (for tens of thousands of objects) but I have difficulties with deleting objects from a scene.
If I call delete!(scene, the_object)
, it successfully removes it – as far as I can tell. I think it does because calling it again complains that it’s “not in scene”. So far so good. The problem is that it’s still displayed
I do not have a MWE yet but I assume that I am not using the API correctly.
I currently have a simple Dict
in the main RBA
struct to store the references to all the plots, so that I can manipulate them when the main loop is running.
To quickly summarise how my scene is created, filled and modified:
This is the main struct to hold things together:
@kwdef mutable struct RBA
scene::Scene = Scene(backgroundcolor=RGBf(0.9))
cam::Makie.Camera3D = cam3d!(scene, rotation_center = :lookat)
# ...
_plots::Dict{String, Any} = Dict()
end
And I fill it with a bunch of stuff (most of them are Lines
and MeshScatter
s) like this:
rba._plots["Detector"] = meshscatter!(
scene,
[m.pos for m ∈ basemodules],
marker=Rect3f(Vec3f(-0.5), Vec3f(0.5)),
markersize=5,
color=:black
)
The references to the plot objects are stored In the rba._plots
dictionary.
And the main loop which is essentially (simplified):
function start_eventloop(rba)
screen = display(GLMakie.Screen(start_renderloop=false, focus_on_show=true, title="RainbowAlga"), rba.scene)
glw = screen.glscreen
GLMakie.GLFW.SetWindowPos(glw, displayparams.pos...)
GLMakie.GLFW.SetWindowSize(glw, displayparams.size...)
while isopen(screen)
frame_start = time()
rotation_enabled() && rotate_cam!(rba.scene, Vec3f(0, 0.001, 0))
GLMakie.pollevents(screen)
GLMakie.render_frame(screen)
GLMakie.GLFW.SwapBuffers(GLMakie.to_native(screen))
yield()
Δt = time() - frame_start
sleep_time = 1.0/simparams.fps - Δt
if sleep_time > 0
sleep(sleep_time)
end
end
GLMakie.destroy!(screen)
end
So now if I want to delete the e.g. the detector base modules, which are the small black boxes at the bottom of each string, I call (here you can see that the second call suggests that it worked):
julia> delete!(rba.scene, rba._plots["Detector"])
julia> delete!(rba.scene, rba._plots["Detector"])
ERROR: MakieCore.MeshScatter{Tuple{Vector{GeometryBasics.Point{3, Float64}}}} not in scene!
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] delete!(scene::Makie.Scene, plot::MakieCore.MeshScatter{Tuple{Vector{GeometryBasics.Point{3, Float64}}}})
@ Makie ~/.julia/packages/Makie/We6MY/src/scenes.jl:489
[3] top-level scope
@ REPL[4]:1
julia>
however, the elements are still displayed.
No matter what I delete from the scene, they are still displayed. Any idea?