Skip to content
This repository has been archived by the owner on Jul 13, 2021. It is now read-only.

Commit

Permalink
Merge pull request #551 from JuliaPlots/sd/polys
Browse files Browse the repository at this point in the history
fix colored polygon animation bug
  • Loading branch information
SimonDanisch authored Nov 8, 2020
2 parents d105fbe + 549b25e commit ff863f5
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 103 deletions.
50 changes: 21 additions & 29 deletions src/basic_recipes/contourf.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,56 +46,48 @@ function AbstractPlotting.plot!(c::Contourf{<:Tuple{Any, Any, Any}})
_get_isoband_levels(levels, extrema_nan(zs)...)
end

PolyType = typeof(Polygon(Point2f0[], [Point2f0[]]))

poly_and_colors = lift(xs, ys, zs, levels) do xs, ys, zs, levels
polys = Observable(PolyType[])
colors = Observable(Float32[])

function calculate_polys(xs, ys, zs, levels)
empty!(polys[])
empty!(colors[])
@assert levels isa Tuple
lows, highs = levels
isos = Isoband.isobands(xs, ys, zs, lows, highs)

allvertices = Point2f0[]
allfaces = NgonFace{3,OffsetInteger{-1,UInt32}}[]
allids = Int[]

# TODO: this is ugly
polys = Vector{typeof(Polygon(rand(Point2f0, 3), [rand(Point2f0, 3)]))}()
colors = Float32[]

levelcenters = (highs .+ lows) ./ 2

foreach(zip(levelcenters, isos)) do (center, group)

for (center, group) in zip(levelcenters, isos)
points = Point2f0.(group.x, group.y)
polygroups = _group_polys(points, group.id)

for polygroup in polygroups

outline = polygroup[1]
holes = polygroup[2:end]

poly = GeometryBasics.Polygon(outline, holes)

push!(polys, poly)
push!(polys[], GeometryBasics.Polygon(outline, holes))
# use contour level center value as color
push!(colors, center)
push!(colors[], center)
end

end

polys, colors
polys[] = polys[]
return
end

polys = @lift($poly_and_colors[1])
colors = @lift($poly_and_colors[2])
onany(calculate_polys, xs, ys, zs, levels)
# onany doesn't get called without a push, so we call
# it on a first run!
calculate_polys(xs[], ys[], zs[], levels[])

poly!(c,
mesh!(c,
polys,
colormap = c.colormap,
colorrange = c.colorrange,
strokewidth = 0,
strokecolor = :transparent,
color = colors)

c
color = colors,
shading=false)
end

