Hey folks, I’m using GLMakie to make some videos with contours, and it would be nice to be able to apply mirroring to a given axis (or two, in my case).
My data is all in one quadrant, and I could make an array four times as big and then copy into it, mirroring the data as needed, and then use contour!(bigarray)
. However, it seems like a waste since it will need to repeat all the work of identifying the iso-surface, which only takes up a small fraction of the array domain. Is there a way to reflect the contours themselves into the other quadrants? Paraview and Tecplot both have this feature and I use it all the time in visualization.
Would showing a video improve the interest a little?
1 Like
Hm, it is somewhat possible to copy an OpenGL object and render it a second time, and modify the uniforms to be flipped…
Sadly, I think the model matrix that does the flipping isn’t 100% implemented correctly for volume, so the flipping causes it to sample incorrectly from the volume:
using GLMakie
function rewrap(robj::GLMakie.RenderObject{Pre}) where {Pre}
GLMakie.ShaderAbstractions.switch_context!(robj.context)
GLMakie.RenderObject{Pre}(
robj.context,
copy(robj.uniforms),
robj.observables,
robj.vertexarray,
robj.prerenderfunction,
robj.postrenderfunction,
Observable(robj.visible),
false
)
end
function copy_plot!(screen::GLMakie.Screen, plot)
robj = screen.cache[objectid(plot)]
cpy = rewrap(robj)
screenid = screen.screen2scene[WeakRef(parent(plot))]
screen.cache2plot[cpy.id] = plot
push!(screen.renderlist, (0, screenid, cpy))
return cpy
end
GLMakie.activate!(float=true)
begin
N = 50
r = LinRange(-1, 1, N)
r2 = LinRange(0, 1, N)
cube = Float32[(x .^ 2 + y .^ 2 + z .^ 2) for x = r, y = r, z = r2]
fig, ax, pl = volume(cube, algorithm=:iso);
if isdefined(Main, :screen)
# messing with the internal renderlist will not clean up correctly, so we need to cleanup manually
screen.renderlist |> empty!
screen.cache2plot |> empty!
end
GLMakie.closeall()
screen = display(fig)
end
cpy = copy_plot!(scren, pl)
robj = scren.cache[objectid(pl)]
model = Makie.scalematrix(Vec3f(1, -1, -1)) * robj[:model][]
cpy.uniforms[:model] = model
cpy.uniforms[:modelinv] = inv(model)
But the correct flip (1, 1, -1)
doesn’t work -.-
1 Like