add rotations and move plotting commands to module

This commit is contained in:
Simon 2016-09-09 11:28:49 +02:00
parent 2c1f58e773
commit dbc12bb9ba

View File

@ -11,7 +11,7 @@ TODO
=#
const _glvisualize_attr = merge_with_base_supported([
#:annotations,
:annotations,
:background_color_legend, :background_color_inside, :background_color_outside,
:foreground_color_grid, :foreground_color_legend, :foreground_color_title,
:foreground_color_axis, :foreground_color_border, :foreground_color_guide, :foreground_color_text,
@ -51,7 +51,13 @@ const _glvisualize_seriestype = [
const _glvisualize_style = [:auto, :solid, :dash, :dot, :dashdot]
const _glvisualize_marker = _allMarkers
const _glvisualize_scale = [:identity, :ln, :log2, :log10]
is_marker_supported(::GLVisualizeBackend, shape::Shape) = true
function _is_marker_supported(::GLVisualizeBackend, shape)
(
isa(shape, GLVisualize.AllPrimitives) ||
GLVisualize.isa_image(shape)
)
end
# --------------------------------------------------------------------------------------
@ -64,6 +70,8 @@ function _initialize_backend(::GLVisualizeBackend; kw...)
import Reactive: Signal
import GLAbstraction: Style
import GLVisualize: visualize
import Plots.GL
Plots.slice_arg(img::Images.AbstractImage, idx) = img
end
end
@ -76,10 +84,16 @@ function add_backend(::GLVisualizeBackend)
end
# TODO: remove this section when the tagged versions catch up
for pkg in ["GLWindow", "GLAbstraction", "GLVisualize", "GeometryTypes", "FixedSizeArrays"]
for pkg in [
"GLWindow", "GLAbstraction",
"GLVisualize", "GeometryTypes", "FixedSizeArrays",
"FreeType", "GLPlot"
]
warn("Running Pkg.checkout(\"$pkg\"). To revert, run Pkg.free(\"$pkg\")")
Pkg.checkout(pkg)
end
warn("Running Pkg.checkout(\"Reactive\", \"sd/betterstop\"). To revert, run Pkg.free(\"Reactive\")")
Pkg.checkout("Reactive", "sd/betterstop")
end
# ---------------------------------------------------------------------------
@ -159,6 +173,9 @@ const _gl_marker_map = KW(
:x => 'x',
)
function gl_marker(shape, size)
shape
end
function gl_marker(shape::Shape, size::FixedSizeArrays.Vec{2,Float32})
points = Point2f0[Vec{2,Float32}(p)*10f0 for p in zip(shape.x, shape.y)]
GeometryTypes.GLNormalMesh(points)
@ -207,12 +224,23 @@ function extract_marker(d, kw_args)
kw_args[:primitive] = shape
end
end
extract_c(d, kw_args, :marker)
# get the color
key = :markercolor
haskey(d, key) || return
c = gl_color(d[key])
if isa(c, AbstractVector) && d[:marker_z] != nothing
extract_colornorm(d, kw_args)
kw_args[:color] = nothing
kw_args[:color_map] = c
kw_args[:intensity] = convert(Vector{Float32}, d[:marker_z])
else
kw_args[:color] = c
end
key = :markerstrokecolor
haskey(d, key) || return
c = gl_color(d[key])
if c != nothing
if !isa(c, Colorant)
if !(isa(c, Colorant) || (isa(c, Vector) && eltype(c) <: Colorant))
error("Stroke Color not supported: $c")
end
kw_args[:stroke_color] = c
@ -392,6 +420,11 @@ function hover(to_hover, to_display, window)
area = map(window.inputs[:mouseposition]) do mp
SimpleRectangle{Int}(round(Int, mp+10)..., 100, 70)
end
background = visualize((GLVisualize.ROUNDED_RECTANGLE, Point2f0[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_width=-1.0f0
)
mh = GLWindow.mouse2id(window)
popup = GLWindow.Screen(window, area=area, hidden=true)
cam = get!(popup.cameras, :perspective) do
@ -404,6 +437,7 @@ function hover(to_hover, to_display, window)
Reactive.preserve(map(mh) do mh
popup.hidden = !(mh.id == to_hover.id)
end)
map(enumerate(to_display)) do id
i,d = id
robj = visualize(d)
@ -418,7 +452,13 @@ function hover(to_hover, to_display, window)
cam.projectiontype.value = GLVisualize.ORTHOGRAPHIC
end
GLVisualize._view(robj, popup, camera=cam)
GLAbstraction.center!(popup, :perspective)
GLVisualize._view(background, popup, camera=:fixed_pixel)
bb = GLAbstraction.boundingbox(robj).value
mini = minimum(bb)
w = GeometryTypes.widths(bb)
wborder = w*0.08f0 #8 percent border
bb = GeometryTypes.AABB{Float32}(mini-wborder, w+2f0*wborder)
GLAbstraction.center!(cam, bb)
end
end)
end
@ -509,7 +549,7 @@ function draw_grid_lines(sp, grid_segs, thickness, style, model, color)
:linecolor => color
)
Plots.extract_linestyle(d, kw_args)
Plots.lines(map(Point2f0, grid_segs.pts), kw_args)
GL.lines(map(Point2f0, grid_segs.pts), kw_args)
end
function align_offset(startpos, lastpos, atlas, rscale, font, align)
@ -572,31 +612,29 @@ function text(position, text, kw_args)
startpos = Vec2f0(position)
atlas = GLVisualize.get_texture_atlas()
font = GLVisualize.DEFAULT_FONT_FACE
rscale2 = kw_args[:relative_scale]
rscale = kw_args[:relative_scale]
m = Reactive.value(kw_args[:model])
xs, ys = m[1,1], m[2,2]
rscale = rscale2 ./ Vec2f0(xs, ys)
position = GLVisualize.calc_position(text.str, startpos, rscale, font, atlas)
offset = GLVisualize.calc_offset(text.str, rscale2, font, atlas)
offset = GLVisualize.calc_offset(text.str, rscale, font, atlas)
alignoff = align_offset(startpos, last(position), atlas, rscale, font, text_align)
map!(position) do pos
pos .+ alignoff
end
kw_args[:position] = position
kw_args[:offset] = offset
kw_args[:scale_primitive] = false
kw_args[:scale_primitive] = true
visualize(text.str, Style(:default), kw_args)
end
function text_model(font)
# if font.rotation != 0.0
# rot = Float32(deg2rad(font.rotation))
# rotm = GLAbstraction.rotationmatrix_z(rot)
# GLAbstraction.translationmatrix(pivot)*rotm*GLAbstraction.translationmatrix(-pivot)
# return
# else
function text_model(font, pivot)
pv = GeometryTypes.Vec3f0(pivot[1], pivot[2], 0)
if font.rotation != 0.0
rot = Float32(deg2rad(font.rotation))
rotm = GLAbstraction.rotationmatrix_z(rot)
return GLAbstraction.translationmatrix(pv)*rotm*GLAbstraction.translationmatrix(-pv)
else
eye(GeometryTypes.Mat4f0)
# end
end
end
function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, area)
xticks, yticks, spine_segs, grid_segs = Plots.axis_drawing_info(sp)
@ -631,18 +669,18 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are
area_w = GeometryTypes.widths(area)
if sp[:title] != ""
tf = sp[:titlefont]; color = gl_color(sp[:foreground_color_title])
font = Plots.Font(tf.family, tf.pointsize, :hcenter, :top, 0.0, color)
kw = Dict{Symbol, Any}(:model => text_model(font))
extract_font(font, kw)
font = Plots.Font(tf.family, tf.pointsize, :hcenter, :top, tf.rotation, color)
xy = Point2f0(area.w/2, area_w[2])
kw = Dict(:model => text_model(font, xy), :scale_primitive=>true)
extract_font(font, kw)
t = PlotText(sp[:title], font)
push!(axis_vis, text(xy, t, kw))
end
if xaxis[:guide] != ""
tf = xaxis[:guidefont]; color = gl_color(xaxis[:foreground_color_guide])
font = Plots.Font(tf.family, tf.pointsize, :hcenter, :bottom, 0.0, color)
kw = Dict{Symbol, Any}(:model => text_model(font))
xy = Point2f0(area.w/2, 0)
font = Plots.Font(tf.family, tf.pointsize, :hcenter, :bottom, tf.rotation, color)
kw = Dict(:model => text_model(font, xy), :scale_primitive=>true)
t = PlotText(xaxis[:guide], font)
extract_font(font, kw)
push!(axis_vis, text(xy, t, kw))
@ -650,9 +688,9 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are
if yaxis[:guide] != ""
tf = yaxis[:guidefont]; color = gl_color(yaxis[:foreground_color_guide])
font = Plots.Font(tf.family, tf.pointsize, :hcenter, :top, 0.0, color)
kw = Dict{Symbol, Any}(:model => text_model(font))
font = Plots.Font(tf.family, tf.pointsize, :hcenter, :top, 90f0, color)
xy = Point2f0(0, area.h/2)
kw = Dict(:model => text_model(font, xy), :scale_primitive=>true)
t = PlotText(yaxis[:guide], font)
extract_font(font, kw)
push!(axis_vis, text(xy, t, kw))
@ -847,7 +885,6 @@ end
# ----------------------------------------------------------------
function _display(plt::Plot{GLVisualizeBackend})
GL = Plots
screen = plt.o
empty_screen!(screen)
sw, sh = plt[:size]
@ -881,9 +918,10 @@ function _display(plt::Plot{GLVisualizeBackend})
model_m = map(Plots.to_modelmatrix, screen.area, sub_area, Signal(rel_plotarea), Signal(sp))
for ann in sp[:annotations]
x, y, plot_text = ann
txt_args = Dict{Symbol, Any}(:model => model_m)
txt_args = Dict{Symbol, Any}(:model => eye(GeometryTypes.Mat4f0))
x, y, _1, _1 = Reactive.value(model_m) * Vec{4,Float32}(x, y, 0, 1)
extract_font(plot_text.font, txt_args)
t = GL.text(Point2f0(x, y), plot_text, txt_args)
t = text(Point2f0(x, y), plot_text, txt_args)
GLVisualize._view(t, sp_screen, camera=cam)
end
# loop over the series and add them to the subplot
@ -894,7 +932,7 @@ function _display(plt::Plot{GLVisualizeBackend})
Reactive.run_till_now() # make sure Reactive.push! arrives
GLAbstraction.center!(cam,
GeometryTypes.AABB(
Vec3f0(0), Vec3f0(GeometryTypes.widths(sp_screen)..., 1)
Vec3f0(-10), Vec3f0((GeometryTypes.widths(sp_screen)+20f0)..., 1)
)
)
else
@ -1024,6 +1062,18 @@ function _show(io::IO, ::MIME"image/png", plt::Plot{GLVisualizeBackend})
FileIO.save(FileIO.Stream(FileIO.DataFormat{:PNG}, io), png)
end
module GL
import GLVisualize, GeometryTypes, Reactive, GLAbstraction, GLWindow, Contour
import GeometryTypes: Point2f0, Point3f0, Vec2f0, Vec3f0, GLNormalMesh, SimpleRectangle
import FileIO, Images, FixedSizeArrays
export GLVisualize
import Reactive: Signal
import GLAbstraction: Style
import GLVisualize: visualize
using Colors
using ..Plots
function image(img, kw_args)
rect = kw_args[:primitive]
@ -1043,6 +1093,7 @@ function handle_segment{P}(lines, line_segments, points::Vector{P}, segment)
push!(lines, P(NaN))
end
end
function lines(points, kw_args)
result = []
isempty(points) && return result
@ -1076,6 +1127,10 @@ function shape(d, kw_args)
end
result
end
tovec2(x::FixedSizeArrays.Vec{2, Float32}) = x
tovec2(x::AbstractVector) = map(tovec2, x)
tovec2(x::FixedSizeArrays.Vec) = Vec2f0(x[1], x[2])
function scatter(points, kw_args)
prim = get(kw_args, :primitive, GeometryTypes.Circle)
@ -1084,8 +1139,17 @@ function scatter(points, kw_args)
s = m[1,1], m[2,2], m[3,3]
1f0./Vec3f0(s)
end
else # 2D prim
kw_args[:scale] = tovec2(kw_args[:scale])
end
if haskey(kw_args, :stroke_width)
s = Reactive.value(kw_args[:scale])
sw = kw_args[:stroke_width]
if sw*5 > cycle(Reactive.value(s), 1)[1] # restrict marker stroke to 1/10th of scale (and handle arrays of scales)
kw_args[:stroke_width] = s[1]/5f0
end
end
kw_args[:scale_primitive] = false
visualize((prim, points), Style(:default), kw_args)
end
@ -1172,7 +1236,7 @@ end
function heatmap(x,y,z, kw_args)
get!(kw_args, :color_norm, Vec2f0(extrema(z)))
get!(kw_args, :color_map, make_gradient(cgrad()))
get!(kw_args, :color_map, Plots.make_gradient(cgrad()))
delete!(kw_args, :intensity)
I = GLVisualize.Intensity{1, Float32}
heatmap = I[z[j,i] for i=1:size(z, 2), j=1:size(z, 1)]
@ -1202,3 +1266,5 @@ function text_plot(text, alignment, kw_args)
GLAbstraction.transformation(obj, transmat)
view(obj, img.screen, camera=:orthographic_pixel)
end
end