"""
Expand Down Expand Up @@ -166,9 +158,9 @@ function _group_polys(points, ids)
to_keep[ii] = false
end
end

unclassified_polyindices = unclassified_polyindices[to_keep]
containment_matrix = containment_matrix[to_keep, to_keep]
end
groups
end
end
11 changes: 4 additions & 7 deletions src/basic_recipes/poly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -138,26 +138,23 @@ function plot!(plot::Mesh{<: Tuple{<: AbstractVector{P}}}) where P <: Union{Abst

bigmesh = if color_node[] isa AbstractVector && length(color_node[]) == length(meshes[])
# One color per mesh
real_colors = Observable(RGBAf0[])
attributes[:color] = real_colors
lift(meshes, color_node, attributes.colormap, attributes.colorrange) do meshes, colors, cmap, crange
# Color are reals, so we need to transform it to colors first
single_colors = if colors isa AbstractVector{<:Number}
interpolated_getindex.((to_colormap(cmap),), colors, (crange,))
else
to_color.(colors)
end
empty!(real_colors[])

real_colors = RGBAf0[]
# Map one single color per mesh to each vertex
for (mesh, color) in zip(meshes, single_colors)
append!(real_colors[], Iterators.repeated(RGBAf0(color), length(coordinates(mesh))))
append!(real_colors, Iterators.repeated(RGBAf0(color), length(coordinates(mesh))))
end
real_colors[] = real_colors[]
# real_colors[] = real_colors[]
if P <: AbstractPolygon
meshes = triangle_mesh.(meshes)
end
return merge(meshes)
return pointmeta(merge(meshes), color=real_colors)
end
else
attributes[:color] = color_node
Expand Down
2 changes: 2 additions & 0 deletions test/ReferenceTests/src/ReferenceTests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ using ghr_jll
using Tar
using Downloads
using Pkg.TOML
using Statistics


basedir(files...) = normpath(joinpath(@__DIR__, "..", files...))
Expand All @@ -29,5 +30,6 @@ include("database.jl")
include("stable_rng.jl")
include("runtests.jl")
include("image_download.jl")
include("html_rendering.jl")

end
94 changes: 30 additions & 64 deletions test/ReferenceTests/src/html_rendering.jl
Original file line number Diff line number Diff line change
@@ -1,19 +1,42 @@
"""
Embedds all produced media in one big html file
"""
function generate_preview(media_root, path=joinpath(@__DIR__, "preview.html"))
function generate_preview(path=joinpath(@__DIR__, "preview.html"); media_root=basedir("recorded"))
open(path, "w") do io
for folder in readdir(media_root)
media = joinpath(media_root, folder, "media")
if !isfile(media) && ispath(media)
for file in readdir(media_root)
media = joinpath(media_root, file)
println(io, "<h1> $file </h1>")
if isdir(media)
medias = joinpath.(media, readdir(media))
println(io, "<h1> $folder </h1>")
embed_media(io, medias)
else
embed_media(io, media)
end
end
end
end

function generate_test_summary(path, recorded_root, refimages_root, scores)
open(path, "w") do io
scores_sorted = sort!(collect(scores), by=last, rev=true)
for (filename, score) in scores_sorted
media_ref = joinpath(refimages_root, filename)
media_recorded = joinpath(recorded_root, filename)
println(io, "<h1> $filename : $(round(score, digits=4)) [reference] - [recorded] </h1>")
println(io, """
<div style="display: flex">
<div>
$(embed_media(media_ref))
</div>
<div>
$(embed_media(media_recorded))
</div>
</div>
""")
end
end
end

function tourl(path)
if Sys.iswindows()
# There might be a nicer way?
Expand All @@ -25,63 +48,6 @@ function tourl(path)
return repr(path)
end

# NOTE: `save_media` is the function you want to overload
# if you want to create a Gallery with custom types.
# Simply overloading the function should do the trick
# and ReferenceTests will take care of the rest.

function save_media(entry, x::Scene, path::String)
path = joinpath(path, "image.png")
save(FileIO.File(DataFormat{:PNG}, path), x) # work around FileIO bug for now
[path]
end

function save_media(entry, x::String, path::String)
out = joinpath(path, basename(x))
if out != x
mv(x, out, force = true)
end
[out]
end

function save_media(entry, x::AbstractPlotting.Stepper, path::String)
# return a list of all file names
images = filter(x-> endswith(x, ".png"), readdir(x.folder))
return map(images) do img
p = joinpath(x.folder, img)
out = joinpath(path, basename(p))
mv(p, out, force = true)
out
end
end

function save_media(entry, results::AbstractVector, path::String)
paths = String[]
for (i, res) in enumerate(results)
# Only save supported results
if res isa Union{Scene, String}
img = joinpath(path, "image$i.png")
save(FileIO.File(DataFormat{:PNG}, img), res) # work around FileIO
push!(paths, img)
end
end
paths
end

function save_media(example, events::RecordEvents, path::String)
# the path is fixed at record time to be stored relative to the example
epath = event_path(example, "")
isfile(epath) || error("Can't find events for example: $(example.unique_name). Please run `record_example_events()`")
# the current path of RecordEvents is where we now actually want to store the video
video_path = joinpath(path, "video.mp4")
record(events.scene, video_path) do io
replay_events(events.scene, epath) do
recordframe!(io)
end
end
return [video_path]
end

"""
embed_image(path::AbstractString)
Returns the html to embed an image
Expand Down Expand Up @@ -126,13 +92,13 @@ function embed_media(path::String, alt = "")
end
end

embed_media(io::IO, path) = println(io, embed_media(path))

"""
Embeds a vector of media files as HTML
"""
function embed_media(io::IO, paths::AbstractVector{<: AbstractString}, caption = "")
for (i, path) in enumerate(paths)
occursin("thumb", path) && continue
for path in paths
println(io, """
<div style="display:inline-block">
<p style="display:inline-block; text-align: center">
Expand Down
3 changes: 2 additions & 1 deletion test/ReferenceTests/src/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ function reference_tests(recorded; ref_images = ReferenceTests.download_refimage
@testset "$name" for (name, score) in scores
@test score < difference
end
return recorded, ref_images, scores
end
end

Expand Down Expand Up @@ -100,7 +101,7 @@ function record_tests(db=load_database(); recording_dir=joinpath(@__DIR__, "..",
return recorded_files, recording_dir
end

function run_tests(db=load_database(); ref_images = ReferenceTests.download_refimages(),
function run_tests(db=load_database(); ref_images = ReferenceTests.download_refimages(),
recording_dir=joinpath(@__DIR__, "..", "recorded"), difference=0.03)
files, dir = record_tests(db, recording_dir=recording_dir)
reference_tests(recording_dir, ref_images=ref_images, difference=difference)
Expand Down
9 changes: 7 additions & 2 deletions test/ReferenceTests/src/tests/examples2d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,13 @@ end
end
end

let
let
struct FitzhughNagumo2
end
(()-> FitzhughNagumo2())()
end

let
let
struct FitzhughNagumo{T}
ϵ::T
s::T
Expand Down Expand Up @@ -343,3 +343,8 @@ end
pie!(ax, 0.1:0.1:1.0, normalize=false)
scene
end

@cell "intersecting polygon" begin
x = LinRange(0, 2pi, 100)
poly(Point2f0.(zip(sin.(x), sin.(2x))), color = :white, strokecolor = :blue, strokewidth = 10)
end

0 comments on commit ff863f5

Please sign in to comment.