various fixes

This commit is contained in:
SimonDanisch 2016-10-14 00:39:54 +02:00
parent 8c6c81e8d0
commit 456602b79f

View File

@ -178,24 +178,23 @@ const _gl_marker_map = KW(
:x => 'x', :x => 'x',
) )
function gl_marker(shape, size) function gl_marker(shape)
shape shape
end end
function gl_marker(shape::Shape, size::FixedSizeArrays.Vec{2,Float32}) function gl_marker(shape::Shape)
points = Point2f0[Vec{2,Float32}(p)*10f0 for p in zip(shape.x, shape.y)] points = Point2f0[Vec{2,Float32}(p)*10f0 for p in zip(shape.x, shape.y)]
GeometryTypes.GLNormalMesh(points) GeometryTypes.GLNormalMesh(points)
end end
# create a marker/shape type # create a marker/shape type
function gl_marker(shape::Symbol, msize) function gl_marker(shape::Symbol)
isa(msize, Array) && (msize = first(msize)) # size doesn't really matter now
if shape == :rect if shape == :rect
GeometryTypes.HyperRectangle(Vec{2, Float32}(0), msize) GeometryTypes.HyperRectangle(Vec2f0(0), Vec2f0(1))
elseif shape == :circle || shape == :none elseif shape == :circle || shape == :none
GeometryTypes.HyperSphere(Point{2, Float32}(0), maximum(msize)) GeometryTypes.HyperSphere(Point2f0(0), 1f0)
elseif haskey(_gl_marker_map, shape) elseif haskey(_gl_marker_map, shape)
_gl_marker_map[shape] _gl_marker_map[shape]
elseif haskey(_shapes, shape) elseif haskey(_shapes, shape)
gl_marker(_shapes[shape], msize) gl_marker(_shapes[shape])
else else
error("Shape $shape not supported by GLVisualize") error("Shape $shape not supported by GLVisualize")
end end
@ -214,6 +213,14 @@ end
function extract_marker(d, kw_args) function extract_marker(d, kw_args)
dim = Plots.is3d(d) ? 3 : 2 dim = Plots.is3d(d) ? 3 : 2
scaling = dim == 3 ? 0.003 : 2 scaling = dim == 3 ? 0.003 : 2
if haskey(d, :markershape)
shape = d[:markershape]
shape = gl_marker(shape)
if shape != :none
kw_args[:primitive] = shape
end
end
dim = isa(kw_args[:primitive], GLVisualize.Sprites) ? 2 : 3
if haskey(d, :markersize) if haskey(d, :markersize)
msize = d[:markersize] msize = d[:markersize]
if isa(msize, AbstractArray) if isa(msize, AbstractArray)
@ -222,13 +229,7 @@ function extract_marker(d, kw_args)
kw_args[:scale] = GeometryTypes.Vec{dim, Float32}(msize*scaling) kw_args[:scale] = GeometryTypes.Vec{dim, Float32}(msize*scaling)
end end
end end
if haskey(d, :markershape)
shape = d[:markershape]
shape = gl_marker(shape, kw_args[:scale])
if shape != :none
kw_args[:primitive] = shape
end
end
# get the color # get the color
key = :markercolor key = :markercolor
haskey(d, key) || return haskey(d, key) || return
@ -425,7 +426,7 @@ function hover(to_hover, to_display, window)
area = map(window.inputs[:mouseposition]) do mp area = map(window.inputs[:mouseposition]) do mp
SimpleRectangle{Int}(round(Int, mp+10)..., 100, 70) SimpleRectangle{Int}(round(Int, mp+10)..., 100, 70)
end end
background = visualize((GLVisualize.ROUNDED_RECTANGLE, Point2f0[0]), background = visualize((GLVisualize.RECTANGLE, Point2f0[0]),
color=RGBA{Float32}(0,0,0,0), scale=Vec2f0(100, 70), offset=Vec2f0(0), color=RGBA{Float32}(0,0,0,0), scale=Vec2f0(100, 70), offset=Vec2f0(0),
stroke_color=RGBA{Float32}(0,0,0,0.4), stroke_color=RGBA{Float32}(0,0,0,0.4),
stroke_width=-1.0f0 stroke_width=-1.0f0
@ -478,7 +479,7 @@ end
function extract_font(font, kw_args) function extract_font(font, kw_args)
kw_args[:family] = font.family kw_args[:family] = font.family
kw_args[:relative_scale] = font.pointsize*1.5 ./ GLVisualize.glyph_scale!('X') kw_args[:relative_scale] = font.pointsize ./ GLVisualize.glyph_scale!('X')
kw_args[:color] = gl_color(font.color) kw_args[:color] = gl_color(font.color)
end end
@ -518,7 +519,11 @@ function extract_c(d, kw_args, sym)
kw_args[:color] = nothing kw_args[:color] = nothing
kw_args[:color_map] = nothing kw_args[:color_map] = nothing
kw_args[:color_norm] = nothing kw_args[:color_norm] = nothing
if isa(c, AbstractVector) if (
isa(c, AbstractVector) &&
((haskey(d, :marker_z) && d[:marker_z] != nothing) ||
(haskey(d, :line_z) && d[:line_z] != nothing))
)
extract_colornorm(d, kw_args) extract_colornorm(d, kw_args)
kw_args[:color_map] = c kw_args[:color_map] = c
else else
@ -590,7 +595,7 @@ function draw_ticks(axis, ticks, align, move, isx, lims, model, text = "", posit
xs, ys = m[1,1], m[2,2] xs, ys = m[1,1], m[2,2]
rscale = rscale2 ./ Vec2f0(xs, ys) rscale = rscale2 ./ Vec2f0(xs, ys)
atlas = GLVisualize.get_texture_atlas() atlas = GLVisualize.get_texture_atlas()
font = GLVisualize.DEFAULT_FONT_FACE font = GLVisualize.defaultfont()
if !(ticks in (nothing, false)) if !(ticks in (nothing, false))
# x labels # x labels
flip = axis[:flip] flip = axis[:flip]
@ -616,7 +621,7 @@ function text(position, text, kw_args)
text_align = alignment2num(text.font) text_align = alignment2num(text.font)
startpos = Vec2f0(position) startpos = Vec2f0(position)
atlas = GLVisualize.get_texture_atlas() atlas = GLVisualize.get_texture_atlas()
font = GLVisualize.DEFAULT_FONT_FACE font = GLVisualize.defaultfont()
rscale = kw_args[:relative_scale] rscale = kw_args[:relative_scale]
m = Reactive.value(kw_args[:model]) m = Reactive.value(kw_args[:model])
position = GLVisualize.calc_position(text.str, startpos, rscale, font, atlas) position = GLVisualize.calc_position(text.str, startpos, rscale, font, atlas)
@ -899,8 +904,9 @@ function _display(plt::Plot{GLVisualizeBackend})
empty_screen!(screen) empty_screen!(screen)
sw, sh = plt[:size] sw, sh = plt[:size]
sw, sh = sw*px, sh*px sw, sh = sw*px, sh*px
resize!(screen, plt[:size]...)
# TODO: use plt.subplots... plt.spmap can't be trusted # TODO: use plt.subplots... plt.spmap can't be trusted
for (name, sp) in plt.spmap for sp in plt.subplots
_3d = Plots.is3d(sp) _3d = Plots.is3d(sp)
# camera = :perspective # camera = :perspective
# initialize the sub-screen for this subplot # initialize the sub-screen for this subplot
@ -912,7 +918,7 @@ function _display(plt::Plot{GLVisualizeBackend})
end end
c = plt[:background_color_outside] c = plt[:background_color_outside]
sp_screen = GLVisualize.Screen( sp_screen = GLVisualize.Screen(
screen, name = name, color = c, screen, color = c,
area = sub_area area = sub_area
) )
cam = get!(sp_screen.cameras, :perspective) do cam = get!(sp_screen.cameras, :perspective) do
@ -1048,7 +1054,7 @@ function _display(plt::Plot{GLVisualizeBackend})
hover(vis, d[:hover], sp_screen) hover(vis, d[:hover], sp_screen)
end end
if isdefined(:GLPlot) && isdefined(Main.GLPlot, :(register_plot!)) if isdefined(:GLPlot) && isdefined(Main.GLPlot, :(register_plot!))
del_signal = Main.GLPlot.register_plot!(vis, sp_screen) del_signal = Main.GLPlot.register_plot!(vis, sp_screen, create_gizmo=false)
append!(_glplot_deletes, del_signal) append!(_glplot_deletes, del_signal)
end end
end end
@ -1072,7 +1078,7 @@ function _show(io::IO, ::MIME"image/png", plt::Plot{GLVisualizeBackend})
GLWindow.render_frame(plt.o) GLWindow.render_frame(plt.o)
GLWindow.swapbuffers(plt.o) GLWindow.swapbuffers(plt.o)
buff = GLWindow.screenbuffer(plt.o) buff = GLWindow.screenbuffer(plt.o)
png = Images.Image(buff, png = Images.Image(map(RGB{U8}, buff),
colorspace = "sRGB", colorspace = "sRGB",
spatialorder = ["y", "x"] spatialorder = ["y", "x"]
) )
@ -1136,13 +1142,19 @@ tovec2(x::FixedSizeArrays.Vec{2, Float32}) = x
tovec2(x::AbstractVector) = map(tovec2, x) tovec2(x::AbstractVector) = map(tovec2, x)
tovec2(x::FixedSizeArrays.Vec) = Vec2f0(x[1], x[2]) tovec2(x::FixedSizeArrays.Vec) = Vec2f0(x[1], x[2])
tovec3(x) = x
tovec3(x::FixedSizeArrays.Vec{3}) = Vec3f0(x)
tovec3(x::AbstractVector) = map(tovec3, x)
tovec3(x::FixedSizeArrays.Vec{2}) = Vec3f0(x[1], x[2], 1)
function gl_scatter(points, kw_args) function gl_scatter(points, kw_args)
prim = get(kw_args, :primitive, GeometryTypes.Circle) prim = get(kw_args, :primitive, GeometryTypes.Circle)
if isa(prim, GLNormalMesh) if isa(prim, GLNormalMesh)
kw_args[:scale] = map(kw_args[:model]) do m if haskey(kw_args, :model)
s = m[1,1], m[2,2], m[3,3] kw_args[:scale] = GLAbstraction.const_lift(kw_args[:model], kw_args[:scale]) do m, sc
1f0./Vec3f0(s) s = m[1,1], m[2,2], m[3,3]
tovec3(sc).*(1f0./Vec3f0(s))
end
end end
else # 2D prim else # 2D prim
kw_args[:scale] = tovec2(kw_args[:scale]) kw_args[:scale] = tovec2(kw_args[:scale])
@ -1234,6 +1246,7 @@ function gl_contour(x,y,z, kw_args)
kw_args[:color] = colors kw_args[:color] = colors
kw_args[:color_map] = nothing kw_args[:color_map] = nothing
kw_args[:color_norm] = nothing kw_args[:color_norm] = nothing
kw_args[:intensity] = nothing
return visualize(result, Style(:lines),kw_args) return visualize(result, Style(:lines),kw_args)
end end
end end
@ -1272,8 +1285,40 @@ function text_plot(text, alignment, kw_args)
view(obj, img.screen, camera=:orthographic_pixel) view(obj, img.screen, camera=:orthographic_pixel)
end end
"""
Ugh, so much special casing (╯°□°)╯︵ ┻━┻
"""
function label_scatter(d, w, ho)
kw = KW()
extract_stroke(d, kw)
extract_marker(d, kw)
kw[:scale] = Vec2f0(w/2)
kw[:offset] = Vec2f0(-w/4)
if haskey(kw, :intensity)
cmap = kw[:color_map]
norm = kw[:color_norm]
kw[:color] = GLVisualize.color_lookup(cmap, kw[:intensity][1], norm)
delete!(kw, :intensity)
delete!(kw, :color_map)
delete!(kw, :color_norm)
else
color = get(kw, :color, nothing)
kw[:color] = isa(color, Array) ? first(color) : color
end
p = get(kw, :primitive, GeometryTypes.Circle)
if isa(p, GLNormalMesh)
bb = GeometryTypes.AABB{Float32}(GeometryTypes.vertices(p))
bbw = GeometryTypes.widths(bb)
mini = minimum(bb)
m = GLAbstraction.translationmatrix(-mini)
m *= GLAbstraction.scalematrix(1f0./bbw)
#m *= GLAbstraction.translationmatrix(-Vec3f0(0.5))
kw[:primitive] = m * p
kw[:scale] = Vec3f0(w/2)
delete!(kw, :offset)
end
GL.gl_scatter(Point2f0[(w/2, ho)], kw)
end
function make_label(sp, series, i) function make_label(sp, series, i)
GL = Plots GL = Plots
w, gap, ho = 20f0, 5f0, 5 w, gap, ho = 20f0, 5f0, 5
@ -1288,44 +1333,15 @@ function make_label(sp, series, i)
kw[:thickness] = 15f0 kw[:thickness] = 15f0
append!(result, GL.gl_lines(points, kw)) append!(result, GL.gl_lines(points, kw))
if d[:markershape] != :none if d[:markershape] != :none
kw = KW() push!(result, label_scatter(d, w, ho))
extract_stroke(d, kw)
extract_marker(d, kw)
kw[:scale] = Vec2f0(w/2)
kw[:offset] = Vec2f0(-w/4)
if haskey(kw, :intensity)
cmap = kw[:color_map]
norm = kw[:color_norm]
kw[:color] = GLVisualize.color_lookup(cmap, kw[:intensity][1], norm)
delete!(kw, :intensity)
delete!(kw, :color_map)
delete!(kw, :color_norm)
else
color = get(kw, :color, nothing)
kw[:color] = isa(color, Array) ? first(color) : color
end
push!(result, GL.gl_scatter(Point2f0[(w/2, ho)], kw))
end end
elseif st in (:scatter, :scatter3d) #|| d[:markershape] != :none elseif st in (:scatter, :scatter3d) #|| d[:markershape] != :none
kw = KW() push!(result, label_scatter(d, w, ho))
extract_stroke(d, kw)
extract_marker(d, kw)
kw[:scale] = Vec2f0(w/2)
kw[:offset] = Vec2f0(-w/4)
if haskey(kw, :intensity)
cmap = kw[:color_map]
norm = kw[:color_norm]
kw[:color] = GLVisualize.color_lookup(cmap, kw[:intensity][1], norm)
delete!(kw, :intensity)
delete!(kw, :color_map)
delete!(kw, :color_norm)
else
color = get(kw, :color, nothing)
kw[:color] = isa(color, Array) ? first(color) : color
end
push!(result, GL.gl_scatter(Point2f0[(w/2, ho)], kw))
else else
extract_c(d, kw_args, :fill) extract_c(d, kw_args, :fill)
if isa(kw_args[:color], AbstractVector)
kw_args[:color] = first(kw_args[:color])
end
push!(result, visualize( push!(result, visualize(
GeometryTypes.SimpleRectangle(-w/2, ho-w/4, w/2, w/2), GeometryTypes.SimpleRectangle(-w/2, ho-w/4, w/2, w/2),
Style(:default), kw_args Style(:default), kw_args
@ -1341,7 +1357,7 @@ function make_label(sp, series, i)
ft = sp[:legendfont] ft = sp[:legendfont]
font = Plots.Font(ft.family, ft.pointsize, :left, :bottom, 0.0, color) font = Plots.Font(ft.family, ft.pointsize, :left, :bottom, 0.0, color)
xy = Point2f0(w+gap, 0.0) xy = Point2f0(w+gap, 0.0)
kw = Dict(:model => text_model(font, xy), :scale_primitive=>true) kw = Dict(:model => text_model(font, xy), :scale_primitive=>false)
extract_font(font, kw) extract_font(font, kw)
t = PlotText(labeltext, font) t = PlotText(labeltext, font)
push!(result, text(xy, t, kw)) push!(result, text(xy, t, kw))
@ -1361,21 +1377,23 @@ function generate_legend(sp, screen, model_m)
if isempty(legend) if isempty(legend)
return return
end end
list = visualize(legend) list = visualize(legend, gap=Vec3f0(0,5,0))
bb = Reactive.value(GLAbstraction.boundingbox(list)) bb = GLAbstraction._boundingbox(list)
wx,wy,_ = GeometryTypes.widths(bb) wx,wy,_ = GeometryTypes.widths(bb)
xmin, _ = Plots.axis_limits(sp[:xaxis]) xmin, _ = Plots.axis_limits(sp[:xaxis])
_, ymax = Plots.axis_limits(sp[:yaxis]) _, ymax = Plots.axis_limits(sp[:yaxis])
area = map(model_m) do m area = map(model_m) do m
@show m
p = m * GeometryTypes.Vec4f0(xmin, ymax, 0, 1) p = m * GeometryTypes.Vec4f0(xmin, ymax, 0, 1)
h = round(Int, wy)+20
w = round(Int, 2*wy) w = round(Int, wx)+20
x,y = round(Int, p[1]) + 20, round(Int, p[2]-w)-40 x,y = round(Int, p[1])+30, round(Int, p[2]-h)-30
GeometryTypes.SimpleRectangle(x, y, round(Int, wx)+20, w+20) GeometryTypes.SimpleRectangle(x, y, w, h)
end end
sscren = GLWindow.Screen(screen, area=area) sscren = GLWindow.Screen(
GLAbstraction._translate!(list, Vec3f0(10,10,0)) screen, area=area,
color=sp[:background_color_legend]
)
GLAbstraction.translate!(list, Vec3f0(10,10,0))
GLVisualize._view(list, sscren, camera=:fixed_pixel) GLVisualize._view(list, sscren, camera=:fixed_pixel)
end end
return return