From e8bdd325c7914611e475b02fc7a3413129be0f52 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 18 Nov 2024 23:07:01 +0100 Subject: [PATCH 1/5] add conversion for Vector of MultiLineString --- src/conversions.jl | 2 +- test/convert_arguments.jl | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/conversions.jl b/src/conversions.jl index b7412d8340f..fe0e475bfc7 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -213,7 +213,7 @@ end Takes an input `Array{LineString}` or a `MultiLineString` and decomposes it to points. """ -function convert_arguments(PB::PointBased, linestring::Union{<:AbstractVector{<:LineString{N, T}}, MultiLineString{N, T}}) where {N, T} +function convert_arguments(PB::PointBased, linestring::Union{AbstractVector{<:LineString{N, T}}, MultiLineString{N, T}, AbstractVector{<:MultiLineString{N,T}}}) where {N, T} T_out = float_type(T) arr = Point{N, T_out}[]; n = length(linestring) for idx in 1:n diff --git a/test/convert_arguments.jl b/test/convert_arguments.jl index 70d2885aca6..84512f5b4c3 100644 --- a/test/convert_arguments.jl +++ b/test/convert_arguments.jl @@ -491,3 +491,25 @@ Makie.convert_arguments(::PointBased, ::MyConvVector) = ([Point(10, 20)],) end end end + +@testset "Explicit convert_arguments" begin + function nan_equal(a::Vector, b::Vector) + length(a) == length(b) || return false + for (x, y) in zip(a, b) + (isnan(x) && isnan(y)) || (x == y) || return false + end + return true + end + + @testset "PointBased" begin + ps = Point2f.([1, 2], [1, 2]) + ls1 = [LineString(ps) for _ in 1:2] + ls2 = MultiLineString(ls1) + ls3 = [ls2, ls2] + ps12 = [ps; [Point2f(NaN)]; ps] + ps3 = [ps12; [Point2f(NaN)]; ps12] + @test nan_equal(convert_arguments(PointBased(), ls1)[1], ps12) + @test nan_equal(convert_arguments(PointBased(), ls2)[1], ps12) + @test nan_equal(convert_arguments(PointBased(), ls3)[1], ps3) + end +end \ No newline at end of file From d405744ffa566247decf012f07ebe254d3a2295e Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 18 Nov 2024 23:20:59 +0100 Subject: [PATCH 2/5] add VecTypes -> color conversions --- src/conversions.jl | 2 ++ test/conversions.jl | 6 ------ test/convert_attributes.jl | 30 ++++++++++++++++++++++++++---- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/conversions.jl b/src/conversions.jl index fe0e475bfc7..c4eccc48da6 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -920,6 +920,8 @@ end to_color(c::Nothing) = c # for when color is not used to_color(c::Real) = Float32(c) to_color(c::Colorant) = convert(RGBA{Float32}, c) +to_color(c::VecTypes{3}) = RGBAf(c[1], c[2], c[3], 1) +to_color(c::VecTypes{4}) = RGBAf(c[1], c[2], c[3], c[4]) to_color(c::Symbol) = to_color(string(c)) to_color(c::String) = parse(RGBA{Float32}, c) to_color(c::AbstractArray) = to_color.(c) diff --git a/test/conversions.jl b/test/conversions.jl index fe725b1c9ae..06b40cce03a 100644 --- a/test/conversions.jl +++ b/test/conversions.jl @@ -243,12 +243,6 @@ end @test Colors.alpha.(cs) == Float32.(LinRange(0, 1, 10)) end -@testset "colors" begin - @test to_color(["red", "green"]) isa Vector{RGBAf} - @test to_color(["red", "green"]) == [to_color("red"), to_color("green")] -end - - @testset "heatmap from three vectors" begin x = [2, 1, 2] y = [2, 3, 3] diff --git a/test/convert_attributes.jl b/test/convert_attributes.jl index 7bad5471edd..17741391cf5 100644 --- a/test/convert_attributes.jl +++ b/test/convert_attributes.jl @@ -1,4 +1,6 @@ using Makie: Mat, Mat3f, convert_attribute, uv_transform, automatic +using Makie: to_color +using Makie.Colors @testset "uv_transform" begin key = Makie.key"uv_transform"() @@ -14,13 +16,13 @@ using Makie: Mat, Mat3f, convert_attribute, uv_transform, automatic for wrap in (identity, x -> [x]) M = Mat{2, 3, Float32}(1,2,3,4,5,6) @test convert_attribute(wrap(M), key) == wrap(M) - + M3 = Mat3f(1,2,0, 3,4,0, 5,6,0) @test convert_attribute(wrap(M3), key) == wrap(M) # transformationmatrix-like @test convert_attribute(wrap(Vec2f(2,3)), key) == wrap(Mat{2, 3, Float32}(2,0,0,3,0,0)) - @test convert_attribute(wrap((Vec2f(-1,-2), Vec2f(2,3))), key) == + @test convert_attribute(wrap((Vec2f(-1,-2), Vec2f(2,3))), key) == wrap(Mat{2, 3, Float32}(2,0,0,3,-1,-2)) @test convert_attribute(wrap(I), key) == wrap(Mat{2, 3, Float32}(1,0,0,1,0,0)) @@ -37,12 +39,32 @@ using Makie: Mat, Mat3f, convert_attribute, uv_transform, automatic @test convert_attribute(wrap((:rotr90, :swap_xy)), key) == wrap(Mat{2, 3, Float32}(1, 0, 0, -1, 0, 1)) @test convert_attribute(wrap((:rotl90, (Vec2f(0.5, 0.5), Vec2f(0.5, 0.5)), :flip_y)), key) == wrap(Mat{2, 3, Float32}(0, 0.5, 0.5, 0, 0, 0.5)) end - + @test convert_attribute(nothing, key) === nothing - + # Not meant to be used via convert_attribute, util for uv_transform @test uv_transform(:meshscatter)[Vec(1,2), Vec(1,2,3)] == convert_attribute(automatic, key, Makie.key"meshscatter"()) @test uv_transform(:mesh)[Vec(1,2), Vec(1,2,3)] == convert_attribute(automatic, key, Makie.key"mesh"()) @test uv_transform(:image)[Vec(1,2), Vec(1,2,3)] == convert_attribute(automatic, key, Makie.key"image"()) @test uv_transform(:surface)[Vec(1,2), Vec(1,2,3)] == convert_attribute(automatic, key, Makie.key"surface"()) +end + +@testset "to_color" begin + @test to_color(nothing) === nothing + @test to_color(1) == 1f0 + @test to_color(17.0) == 17f0 + @test to_color(colorant"blue") == RGBAf(0,0,1,1) + @test to_color(HSV(120, 1, 1)) == RGBAf(0,1,0,1) + @test to_color(RGB(1,0,0)) == RGBAf(1,0,0,1) + @test to_color(RGBA(1,0,0,0.5)) == RGBAf(1,0,0,0.5) + @test to_color(Vec3f(0.5, 0.6, 0.4)) == RGBAf(0.5, 0.6, 0.4, 1) + @test to_color(Vec4f(0.2, 0.3, 0.4, 0.5)) == RGBAf(0.2, 0.3, 0.4, 0.5) + @test to_color(:black) == RGBAf(0,0,0,1) + @test to_color("red") == RGBAf(1,0,0,1) + @test to_color([RGBf(0.5, 1, 0.5), :red, "blue"]) == [RGBAf(0.5, 1, 0.5, 1), RGBAf(1,0,0,1), RGBAf(0,0,1,1)] + @test to_color([HSV(0, 1, 1), HSV(120, 1, 1)]) == [RGBAf(1,0,0,1), RGBAf(0,1,0,1)] + @test to_color((:red, 0.5)) == RGBAf(1, 0, 0, 0.5) + @test to_color((RGBAf(0.2, 0.3, 0.4, 0.5), 0.5)) == RGBAf(0.2, 0.3, 0.4, 0.25) + + # TODO: Pattern, Palette end \ No newline at end of file From 3d155d5f2d8cefc9e845826655c57843db76c8f8 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 18 Nov 2024 23:31:39 +0100 Subject: [PATCH 3/5] add padding converts for Label --- src/basic_recipes/tooltip.jl | 13 ++----------- src/conversions.jl | 5 +++++ src/makielayout/blocks/label.jl | 6 ++++-- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/basic_recipes/tooltip.jl b/src/basic_recipes/tooltip.jl index c833908be12..41ab8affd49 100644 --- a/src/basic_recipes/tooltip.jl +++ b/src/basic_recipes/tooltip.jl @@ -81,16 +81,7 @@ function plot!(p::Tooltip{<:Tuple{<:VecTypes}}) # Text - textpadding = map(p, p.textpadding) do pad - if pad isa Real - return (pad, pad, pad, pad) - elseif length(pad) == 4 - return pad - else - @error "Failed to parse $pad as (left, right, bottom, top). Using defaults" - return (4, 4, 4, 4) - end - end + textpadding = map(to_lrbt_padding, p, p.textpadding) text_offset = map(p, p.offset, textpadding, p.triangle_size, p.placement, p.align) do o, pad, ts, placement, align l, r, b, t = pad @@ -195,7 +186,7 @@ function plot!(p::Tooltip{<:Tuple{<:VecTypes}}) mesh!( p, tri_points, [1 2 3], shading = NoShading, space = :pixel, - color = p.backgroundcolor, fxaa = false, + color = p.backgroundcolor, fxaa = false, transparency = p.transparency, visible = p.visible, overdraw = p.overdraw, depth_shift = p.depth_shift, inspectable = p.inspectable, transformation = Transformation() diff --git a/src/conversions.jl b/src/conversions.jl index c4eccc48da6..4f5355169b8 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -1982,3 +1982,8 @@ assemble_colors(::ShaderAbstractions.Sampler, color, plot) = Observable(el32conv # BUFFER OVERLOAD GeometryBasics.collect_with_eltype(::Type{T}, vec::ShaderAbstractions.Buffer{T}) where {T} = vec + +# Used in Label, maybe useful elsewhere? +to_lrbt_padding(x::Real) = Vec4f(x) +to_lrbt_padding(xy::VecTypes{2}) = Vec4f(xy[1], xy[1], xy[2], xy[2]) +to_lrbt_padding(pad::VecTypes{4}) = to_ndim(Vec4f, pad, 0) \ No newline at end of file diff --git a/src/makielayout/blocks/label.jl b/src/makielayout/blocks/label.jl index dabb36cb830..da5853b998f 100644 --- a/src/makielayout/blocks/label.jl +++ b/src/makielayout/blocks/label.jl @@ -17,7 +17,8 @@ function initialize_block!(l::Label) textbb = Ref(BBox(0, 1, 0, 1)) onany(topscene, l.text, l.fontsize, l.font, l.rotation, word_wrap_width, - l.padding) do _, _, _, _, _, padding + l.padding) do _, _, _, _, _, pad + padding = to_lrbt_padding(pad) textbb[] = Rect2f(boundingbox(t, :data)) autowidth = width(textbb[]) + padding[1] + padding[2] autoheight = height(textbb[]) + padding[3] + padding[4] @@ -29,7 +30,8 @@ function initialize_block!(l::Label) return end - onany(topscene, layoutobservables.computedbbox, l.padding) do bbox, padding + onany(topscene, layoutobservables.computedbbox, l.padding) do bbox, pad + padding = to_lrbt_padding(pad) if l.word_wrap[] tw = width(bbox) - padding[1] - padding[2] else From 36088d48d36c6e2aac9b34215da0c18ac32deb87 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Tue, 19 Nov 2024 00:05:43 +0100 Subject: [PATCH 4/5] guard against NaN rotation and markersize in CairoMakie --- CairoMakie/src/primitives.jl | 5 +++-- ReferenceTests/src/tests/attributes.jl | 10 ++++++++++ src/utilities/quaternions.jl | 2 ++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CairoMakie/src/primitives.jl b/CairoMakie/src/primitives.jl index 4cf37ea8b7c..267b48aa210 100644 --- a/CairoMakie/src/primitives.jl +++ b/CairoMakie/src/primitives.jl @@ -362,6 +362,7 @@ function draw_atomic_scatter( markersize, strokecolor, strokewidth, m, mo, rotation isnan(pos) && return + isnan(rotation) && return # matches GLMakie scale = project_scale(scene, markerspace, markersize, size_model) offset = project_scale(scene, markerspace, mo, size_model) @@ -372,7 +373,7 @@ function draw_atomic_scatter( # Setting a markersize of 0.0 somehow seems to break Cairos global state? # At least it stops drawing any marker afterwards # TODO, maybe there's something wrong somewhere else? - if !(norm(scale) ≈ 0.0) + if !(isnan(scale) || norm(scale) ≈ 0.0) if m isa Char draw_marker(ctx, m, best_font(m, font), pos, scale, strokecolor, strokewidth, offset, rotation) else @@ -1254,7 +1255,7 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Maki scale = Makie.voxel_size(primitive) colors = Makie.voxel_colors(primitive) marker = GeometryBasics.normal_mesh(Rect3f(Point3f(-0.5), Vec3f(1))) - + # Face culling if !isempty(primitive.clip_planes[]) && Makie.is_data_space(primitive.space[]) valid = [is_visible(primitive.clip_planes[], p) for p in pos] diff --git a/ReferenceTests/src/tests/attributes.jl b/ReferenceTests/src/tests/attributes.jl index c045cc717f3..fd5483748b9 100644 --- a/ReferenceTests/src/tests/attributes.jl +++ b/ReferenceTests/src/tests/attributes.jl @@ -5,3 +5,13 @@ scatter(fig[1, 2], RNG.randn(20), color=colors, markersize=10, visible=false) fig end + +@reference_test "(mesh)scatter with NaN rotation and markersize" begin + scene = Scene(size = (150, 300)) + xs = [-0.6, 0.0, 0.6] + scatter!(scene, xs, fill( 0.75, 3), marker = :ltriangle, rotation = [0.5, NaN, -0.5], markersize = 50) + scatter!(scene, xs, fill( 0.25, 3), marker = :ltriangle, markersize = [50, NaN, 50]) + meshscatter!(scene, xs, fill(-0.25, 3), marker = Rect2f(-0.5,-0.5,1,1), rotation = [0.5, NaN, -0.5], markersize = 0.2) + meshscatter!(scene, xs, fill(-0.75, 3), marker = Rect2f(-0.5,-0.5,1,1), markersize = [0.2, NaN, 0.2]) + scene +end \ No newline at end of file diff --git a/src/utilities/quaternions.jl b/src/utilities/quaternions.jl index 917bf21690b..59d6204a942 100644 --- a/src/utilities/quaternions.jl +++ b/src/utilities/quaternions.jl @@ -157,6 +157,8 @@ function quaternion_to_2d_angle(quat::Quaternion) end Base.isinf(q::Quaternion) = any(isinf, q.data) +Base.isnan(q::Quaternion) = any(isnan, q.data) +Base.isfinite(q::Quaternion) = all(isfinite, q.data) Base.abs2(q::Quaternion) = mapreduce(*, +, q.data, q.data) function Base.inv(q::Quaternion) if isinf(q) From 94bb82a5cd17267108ab1c331377a3d05dce8fdf Mon Sep 17 00:00:00 2001 From: Frederic Freyer Date: Tue, 19 Nov 2024 16:37:15 +0100 Subject: [PATCH 5/5] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e317433019..a021244e4e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ - Fix an error in `convert_arguments` for PointBased plots and 3D polygons [#4585](https://github.com/MakieOrg/Makie.jl/pull/4585). - Fix polygon rendering issue of `crossbar(..., show_notch = true)` in CairoMakie [#4587](https://github.com/MakieOrg/Makie.jl/pull/4587). - Fix render order of Axis3 frame lines in CairoMakie [#4591](https://github.com/MakieOrg/Makie.jl/pull/4591) +- Added PointBased conversion for `Vector{MultiLineString}` [#4599](https://github.com/MakieOrg/Makie.jl/pull/4599) +- Added color conversions for tuples, Points and Vecs [#4599](https://github.com/MakieOrg/Makie.jl/pull/4599) +- Added conversions for 1 and 2 value paddings in `Label` and `tooltip` [#4599](https://github.com/MakieOrg/Makie.jl/pull/4599) +- Fixed `NaN` in scatter rotation and markersize breaking Cairo state [#4599](https://github.com/MakieOrg/Makie.jl/pull/4599) ## [0.21.16] - 2024-11-06