From 0d86adc5d502ab4873fb6d57d0c4e2f1e2ddb813 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 8 Jan 2023 16:06:05 +0100 Subject: [PATCH 01/49] prototype scatter in scene --- CairoMakie/src/utils.jl | 8 +++--- src/Makie.jl | 7 +++++ src/camera/projection_math.jl | 4 +-- src/conversions.jl | 52 +++++++++++++++++++---------------- src/types.jl | 12 ++++---- 5 files changed, 47 insertions(+), 36 deletions(-) diff --git a/CairoMakie/src/utils.jl b/CairoMakie/src/utils.jl index 695f957aa0e..58525f14cd6 100644 --- a/CairoMakie/src/utils.jl +++ b/CairoMakie/src/utils.jl @@ -10,15 +10,15 @@ end function _project_position(scene, space, point, model, yflip) res = scene.camera.resolution[] - p4d = to_ndim(Vec4f, to_ndim(Vec3f, point, 0f0), 1f0) - clip = Makie.space_to_clip(scene.camera, space) * model * p4d + p4d = to_ndim(Vec4{Float64}, to_ndim(Vec3{Float64}, point, 0.0), 1.0) + clip = Mat4{Float64}(Makie.space_to_clip(scene.camera, space)) * Mat4{Float64}(model) * p4d @inbounds begin # between -1 and 1 p = (clip ./ clip[4])[Vec(1, 2)] # flip y to match cairo - p_yflip = Vec2f(p[1], (1f0 - 2f0 * yflip) * p[2]) + p_yflip = Vec2{Float64}(p[1], (1.0 - 2.0 * yflip) * p[2]) # normalize to between 0 and 1 - p_0_to_1 = (p_yflip .+ 1f0) ./ 2f0 + p_0_to_1 = (p_yflip .+ 1.0) ./ 2.0 end # multiply with scene resolution for final position return p_0_to_1 .* res diff --git a/src/Makie.jl b/src/Makie.jl index 9de6f9550e9..7b232166ff1 100644 --- a/src/Makie.jl +++ b/src/Makie.jl @@ -89,6 +89,13 @@ const RGBAf = RGBA{Float32} const RGBf = RGB{Float32} const NativeFont = FreeTypeAbstraction.FTFont +const Vec2e = Vec2{Float64} +const Vec3e = Vec3{Float64} +const Vec4e = Vec4{Float64} +const Point2e = Point2{Float64} +const Point3e = Point3{Float64} +const Point4e = Point4{Float64} + const ASSETS_DIR = RelocatableFolders.@path joinpath(@__DIR__, "..", "assets") assetpath(files...) = normpath(joinpath(ASSETS_DIR, files...)) diff --git a/src/camera/projection_math.jl b/src/camera/projection_math.jl index 717224c6a6a..2b9c8ffc3c5 100644 --- a/src/camera/projection_math.jl +++ b/src/camera/projection_math.jl @@ -291,13 +291,13 @@ function project(scene::Scene, point::T) where T<:StaticVector ) end -function project(matrix::Mat4f, p::T, dim4 = 1.0) where T <: VecTypes +function project(matrix::Mat4, p::T, dim4 = 1.0) where T <: VecTypes p = to_ndim(Vec4f, to_ndim(Vec3f, p, 0.0), dim4) p = matrix * p to_ndim(T, p, 0.0) end -function project(proj_view::Mat4f, resolution::Vec2, point::Point) +function project(proj_view::Mat4, resolution::Vec2, point::Point) p4d = to_ndim(Vec4f, to_ndim(Vec3f, point, 0f0), 1f0) clip = proj_view * p4d p = (clip ./ clip[4])[Vec(1, 2)] diff --git a/src/conversions.jl b/src/conversions.jl index 71c94634ba1..2543bd7ad3c 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -69,12 +69,12 @@ convert_single_argument(x) = x # replace missings with NaNs function convert_single_argument(a::AbstractArray{<:Union{Missing, <:Real}}) - [ismissing(x) ? NaN32 : convert(Float32, x) for x in a] + [ismissing(x) ? NaN : convert(Float64, x) for x in a] end # same for points function convert_single_argument(a::AbstractArray{<:Union{Missing, <:Point{N}}}) where N - [ismissing(x) ? Point{N, Float32}(NaN32) : Point{N, Float32}(x) for x in a] + [ismissing(x) ? Point{N, Float64}(NaN) : Point{N, Float64}(x) for x in a] end ################################################################################ @@ -85,19 +85,19 @@ end Wrap a single point or equivalent object in a single-element array. """ function convert_arguments(::PointBased, x::Real, y::Real) - ([Point2f(x, y)],) + ([Point2e(x, y)],) end function convert_arguments(::PointBased, x::Real, y::Real, z::Real) - ([Point3f(x, y, z)],) + ([Point3e(x, y, z)],) end function convert_arguments(::PointBased, position::VecTypes{N, <: Number}) where N - ([convert(Point{N, Float32}, position)],) + ([convert(Point{N, Float64}, position)],) end function convert_arguments(::PointBased, positions::AbstractVector{<: VecTypes{N, <: Number}}) where N - (elconvert(Point{N, Float32}, positions),) + (elconvert(Point{N, Float64}, positions),) end function convert_arguments(::PointBased, positions::SubArray{<: VecTypes, 1}) @@ -110,7 +110,7 @@ Enables to use scatter like a surface plot with x::Vector, y::Vector, z::Matrix spanning z over the grid spanned by x y """ function convert_arguments(::PointBased, x::AbstractVector, y::AbstractVector, z::AbstractMatrix) - (vec(Point3f.(x, y', z)),) + (vec(Point3e.(x, y', z)),) end """ convert_arguments(P, x, y, z)::(Vector) @@ -119,7 +119,7 @@ Takes vectors `x`, `y`, and `z` and turns it into a vector of 3D points of the v from `x`, `y`, and `z`. `P` is the plot Type (it is optional). """ -convert_arguments(::PointBased, x::RealVector, y::RealVector, z::RealVector) = (Point3f.(x, y, z),) +convert_arguments(::PointBased, x::RealVector, y::RealVector, z::RealVector) = (Point3e.(x, y, z),) """ convert_arguments(P, x)::(Vector) @@ -133,9 +133,11 @@ function convert_arguments(::PointBased, pos::AbstractMatrix{<: Number}) (to_vertices(pos),) end -convert_arguments(P::PointBased, x::AbstractVector{<:Real}, y::AbstractVector{<:Real}) = (Point2f.(x, y),) +function convert_arguments(P::PointBased, x::AbstractVector{<:Real}, y::AbstractVector{<:Real}) + (Point2e.(x, y),) +end -convert_arguments(P::PointBased, x::AbstractVector{<:Real}, y::AbstractVector{<:Real}, z::AbstractVector{<:Real}) = (Point3f.(x, y, z),) +convert_arguments(P::PointBased, x::AbstractVector{<:Real}, y::AbstractVector{<:Real}, z::AbstractVector{<:Real}) = (Point3e.(x, y, z),) """ convert_arguments(P, y)::Vector @@ -155,7 +157,9 @@ from `x` and `y`. `P` is the plot Type (it is optional). """ #convert_arguments(::PointBased, x::RealVector, y::RealVector) = (Point2f.(x, y),) -convert_arguments(P::PointBased, x::ClosedInterval, y::RealVector) = convert_arguments(P, LinRange(extrema(x)..., length(y)), y) +function convert_arguments(P::PointBased, x::ClosedInterval, y::RealVector) + return convert_arguments(P, LinRange(extrema(x)..., length(y)), y) +end convert_arguments(P::PointBased, x::RealVector, y::ClosedInterval) = convert_arguments(P, x, LinRange(extrema(y)..., length(x))) @@ -168,11 +172,11 @@ Takes an input `Rect` `x` and decomposes it to points. """ function convert_arguments(P::PointBased, x::Rect2) # TODO fix the order of decompose - return convert_arguments(P, decompose(Point2f, x)[[1, 2, 4, 3]]) + return convert_arguments(P, decompose(Point2e, x)[[1, 2, 4, 3]]) end function convert_arguments(P::PointBased, mesh::AbstractMesh) - return convert_arguments(P, decompose(Point3f, mesh)) + return convert_arguments(P, decompose(Point3e, mesh)) end function convert_arguments(PB::PointBased, linesegments::FaceView{<:Line, P}) where {P<:AbstractPoint} @@ -181,18 +185,18 @@ function convert_arguments(PB::PointBased, linesegments::FaceView{<:Line, P}) wh end function convert_arguments(P::PointBased, rect::Rect3) - return (decompose(Point3f, rect),) + return (decompose(Point3e, rect),) end function convert_arguments(P::Type{<: LineSegments}, rect::Rect3) f = decompose(LineFace{Int}, rect) - p = connect(decompose(Point3f, rect), f) + p = connect(decompose(Point3e, rect), f) return convert_arguments(P, p) end function convert_arguments(::Type{<: Lines}, rect::Rect3) - points = unique(decompose(Point3f, rect)) - push!(points, Point3f(NaN)) # use to seperate linesegments + points = unique(decompose(Point3e, rect)) + push!(points, Point3e(NaN)) # use to seperate linesegments return (points[[1, 2, 3, 4, 1, 5, 6, 2, 9, 6, 8, 3, 9, 5, 7, 4, 9, 7, 8]],) end """ @@ -213,7 +217,7 @@ Takes an input `Array{LineString}` or a `MultiLineString` and decomposes it to p function convert_arguments(PB::PointBased, linestring::Union{Array{<:LineString}, MultiLineString}) arr = copy(convert_arguments(PB, linestring[1])[1]) for ls in 2:length(linestring) - push!(arr, Point2f(NaN)) + push!(arr, Point2e(NaN)) append!(arr, convert_arguments(PB, linestring[ls])[1]) end return (arr,) @@ -229,12 +233,12 @@ function convert_arguments(PB::PointBased, pol::Polygon) arr = copy(convert_arguments(PB, pol.exterior)[1]) push!(arr, arr[1]) # close exterior if !isempty(pol.interiors) - push!(arr, Point2f(NaN)) + push!(arr, Point2e(NaN)) for interior in pol.interiors inter = convert_arguments(PB, interior)[1] append!(arr, inter) # close interior + separate! - push!(arr, inter[1], Point2f(NaN)) + push!(arr, inter[1], Point2e(NaN)) end end return (arr,) @@ -249,7 +253,7 @@ Takes an input `Array{Polygon}` or a `MultiPolygon` and decomposes it to points. function convert_arguments(PB::PointBased, mp::Union{Array{<:Polygon}, MultiPolygon}) arr = copy(convert_arguments(PB, mp[1])[1]) for p in 2:length(mp) - push!(arr, Point2f(NaN)) + push!(arr, Point2e(NaN)) append!(arr, convert_arguments(PB, mp[p])[1]) end return (arr,) @@ -430,7 +434,7 @@ end function convert_arguments(::Type{<: Lines}, x::Rect2) # TODO fix the order of decompose - points = decompose(Point2f, x) + points = decompose(Point2e, x) return (points[[1, 2, 4, 3, 1]],) end @@ -443,12 +447,12 @@ Accepts a Vector of Pair of Points (e.g. `[Point(0, 0) => Point(1, 1), ...]`) to encode e.g. linesegments or directions. """ function convert_arguments(::Type{<: LineSegments}, positions::AbstractVector{E}) where E <: Union{Pair{A, A}, Tuple{A, A}} where A <: VecTypes{N, T} where {N, T} - (elconvert(Point{N, Float32}, reinterpret(Point{N, T}, positions)),) + (elconvert(Point{N, Float64}, reinterpret(Point{N, T}, positions)),) end function convert_arguments(::Type{<: LineSegments}, x::Rect2) # TODO fix the order of decompose - points = decompose(Point2f, x) + points = decompose(Point2e, x) return (points[[1, 2, 2, 4, 4, 3, 3, 1]],) end diff --git a/src/types.jl b/src/types.jl index c28e74df6a8..ebe4180dd7d 100644 --- a/src/types.jl +++ b/src/types.jl @@ -205,32 +205,32 @@ struct Camera """ projection used to convert pixel to device units """ - pixel_space::Observable{Mat4f} + pixel_space::Observable{Mat4{Float64}} """ View matrix is usually used to rotate, scale and translate the scene """ - view::Observable{Mat4f} + view::Observable{Mat4{Float64}} """ Projection matrix is used for any perspective transformation """ - projection::Observable{Mat4f} + projection::Observable{Mat4{Float64}} """ just projection * view """ - projectionview::Observable{Mat4f} + projectionview::Observable{Mat4{Float64}} """ resolution of the canvas this camera draws to """ - resolution::Observable{Vec2f} + resolution::Observable{Vec2{Float64}} """ Eye position of the camera, sued for e.g. ray tracing. """ - eyeposition::Observable{Vec3f} + eyeposition::Observable{Vec3{Float64}} """ To make camera interactive, steering observables are connected to the different matrices. From 1f907155d8665ada42a205508db9e7d9abdbf933 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 8 Jan 2023 16:52:57 +0100 Subject: [PATCH 02/49] get axis working --- src/camera/camera.jl | 16 ++++++++-------- src/makielayout/blocks/axis.jl | 28 +++++++++++++++------------- src/makielayout/interactions.jl | 4 ++-- src/makielayout/lineaxis.jl | 12 ++++++------ src/makielayout/types.jl | 8 ++++---- 5 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/camera/camera.jl b/src/camera/camera.jl index 48d63063fa7..68a9b40154f 100644 --- a/src/camera/camera.jl +++ b/src/camera/camera.jl @@ -69,21 +69,21 @@ end function Camera(px_area) pixel_space = lift(px_area) do window_size - nearclip = -10_000f0 - farclip = 10_000f0 - w, h = Float32.(widths(window_size)) - return orthographicprojection(0f0, w, 0f0, h, nearclip, farclip) + nearclip = -10_000.0 + farclip = 10_000.0 + w, h = Float64.(widths(window_size)) + return orthographicprojection(0.0, w, 0.0, h, nearclip, farclip) end - view = Observable(Mat4f(I)) - proj = Observable(Mat4f(I)) + view = Observable(Mat4{Float64}(I)) + proj = Observable(Mat4{Float64}(I)) proj_view = map(*, proj, view) return Camera( pixel_space, view, proj, proj_view, - lift(a-> Vec2f(widths(a)), px_area), - Observable(Vec3f(1)), + lift(a-> Vec2e(widths(a)), px_area), + Observable(Vec3e(1)), ObserverFunction[] ) end diff --git a/src/makielayout/blocks/axis.jl b/src/makielayout/blocks/axis.jl index 5b5a1180320..be3da6616a9 100644 --- a/src/makielayout/blocks/axis.jl +++ b/src/makielayout/blocks/axis.jl @@ -79,12 +79,11 @@ function register_events!(ax, scene) end function update_axis_camera(camera::Camera, t, lims, xrev::Bool, yrev::Bool) - nearclip = -10_000f0 - farclip = 10_000f0 + nearclip = -10_000.0 + farclip = 10_000.0 # we are computing transformed camera position, so this isn't space dependent tlims = Makie.apply_transform(t, lims) - left, bottom = minimum(tlims) right, top = maximum(tlims) @@ -92,11 +91,11 @@ function update_axis_camera(camera::Camera, t, lims, xrev::Bool, yrev::Bool) bottomtop = yrev ? (top, bottom) : (bottom, top) projection = Makie.orthographicprojection( - Float32, + Float64, leftright..., bottomtop..., nearclip, farclip) - Makie.set_proj_view!(camera, projection, Makie.Mat4f(Makie.I)) + Makie.set_proj_view!(camera, projection, Makie.Mat4{Float64}(Makie.I)) return end @@ -177,8 +176,8 @@ function initialize_block!(ax::Axis; palette = nothing) # initialize either with user limits, or pick defaults based on scales # so that we don't immediately error - targetlimits = Observable{Rect2f}(defaultlimits(ax.limits[], ax.xscale[], ax.yscale[])) - finallimits = Observable{Rect2f}(targetlimits[]; ignore_equal_values=true) + targetlimits = Observable{Rect2{Float64}}(defaultlimits(ax.limits[], ax.xscale[], ax.yscale[])) + finallimits = Observable{Rect2{Float64}}(targetlimits[]; ignore_equal_values=true) setfield!(ax, :targetlimits, targetlimits) setfield!(ax, :finallimits, finallimits) @@ -572,7 +571,7 @@ function reset_limits!(ax; xauto = true, yauto = true, zauto = true) (lo, hi) end else - convert(Tuple{Float32, Float32}, tuple(mxlims...)) + convert(Tuple{Float64, Float64}, tuple(mxlims...)) end ylims = if isnothing(mylims) || mylims[1] === nothing || mylims[2] === nothing l = if yauto @@ -588,7 +587,7 @@ function reset_limits!(ax; xauto = true, yauto = true, zauto = true) (lo, hi) end else - convert(Tuple{Float32, Float32}, tuple(mylims...)) + convert(Tuple{Float64, Float64}, tuple(mylims...)) end if ax isa Axis3 @@ -606,7 +605,7 @@ function reset_limits!(ax; xauto = true, yauto = true, zauto = true) (lo, hi) end else - convert(Tuple{Float32, Float32}, tuple(mzlims...)) + convert(Tuple{Float64, Float64}, tuple(mzlims...)) end end @@ -623,7 +622,7 @@ function reset_limits!(ax; xauto = true, yauto = true, zauto = true) end if ax isa Axis - ax.targetlimits[] = BBox(xlims..., ylims...) + ax.targetlimits[] = Rect2{Float64}(xlims[1], ylims[1], xlims[2]-xlims[1], ylims[2]-ylims[1]) elseif ax isa Axis3 ax.targetlimits[] = Rect3f( Vec3f(xlims[1], ylims[1], zlims[1]), @@ -1316,7 +1315,9 @@ Makie.transform_func(ax::Axis) = Makie.transform_func(ax.scene) # these functions pick limits for different x and y scales, so that # we don't pick values that are invalid, such as 0 for log etc. function defaultlimits(userlimits::Tuple{Real, Real, Real, Real}, xscale, yscale) - BBox(userlimits...) + # BBox(userlimits...) + x0, x1, y0, x1 = userlimits + Rect2{Float64}(x0, y0, x1-x0, y1-y0) end defaultlimits(l::Tuple{Any, Any, Any, Any}, xscale, yscale) = defaultlimits(((l[1], l[2]), (l[3], l[4])), xscale, yscale) @@ -1324,7 +1325,8 @@ defaultlimits(l::Tuple{Any, Any, Any, Any}, xscale, yscale) = defaultlimits(((l[ function defaultlimits(userlimits::Tuple{Any, Any}, xscale, yscale) xl = defaultlimits(userlimits[1], xscale) yl = defaultlimits(userlimits[2], yscale) - BBox(xl..., yl...) + # BBox(xl..., yl...) + Rect2{Float64}(xl[1], yl[1], xl[2]-xl[1], yl[2]-yl[1]) end defaultlimits(limits::Nothing, scale) = defaultlimits(scale) diff --git a/src/makielayout/interactions.jl b/src/makielayout/interactions.jl index 537f114a552..2a2fbaf4f4a 100644 --- a/src/makielayout/interactions.jl +++ b/src/makielayout/interactions.jl @@ -203,11 +203,11 @@ function process_interaction(r::RectangleZoom, event::KeysEvent, ax::Axis) return Consume(true) end -function positivize(r::Rect2f) +function positivize(r::Rect2) negwidths = r.widths .< 0 newori = ifelse.(negwidths, r.origin .+ r.widths, r.origin) newwidths = ifelse.(negwidths, -r.widths, r.widths) - return Rect2f(newori, newwidths) + return Rect2(newori, newwidths) end function process_interaction(l::LimitReset, event::MouseEvent, ax::Axis) diff --git a/src/makielayout/lineaxis.jl b/src/makielayout/lineaxis.jl index aed8d714e90..bedefb2feac 100644 --- a/src/makielayout/lineaxis.jl +++ b/src/makielayout/lineaxis.jl @@ -185,7 +185,7 @@ end function update_tickpos_string(closure_args, tickvalues_labels_unfiltered, reversed::Bool, scale) tickstrings, tickpositions, tickvalues, pos_extents_horizontal, limits_obs = closure_args - limits = limits_obs[]::NTuple{2, Float32} + limits = limits_obs[]::NTuple{2, Float64} tickvalues_unfiltered, tickstrings_unfiltered = tickvalues_labels_unfiltered @@ -226,7 +226,7 @@ function update_tickpos_string(closure_args, tickvalues_labels_unfiltered, rever return end -function update_minor_ticks(minortickpositions, limits::NTuple{2, Float32}, pos_extents_horizontal, minortickvalues, scale, reversed::Bool) +function update_minor_ticks(minortickpositions, limits::NTuple{2, Float64}, pos_extents_horizontal, minortickvalues, scale, reversed::Bool) position::Float32, extents_uncorrected::NTuple{2, Float32}, horizontal::Bool = pos_extents_horizontal extents = reversed ? reverse(extents_uncorrected) : extents_uncorrected @@ -266,7 +266,7 @@ function LineAxis(parent::Scene, attrs::Attributes) pos_extents_horizontal = lift(calculate_horizontal_extends, endpoints; ignore_equal_values=true) horizontal = lift(x-> x[3], pos_extents_horizontal) # Tuple constructor converts more than `convert(NTuple{2, Float32}, x)` but we still need the conversion to Float32 tuple: - limits = lift(x-> convert(NTuple{2, Float32}, Tuple(x)), attrs.limits; ignore_equal_values=true) + limits = lift(x-> convert(NTuple{2, Float64}, Tuple(x)), attrs.limits; ignore_equal_values=true) flipped = lift(x-> convert(Bool, x), attrs.flipped; ignore_equal_values=true) ticksnode = Observable(Point2f[]; ignore_equal_values=true) @@ -407,9 +407,9 @@ function LineAxis(parent::Scene, attrs::Attributes) decorations[:labeltext] = labeltext - tickvalues = Observable(Float32[]; ignore_equal_values=true) + tickvalues = Observable(Float64[]; ignore_equal_values=true) - tickvalues_labels_unfiltered = Observable{Tuple{Vector{Float32},Vector{AbstractString}}}() + tickvalues_labels_unfiltered = Observable{Tuple{Vector{Float64},Vector{AbstractString}}}() map!(tickvalues_labels_unfiltered, pos_extents_horizontal, limits, ticks, tickformat, attrs.scale) do (position, extents, horizontal), limits, ticks, tickformat, scale get_ticks(ticks, scale, tickformat, limits...) @@ -422,7 +422,7 @@ function LineAxis(parent::Scene, attrs::Attributes) Observable((tickstrings, tickpositions, tickvalues, pos_extents_horizontal, limits)), tickvalues_labels_unfiltered, reversed, attrs.scale) - minortickvalues = Observable(Float32[]; ignore_equal_values=true) + minortickvalues = Observable(Float64[]; ignore_equal_values=true) minortickpositions = Observable(Point2f[]; ignore_equal_values=true) onany(tickvalues, minorticks) do tickvalues, minorticks diff --git a/src/makielayout/types.jl b/src/makielayout/types.jl index fd296c4a2f8..18a7d70a4eb 100644 --- a/src/makielayout/types.jl +++ b/src/makielayout/types.jl @@ -125,10 +125,10 @@ mutable struct LineAxis attributes::Attributes elements::Dict{Symbol, Any} tickpositions::Observable{Vector{Point2f}} - tickvalues::Observable{Vector{Float32}} + tickvalues::Observable{Vector{Float64}} ticklabels::Observable{Vector{AbstractString}} minortickpositions::Observable{Vector{Point2f}} - minortickvalues::Observable{Vector{Float32}} + minortickvalues::Observable{Vector{Float64}} end struct LimitReset end @@ -188,8 +188,8 @@ end scene::Scene xaxislinks::Vector{Axis} yaxislinks::Vector{Axis} - targetlimits::Observable{Rect2f} - finallimits::Observable{Rect2f} + targetlimits::Observable{Rect2{Float64}} + finallimits::Observable{Rect2{Float64}} cycler::Cycler palette::Attributes block_limit_linking::Observable{Bool} From b24313cf471ebbe3e6d2fd92298ee6a9047068d5 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 8 Jan 2023 18:02:12 +0100 Subject: [PATCH 03/49] fix autolimits --- src/camera/projection_math.jl | 6 +++--- src/layouting/boundingbox.jl | 37 +++++++++++++++++------------------ src/layouting/data_limits.jl | 26 ++++++++++++------------ 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/camera/projection_math.jl b/src/camera/projection_math.jl index 2b9c8ffc3c5..c7ac88f7436 100644 --- a/src/camera/projection_math.jl +++ b/src/camera/projection_math.jl @@ -291,10 +291,10 @@ function project(scene::Scene, point::T) where T<:StaticVector ) end -function project(matrix::Mat4, p::T, dim4 = 1.0) where T <: VecTypes - p = to_ndim(Vec4f, to_ndim(Vec3f, p, 0.0), dim4) +function project(matrix::Mat4, p::VT, dim4 = 1.0) where {N, T, VT <: VecTypes{N, T}} + p = to_ndim(Vec4{T}, to_ndim(Vec3{T}, p, 0.0), dim4) p = matrix * p - to_ndim(T, p, 0.0) + to_ndim(VT, p, 0.0) end function project(proj_view::Mat4, resolution::Vec2, point::Point) diff --git a/src/layouting/boundingbox.jl b/src/layouting/boundingbox.jl index 18757dcb7a5..a0942dc8aa6 100644 --- a/src/layouting/boundingbox.jl +++ b/src/layouting/boundingbox.jl @@ -1,6 +1,6 @@ function parent_transform(x) p = parent(transformation(x)) - isnothing(p) ? Mat4f(I) : p.model[] + isnothing(p) ? Mat4{Float64}(I) : Mat4{Float64}(p.model[]) end function boundingbox(x, exclude = (p)-> false) @@ -13,9 +13,9 @@ function project_widths(matrix, vec) return pr - zero end -function rotate_bbox(bb::Rect3f, rot) - points = decompose(Point3f, bb) - Rect3f(Ref(rot) .* points) +function rotate_bbox(bb::Rect3, rot) + points = decompose(Point3e, bb) + Rect3{Float64}(Ref(rot) .* points) end function gl_bboxes(gl::GlyphCollection) @@ -23,10 +23,9 @@ function gl_bboxes(gl::GlyphCollection) map(gl.glyphs, gl.extents, scales) do c, ext, scale hi_bb = height_insensitive_boundingbox_with_advance(ext) # TODO c != 0 filters out all non renderables, which is not always desired - Rect2f( - Makie.origin(hi_bb) * scale, - (c != 0) * widths(hi_bb) * scale - ) + o = Makie.origin(hi_bb) * scale + w = (c != 0) * widths(hi_bb) * scale + Rect3{Float64}(Point3{Float64}(o[1], o[2], 0.0), Vec3{Float64}(w[1], w[2], 0)) end end @@ -35,7 +34,7 @@ function height_insensitive_boundingbox(ext::GlyphExtent) w = ext.ink_bounding_box.widths[1] b = ext.descender h = ext.ascender - return Rect2f((l, b), (w, h - b)) + return Rect2{Float64}((l, b), (w, h - b)) end function height_insensitive_boundingbox_with_advance(ext::GlyphExtent) @@ -43,26 +42,26 @@ function height_insensitive_boundingbox_with_advance(ext::GlyphExtent) r = ext.hadvance b = ext.descender h = ext.ascender - return Rect2f((l, b), (r - l, h - b)) + return Rect2{Float64}((l, b), (r - l, h - b)) end _inkboundingbox(ext::GlyphExtent) = ext.ink_bounding_box -function boundingbox(glyphcollection::GlyphCollection, position::Point3f, rotation::Quaternion) +function boundingbox(glyphcollection::GlyphCollection, position::Point3, rotation::Quaternion) return boundingbox(glyphcollection, rotation) + position end function boundingbox(glyphcollection::GlyphCollection, rotation::Quaternion) if isempty(glyphcollection.glyphs) - return Rect3f(Point3f(0), Vec3f(0)) + return Rect3(Point3e(0), Vec3e(0)) end glyphorigins = glyphcollection.origins glyphbbs = gl_bboxes(glyphcollection) - bb = Rect3f() + bb = Rect3{Float64}() for (charo, glyphbb) in zip(glyphorigins, glyphbbs) - charbb = rotate_bbox(Rect3f(glyphbb), rotation) + charo + charbb = rotate_bbox(Rect3{Float64}(glyphbb), rotation) + charo if !isfinite_rect(bb) bb = charbb else @@ -75,9 +74,9 @@ end function boundingbox(layouts::AbstractArray{<:GlyphCollection}, positions, rotations) if isempty(layouts) - return Rect3f((0, 0, 0), (0, 0, 0)) + return Rect3{Float64}((0, 0, 0), (0, 0, 0)) else - bb = Rect3f() + bb = Rect3{Float64}() broadcast_foreach(layouts, positions, rotations) do layout, pos, rot if !isfinite_rect(bb) bb = boundingbox(layout, pos, rot) @@ -92,7 +91,7 @@ end function boundingbox(x::Text{<:Tuple{<:GlyphCollection}}) if x.space[] == x.markerspace[] - pos = to_ndim(Point3f, x.position[], 0) + pos = to_ndim(Point3e, x.position[], 0) else cam = parent_scene(x).camera transformed = apply_transform(x.transformation.transform_func[], x.position[]) @@ -103,7 +102,7 @@ end function boundingbox(x::Text{<:Tuple{<:AbstractArray{<:GlyphCollection}}}) if x.space[] == x.markerspace[] - pos = to_ndim.(Point3f, x.position[], 0) + pos = to_ndim.(Point3e, x.position[], 0) else cam = (parent_scene(x).camera,) transformed = apply_transform(x.transformation.transform_func[], x.position[]) @@ -113,7 +112,7 @@ function boundingbox(x::Text{<:Tuple{<:AbstractArray{<:GlyphCollection}}}) end function boundingbox(plot::Text) - bb = Rect3f() + bb = Rect3{Float64}() for p in plot.plots _bb = boundingbox(p) if !isfinite_rect(bb) diff --git a/src/layouting/data_limits.jl b/src/layouting/data_limits.jl index 4d3e624d2a5..9fe5528d8fb 100644 --- a/src/layouting/data_limits.jl +++ b/src/layouting/data_limits.jl @@ -120,7 +120,7 @@ function point_iterator(x::Volume) extremata = map(extrema∘to_value, axes) minpoint = Point3f(first.(extremata)...) widths = last.(extremata) .- first.(extremata) - rect = Rect3f(minpoint, Vec3f(widths)) + rect = Rect3(minpoint, Vec3(widths)) return unique(decompose(Point, rect)) end @@ -169,12 +169,12 @@ function iterate_transformed(plot) end function iterate_transformed(points, model, trans_func) - (to_ndim(Point3f, project(model, apply_transform(trans_func, point)), 0f0) for point in points) + (to_ndim(Point3{eltype(point)}, project(model, apply_transform(trans_func, point)), 0.0) for point in points) end function update_boundingbox!(bb_ref, point) if all(isfinite, point) - vec = to_ndim(Vec3f, point, 0.0) + vec = to_ndim(Vec3{Float64}, point, 0.0) bb_ref[] = update(bb_ref[], vec) end end @@ -210,14 +210,14 @@ function _update_rect(rect::Rect{N, T}, point::Point{N, T}) where {N, T} end function limits_from_transformed_points(points_iterator) - isempty(points_iterator) && return Rect3f() + isempty(points_iterator) && return Rect3{Float64}() first, rest = Iterators.peel(points_iterator) - bb = foldl(_update_rect, rest, init = Rect3f(first, zero(first))) + bb = foldl(_update_rect, rest, init = Rect3{Float64}(first, zero(first))) return bb end function data_limits(scenelike, exclude=(p)-> false) - bb_ref = Base.RefValue(Rect3f()) + bb_ref = Base.RefValue(Rect3{Float64}()) foreach_plot(scenelike) do plot if !exclude(plot) update_boundingbox!(bb_ref, data_limits(plot)) @@ -231,19 +231,19 @@ function data_limits(plot::Surface) mini_maxi = extrema_nan.((plot.x[], plot.y[], plot.z[])) mini = first.(mini_maxi) maxi = last.(mini_maxi) - return Rect3f(mini, maxi .- mini) + return Rect3{Float64}(mini, maxi .- mini) end function data_limits(plot::Heatmap) mini_maxi = extrema_nan.((plot.x[], plot.y[])) - mini = Vec3f(first.(mini_maxi)..., 0) - maxi = Vec3f(last.(mini_maxi)..., 0) - return Rect3f(mini, maxi .- mini) + mini = Vec3(first.(mini_maxi)..., 0) + maxi = Vec3(last.(mini_maxi)..., 0) + return Rect3{Float64}(mini, maxi .- mini) end function data_limits(plot::Image) mini_maxi = extrema_nan.((plot.x[], plot.y[])) - mini = Vec3f(first.(mini_maxi)..., 0) - maxi = Vec3f(last.(mini_maxi)..., 0) - return Rect3f(mini, maxi .- mini) + mini = Vec3(first.(mini_maxi)..., 0) + maxi = Vec3(last.(mini_maxi)..., 0) + return Rect3{Float64}(mini, maxi .- mini) end From 13ce7417e06c4c2acaca4801461c65cc92471bba Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 8 Jan 2023 18:27:43 +0100 Subject: [PATCH 04/49] get mesh working? --- CairoMakie/src/primitives.jl | 4 ++-- src/conversions.jl | 6 +++--- src/layouting/data_limits.jl | 10 +++++++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/CairoMakie/src/primitives.jl b/CairoMakie/src/primitives.jl index 765295e6d0a..4a6c13196c1 100644 --- a/CairoMakie/src/primitives.jl +++ b/CairoMakie/src/primitives.jl @@ -688,7 +688,7 @@ end function draw_mesh2D(scene, screen, @nospecialize(plot), @nospecialize(mesh)) @get_attribute(plot, (color,)) color = to_color(hasproperty(mesh, :color) ? mesh.color : color) - vs = decompose(Point2f, mesh)::Vector{Point2f} + vs = decompose(Point2{Float64}, mesh)::Vector{Point2{Float64}} fs = decompose(GLTriangleFace, mesh)::Vector{GLTriangleFace} uv = decompose_uv(mesh)::Union{Nothing, Vector{Vec2f}} model = plot.model[]::Mat4f @@ -708,7 +708,7 @@ function draw_mesh2D(scene, screen, @nospecialize(plot), @nospecialize(mesh)) end function draw_mesh2D(scene, screen, per_face_cols, space::Symbol, - vs::Vector{Point2f}, fs::Vector{GLTriangleFace}, model::Mat4f) + vs::Vector{Point2{Float64}}, fs::Vector{GLTriangleFace}, model::Mat4f) ctx = screen.context # Priorize colors of the mesh if present diff --git a/src/conversions.jl b/src/conversions.jl index 2543bd7ad3c..690a575b1dd 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -482,7 +482,7 @@ function convert_arguments( T::Type{<:Mesh}, x::RealVector, y::RealVector, z::RealVector ) - convert_arguments(T, Point3f.(x, y, z)) + convert_arguments(T, Point3e.(x, y, z)) end """ convert_arguments(Mesh, xyz::AbstractVector)::GLNormalMesh @@ -508,7 +508,7 @@ function convert_arguments(::Type{<:Mesh}, mesh::GeometryBasics.Mesh{N}) where { mesh = GeometryBasics.pointmeta(mesh, decompose(Vec3f, n)) end end - return (GeometryBasics.mesh(mesh, pointtype=Point{N, Float32}, facetype=GLTriangleFace),) + return (GeometryBasics.mesh(mesh, pointtype=Point{N, Float64}, facetype=GLTriangleFace),) end function convert_arguments( @@ -542,7 +542,7 @@ function convert_arguments( x::RealVector, y::RealVector, z::RealVector, indices::AbstractVector ) - return convert_arguments(T, Point3f.(x, y, z), indices) + return convert_arguments(T, Point3e.(x, y, z), indices) end """ diff --git a/src/layouting/data_limits.jl b/src/layouting/data_limits.jl index 9fe5528d8fb..2a33953d819 100644 --- a/src/layouting/data_limits.jl +++ b/src/layouting/data_limits.jl @@ -168,8 +168,11 @@ function iterate_transformed(plot) iterate_transformed(points, model, trans_func) end -function iterate_transformed(points, model, trans_func) - (to_ndim(Point3{eltype(point)}, project(model, apply_transform(trans_func, point)), 0.0) for point in points) +function iterate_transformed(points::Vector{<: VecTypes{N}}, model, trans_func) where N + Iterators.map(points) do point + p = apply_transform(trans_func, Point{N, Float64}(point)) + to_ndim(Point3e, project(model, p), 0.0) + end end function update_boundingbox!(bb_ref, point) @@ -200,7 +203,8 @@ function _update_rect(rect::Rect{N, T}, point::Point{N, T}) where {N, T} mi = minimum(rect) ma = maximum(rect) mis_mas = map(mi, ma, point) do _mi, _ma, _p - (isnan(_mi) ? _p : _p < _mi ? _p : _mi), (isnan(_ma) ? _p : _p > _ma ? _p : _ma) + (isnan(_mi) ? _p : _p < _mi ? _p : _mi), + (isnan(_ma) ? _p : _p > _ma ? _p : _ma) end new_o = map(first, mis_mas) new_w = map(mis_mas) do (mi, ma) From 10697546ebf42122e240bdcd6836f1b7e3a35897 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 8 Jan 2023 18:59:21 +0100 Subject: [PATCH 05/49] fix compilation --- src/layouting/data_limits.jl | 4 ++-- src/makielayout/blocks/scene.jl | 5 +++-- src/scenes.jl | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/layouting/data_limits.jl b/src/layouting/data_limits.jl index 2a33953d819..03526fe8c1b 100644 --- a/src/layouting/data_limits.jl +++ b/src/layouting/data_limits.jl @@ -168,9 +168,9 @@ function iterate_transformed(plot) iterate_transformed(points, model, trans_func) end -function iterate_transformed(points::Vector{<: VecTypes{N}}, model, trans_func) where N +function iterate_transformed(points, model, trans_func) Iterators.map(points) do point - p = apply_transform(trans_func, Point{N, Float64}(point)) + p = apply_transform(trans_func, Point{length(point), Float64}(point)) to_ndim(Point3e, project(model, p), 0.0) end end diff --git a/src/makielayout/blocks/scene.jl b/src/makielayout/blocks/scene.jl index f1c05989190..1cc790c983b 100644 --- a/src/makielayout/blocks/scene.jl +++ b/src/makielayout/blocks/scene.jl @@ -29,16 +29,17 @@ function initialize_block!(ls::LScene; scenekw = NamedTuple()) # Add axis on first plot!, if requested # update limits when scene limits change limits = lift(ls.scene.theme.limits) do lims - if lims === automatic + out = if lims === automatic dl = data_limits(ls.scene, p -> Makie.isaxis(p) || Makie.not_in_data_space(p)) if any(isinf, widths(dl)) || any(isinf, Makie.origin(dl)) - Rect3f((0f0, 0f0, 0f0), (1f0, 1f0, 1f0)) + Rect3((0.0, 0.0, 0.0), (1.0, 1.0, 1.0)) else dl end else lims end + Rect3{Float64}(out) end Makie.axis3d!(ls.scene, limits) # Make sure axis is always in pos 1 diff --git a/src/scenes.jl b/src/scenes.jl index 29633cf39d5..d2c574aeeb3 100644 --- a/src/scenes.jl +++ b/src/scenes.jl @@ -512,10 +512,10 @@ end function center!(scene::Scene, padding=0.01, exclude = not_in_data_space) bb = boundingbox(scene, exclude) - bb = transformationmatrix(scene)[] * bb + bb = Mat4{Float64}(transformationmatrix(scene)[]) * bb w = widths(bb) padd = w .* padding - bb = Rect3f(minimum(bb) .- padd, w .+ 2padd) + bb = Rect3{Float64}(minimum(bb) .- padd, w .+ 2padd) update_cam!(scene, bb) scene end From d561a3ee2aa3122d48f02cb8830fab902232c505 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 8 Jan 2023 21:38:52 +0100 Subject: [PATCH 06/49] get heatmap & image going --- CairoMakie/src/primitives.jl | 5 +++-- src/conversions.jl | 7 +++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CairoMakie/src/primitives.jl b/CairoMakie/src/primitives.jl index 4a6c13196c1..022f5f0024b 100644 --- a/CairoMakie/src/primitives.jl +++ b/CairoMakie/src/primitives.jl @@ -550,6 +550,7 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Unio ctx = screen.context image = primitive[3][] xs, ys = primitive[1][], primitive[2][] + if !(xs isa AbstractVector) l, r = extrema(xs) N = size(image, 1) @@ -590,8 +591,8 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Unio # find projected image corners # this already takes care of flipping the image to correct cairo orientation space = to_value(get(primitive, :space, :data)) - xy = project_position(scene, space, Point2f(first.(imsize)), model) - xymax = project_position(scene, space, Point2f(last.(imsize)), model) + xy = project_position(scene, space, Point2{Float64}(first.(imsize)), model) + xymax = project_position(scene, space, Point2{Float64}(last.(imsize)), model) w, h = xymax .- xy can_use_fast_path = !(is_vector && !interpolate) && regular_grid && identity_transform diff --git a/src/conversions.jl b/src/conversions.jl index 690a575b1dd..b3cd4ab9473 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -297,10 +297,10 @@ If they are centers, convert to edges. Convert eltypes to `Float32` and return outputs as a `Tuple`. """ function convert_arguments(SL::SurfaceLike, x::AbstractVecOrMat{<: Number}, y::AbstractVecOrMat{<: Number}, z::AbstractMatrix{<: Union{Number, Colorant}}) - return map(el32convert, adjust_axes(SL, x, y, z)) + return adjust_axes(SL, x, y, z) end function convert_arguments(SL::SurfaceLike, x::AbstractVecOrMat{<: Number}, y::AbstractVecOrMat{<: Number}, z::AbstractMatrix{<:Number}) - return map(el32convert, adjust_axes(SL, x, y, z)) + return adjust_axes(SL, x, y, z) end convert_arguments(sl::SurfaceLike, x::AbstractMatrix, y::AbstractMatrix) = convert_arguments(sl, x, y, zeros(size(y))) @@ -634,6 +634,9 @@ function el32convert(x::AbstractArray{T, N}) where {T<:Union{Missing, <: Number} return (ismissing(elem) ? NaN32 : convert(Float32, elem))::Float32 end::Array{Float32, N} end + + + """ to_triangles(indices) From d7565618c106054edc000f4f196122f673e6fbf1 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 8 Jan 2023 21:49:46 +0100 Subject: [PATCH 07/49] get meshscatter working --- CairoMakie/src/primitives.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CairoMakie/src/primitives.jl b/CairoMakie/src/primitives.jl index 022f5f0024b..3dee00884ef 100644 --- a/CairoMakie/src/primitives.jl +++ b/CairoMakie/src/primitives.jl @@ -754,7 +754,7 @@ function draw_mesh3D(scene, screen, attributes, mesh; pos = Vec4f(0), scale = 1f matcap = to_value(get(attributes, :matcap, nothing)) color = hasproperty(mesh, :color) ? mesh.color : color - meshpoints = decompose(Point3f, mesh)::Vector{Point3f} + meshpoints = decompose(Point3{Float64}, mesh)::Vector{Point3{Float64}} meshfaces = decompose(GLTriangleFace, mesh)::Vector{GLTriangleFace} meshnormals = decompose_normals(mesh)::Vector{Vec3f} meshuvs = texturecoordinates(mesh)::Union{Nothing, Vector{Vec2f}} @@ -800,8 +800,8 @@ function draw_mesh3D( vs = broadcast(meshpoints, (func,)) do v, f # Should v get a nan2zero? v = Makie.apply_transform(f, v, space) - p4d = to_ndim(Vec4f, scale .* to_ndim(Vec3f, v, 0f0), 1f0) - view * (model * p4d .+ to_ndim(Vec4f, pos, 0f0)) + p4d = to_ndim(Vec4{Float64}, scale .* to_ndim(Vec3{Float64}, v, 0.0), 1.0) + view * (model * p4d .+ to_ndim(Vec4{Float64}, pos, 0.0)) end ns = map(n -> normalize(normalmatrix * n), meshnormals) From 23e7cd1d06c37e453c9d17e25ab5e7331189a7c4 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 8 Jan 2023 22:28:03 +0100 Subject: [PATCH 08/49] fix compilation --- src/conversions.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/conversions.jl b/src/conversions.jl index b3cd4ab9473..fd19bef1b5d 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -297,10 +297,12 @@ If they are centers, convert to edges. Convert eltypes to `Float32` and return outputs as a `Tuple`. """ function convert_arguments(SL::SurfaceLike, x::AbstractVecOrMat{<: Number}, y::AbstractVecOrMat{<: Number}, z::AbstractMatrix{<: Union{Number, Colorant}}) - return adjust_axes(SL, x, y, z) + _x, _y, _z = adjust_axes(SL, x, y, z) + return elconvert(Float64, _x), elconvert(Float64, _y), el32convert(_z) end function convert_arguments(SL::SurfaceLike, x::AbstractVecOrMat{<: Number}, y::AbstractVecOrMat{<: Number}, z::AbstractMatrix{<:Number}) - return adjust_axes(SL, x, y, z) + _x, _y, _z = adjust_axes(SL, x, y, z) + return elconvert(Float64, _x), elconvert(Float64, _y), el32convert(_z) end convert_arguments(sl::SurfaceLike, x::AbstractMatrix, y::AbstractMatrix) = convert_arguments(sl, x, y, zeros(size(y))) From feca2c743a4505635f172c119daa195a71546208 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 8 Jan 2023 22:29:56 +0100 Subject: [PATCH 09/49] get Axis3 going --- src/camera/projection_math.jl | 8 ++++---- src/makielayout/blocks/axis.jl | 6 +++--- src/makielayout/blocks/axis3d.jl | 28 ++++++++++++++-------------- src/makielayout/types.jl | 4 ++-- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/camera/projection_math.jl b/src/camera/projection_math.jl index c7ac88f7436..6d0edfe8da2 100644 --- a/src/camera/projection_math.jl +++ b/src/camera/projection_math.jl @@ -297,12 +297,12 @@ function project(matrix::Mat4, p::VT, dim4 = 1.0) where {N, T, VT <: VecTypes{N, to_ndim(VT, p, 0.0) end -function project(proj_view::Mat4, resolution::Vec2, point::Point) - p4d = to_ndim(Vec4f, to_ndim(Vec3f, point, 0f0), 1f0) +function project(proj_view::Mat4, resolution::Vec2, point::Point{N, T}) where {N, T} + p4d = to_ndim(Vec4{T}, to_ndim(Vec3{T}, point, 0.0), 1.0) clip = proj_view * p4d p = (clip ./ clip[4])[Vec(1, 2)] - p = Vec2f(p[1], p[2]) - return (((p .+ 1f0) ./ 2f0) .* (resolution .- 1f0)) .+ 1f0 + p = Vec2{T}(p[1], p[2]) + return (((p .+ 1) ./ 2) .* (resolution .- 1)) .+ 1 end function project_point2(mat4::Mat4, point2::Point2) diff --git a/src/makielayout/blocks/axis.jl b/src/makielayout/blocks/axis.jl index be3da6616a9..a987dff15a2 100644 --- a/src/makielayout/blocks/axis.jl +++ b/src/makielayout/blocks/axis.jl @@ -624,9 +624,9 @@ function reset_limits!(ax; xauto = true, yauto = true, zauto = true) if ax isa Axis ax.targetlimits[] = Rect2{Float64}(xlims[1], ylims[1], xlims[2]-xlims[1], ylims[2]-ylims[1]) elseif ax isa Axis3 - ax.targetlimits[] = Rect3f( - Vec3f(xlims[1], ylims[1], zlims[1]), - Vec3f(xlims[2] - xlims[1], ylims[2] - ylims[1], zlims[2] - zlims[1]), + ax.targetlimits[] = Rect3( + Vec3(xlims[1], ylims[1], zlims[1]), + Vec3(xlims[2] - xlims[1], ylims[2] - ylims[1], zlims[2] - zlims[1]), ) end nothing diff --git a/src/makielayout/blocks/axis3d.jl b/src/makielayout/blocks/axis3d.jl index bad81bdc8c8..c5547a0d37d 100644 --- a/src/makielayout/blocks/axis3d.jl +++ b/src/makielayout/blocks/axis3d.jl @@ -9,7 +9,7 @@ function initialize_block!(ax::Axis3) end notify(ax.protrusions) - finallimits = Observable(Rect3f(Vec3f(0f0, 0f0, 0f0), Vec3f(100f0, 100f0, 100f0))) + finallimits = Observable(Rect3(Vec3(0.0), Vec3(100.0))) setfield!(ax, :finallimits, finallimits) scenearea = lift(round_to_IRect2D, ax.layoutobservables.computedbbox) @@ -218,10 +218,10 @@ function calculate_matrices(limits, px_area, elev, azim, perspectiveness, aspect view_matrix = lookat_matrix * scale_matrix projection_matrix = projectionmatrix(view_matrix, limits, eyepos, radius, azim, elev, angle, w, h, scales, viewmode) - + # for eyeposition dependent algorithms, we need to present the position as if # there was no scaling applied - eyeposition = Vec3f(inv(scale_matrix) * Vec4f(eyepos..., 1)) + eyeposition = Vec3{Float64}(inv(scale_matrix) * Vec4(eyepos..., 1.0)) view_matrix, projection_matrix, eyeposition end @@ -240,8 +240,8 @@ function projectionmatrix(viewmatrix, limits, eyepos, radius, azim, elev, angle, pm = Makie.perspectiveprojection(Float64, angle, aspect_ratio, near, far) if viewmode in (:fitzoom, :stretch) - points = decompose(Point3f, limits) - projpoints = Ref(pm * viewmatrix) .* to_ndim.(Point4f, points, 1) + points = decompose(Point3{Float64}, limits) + projpoints = Ref(pm * viewmatrix) .* to_ndim.(Point4{Float64}, points, 1) maxx = maximum(x -> abs(x[1] / x[4]), projpoints) maxy = maximum(x -> abs(x[2] / x[4]), projpoints) @@ -302,15 +302,15 @@ function autolimits!(ax::Axis3) ylims = getlimits(ax, 2) zlims = getlimits(ax, 3) - ori = Vec3f(xlims[1], ylims[1], zlims[1]) - widths = Vec3f(xlims[2] - xlims[1], ylims[2] - ylims[1], zlims[2] - zlims[1]) + ori = Vec3(xlims[1], ylims[1], zlims[1]) + widths = Vec3(xlims[2] - xlims[1], ylims[2] - ylims[1], zlims[2] - zlims[1]) enlarge_factor = 0.1 nori = ori .- (0.5 * enlarge_factor) * widths nwidths = widths .* (1 + enlarge_factor) - lims = Rect3f(nori, nwidths) + lims = Rect3(nori, nwidths) ax.finallimits[] = lims nothing @@ -453,10 +453,10 @@ end # small z value function to_topscene_z_2d(p3d, scene) o = scene.px_area[].origin - p2d = Point2f(o + Makie.project(scene, p3d)) + p2d = Point2{Float64}(o + Makie.project(scene, p3d)) # -10000 is an arbitrary weird constant that in preliminary testing didn't seem # to clip into plot objects anymore - Point3f(p2d..., -10000) + return Point3(p2d..., -10000.0) end function add_ticks_and_ticklabels!(topscene, scene, ax, dim::Int, limits, ticknode, miv, min1, min2, azimuth) @@ -518,7 +518,7 @@ function add_ticks_and_ticklabels!(topscene, scene, ax, dim::Int, limits, tickno tick_segments, ticklabels, attr(:ticklabelpad)) do pxa, pv, ticksegs, ticklabs, pad o = pxa.origin - + points = map(ticksegs) do (tstart, tend) tstartp = Point2f(o + Makie.project(scene, tstart)) tendp = Point2f(o + Makie.project(scene, tend)) @@ -550,7 +550,7 @@ function add_ticks_and_ticklabels!(topscene, scene, ax, dim::Int, limits, tickno translate!(ticklabels, 0, 0, 1000) - label_position = Observable(Point2f(0)) + label_position = Observable(Point2(0.0)) label_rotation = Observable(0f0) label_align = Observable((:center, :top)) @@ -569,8 +569,8 @@ function add_ticks_and_ticklabels!(topscene, scene, ax, dim::Int, limits, tickno p2 = dpoint(maximum(lims)[dim], f1, f2) # project them into screen space - pp1 = Point2f(o + Makie.project(scene, p1)) - pp2 = Point2f(o + Makie.project(scene, p2)) + pp1 = Point2e(o + Makie.project(scene, p1)) + pp2 = Point2e(o + Makie.project(scene, p2)) # find the midpoint midpoint = (pp1 + pp2) ./ 2 diff --git a/src/makielayout/types.jl b/src/makielayout/types.jl index 18a7d70a4eb..14f8ac8a0eb 100644 --- a/src/makielayout/types.jl +++ b/src/makielayout/types.jl @@ -1147,7 +1147,7 @@ end @Block Axis3 begin scene::Scene - finallimits::Observable{Rect3f} + finallimits::Observable{Rect3{Float64}} mouseeventhandle::MouseEventHandle scrollevents::Observable{ScrollEvent} keysevents::Observable{KeysEvent} @@ -1366,7 +1366,7 @@ end "Controls if the xz panel is visible" xzpanelvisible = true "The limits that the axis tries to set given other constraints like aspect. Don't set this directly, use `xlims!`, `ylims!` or `limits!` instead." - targetlimits = Rect3f(Vec3f(0, 0, 0), Vec3f(1, 1, 1)) + targetlimits = Rect3(Vec3(0.0), Vec3(1.0)) "The limits that the user has manually set. They are reinstated when calling `reset_limits!` and are set to nothing by `autolimits!`. Can be either a tuple (xlow, xhigh, ylow, high, zlow, zhigh) or a tuple (nothing_or_xlims, nothing_or_ylims, nothing_or_zlims). Are set by `xlims!`, `ylims!`, `zlims!` and `limits!`." limits = (nothing, nothing, nothing) "The relative margins added to the autolimits in x direction." From 230e8ec0210356421813dcaa5e056bf4a0d2c7ca Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 8 Jan 2023 22:34:45 +0100 Subject: [PATCH 10/49] get surface going --- src/utilities/utilities.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utilities/utilities.jl b/src/utilities/utilities.jl index 1ffd98deb0f..8aa54e18bd1 100644 --- a/src/utilities/utilities.jl +++ b/src/utilities/utilities.jl @@ -330,7 +330,7 @@ Allows to supply `f`, which gets applied to every point. """ function matrix_grid(f, x::AbstractArray, y::AbstractArray, z::AbstractMatrix) g = map(CartesianIndices(z)) do i - return f(Point3f(get_dim(x, i, 1, size(z)), get_dim(y, i, 2, size(z)), z[i])) + return f(Point3(get_dim(x, i, 1, size(z)), get_dim(y, i, 2, size(z)), z[i])) end return vec(g) end From 77998bce8898449bc25ae6ac113a78fd1f706368 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 8 Jan 2023 23:42:32 +0100 Subject: [PATCH 11/49] fixes --- src/layouting/data_limits.jl | 2 +- src/makielayout/blocks/axis.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/layouting/data_limits.jl b/src/layouting/data_limits.jl index 03526fe8c1b..703834ce4c4 100644 --- a/src/layouting/data_limits.jl +++ b/src/layouting/data_limits.jl @@ -185,7 +185,7 @@ end function update_boundingbox!(bb_ref, bb::Rect) # ref is uninitialized, so just set it to the first bb if !isfinite_rect(bb_ref[]) - bb_ref[] = bb + bb_ref[] = Rect3{Float64}(bb) # TODO check when this avoids an error # hexbin scale, hexbin threshold return end # don't update if not finite diff --git a/src/makielayout/blocks/axis.jl b/src/makielayout/blocks/axis.jl index a987dff15a2..85177f64a5d 100644 --- a/src/makielayout/blocks/axis.jl +++ b/src/makielayout/blocks/axis.jl @@ -1316,7 +1316,7 @@ Makie.transform_func(ax::Axis) = Makie.transform_func(ax.scene) # we don't pick values that are invalid, such as 0 for log etc. function defaultlimits(userlimits::Tuple{Real, Real, Real, Real}, xscale, yscale) # BBox(userlimits...) - x0, x1, y0, x1 = userlimits + x0, x1, y0, y1 = userlimits Rect2{Float64}(x0, y0, x1-x0, y1-y0) end From 9d8e919042ec0c556e275fc30e4ac278585bab1d Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 8 Jan 2023 23:49:07 +0100 Subject: [PATCH 12/49] get GLMakie working again --- GLMakie/src/GLAbstraction/GLUniforms.jl | 4 +-- GLMakie/src/drawing_primitives.jl | 34 ++++++++++++++----------- src/camera/camera.jl | 12 ++++----- src/conversions.jl | 2 ++ src/types.jl | 6 ++--- 5 files changed, 32 insertions(+), 26 deletions(-) diff --git a/GLMakie/src/GLAbstraction/GLUniforms.jl b/GLMakie/src/GLAbstraction/GLUniforms.jl index 17f83cc7ec8..8aacf04f0c7 100644 --- a/GLMakie/src/GLAbstraction/GLUniforms.jl +++ b/GLMakie/src/GLAbstraction/GLUniforms.jl @@ -15,11 +15,11 @@ opengl_postfix(T) = error("Object $T is not a supported uniform element type") opengl_prefix(x::Type{T}) where {T <: Union{FixedPoint, Float32, Float16}} = "" -opengl_prefix(x::Type{T}) where {T <: Float64} = "d" +opengl_prefix(x::Type{T}) where {T <: Float64} = error("Float64") # "d" opengl_prefix(x::Type{Cint}) = "i" opengl_prefix(x::Type{T}) where {T <: Union{Cuint, UInt8, UInt16}} = "u" -opengl_postfix(x::Type{Float64}) = "dv" +opengl_postfix(x::Type{Float64}) = error("Float64") # "dv" opengl_postfix(x::Type{Float32}) = "fv" opengl_postfix(x::Type{Cint}) = "iv" opengl_postfix(x::Type{Cuint}) = "uiv" diff --git a/GLMakie/src/drawing_primitives.jl b/GLMakie/src/drawing_primitives.jl index dc438ca4796..7f696b86f8e 100644 --- a/GLMakie/src/drawing_primitives.jl +++ b/GLMakie/src/drawing_primitives.jl @@ -47,29 +47,29 @@ end function connect_camera!(gl_attributes, cam, space = gl_attributes[:space]) for key in (:pixel_space, :resolution, :eyeposition) # Overwrite these, user defined attributes shouldn't use those! - gl_attributes[key] = copy(getfield(cam, key)) + gl_attributes[key] = getfield(cam, key) end get!(gl_attributes, :view) do return lift(cam.view, space) do view, space - return is_data_space(space) ? view : Mat4f(I) + return is_data_space(space) ? Mat4f(view) : Mat4f(I) end end get!(gl_attributes, :normalmatrix) do return lift(gl_attributes[:view], gl_attributes[:model]) do v, m i = Vec(1, 2, 3) - return transpose(inv(v[i, i] * m[i, i])) + return transpose(inv(Mat3f(v[i, i]) * Mat3f(m[i, i]))) end end get!(gl_attributes, :projection) do return lift(cam.projection, cam.pixel_space, space) do _, _, space - return Makie.space_to_clip(cam, space, false) + return Mat4f(Makie.space_to_clip(cam, space, false)) end end get!(gl_attributes, :projectionview) do return lift(cam.projectionview, cam.pixel_space, space) do _, _, space - Makie.space_to_clip(cam, space, true) + Mat4f(Makie.space_to_clip(cam, space, true)) end end @@ -203,12 +203,13 @@ function draw_atomic(screen::Screen, scene::Scene, @nospecialize(x::Union{Scatte space = get(gl_attributes, :space, :data) # needs to happen before connect_camera! call positions = handle_view(x[1], gl_attributes) positions = apply_transform(transform_func_obs(x), positions, space) + positions = map(el32convert, positions) if isa(x, Scatter) mspace = get(gl_attributes, :markerspace, :pixel) cam = scene.camera gl_attributes[:preprojection] = map(space, mspace, cam.projectionview, cam.resolution) do space, mspace, _, _ - return Makie.clip_to_space(cam, mspace) * Makie.space_to_clip(cam, space) + return Mat4f(Makie.clip_to_space(cam, mspace) * Makie.space_to_clip(cam, space)) end # fast pixel does its own setup if !(marker[] isa FastPixel) @@ -274,6 +275,7 @@ function draw_atomic(screen::Screen, scene::Scene, @nospecialize(x::Lines)) space = get(gl_attributes, :space, :data) # needs to happen before connect_camera! call positions = handle_view(x[1], data) positions = apply_transform(transform_func_obs(x), positions, space) + positions = map(el32convert, positions) handle_intensities!(data) connect_camera!(data, scene.camera) return draw_lines(screen, positions, data) @@ -294,6 +296,7 @@ function draw_atomic(screen::Screen, scene::Scene, @nospecialize(x::LineSegments space = get(gl_attributes, :space, :data) # needs to happen before connect_camera! call positions = handle_view(x.converted[1], data) positions = apply_transform(transform_func_obs(x), positions, space) + positions = map(el32convert, positions) if haskey(data, :color) && data[:color][] isa AbstractVector{<: Number} c = pop!(data, :color) data[:color] = el32convert(c) @@ -330,7 +333,6 @@ function draw_atomic(screen::Screen, scene::Scene, lift(getindex, glyph_data, i) end - filter!(gl_attributes) do (k, v) # These are liftkeys without model !(k in ( @@ -373,9 +375,8 @@ function draw_atomic(screen::Screen, scene::Scene, gl_attributes[:distancefield] = get_texture!(atlas) gl_attributes[:visible] = x.visible cam = scene.camera - # gl_attributes[:preprojection] = Observable(Mat4f(I)) gl_attributes[:preprojection] = map(space, markerspace, cam.projectionview, cam.resolution) do s, ms, pv, res - Makie.clip_to_space(cam, ms) * Makie.space_to_clip(cam, s) + Mat4f(Makie.clip_to_space(cam, ms) * Makie.space_to_clip(cam, s)) end connect_camera!(gl_attributes, cam, markerspace) @@ -458,10 +459,10 @@ function draw_atomic(screen::Screen, scene::Scene, x::Image) end function update_positions(mesh::GeometryBasics.Mesh, positions) - points = coordinates(mesh) + points = el32convert(positions) attr = GeometryBasics.attributes(points) delete!(attr, :position) # position == metafree(points) - return GeometryBasics.Mesh(meta(positions; attr...), faces(mesh)) + return GeometryBasics.Mesh(meta(points; attr...), faces(mesh)) end function mesh_inner(screen::Screen, mesh, transfunc, gl_attributes, space=:data) @@ -492,9 +493,12 @@ function mesh_inner(screen::Screen, mesh, transfunc, gl_attributes, space=:data) end mesh = map(mesh, transfunc, space) do mesh, func, space if !Makie.is_identity_transform(func) - return update_positions(mesh, apply_transform.(Ref(func), mesh.position, space)) + pos = apply_transform.(Ref(func), mesh.position, space) + else + pos = mesh.position end - return mesh + m = update_positions(mesh, pos) + return m end return draw_mesh(screen, mesh, gl_attributes) end @@ -545,14 +549,14 @@ function draw_atomic(screen::Screen, scene::Scene, x::Surface) xypos = map(t, x[1], x[2], space) do t, x, y, space # Only if transform doesn't do anything, we can stay linear in 1/2D if Makie.is_identity_transform(t) - return (x, y) + return (el32convert(x), el32convert(y)) else matrix = if x isa AbstractMatrix && y isa AbstractMatrix apply_transform.((t,), Point.(x, y), space) else # If we do any transformation, we have to assume things aren't on the grid anymore # so x + y need to become matrices. - [apply_transform(t, Point(x, y), space) for x in x, y in y] + Point3f[apply_transform(t, Point(x, y), space) for x in x, y in y] end return (first.(matrix), last.(matrix)) end diff --git a/src/camera/camera.jl b/src/camera/camera.jl index 68a9b40154f..8c8f2937265 100644 --- a/src/camera/camera.jl +++ b/src/camera/camera.jl @@ -69,10 +69,10 @@ end function Camera(px_area) pixel_space = lift(px_area) do window_size - nearclip = -10_000.0 - farclip = 10_000.0 - w, h = Float64.(widths(window_size)) - return orthographicprojection(0.0, w, 0.0, h, nearclip, farclip) + nearclip = -10_000f0 + farclip = 10_000f0 + w, h = Float32.(widths(window_size)) + return orthographicprojection(0f0, w, 0f0, h, nearclip, farclip) end view = Observable(Mat4{Float64}(I)) proj = Observable(Mat4{Float64}(I)) @@ -82,8 +82,8 @@ function Camera(px_area) view, proj, proj_view, - lift(a-> Vec2e(widths(a)), px_area), - Observable(Vec3e(1)), + lift(a-> Vec2f(widths(a)), px_area), + Observable(Vec3f(1)), ObserverFunction[] ) end diff --git a/src/conversions.jl b/src/conversions.jl index fd19bef1b5d..4a123c86a53 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -624,6 +624,8 @@ float32type(x::Type) = Float32 float32type(::Type{<: RGB}) = RGB{Float32} float32type(::Type{<: RGBA}) = RGBA{Float32} float32type(::Type{<: Colorant}) = RGBA{Float32} +float32type(::Type{<: Point{N}}) where {N} = Point{N, Float32} +float32type(::Type{<: Vec{N}}) where {N} = Vec{N, Float32} float32type(x::AbstractArray{T}) where T = float32type(T) float32type(x::T) where T = float32type(T) el32convert(x::AbstractArray) = elconvert(float32type(x), x) diff --git a/src/types.jl b/src/types.jl index ebe4180dd7d..a657da6ebc2 100644 --- a/src/types.jl +++ b/src/types.jl @@ -205,7 +205,7 @@ struct Camera """ projection used to convert pixel to device units """ - pixel_space::Observable{Mat4{Float64}} + pixel_space::Observable{Mat4f} """ View matrix is usually used to rotate, scale and translate the scene @@ -225,12 +225,12 @@ struct Camera """ resolution of the canvas this camera draws to """ - resolution::Observable{Vec2{Float64}} + resolution::Observable{Vec2f} """ Eye position of the camera, sued for e.g. ray tracing. """ - eyeposition::Observable{Vec3{Float64}} + eyeposition::Observable{Vec3f} # TODO Should this be Float64? """ To make camera interactive, steering observables are connected to the different matrices. From d7e2306c5478ff0edb6bf3a3d04acb658655b938 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 9 Jan 2023 00:00:13 +0100 Subject: [PATCH 13/49] fix GLMakie tests --- GLMakie/src/drawing_primitives.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GLMakie/src/drawing_primitives.jl b/GLMakie/src/drawing_primitives.jl index 7f696b86f8e..186daf37535 100644 --- a/GLMakie/src/drawing_primitives.jl +++ b/GLMakie/src/drawing_primitives.jl @@ -460,7 +460,7 @@ end function update_positions(mesh::GeometryBasics.Mesh, positions) points = el32convert(positions) - attr = GeometryBasics.attributes(points) + attr = GeometryBasics.attributes(mesh) delete!(attr, :position) # position == metafree(points) return GeometryBasics.Mesh(meta(points; attr...), faces(mesh)) end From 1084f4a46c858cf4f4b5b5e40f1865af2b71f75e Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 9 Jan 2023 00:31:52 +0100 Subject: [PATCH 14/49] fix CairoMakie tests --- src/conversions.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/conversions.jl b/src/conversions.jl index 4a123c86a53..814aead8548 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -327,13 +327,13 @@ and stores the `ClosedInterval` to `n` and `m`, plus the original matrix in a Tu `P` is the plot Type (it is optional). """ function convert_arguments(sl::SurfaceLike, data::AbstractMatrix) - n, m = Float32.(size(data)) - convert_arguments(sl, 0f0 .. n, 0f0 .. m, el32convert(data)) + n, m = Float64.(size(data)) + convert_arguments(sl, 0.0 .. n, 0.0 .. m, el32convert(data)) end function convert_arguments(ds::DiscreteSurface, data::AbstractMatrix) - n, m = Float32.(size(data)) - convert_arguments(ds, edges(1:n), edges(1:m), el32convert(data)) + n, m = Float64.(size(data)) + convert_arguments(ds, edges(1.0:n), edges(1.0:m), el32convert(data)) end function convert_arguments(SL::SurfaceLike, x::AbstractVector{<:Number}, y::AbstractVector{<:Number}, z::AbstractVector{<:Number}) @@ -620,14 +620,14 @@ to_linspace(interval, N) = range(minimum(interval), stop = maximum(interval), le Converts the elemen array type to `T1` without making a copy if the element type matches """ elconvert(::Type{T1}, x::AbstractArray{T2, N}) where {T1, T2, N} = convert(AbstractArray{T1, N}, x) -float32type(x::Type) = Float32 +float32type(::Type) = Float32 float32type(::Type{<: RGB}) = RGB{Float32} float32type(::Type{<: RGBA}) = RGBA{Float32} float32type(::Type{<: Colorant}) = RGBA{Float32} float32type(::Type{<: Point{N}}) where {N} = Point{N, Float32} float32type(::Type{<: Vec{N}}) where {N} = Vec{N, Float32} -float32type(x::AbstractArray{T}) where T = float32type(T) -float32type(x::T) where T = float32type(T) +float32type(::AbstractArray{T}) where T = float32type(T) +float32type(::T) where T = float32type(T) el32convert(x::AbstractArray) = elconvert(float32type(x), x) el32convert(x::AbstractArray{Float32}) = x el32convert(x::Observable) = lift(el32convert, x) From ee1022bc95d3b1e5aeff108d42f0b996c0551a31 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 9 Jan 2023 00:32:24 +0100 Subject: [PATCH 15/49] remove duplicate convert? --- src/conversions.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/conversions.jl b/src/conversions.jl index 814aead8548..ae63d8a035d 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -300,10 +300,10 @@ function convert_arguments(SL::SurfaceLike, x::AbstractVecOrMat{<: Number}, y::A _x, _y, _z = adjust_axes(SL, x, y, z) return elconvert(Float64, _x), elconvert(Float64, _y), el32convert(_z) end -function convert_arguments(SL::SurfaceLike, x::AbstractVecOrMat{<: Number}, y::AbstractVecOrMat{<: Number}, z::AbstractMatrix{<:Number}) - _x, _y, _z = adjust_axes(SL, x, y, z) - return elconvert(Float64, _x), elconvert(Float64, _y), el32convert(_z) -end +# function convert_arguments(SL::SurfaceLike, x::AbstractVecOrMat{<: Number}, y::AbstractVecOrMat{<: Number}, z::AbstractMatrix{<:Number}) +# _x, _y, _z = adjust_axes(SL, x, y, z) +# return elconvert(Float64, _x), elconvert(Float64, _y), el32convert(_z) +# end convert_arguments(sl::SurfaceLike, x::AbstractMatrix, y::AbstractMatrix) = convert_arguments(sl, x, y, zeros(size(y))) From 48d9b97246b03023d1c8b0c9f8f5f18402411630 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Tue, 10 Jan 2023 10:34:54 +0100 Subject: [PATCH 16/49] get WGLMakie working --- GLMakie/src/drawing_primitives.jl | 9 +-------- WGLMakie/src/imagelike.jl | 15 +++++++++------ WGLMakie/src/meshes.jl | 6 +++--- WGLMakie/src/particles.jl | 12 ++++++++---- WGLMakie/src/serialization.jl | 7 ++++++- src/conversions.jl | 10 ++++++++++ 6 files changed, 37 insertions(+), 22 deletions(-) diff --git a/GLMakie/src/drawing_primitives.jl b/GLMakie/src/drawing_primitives.jl index 186daf37535..688e3343b0a 100644 --- a/GLMakie/src/drawing_primitives.jl +++ b/GLMakie/src/drawing_primitives.jl @@ -458,13 +458,6 @@ function draw_atomic(screen::Screen, scene::Scene, x::Image) end end -function update_positions(mesh::GeometryBasics.Mesh, positions) - points = el32convert(positions) - attr = GeometryBasics.attributes(mesh) - delete!(attr, :position) # position == metafree(points) - return GeometryBasics.Mesh(meta(points; attr...), faces(mesh)) -end - function mesh_inner(screen::Screen, mesh, transfunc, gl_attributes, space=:data) # signals not supported for shading yet gl_attributes[:shading] = to_value(pop!(gl_attributes, :shading)) @@ -497,7 +490,7 @@ function mesh_inner(screen::Screen, mesh, transfunc, gl_attributes, space=:data) else pos = mesh.position end - m = update_positions(mesh, pos) + m = el32convert(mesh, pos) return m end return draw_mesh(screen, mesh, gl_attributes) diff --git a/WGLMakie/src/imagelike.jl b/WGLMakie/src/imagelike.jl index f27b422223e..305416871de 100644 --- a/WGLMakie/src/imagelike.jl +++ b/WGLMakie/src/imagelike.jl @@ -30,7 +30,7 @@ function draw_mesh(mscene::Scene, mesh, plot; uniforms...) get!(uniforms, :interpolate_in_fragment_shader, true) uniforms[:normalmatrix] = map(mscene.camera.view, plot.model) do v, m i = Vec(1, 2, 3) - return transpose(inv(v[i, i] * m[i, i])) + return Mat3f(transpose(inv(v[i, i] * m[i, i]))) end # id + picking gets filled in JS, needs to be here to emit the correct shader uniforms @@ -48,6 +48,7 @@ function limits_to_uvmesh(plot) px, py, pz = plot[1], plot[2], plot[3] px = map((x, z)-> xy_convert(x, size(z, 1)), px, pz) py = map((y, z)-> xy_convert(y, size(z, 2)), py, pz) + @info px # Special path for ranges of length 2 which # can be displayed as a rectangle t = Makie.transform_func_obs(plot)[] @@ -55,19 +56,20 @@ function limits_to_uvmesh(plot) rect = lift(px, py) do x, y xmin, xmax = extrema(x) ymin, ymax = extrema(y) - return Rect2(xmin, ymin, xmax - xmin, ymax - ymin) + return Rect2f(xmin, ymin, xmax - xmin, ymax - ymin) end positions = Buffer(lift(rect-> decompose(Point2f, rect), rect)) faces = Buffer(lift(rect -> decompose(GLTriangleFace, rect), rect)) uv = Buffer(lift(decompose_uv, rect)) else - grid(x, y, trans, space) = Makie.matrix_grid(p-> apply_transform(trans, p, space), x, y, zeros(length(x), length(y))) - rect = lift((x, y) -> Tesselation(Rect2(0f0, 0f0, 1f0, 1f0), (length(x), length(y))), px, py) + # TODO can we skip the second el32converet? + grid(x, y, trans, space) = el32convert(Makie.matrix_grid(p-> apply_transform(trans, p, space), x, y, zeros(length(x), length(y)))) + rect = lift((x, y) -> Tesselation(Rect2f(0f0, 0f0, 1f0, 1f0), (length(x), length(y))), px, py) positions = Buffer(lift(grid, px, py, t, get(plot, :space, :data))) faces = Buffer(lift(r -> decompose(GLTriangleFace, r), rect)) uv = Buffer(lift(decompose_uv, rect)) end - + @info positions vertices = GeometryBasics.meta(positions; uv=uv) return GeometryBasics.Mesh(vertices, faces) @@ -84,7 +86,7 @@ end function create_shader(mscene::Scene, plot::Surface) # TODO OWN OPTIMIZED SHADER ... Or at least optimize this a bit more ... px, py, pz = plot[1], plot[2], plot[3] - grid(x, y, z, trans, space) = Makie.matrix_grid(p-> apply_transform(trans, p, space), x, y, z) + grid(x, y, z, trans, space) = el32convert(Makie.matrix_grid(p-> apply_transform(trans, p, space), x, y, z)) positions = Buffer(lift(grid, px, py, pz, transform_func_obs(plot), get(plot, :space, :data))) rect = lift(z -> Tesselation(Rect2(0f0, 0f0, 1f0, 1f0), size(z)), pz) faces = Buffer(lift(r -> decompose(GLTriangleFace, r), rect)) @@ -119,6 +121,7 @@ function create_shader(mscene::Scene, plot::Union{Heatmap, Image}) color = Sampler(map(x -> el32convert(x'), image); minfilter=to_value(get(plot, :interpolate, false)) ? :linear : :nearest) mesh = limits_to_uvmesh(plot) + @info mesh plot_attributes = copy(plot.attributes) if eltype(color) <: Colorant delete!(plot_attributes, :colormap) diff --git a/WGLMakie/src/meshes.jl b/WGLMakie/src/meshes.jl index 8abdfb832b2..72e7162eaa7 100644 --- a/WGLMakie/src/meshes.jl +++ b/WGLMakie/src/meshes.jl @@ -1,6 +1,6 @@ function vertexbuffer(x, trans, space) pos = decompose(Point, x) - return apply_transform(trans, pos, space) + return el32convert(apply_transform(trans, pos, space)) end function vertexbuffer(x::Observable, p) @@ -41,7 +41,7 @@ function create_shader(scene::Scene, plot::Makie.Mesh) for (key, default) in (:uv => Vec2f(0), :normals => Vec3f(0)) if haskey(data, key) - attributes[key] = Buffer(get_attribute(mesh_signal, key)) + attributes[key] = Buffer(map(el32convert, get_attribute(mesh_signal, key))) else uniforms[key] = Observable(default) end @@ -121,7 +121,7 @@ function create_shader(scene::Scene, plot::Makie.Mesh) uniforms[:normalmatrix] = map(scene.camera.view, plot.model) do v, m i = Vec(1, 2, 3) - return transpose(inv(v[i, i] * m[i, i])) + return transpose(Mat3f(inv(v[i, i] * m[i, i]))) end # id + picking gets filled in JS, needs to be here to emit the correct shader uniforms diff --git a/WGLMakie/src/particles.jl b/WGLMakie/src/particles.jl index 1564feb8135..c9b954afa35 100644 --- a/WGLMakie/src/particles.jl +++ b/WGLMakie/src/particles.jl @@ -54,7 +54,9 @@ function create_shader(scene::Scene, plot::MeshScatter) return k in per_instance_keys && !(isscalar(v[])) end space = get(plot, :space, :data) - per_instance[:offset] = apply_transform(transform_func_obs(plot), plot[1], space) + per_instance[:offset] = map(transform_func_obs(plot), plot[1], space) do tf, pos, space + el32convert(apply_transform(tf, pos, space)) + end for (k, v) in per_instance per_instance[k] = Buffer(lift_convert(k, v, plot)) @@ -71,7 +73,7 @@ function create_shader(scene::Scene, plot::MeshScatter) end handle_color!(uniform_dict, per_instance) - instance = convert_attribute(plot.marker[], key"marker"(), key"meshscatter"()) + instance = el32convert(convert_attribute(plot.marker[], key"marker"(), key"meshscatter"())) if !hasproperty(instance, :uv) uniform_dict[:uv] = Vec2f(0) @@ -182,7 +184,7 @@ function scatter_shader(scene::Scene, attributes) handle_color!(uniform_dict, per_instance) - instance = uv_mesh(Rect2(-0.5f0, -0.5f0, 1f0, 1f0)) + instance = uv_mesh(Rect2f(-0.5f0, -0.5f0, 1f0, 1f0)) # Don't send obs, since it's overwritten in JS to be updated by the camera uniform_dict[:resolution] = to_value(scene.camera.resolution) @@ -204,7 +206,9 @@ function create_shader(scene::Scene, plot::Scatter) space = get(attributes, :space, :data) cam = scene.camera attributes[:preprojection] = Mat4f(I) # calculate this in JS - attributes[:pos] = apply_transform(transform_func_obs(plot), plot[1], space) + attributes[:pos] = map(transform_func_obs(plot), plot[1], space) do tf, pos, space + el32convert(apply_transform(tf, pos, space)) + end quad_offset = get(attributes, :marker_offset, Observable(Vec2f(0))) attributes[:marker_offset] = Vec3f(0) diff --git a/WGLMakie/src/serialization.jl b/WGLMakie/src/serialization.jl index 7be3001196c..847b9cda615 100644 --- a/WGLMakie/src/serialization.jl +++ b/WGLMakie/src/serialization.jl @@ -342,5 +342,10 @@ function serialize_camera(scene::Scene) # a view matrix change! ep = cam.eyeposition[] return [vec(collect(view)), vec(collect(proj)), Int32[res...], Float32[ep...]] + # eyepos32 = Vector{Float32}(cam.eyeposition[]) + # res32 = Vector{Int32}(res) + # view32 = Vector{Float32}(vec(view)) + # proj32 = Vector{Float32}(vec(proj)) + # return [view32, proj32, res32, eyepos32] end -end +end \ No newline at end of file diff --git a/src/conversions.jl b/src/conversions.jl index ae63d8a035d..e9f4332d1a9 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -639,6 +639,16 @@ function el32convert(x::AbstractArray{T, N}) where {T<:Union{Missing, <: Number} end::Array{Float32, N} end +function el32convert(mesh::GeometryBasics.Mesh, positions = mesh.position) + points = el32convert(positions) + attr = GeometryBasics.attributes(mesh) + delete!(attr, :position) + for key in keys(attr) + attr[key] = el32convert(attr[key]) + end + return GeometryBasics.Mesh(meta(points; attr...), faces(mesh)) +end + """ From c2f0109fbb2052adbc21f6b6d9a419ac16e1153e Mon Sep 17 00:00:00 2001 From: ffreyer Date: Tue, 10 Jan 2023 12:42:02 +0100 Subject: [PATCH 17/49] cleanup prints --- WGLMakie/src/imagelike.jl | 3 --- 1 file changed, 3 deletions(-) diff --git a/WGLMakie/src/imagelike.jl b/WGLMakie/src/imagelike.jl index 305416871de..fa66b278784 100644 --- a/WGLMakie/src/imagelike.jl +++ b/WGLMakie/src/imagelike.jl @@ -48,7 +48,6 @@ function limits_to_uvmesh(plot) px, py, pz = plot[1], plot[2], plot[3] px = map((x, z)-> xy_convert(x, size(z, 1)), px, pz) py = map((y, z)-> xy_convert(y, size(z, 2)), py, pz) - @info px # Special path for ranges of length 2 which # can be displayed as a rectangle t = Makie.transform_func_obs(plot)[] @@ -69,7 +68,6 @@ function limits_to_uvmesh(plot) faces = Buffer(lift(r -> decompose(GLTriangleFace, r), rect)) uv = Buffer(lift(decompose_uv, rect)) end - @info positions vertices = GeometryBasics.meta(positions; uv=uv) return GeometryBasics.Mesh(vertices, faces) @@ -121,7 +119,6 @@ function create_shader(mscene::Scene, plot::Union{Heatmap, Image}) color = Sampler(map(x -> el32convert(x'), image); minfilter=to_value(get(plot, :interpolate, false)) ? :linear : :nearest) mesh = limits_to_uvmesh(plot) - @info mesh plot_attributes = copy(plot.attributes) if eltype(color) <: Colorant delete!(plot_attributes, :colormap) From cbf702c6c7e38bebf43ff5e3b0d8f84bcd92bf32 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Tue, 10 Jan 2023 13:48:15 +0100 Subject: [PATCH 18/49] add BBox64 --- src/makielayout/blocks/axis.jl | 13 ++++----- src/makielayout/helpers.jl | 6 +++++ test/makielayout.jl | 48 ++++++++++++++++++---------------- 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/src/makielayout/blocks/axis.jl b/src/makielayout/blocks/axis.jl index 85177f64a5d..fad98be3f03 100644 --- a/src/makielayout/blocks/axis.jl +++ b/src/makielayout/blocks/axis.jl @@ -622,7 +622,7 @@ function reset_limits!(ax; xauto = true, yauto = true, zauto = true) end if ax isa Axis - ax.targetlimits[] = Rect2{Float64}(xlims[1], ylims[1], xlims[2]-xlims[1], ylims[2]-ylims[1]) + ax.targetlimits[] = BBox64(xlims[1], xlims[2], ylims[1], ylims[2]) elseif ax isa Axis3 ax.targetlimits[] = Rect3( Vec3(xlims[1], ylims[1], zlims[1]), @@ -895,7 +895,7 @@ function update_linked_limits!(block_limit_linking, xaxislinks, yaxislinks, tlim otherylims = limits(otherlims, 2) if thisxlims != otherxlims xlink.block_limit_linking[] = true - xlink.targetlimits[] = BBox(thisxlims[1], thisxlims[2], otherylims[1], otherylims[2]) + xlink.targetlimits[] = BBox64(thisxlims[1], thisxlims[2], otherylims[1], otherylims[2]) xlink.block_limit_linking[] = false end end @@ -906,7 +906,7 @@ function update_linked_limits!(block_limit_linking, xaxislinks, yaxislinks, tlim otherylims = limits(otherlims, 2) if thisylims != otherylims ylink.block_limit_linking[] = true - ylink.targetlimits[] = BBox(otherxlims[1], otherxlims[2], thisylims[1], thisylims[2]) + ylink.targetlimits[] = BBox64(otherxlims[1], otherxlims[2], thisylims[1], thisylims[2]) ylink.block_limit_linking[] = false end end @@ -1315,9 +1315,7 @@ Makie.transform_func(ax::Axis) = Makie.transform_func(ax.scene) # these functions pick limits for different x and y scales, so that # we don't pick values that are invalid, such as 0 for log etc. function defaultlimits(userlimits::Tuple{Real, Real, Real, Real}, xscale, yscale) - # BBox(userlimits...) - x0, x1, y0, y1 = userlimits - Rect2{Float64}(x0, y0, x1-x0, y1-y0) + BBox64(userlimits...) end defaultlimits(l::Tuple{Any, Any, Any, Any}, xscale, yscale) = defaultlimits(((l[1], l[2]), (l[3], l[4])), xscale, yscale) @@ -1325,8 +1323,7 @@ defaultlimits(l::Tuple{Any, Any, Any, Any}, xscale, yscale) = defaultlimits(((l[ function defaultlimits(userlimits::Tuple{Any, Any}, xscale, yscale) xl = defaultlimits(userlimits[1], xscale) yl = defaultlimits(userlimits[2], yscale) - # BBox(xl..., yl...) - Rect2{Float64}(xl[1], yl[1], xl[2]-xl[1], yl[2]-yl[1]) + BBox64(xl..., yl...) end defaultlimits(limits::Nothing, scale) = defaultlimits(scale) diff --git a/src/makielayout/helpers.jl b/src/makielayout/helpers.jl index 5d0b24ef525..fa0dc03a9ad 100644 --- a/src/makielayout/helpers.jl +++ b/src/makielayout/helpers.jl @@ -431,3 +431,9 @@ end Makie.get_scene(ax::Axis) = ax.scene Makie.get_scene(ax::Axis3) = ax.scene Makie.get_scene(ax::LScene) = ax.scene + +function BBox64(left::Number, right::Number, bottom::Number, top::Number) + mini = (left, bottom) + maxi = (right, top) + return Rect2{Float64}(mini, maxi .- mini) +end \ No newline at end of file diff --git a/test/makielayout.jl b/test/makielayout.jl index 92008f2bc0c..3dc998061b9 100644 --- a/test/makielayout.jl +++ b/test/makielayout.jl @@ -54,19 +54,21 @@ end end @testset "Axis limits basics" begin + using Makie: BBox64 + f = Figure() ax = Axis(f[1, 1], limits = (nothing, nothing)) - ax.targetlimits[] = BBox(0, 10, 0, 20) - @test ax.finallimits[] == BBox(0, 10, 0, 20) + ax.targetlimits[] = BBox64(0, 10, 0, 20) + @test ax.finallimits[] == BBox64(0, 10, 0, 20) @test ax.limits[] == (nothing, nothing) xlims!(ax, -10, 10) @test ax.limits[] == ((-10, 10), nothing) - @test ax.finallimits[] == BBox(-10, 10, 0, 20) + @test ax.finallimits[] == BBox64(-10, 10, 0, 20) ylims!(ax, -20, 30) @test ax.limits[] == ((-10, 10), (-20, 30)) - @test ax.finallimits[] == BBox(-10, 10, -20, 30) + @test ax.finallimits[] == BBox64(-10, 10, -20, 30) limits!(ax, -5, 5, -10, 10) - @test ax.finallimits[] == BBox(-5, 5, -10, 10) + @test ax.finallimits[] == BBox64(-5, 5, -10, 10) @test ax.limits[] == ((-5, 5), (-10, 10)) ax.limits[] = (nothing, nothing) ax.xautolimitmargin = (0, 0) @@ -74,45 +76,45 @@ end scatter!(Point2f[(0, 0), (1, 2)]) reset_limits!(ax) @test ax.limits[] == (nothing, nothing) - @test ax.targetlimits[] == BBox(0, 1, 0, 2) - @test ax.finallimits[] == BBox(0, 1, 0, 2) + @test ax.targetlimits[] == BBox64(0, 1, 0, 2) + @test ax.finallimits[] == BBox64(0, 1, 0, 2) scatter!(Point2f(3, 4)) reset_limits!(ax) @test ax.limits[] == (nothing, nothing) - @test ax.targetlimits[] == BBox(0, 3, 0, 4) - @test ax.finallimits[] == BBox(0, 3, 0, 4) + @test ax.targetlimits[] == BBox64(0, 3, 0, 4) + @test ax.finallimits[] == BBox64(0, 3, 0, 4) limits!(ax, -1, 1, 0, 2) @test ax.limits[] == ((-1, 1), (0, 2)) - @test ax.targetlimits[] == BBox(-1, 1, 0, 2) - @test ax.finallimits[] == BBox(-1, 1, 0, 2) + @test ax.targetlimits[] == BBox64(-1, 1, 0, 2) + @test ax.finallimits[] == BBox64(-1, 1, 0, 2) scatter!(Point2f(5, 6)) reset_limits!(ax) @test ax.limits[] == ((-1, 1), (0, 2)) - @test ax.targetlimits[] == BBox(-1, 1, 0, 2) - @test ax.finallimits[] == BBox(-1, 1, 0, 2) + @test ax.targetlimits[] == BBox64(-1, 1, 0, 2) + @test ax.finallimits[] == BBox64(-1, 1, 0, 2) autolimits!(ax) @test ax.limits[] == (nothing, nothing) - @test ax.targetlimits[] == BBox(0, 5, 0, 6) - @test ax.finallimits[] == BBox(0, 5, 0, 6) + @test ax.targetlimits[] == BBox64(0, 5, 0, 6) + @test ax.finallimits[] == BBox64(0, 5, 0, 6) xlims!(ax, [-10, 10]) @test ax.limits[] == ([-10, 10], nothing) - @test ax.targetlimits[] == BBox(-10, 10, 0, 6) - @test ax.finallimits[] == BBox(-10, 10, 0, 6) + @test ax.targetlimits[] == BBox64(-10, 10, 0, 6) + @test ax.finallimits[] == BBox64(-10, 10, 0, 6) scatter!(Point2f(11, 12)) reset_limits!(ax) @test ax.limits[] == ([-10, 10], nothing) - @test ax.targetlimits[] == BBox(-10, 10, 0, 12) - @test ax.finallimits[] == BBox(-10, 10, 0, 12) + @test ax.targetlimits[] == BBox64(-10, 10, 0, 12) + @test ax.finallimits[] == BBox64(-10, 10, 0, 12) autolimits!(ax) ylims!(ax, [5, 7]) @test ax.limits[] == (nothing, [5, 7]) - @test ax.targetlimits[] == BBox(0, 11, 5, 7) - @test ax.finallimits[] == BBox(0, 11, 5, 7) + @test ax.targetlimits[] == BBox64(0, 11, 5, 7) + @test ax.finallimits[] == BBox64(0, 11, 5, 7) scatter!(Point2f(-5, -7)) reset_limits!(ax) @test ax.limits[] == (nothing, [5, 7]) - @test ax.targetlimits[] == BBox(-5, 11, 5, 7) - @test ax.finallimits[] == BBox(-5, 11, 5, 7) + @test ax.targetlimits[] == BBox64(-5, 11, 5, 7) + @test ax.finallimits[] == BBox64(-5, 11, 5, 7) end @testset "Colorbar plot object kwarg clash" begin From dbccd6921ec212020b0d3288956b53da4f5b36af Mon Sep 17 00:00:00 2001 From: ffreyer Date: Tue, 10 Jan 2023 16:20:03 +0100 Subject: [PATCH 19/49] move GeometryBasics changes to Makie --- src/basic_recipes/poly.jl | 15 +++++++----- src/conversions.jl | 50 ++++++++++++++++++++++----------------- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/basic_recipes/poly.jl b/src/basic_recipes/poly.jl index e8d4a7ee57a..902d17df2f8 100644 --- a/src/basic_recipes/poly.jl +++ b/src/basic_recipes/poly.jl @@ -10,7 +10,7 @@ convert_arguments(::Type{<: Poly}, m::GeometryBasics.GeometryPrimitive) = (m,) function plot!(plot::Poly{<: Tuple{Union{GeometryBasics.Mesh, GeometryPrimitive}}}) mesh!( - plot, lift(triangle_mesh, plot[1]), + plot, lift(_triangle_mesh, plot[1]), color = plot[:color], colormap = plot[:colormap], colorrange = plot[:colorrange], @@ -33,19 +33,22 @@ function plot!(plot::Poly{<: Tuple{Union{GeometryBasics.Mesh, GeometryPrimitive} end # Poly conversion +function _triangle_mesh(geom::GeometryBasics.Meshable{N, T}) where {N, T} + GeometryBasics.mesh(geom; pointtype = Point{N, T}, facetype=GeometryBasics.GLTriangleFace) +end function poly_convert(geometries) isempty(geometries) && return typeof(GeometryBasics.Mesh(Point2f[], GLTriangleFace[]))[] - return triangle_mesh.(geometries) + return _triangle_mesh.(geometries) end poly_convert(meshes::AbstractVector{<:AbstractMesh}) = meshes -poly_convert(polys::AbstractVector{<:Polygon}) = triangle_mesh.(polys) +poly_convert(polys::AbstractVector{<:Polygon}) = _triangle_mesh.(polys) function poly_convert(multipolygons::AbstractVector{<:MultiPolygon}) - return [merge(triangle_mesh.(multipoly.polygons)) for multipoly in multipolygons] + return [merge(_triangle_mesh.(multipoly.polygons)) for multipoly in multipolygons] end poly_convert(mesh::GeometryBasics.Mesh) = mesh -poly_convert(polygon::Polygon) = triangle_mesh(polygon) +poly_convert(polygon::Polygon) = _triangle_mesh(polygon) function poly_convert(polygon::AbstractVector{<: VecTypes}) return poly_convert([convert_arguments(Scatter, polygon)[1]]) @@ -171,7 +174,7 @@ function plot!(plot::Mesh{<: Tuple{<: AbstractVector{P}}}) where P <: Union{Abst if isempty(meshes) return GeometryBasics.Mesh(Point2f[], GLTriangleFace[]) else - return merge(GeometryBasics.triangle_mesh.(meshes)) + return merge(_triangle_mesh.(meshes)) end end mesh!(plot, attributes, bigmesh) diff --git a/src/conversions.jl b/src/conversions.jl index e9f4332d1a9..e0a0f7686b0 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -510,7 +510,8 @@ function convert_arguments(::Type{<:Mesh}, mesh::GeometryBasics.Mesh{N}) where { mesh = GeometryBasics.pointmeta(mesh, decompose(Vec3f, n)) end end - return (GeometryBasics.mesh(mesh, pointtype=Point{N, Float64}, facetype=GLTriangleFace),) + PT = eltype(mesh.position) # TODO do we need to guard against abstract types? + return (GeometryBasics.mesh(mesh, pointtype=PT, facetype=GLTriangleFace),) end function convert_arguments( @@ -522,15 +523,20 @@ end function convert_arguments( MT::Type{<:Mesh}, - xyz::Union{AbstractPolygon, AbstractVector{<: AbstractPoint{2}}} + xyz::Union{AbstractPolygon{2, T}, AbstractVector{<: AbstractPoint{2, T}}} where T ) - return convert_arguments(MT, triangle_mesh(xyz)) + return (GeometryBasics.mesh( + xyz; pointtype = Point{2, T}, facetype = GeometryBasics.GLTriangleFace + ), ) end -function convert_arguments(MT::Type{<:Mesh}, geom::GeometryPrimitive) +function convert_arguments(MT::Type{<:Mesh}, geom::GeometryPrimitive{N, T}) where {N, T} # we convert to UV mesh as default, because otherwise the uv informations get lost # - we can still drop them, but we can't add them later on - return (GeometryBasics.uv_normal_mesh(geom),) + return (GeometryBasics.mesh( + geom; pointtype = Point{N,T}, uv = Vec2f, normaltype = Vec3f, + facetype = GeometryBasics.GLTriangleFace + ), ) end """ @@ -555,12 +561,13 @@ See [`to_vertices`](@ref) and [`to_triangles`](@ref) for more information about accepted types. """ function convert_arguments( - ::Type{<:Mesh}, - vertices::AbstractArray, - indices::AbstractArray - ) - m = normal_mesh(to_vertices(vertices), to_triangles(indices)) - (m,) + ::Type{<:Mesh}, vertices::AbstractArray{PT}, indices::AbstractArray + ) where {PT <: Point} + _points = GeometryBasics.decompose(PT, to_vertices(vertices)) + _faces = to_triangles(indices) + return (GeometryBasics.Mesh(GeometryBasics.meta( + _points; normals = GeometryBasics.normals(_points, _faces) + ), _faces), ) end ################################################################################ @@ -685,7 +692,7 @@ end to_vertices(v) Converts a representation of vertices `v` to its canonical representation as a -`Vector{Point3f}`. `v` can be: +`Vector{Point3{T}}`. `v` can be: - An `AbstractVector` of 3-element `Tuple`s or `StaticVector`s, @@ -697,15 +704,14 @@ Converts a representation of vertices `v` to its canonical representation as a - otherwise if `v` has 2 or 3 columns, it will treat each row as a vertex. """ function to_vertices(verts::AbstractVector{<: VecTypes{3, T}}) where T - vert3f0 = T != Float32 ? Point3f.(verts) : verts - return reinterpret(Point3f, vert3f0) + return reinterpret(Point3{T}, verts) end -function to_vertices(verts::AbstractVector{<: VecTypes}) - to_vertices(to_ndim.(Point3f, verts, 0.0)) +function to_vertices(verts::AbstractVector{<: VecTypes{N, T}}) where {N, T} + to_vertices(to_ndim.(Point{3, T}, verts, 0.0)) end -function to_vertices(verts::AbstractMatrix{<: Number}) +function to_vertices(verts::AbstractMatrix{<: Real}) if size(verts, 1) in (2, 3) to_vertices(verts, Val(1)) elseif size(verts, 2) in (2, 3) @@ -715,23 +721,23 @@ function to_vertices(verts::AbstractMatrix{<: Number}) end end -function to_vertices(verts::AbstractMatrix{T}, ::Val{1}) where T <: Number +function to_vertices(verts::AbstractMatrix{T}, ::Val{1}) where T <: Real N = size(verts, 1) - if T == Float32 && N == 3 + if N == 3 reinterpret(Point{N, T}, elconvert(T, vec(verts))) else let N = Val(N), lverts = verts broadcast(1:size(verts, 2), N) do vidx, n - to_ndim(Point3f, ntuple(i-> lverts[i, vidx], n), 0.0) + to_ndim(Point3{T}, ntuple(i-> lverts[i, vidx], n), 0.0) end end end end -function to_vertices(verts::AbstractMatrix{T}, ::Val{2}) where T <: Number +function to_vertices(verts::AbstractMatrix{T}, ::Val{2}) where T <: Real let N = Val(size(verts, 2)), lverts = verts broadcast(1:size(verts, 1), N) do vidx, n - to_ndim(Point3f, ntuple(i-> lverts[vidx, i], n), 0.0) + to_ndim(Point3{T}, ntuple(i-> lverts[vidx, i], n), 0.0) end end end From d7f5693c6551f05f1bf7531c1e2c088e2632c7ac Mon Sep 17 00:00:00 2001 From: ffreyer Date: Tue, 10 Jan 2023 17:34:31 +0100 Subject: [PATCH 20/49] fix mesh conversion --- src/conversions.jl | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/conversions.jl b/src/conversions.jl index e0a0f7686b0..e0efa1b4428 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -560,14 +560,17 @@ Takes `vertices` and `indices`, and creates a triangle mesh out of those. See [`to_vertices`](@ref) and [`to_triangles`](@ref) for more information about accepted types. """ +function convert_arguments(MT::Type{<:Mesh}, vertices::AbstractArray, indices::AbstractArray) + return convert_arguments(MT, to_vertices(vertices), to_triangles(indices)) +end + function convert_arguments( - ::Type{<:Mesh}, vertices::AbstractArray{PT}, indices::AbstractArray - ) where {PT <: Point} - _points = GeometryBasics.decompose(PT, to_vertices(vertices)) - _faces = to_triangles(indices) + ::Type{<:Mesh}, pos::Vector{VT}, faces::Vector{GLTriangleFace} + ) where {N, T, VT <: VecTypes{N, T}} + _points = decompose(Point{N, T}, pos) return (GeometryBasics.Mesh(GeometryBasics.meta( - _points; normals = GeometryBasics.normals(_points, _faces) - ), _faces), ) + _points; normals = GeometryBasics.normals(_points, faces) + ), faces), ) end ################################################################################ @@ -711,6 +714,10 @@ function to_vertices(verts::AbstractVector{<: VecTypes{N, T}}) where {N, T} to_vertices(to_ndim.(Point{3, T}, verts, 0.0)) end +function to_vertices(verts::AbstractVector{<: VecTypes}) + to_vertices(to_ndim.(Point{3, Float32}, verts, 0.0)) +end + function to_vertices(verts::AbstractMatrix{<: Real}) if size(verts, 1) in (2, 3) to_vertices(verts, Val(1)) From e955f31db7a8bc1a5089380d7e14e1c11472b5c5 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Tue, 10 Jan 2023 17:56:14 +0100 Subject: [PATCH 21/49] fix more mesh conversion problems --- src/conversions.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/conversions.jl b/src/conversions.jl index e0efa1b4428..aa7d05d7a38 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -565,9 +565,9 @@ function convert_arguments(MT::Type{<:Mesh}, vertices::AbstractArray, indices::A end function convert_arguments( - ::Type{<:Mesh}, pos::Vector{VT}, faces::Vector{GLTriangleFace} + ::Type{<:Mesh}, pos::AbstractVector{VT}, faces::AbstractVector{GLTriangleFace} ) where {N, T, VT <: VecTypes{N, T}} - _points = decompose(Point{N, T}, pos) + _points = to_ndim.(Point{3, T}, pos, T(0)) return (GeometryBasics.Mesh(GeometryBasics.meta( _points; normals = GeometryBasics.normals(_points, faces) ), faces), ) From 7cb6aacd828506bae2c877c90b9bec9d93138303 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Tue, 10 Jan 2023 18:30:17 +0100 Subject: [PATCH 22/49] fix Makie tests --- src/conversions.jl | 4 ++-- test/conversions.jl | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/conversions.jl b/src/conversions.jl index aa7d05d7a38..c7cae502e34 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -523,8 +523,8 @@ end function convert_arguments( MT::Type{<:Mesh}, - xyz::Union{AbstractPolygon{2, T}, AbstractVector{<: AbstractPoint{2, T}}} where T - ) + xyz::Union{AbstractPolygon{2, T}, AbstractVector{<: AbstractPoint{2, T}}} + ) where T return (GeometryBasics.mesh( xyz; pointtype = Point{2, T}, facetype = GeometryBasics.GLTriangleFace ), ) diff --git a/test/conversions.jl b/test/conversions.jl index 8c01def1a27..d08c0b633e2 100644 --- a/test/conversions.jl +++ b/test/conversions.jl @@ -29,29 +29,29 @@ end @testset "to_vertices" begin X1 = [Point(rand(3)...) for i = 1:10] V1 = to_vertices(X1) - @test Float32(X1[7][1]) == V1[7][1] + @test X1[7][1] == V1[7][1] X2 = [tuple(rand(3)...) for i = 1:10] V2 = to_vertices(X2) - @test Float32(X2[7][1]) == V2[7][1] + @test X2[7][1] == V2[7][1] X4 = rand(2,10) V4 = to_vertices(X4) - @test Float32(X4[1,7]) == V4[7][1] + @test X4[1,7] == V4[7][1] @test V4[7][3] == 0 X5 = rand(3,10) V5 = to_vertices(X5) - @test Float32(X5[1,7]) == V5[7][1] + @test X5[1,7] == V5[7][1] X6 = rand(10,2) V6 = to_vertices(X6) - @test Float32(X6[7,1]) == V6[7][1] + @test X6[7,1] == V6[7][1] @test V6[7][3] == 0 X7 = rand(10,3) V7 = to_vertices(X7) - @test Float32(X7[7,1]) == V7[7][1] + @test X7[7,1] == V7[7][1] end @testset "functions" begin From a3b925f16b9fe6b579d727391d72012772cd3f01 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Thu, 12 Jan 2023 16:05:54 +0100 Subject: [PATCH 23/49] fix BBox type --- src/makielayout/blocks/axis.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/makielayout/blocks/axis.jl b/src/makielayout/blocks/axis.jl index fad98be3f03..38389cc09ce 100644 --- a/src/makielayout/blocks/axis.jl +++ b/src/makielayout/blocks/axis.jl @@ -1013,7 +1013,7 @@ function adjustlimits!(la) ylims = expandlimits(ylims, (((1 / correction_factor) - 1) .* ratios)..., identity) # don't use scale here? end - bbox = BBox(xlims[1], xlims[2], ylims[1], ylims[2]) + bbox = BBox64(xlims[1], xlims[2], ylims[1], ylims[2]) la.finallimits[] = bbox return end From c0e2db9565bfb8eddb3860d7587604f57901bc6c Mon Sep 17 00:00:00 2001 From: ffreyer Date: Thu, 12 Jan 2023 17:02:15 +0100 Subject: [PATCH 24/49] fix ssao --- GLMakie/src/postprocessing.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GLMakie/src/postprocessing.jl b/GLMakie/src/postprocessing.jl index 3c295d158a6..d639c012fbb 100644 --- a/GLMakie/src/postprocessing.jl +++ b/GLMakie/src/postprocessing.jl @@ -173,7 +173,7 @@ function ssao_postprocessor(framebuffer, shader_cache) a = pixelarea(scene)[] glScissor(minimum(a)..., widths(a)...) # update uniforms - data1[:projection] = scene.camera.projection[] + data1[:projection] = Mat4f(scene.camera.projection[]) data1[:bias] = scene.ssao.bias[] data1[:radius] = scene.ssao.radius[] GLAbstraction.render(pass1) From 05ee945dc707d94ad9fd92070cd6bac09f59f85b Mon Sep 17 00:00:00 2001 From: ffreyer Date: Thu, 12 Jan 2023 17:59:18 +0100 Subject: [PATCH 25/49] stricter Float64 typing --- src/conversions.jl | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/conversions.jl b/src/conversions.jl index c7cae502e34..35fea023351 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -127,7 +127,7 @@ convert_arguments(::PointBased, x::RealVector, y::RealVector, z::RealVector) = ( Takes an input GeometryPrimitive `x` and decomposes it to points. `P` is the plot Type (it is optional). """ -convert_arguments(p::PointBased, x::GeometryPrimitive) = convert_arguments(p, decompose(Point, x)) +convert_arguments(p::PointBased, x::GeometryPrimitive) = convert_arguments(p, decompose(Point3e, x)) function convert_arguments(::PointBased, pos::AbstractMatrix{<: Number}) (to_vertices(pos),) @@ -510,8 +510,8 @@ function convert_arguments(::Type{<:Mesh}, mesh::GeometryBasics.Mesh{N}) where { mesh = GeometryBasics.pointmeta(mesh, decompose(Vec3f, n)) end end - PT = eltype(mesh.position) # TODO do we need to guard against abstract types? - return (GeometryBasics.mesh(mesh, pointtype=PT, facetype=GLTriangleFace),) + # PT = eltype(mesh.position) # TODO do we need to guard against abstract types? + return (GeometryBasics.mesh(mesh, pointtype=Point{N, Float64}, facetype=GLTriangleFace),) end function convert_arguments( @@ -526,7 +526,7 @@ function convert_arguments( xyz::Union{AbstractPolygon{2, T}, AbstractVector{<: AbstractPoint{2, T}}} ) where T return (GeometryBasics.mesh( - xyz; pointtype = Point{2, T}, facetype = GeometryBasics.GLTriangleFace + xyz; pointtype = Point{2, Float64}, facetype = GeometryBasics.GLTriangleFace ), ) end @@ -534,7 +534,7 @@ function convert_arguments(MT::Type{<:Mesh}, geom::GeometryPrimitive{N, T}) wher # we convert to UV mesh as default, because otherwise the uv informations get lost # - we can still drop them, but we can't add them later on return (GeometryBasics.mesh( - geom; pointtype = Point{N,T}, uv = Vec2f, normaltype = Vec3f, + geom; pointtype = Point{N, Float64}, uv = Vec2f, normaltype = Vec3f, facetype = GeometryBasics.GLTriangleFace ), ) end @@ -706,16 +706,16 @@ Converts a representation of vertices `v` to its canonical representation as a - if `v` has 2 or 3 rows, it will treat each column as a vertex, - otherwise if `v` has 2 or 3 columns, it will treat each row as a vertex. """ -function to_vertices(verts::AbstractVector{<: VecTypes{3, T}}) where T - return reinterpret(Point3{T}, verts) -end +# function to_vertices(verts::AbstractVector{<: VecTypes{3, T}}) where T +# return reinterpret(Point3{Float64}, verts) +# end -function to_vertices(verts::AbstractVector{<: VecTypes{N, T}}) where {N, T} - to_vertices(to_ndim.(Point{3, T}, verts, 0.0)) -end +# function to_vertices(verts::AbstractVector{<: VecTypes{N, T}}) where {N, T} +# to_vertices(to_ndim.(Point{3, Float64}, verts, 0.0)) +# end function to_vertices(verts::AbstractVector{<: VecTypes}) - to_vertices(to_ndim.(Point{3, Float32}, verts, 0.0)) + to_ndim.(Point{3, Float64}, verts, 0.0) end function to_vertices(verts::AbstractMatrix{<: Real}) From 4e1afcb6022fea233ca09683a0ad69f793f1fdea Mon Sep 17 00:00:00 2001 From: ffreyer Date: Thu, 12 Jan 2023 18:21:01 +0100 Subject: [PATCH 26/49] fix example --- docs/documentation/recipes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/documentation/recipes.md b/docs/documentation/recipes.md index ba663ba44d6..cd36483996c 100644 --- a/docs/documentation/recipes.md +++ b/docs/documentation/recipes.md @@ -238,7 +238,9 @@ function Makie.plot!( push!(bar_tos[], s.close) end append!(colors[], [x.close > x.open for x in stockvalues]) - colors[] = colors[] + notify(linesegs) + notify(colors) + return end # connect `update_plot` so that it is called whenever `times` From 53c8e21a67e2d1941207293dd3cc6a6ea5f82192 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Thu, 12 Jan 2023 18:21:38 +0100 Subject: [PATCH 27/49] use map! instead of onany --- src/interfaces.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interfaces.jl b/src/interfaces.jl index da63febdc95..f54ab0d4447 100644 --- a/src/interfaces.jl +++ b/src/interfaces.jl @@ -322,7 +322,7 @@ function plot!(scene::Union{Combined, SceneLike}, P::PlotFunc, attributes::Attri FinalType, argsconverted = apply_convert!(PreType, attributes, converted) converted_node = Observable(argsconverted) input_nodes = convert.(Observable, args) - onany(kw_signal, input_nodes...) do kwargs, args... + map!(converted_node, kw_signal, input_nodes...) do kwargs, args... # do the argument conversion inside a lift result = convert_arguments(FinalType, args...; kwargs...) finaltype, argsconverted_ = apply_convert!(FinalType, attributes, result) # avoid a Core.Box (https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-captured) @@ -331,7 +331,7 @@ function plot!(scene::Union{Combined, SceneLike}, P::PlotFunc, attributes::Attri Changing the plot type based on values in convert_arguments is not allowed" ) end - converted_node[] = argsconverted_ + return argsconverted_ end plot!(scene, FinalType, attributes, input_nodes, converted_node) end From 33251b0f4fef2b6dba15152616dd3f75ef386fe9 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Thu, 12 Jan 2023 19:46:54 +0100 Subject: [PATCH 28/49] fix test failure --- test/conversions.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/conversions.jl b/test/conversions.jl index d08c0b633e2..747f67deb36 100644 --- a/test/conversions.jl +++ b/test/conversions.jl @@ -21,7 +21,7 @@ end @testset "changing input types" begin input = Observable{Any}(decompose(Point2f, Circle(Point2f(0), 2f0))) f, ax, pl = mesh(input) - m = Makie.triangle_mesh(Circle(Point2f(0), 1f0)) + m = Makie._triangle_mesh(Circle(Point2(0.0), 1.0)) input[] = m @test pl[1][] == m end From 74b689b8d7ffa5d6f5a9cea3fed905b6729a5367 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sat, 14 Jan 2023 16:27:37 +0100 Subject: [PATCH 29/49] skip initialization update of converted_node --- src/interfaces.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces.jl b/src/interfaces.jl index f54ab0d4447..20d2b0ac8d0 100644 --- a/src/interfaces.jl +++ b/src/interfaces.jl @@ -322,7 +322,7 @@ function plot!(scene::Union{Combined, SceneLike}, P::PlotFunc, attributes::Attri FinalType, argsconverted = apply_convert!(PreType, attributes, converted) converted_node = Observable(argsconverted) input_nodes = convert.(Observable, args) - map!(converted_node, kw_signal, input_nodes...) do kwargs, args... + map!(converted_node, kw_signal, input_nodes..., update = false) do kwargs, args... # do the argument conversion inside a lift result = convert_arguments(FinalType, args...; kwargs...) finaltype, argsconverted_ = apply_convert!(FinalType, attributes, result) # avoid a Core.Box (https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-captured) From 07c411dbf0b935de06a8ef076c3b2970ca805869 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sat, 14 Jan 2023 16:49:32 +0100 Subject: [PATCH 30/49] fix ecdf conversions --- src/stats/ecdf.jl | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/stats/ecdf.jl b/src/stats/ecdf.jl index 6494ca58df9..f5ab9e22a39 100644 --- a/src/stats/ecdf.jl +++ b/src/stats/ecdf.jl @@ -19,11 +19,13 @@ function convert_arguments(P::PlotFunc, ecdf::StatsBase.ECDF; npoints=10_000) end return to_plotspec(ptype, convert_arguments(ptype, x, ecdf(x)); kwargs...) end + function convert_arguments(P::PlotFunc, x::AbstractVector, ecdf::StatsBase.ECDF) ptype = plottype(P, Stairs) kwargs = ptype <: Stairs ? (; step=:post) : NamedTuple() return to_plotspec(ptype, convert_arguments(ptype, x, ecdf(x)); kwargs...) end + function convert_arguments(P::PlotFunc, x0::AbstractInterval, ecdf::StatsBase.ECDF) xmin, xmax = extrema(x0) z = ecdf_xvalues(ecdf, Inf) @@ -47,16 +49,19 @@ If `weights` for the values are provided, a weighted ECDF is plotted. $(ATTRIBUTES) """ @recipe(ECDFPlot) do scene - default_theme(scene, Stairs) + merge!( + default_theme(scene, Stairs), + Attributes( + npoints = 10_000, + weights = StatsBase.Weights(Float64[]) + ) + ) end -used_attributes(::Type{<:ECDFPlot}, ::AbstractVector) = (:npoints, :weights) -function convert_arguments( - ::Type{<:ECDFPlot}, - x::AbstractVector; - npoints=10_000, - weights=StatsBase.Weights(Float64[]), -) - ecdf = StatsBase.ecdf(x; weights=weights) - return convert_arguments(Stairs, ecdf; npoints=npoints) -end +function plot!(p::ECDFPlot) + attr = copy(p.attributes) + weights = pop!(attr, :weights) + ecdf = map((x, w) -> StatsBase.ecdf(x; weights=w), p[1], weights) + stairs!(p, attr, ecdf) + return p +end \ No newline at end of file From 3fbd6ab6e58a02010bfe0f87b3872b30094d2e7e Mon Sep 17 00:00:00 2001 From: ffreyer Date: Wed, 25 Jan 2023 15:33:02 +0100 Subject: [PATCH 31/49] add NEWS entry --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index 99f100d199d..64535398414 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,7 @@ - Fixed an issue where `poly` plots with `Vector{<: MultiPolygon}` inputs with per-polygon color were mistakenly rendered as meshes using CairoMakie. [#2590](https://github.com/MakieOrg/Makie.jl/pulls/2478) - Fixed a small typo which caused an error in the `Stepper` constructor. [#2600](https://github.com/MakieOrg/Makie.jl/pulls/2478) +- Switch `plot.converted` to Float64 types to avoid loss of precision. This should fix precision related issues for CairoMakie but not GL backends [2573](https://github.com/MakieOrg/Makie.jl/pull/2573) ## v0.19.1 From a35a108a52d905d2619eb2f007efdfedaab92dac Mon Sep 17 00:00:00 2001 From: ffreyer Date: Wed, 25 Jan 2023 17:11:56 +0100 Subject: [PATCH 32/49] add test for "range step cannot be zero" --- test/makielayout.jl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/makielayout.jl b/test/makielayout.jl index 6b39468db4d..1af8ec330de 100644 --- a/test/makielayout.jl +++ b/test/makielayout.jl @@ -58,18 +58,27 @@ end f = Figure() ax = Axis(f[1, 1], limits = (nothing, nothing)) + ax.targetlimits[] = BBox64(0, 10, 0, 20) @test ax.finallimits[] == BBox64(0, 10, 0, 20) @test ax.limits[] == (nothing, nothing) + xlims!(ax, -10, 10) @test ax.limits[] == ((-10, 10), nothing) @test ax.finallimits[] == BBox64(-10, 10, 0, 20) + ylims!(ax, -20, 30) @test ax.limits[] == ((-10, 10), (-20, 30)) @test ax.finallimits[] == BBox64(-10, 10, -20, 30) + + ylims!(ax, 1 - 0.5e-9, 1 + 1.5e-9) + @test ax.limits[] == ((-10, 10), (0.9999999995, 1.0000000015)) + @test ax.finallimits[] == BBox64(-10, 10, 0.9999999995, 1.0000000015) + limits!(ax, -5, 5, -10, 10) @test ax.finallimits[] == BBox64(-5, 5, -10, 10) @test ax.limits[] == ((-5, 5), (-10, 10)) + ax.limits[] = (nothing, nothing) ax.xautolimitmargin = (0, 0) ax.yautolimitmargin = (0, 0) @@ -78,43 +87,53 @@ end @test ax.limits[] == (nothing, nothing) @test ax.targetlimits[] == BBox64(0, 1, 0, 2) @test ax.finallimits[] == BBox64(0, 1, 0, 2) + scatter!(Point2f(3, 4)) reset_limits!(ax) @test ax.limits[] == (nothing, nothing) @test ax.targetlimits[] == BBox64(0, 3, 0, 4) @test ax.finallimits[] == BBox64(0, 3, 0, 4) + limits!(ax, -1, 1, 0, 2) @test ax.limits[] == ((-1, 1), (0, 2)) @test ax.targetlimits[] == BBox64(-1, 1, 0, 2) @test ax.finallimits[] == BBox64(-1, 1, 0, 2) + scatter!(Point2f(5, 6)) reset_limits!(ax) @test ax.limits[] == ((-1, 1), (0, 2)) @test ax.targetlimits[] == BBox64(-1, 1, 0, 2) @test ax.finallimits[] == BBox64(-1, 1, 0, 2) + autolimits!(ax) @test ax.limits[] == (nothing, nothing) @test ax.targetlimits[] == BBox64(0, 5, 0, 6) @test ax.finallimits[] == BBox64(0, 5, 0, 6) + xlims!(ax, [-10, 10]) @test ax.limits[] == ([-10, 10], nothing) @test ax.targetlimits[] == BBox64(-10, 10, 0, 6) @test ax.finallimits[] == BBox64(-10, 10, 0, 6) + scatter!(Point2f(11, 12)) reset_limits!(ax) @test ax.limits[] == ([-10, 10], nothing) @test ax.targetlimits[] == BBox64(-10, 10, 0, 12) @test ax.finallimits[] == BBox64(-10, 10, 0, 12) + autolimits!(ax) ylims!(ax, [5, 7]) @test ax.limits[] == (nothing, [5, 7]) @test ax.targetlimits[] == BBox64(0, 11, 5, 7) @test ax.finallimits[] == BBox64(0, 11, 5, 7) + scatter!(Point2f(-5, -7)) reset_limits!(ax) @test ax.limits[] == (nothing, [5, 7]) @test ax.targetlimits[] == BBox64(-5, 11, 5, 7) @test ax.finallimits[] == BBox64(-5, 11, 5, 7) + + end @testset "Colorbar plot object kwarg clash" begin From 523a514fea792f58a8e875b3e1ab2bafe9b96703 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Wed, 25 Jan 2023 20:27:36 +0100 Subject: [PATCH 33/49] fix rectzoom error --- src/makielayout/interactions.jl | 6 +++--- src/makielayout/types.jl | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/makielayout/interactions.jl b/src/makielayout/interactions.jl index 2a2fbaf4f4a..d56fa0f7ce7 100644 --- a/src/makielayout/interactions.jl +++ b/src/makielayout/interactions.jl @@ -109,15 +109,15 @@ end function _chosen_limits(rz, ax) - r = positivize(Rect2f(rz.from, rz.to .- rz.from)) + r = positivize(Rect2{Float64}(rz.from, rz.to .- rz.from)) lims = ax.finallimits[] # restrict to y change if rz.restrict_x || !ax.xrectzoom[] - r = Rect2f(lims.origin[1], r.origin[2], widths(lims)[1], widths(r)[2]) + r = Rect2{Float64}(lims.origin[1], r.origin[2], widths(lims)[1], widths(r)[2]) end # restrict to x change if rz.restrict_y || !ax.yrectzoom[] - r = Rect2f(r.origin[1], lims.origin[2], widths(r)[1], widths(lims)[2]) + r = Rect2{Float64}(r.origin[1], lims.origin[2], widths(r)[1], widths(lims)[2]) end return r end diff --git a/src/makielayout/types.jl b/src/makielayout/types.jl index b4cee937cd4..916c95fbce9 100644 --- a/src/makielayout/types.jl +++ b/src/makielayout/types.jl @@ -138,14 +138,14 @@ mutable struct RectangleZoom active::Observable{Bool} restrict_x::Bool restrict_y::Bool - from::Union{Nothing, Point2f} - to::Union{Nothing, Point2f} - rectnode::Observable{Rect2f} + from::Union{Nothing, Point2e} + to::Union{Nothing, Point2e} + rectnode::Observable{Rect2{Float64}} end function RectangleZoom(callback::Function; restrict_x=false, restrict_y=false) return RectangleZoom(callback, Observable(false), restrict_x, restrict_y, - nothing, nothing, Observable(Rect2f(0, 0, 1, 1))) + nothing, nothing, Observable(Rect2{Float64}(0, 0, 1, 1))) end struct ScrollZoom From b1a71a656a08ef14ca86dd296a21649588db304e Mon Sep 17 00:00:00 2001 From: ffreyer Date: Wed, 25 Jan 2023 20:32:17 +0100 Subject: [PATCH 34/49] Fully convert cameras to Float64 --- src/camera/camera.jl | 10 +-- src/camera/camera2d.jl | 78 +++++++++--------- src/camera/camera3d.jl | 162 ++++++++++++++++++------------------- src/camera/old_camera3d.jl | 96 +++++++++++----------- 4 files changed, 173 insertions(+), 173 deletions(-) diff --git a/src/camera/camera.jl b/src/camera/camera.jl index 8c8f2937265..67584c5c61c 100644 --- a/src/camera/camera.jl +++ b/src/camera/camera.jl @@ -69,10 +69,10 @@ end function Camera(px_area) pixel_space = lift(px_area) do window_size - nearclip = -10_000f0 - farclip = 10_000f0 - w, h = Float32.(widths(window_size)) - return orthographicprojection(0f0, w, 0f0, h, nearclip, farclip) + nearclip = -10_000.0 + farclip = 10_000.0 + w, h = Float64.(widths(window_size)) + return orthographicprojection(0.0, w, 0.0, h, nearclip, farclip) end view = Observable(Mat4{Float64}(I)) proj = Observable(Mat4{Float64}(I)) @@ -83,7 +83,7 @@ function Camera(px_area) proj, proj_view, lift(a-> Vec2f(widths(a)), px_area), - Observable(Vec3f(1)), + Observable(Vec3e(1)), ObserverFunction[] ) end diff --git a/src/camera/camera2d.jl b/src/camera/camera2d.jl index 3a9a07c9024..44452a1deaa 100644 --- a/src/camera/camera2d.jl +++ b/src/camera/camera2d.jl @@ -1,9 +1,9 @@ struct Camera2D <: AbstractCamera - area::Observable{Rect2f} - zoomspeed::Observable{Float32} + area::Observable{Rect2{Float64}} + zoomspeed::Observable{Float64} zoombutton::Observable{ButtonTypes} panbutton::Observable{Union{ButtonTypes, Vector{ButtonTypes}}} - padding::Observable{Float32} + padding::Observable{Float64} last_area::Observable{Vec{2, Int}} update_limits::Observable{Bool} end @@ -16,8 +16,8 @@ Creates a 2D camera for the given Scene. function cam2d!(scene::SceneLike; kw_args...) cam_attributes = merged_get!(:cam2d, scene, Attributes(kw_args)) do Attributes( - area = Observable(Rectf(0, 0, 1, 1)), - zoomspeed = 0.10f0, + area = Observable(Rect2{Float64}(0, 0, 1, 1)), + zoomspeed = 0.10, zoombutton = nothing, panbutton = Mouse.right, selectionbutton = (Keyboard.space, Mouse.left), @@ -55,7 +55,7 @@ Useful when using the `Observable` pipeline. update_cam!(scene::SceneLike) = update_cam!(scene, cameracontrols(scene), limits(scene)[]) function update_cam!(scene::Scene, cam::Camera2D, area3d::Rect) - area = Rect2f(area3d) + area = Rect2{Float64}(area3d) area = positive_widths(area) # ignore rects with width almost 0 any(x-> x ≈ 0.0, widths(area)) && return @@ -71,18 +71,18 @@ function update_cam!(scene::Scene, cam::Camera2D, area3d::Rect) # so we make the minimum 1.0, and grow in the other dimension s = ratio ./ minimum(ratio) newwh = s .* widths(area) - cam.area[] = Rectf(minimum(area), newwh) + cam.area[] = Rect2{Float64}(minimum(area), newwh) end update_cam!(scene, cam) end function update_cam!(scene::SceneLike, cam::Camera2D) x, y = minimum(cam.area[]) - w, h = widths(cam.area[]) ./ 2f0 + w, h = widths(cam.area[]) ./ 2.0 # These observables should be final, no one should do map(cam.projection), # so we don't push! and just update the value in place - view = translationmatrix(Vec3f(-x - w, -y - h, 0)) - projection = orthographicprojection(-w, w, -h, h, -10_000f0, 10_000f0) + view = translationmatrix(Vec3e(-x - w, -y - h, 0)) + projection = orthographicprojection(-w, w, -h, h, -10_000.0, 10_000.0) set_proj_view!(camera(scene), projection, view) cam.last_area[] = Vec(size(scene)) return @@ -94,7 +94,7 @@ function correct_ratio!(scene, cam) change = neww .- cam.last_area[] if !(change ≈ Vec(0.0, 0.0)) s = 1.0 .+ (change ./ cam.last_area[]) - camrect = Rectf(minimum(cam.area[]), widths(cam.area[]) .* s) + camrect = Rect2{Float64}(minimum(cam.area[]), widths(cam.area[]) .* s) cam.area[] = camrect update_cam!(scene, cam) end @@ -124,7 +124,7 @@ function add_pan!(scene::SceneLike, cam::Camera2D) startpos[] = mp area = cam.area[] diff = Vec(diff) .* wscale(pixelarea(scene)[], area) - cam.area[] = Rectf(minimum(area) .+ diff, widths(area)) + cam.area[] = Rect2{Float64}(minimum(area) .+ diff, widths(area)) update_cam!(scene, cam) active[] = false return Consume(true) @@ -142,7 +142,7 @@ function add_pan!(scene::SceneLike, cam::Camera2D) startpos[] = pos area = cam.area[] diff = Vec(diff) .* wscale(pixelarea(scene)[], area) - cam.area[] = Rectf(minimum(area) .+ diff, widths(area)) + cam.area[] = Rect2{Float64}(minimum(area) .+ diff, widths(area)) update_cam!(scene, cam) return Consume(true) end @@ -154,17 +154,17 @@ function add_zoom!(scene::SceneLike, cam::Camera2D) e = events(scene) on(camera(scene), e.scroll) do x @extractvalue cam (zoomspeed, zoombutton, area) - zoom = Float32(x[2]) + zoom = Float64(x[2]) if zoom != 0 && ispressed(scene, zoombutton) && is_mouseinside(scene) pa = pixelarea(scene)[] - z = (1f0 - zoomspeed)^zoom - mp = Vec2f(e.mouseposition[]) - minimum(pa) + z = (1.0 - zoomspeed)^zoom + mp = Vec2e(e.mouseposition[]) - minimum(pa) mp = (mp .* wscale(pa, area)) + minimum(area) p1, p2 = minimum(area), maximum(area) p1, p2 = p1 - mp, p2 - mp # translate to mouse position p1, p2 = z * p1, z * p2 p1, p2 = p1 + mp, p2 + mp - cam.area[] = Rectf(p1, p2 - p1) + cam.area[] = Rect2{Float64}(p1, p2 - p1) update_cam!(scene, cam) return Consume(true) end @@ -182,13 +182,13 @@ function absrect(rect) xy = ntuple(Val(2)) do i wh[i] < 0 ? xy[i] + wh[i] : xy[i] end - return Rectf(Vec2f(xy), Vec2f(abs.(wh))) + return Rect2{Float64}(Vec2e(xy), Vec2e(abs.(wh))) end function selection_rect!(scene, cam, key) - rect = RefValue(Rectf(NaN, NaN, NaN, NaN)) - lw = 2f0 + rect = RefValue(Rect2{Float64}(NaN, NaN, NaN, NaN)) + lw = 2.0 scene_unscaled = Scene( scene, transformation = Transformation(), cam = copy(camera(scene)), clear = false @@ -198,7 +198,7 @@ function selection_rect!(scene, cam, key) scene_unscaled, rect[], linestyle = :dot, - linewidth = 2f0, + linewidth = 2.0, color = (:black, 0.4), visible = false ) @@ -209,7 +209,7 @@ function selection_rect!(scene, cam, key) if event.action == Mouse.press && !waspressed[] waspressed[] = true rect_vis[:visible] = true # start displaying - rect[] = Rectf(mp, 0, 0) + rect[] = Rect2{Float64}(mp, Vec2e(0)) rect_vis[1] = rect[] return Consume(true) end @@ -221,7 +221,7 @@ function selection_rect!(scene, cam, key) if w > 0.0 && h > 0.0 update_cam!(scene, cam, r) end - rect[] = Rectf(NaN, NaN, NaN, NaN) + rect[] = Rect2{Float64}(NaN, NaN, NaN, NaN) rect_vis[1] = rect[] return Consume(true) end @@ -237,7 +237,7 @@ function selection_rect!(scene, cam, key) if ispressed(scene, key) && is_mouseinside(scene) mp = camspace(scene, cam, mp) mini = minimum(rect[]) - rect[] = Rectf(mini, mp - mini) + rect[] = Rect2{Float64}(mini, mp - mini) rect_vis[1] = rect[] return Consume(true) end @@ -256,14 +256,14 @@ function reset!(cam, boundingbox, preserveratio = true) ratio = w2 ./ w1 w1 = if ratio[1] > ratio[2] s = w2[1] ./ w2[2] - Vec2f(s * w1[2], w1[2]) + Vec2e(s * w1[2], w1[2]) else s = w2[2] ./ w2[1] - Vec2f(w1[1], s * w1[1]) + Vec2e(w1[1], s * w1[1]) end end p = minimum(w1) .* 0.001 # 2mm padding - update_cam!(cam, Rectf(-p, -p, w1 .+ 2p)) + update_cam!(cam, Rect2{Float64}(-p, -p, w1 .+ 2p)) return end @@ -272,7 +272,7 @@ function add_restriction!(cam, window, rarea::Rect2, minwidths::Vec) restrict_action = paused_action(1.0) do t o = lerp(origin(area_ref[]), origin(cam[Area]), t) wh = lerp(widths(area_ref[]), widths(cam[Area]), t) - update_cam!(cam, Rectf(o, wh)) + update_cam!(cam, Rect2{Float64}(o, wh)) end on(window, Mouse.Drag) do drag if drag == Mouse.up && !isplaying(restrict_action) @@ -284,13 +284,13 @@ function add_restriction!(cam, window, rarea::Rect2, minwidths::Vec) maxi = maxi - newmax newo = newo - maxi newwh = newmax - newo - scale = 1f0 + scale = 1.0 for (w1, w2) in zip(minwidths, newwh) - stmp = w1 > w2 ? w1 / w2 : 1f0 + stmp = w1 > w2 ? w1 / w2 : 1.0 scale = max(scale, stmp) end newwh = newwh * scale - area_ref[] = Rectf(newo, newwh) + area_ref[] = Rect2{Float64}(newo, newwh) if area_ref[] != cam[Area] play!(restrict_action) end @@ -305,22 +305,22 @@ struct PixelCamera <: AbstractCamera end struct UpdatePixelCam camera::Camera - near::Float32 - far::Float32 + near::Float64 + far::Float64 end function (cam::UpdatePixelCam)(window_size) - w, h = Float32.(widths(window_size)) - projection = orthographicprojection(0f0, w, 0f0, h, cam.near, cam.far) + w, h = Float64.(widths(window_size)) + projection = orthographicprojection(0.0, w, 0.0, h, cam.near, cam.far) set_proj_view!(cam.camera, projection, Mat4f(I)) end """ - campixel!(scene; nearclip=-1000f0, farclip=1000f0) + campixel!(scene; nearclip=-1000.0, farclip=1000.0) Creates a pixel-level camera for the `Scene`. No controls! """ -function campixel!(scene::Scene; nearclip=-10_000f0, farclip=10_000f0) +function campixel!(scene::Scene; nearclip=-10_000.0, farclip=10_000.0) disconnect!(camera(scene)) update_once = Observable(false) closure = UpdatePixelCam(camera(scene), nearclip, farclip) @@ -340,8 +340,8 @@ struct RelativeCamera <: AbstractCamera end Creates a pixel-level camera for the `Scene`. No controls! """ -function cam_relative!(scene::Scene; nearclip=-10_000f0, farclip=10_000f0) - projection = orthographicprojection(0f0, 1f0, 0f0, 1f0, nearclip, farclip) +function cam_relative!(scene::Scene; nearclip=-10_000.0, farclip=10_000.0) + projection = orthographicprojection(0.0, 1.0, 0.0, 1.0, nearclip, farclip) set_proj_view!(camera(scene), projection, Mat4f(I)) cam = RelativeCamera() cameracontrols!(scene, cam) diff --git a/src/camera/camera3d.jl b/src/camera/camera3d.jl index d7a8b6dace2..6f1f0bfb6b5 100644 --- a/src/camera/camera3d.jl +++ b/src/camera/camera3d.jl @@ -1,12 +1,12 @@ struct Camera3D <: AbstractCamera - eyeposition::Observable{Vec3f} - lookat::Observable{Vec3f} - upvector::Observable{Vec3f} - - zoom_mult::Observable{Float32} - fov::Observable{Float32} # WGLMakie compat - near::Observable{Float32} - far::Observable{Float32} + eyeposition::Observable{Vec3e} + lookat::Observable{Vec3e} + upvector::Observable{Vec3e} + + zoom_mult::Observable{Float64} + fov::Observable{Float64} # WGLMakie compat + near::Observable{Float64} + far::Observable{Float64} pulser::Observable{Float64} attributes::Attributes @@ -19,7 +19,7 @@ Creates a 3d camera with a lot of controls. The 3D camera is (or can be) unrestricted in terms of rotations and translations. Both `cam3d!(scene)` and `cam3d_cad!(scene)` create this camera type. Unlike the 2D camera, settings and controls are stored in the `cam.attributes` field rather than in the struct directly, but can still be passed as keyword arguments. The general camera settings include -- `fov = 45f0` sets the "neutral" field of view, i.e. the fov corresponding to no zoom. This is irrelevant if the camera uses an orthographic projection. +- `fov = 45.0` sets the "neutral" field of view, i.e. the fov corresponding to no zoom. This is irrelevant if the camera uses an orthographic projection. - `near = automatic` sets the value of the near clip. By default this will be chosen based on the scenes bounding box. The final value is in `cam.near`. - `far = automatic` sets the value of the far clip. By default this will be chosen based on the scenes bounding box. The final value is in `cam.far`. - `rotation_center = :lookat` sets the default center for camera rotations. Currently allows `:lookat` or `:eyeposition`. @@ -28,7 +28,7 @@ The 3D camera is (or can be) unrestricted in terms of rotations and translations - `zoom_shift_lookat = true`: If true attempts to keep data under the cursor in view when zooming. - `cad = false`: If true rotates the view around `lookat` when zooming off-center. -The camera view follows from the position of the camera `eyeposition`, the point which the camera focuses `lookat` and the up direction of the camera `upvector`. These can be accessed as `cam.eyeposition` etc and adjusted via `update_cam!(scene, cameracontrols(scene), eyeposition, lookat[, upvector = Vec3f(0, 0, 1)])`. They can also be passed as keyword arguments when the camera is constructed. +The camera view follows from the position of the camera `eyeposition`, the point which the camera focuses `lookat` and the up direction of the camera `upvector`. These can be accessed as `cam.eyeposition` etc and adjusted via `update_cam!(scene, cameracontrols(scene), eyeposition, lookat[, upvector = Vec3e(0, 0, 1)])`. They can also be passed as keyword arguments when the camera is constructed. The camera can be controlled by keyboard and mouse. The keyboard has the following available attributes @@ -51,9 +51,9 @@ The camera can be controlled by keyboard and mouse. The keyboard has the followi - `roll_clockwise_key = Keyboard.e` sets the key for rotations of the screen. - `roll_counterclockwise_key = Keyboard.q` sets the key for rotations of the screen. -- `keyboard_rotationspeed = 1f0` sets the speed of keyboard based rotations. -- `keyboard_translationspeed = 0.5f0` sets the speed of keyboard based translations. -- `keyboard_zoomspeed = 1f0` sets the speed of keyboard based zooms. +- `keyboard_rotationspeed = 1.0` sets the speed of keyboard based rotations. +- `keyboard_translationspeed = 0.5` sets the speed of keyboard based translations. +- `keyboard_zoomspeed = 1.0` sets the speed of keyboard based zooms. - `update_rate = 1/30` sets the rate at which keyboard based camera updates are evaluated. and mouse interactions are controlled by @@ -62,9 +62,9 @@ and mouse interactions are controlled by - `scroll_mod = true` sets an additional modifier button for scroll-based zoom. (true being neutral) - `rotation_button = Mouse.left` sets the mouse button for drag-rotations. (pan, tilt) -- `mouse_rotationspeed = 1f0` sets the speed of mouse rotations. -- `mouse_translationspeed = 0.5f0` sets the speed of mouse translations. -- `mouse_zoomspeed = 1f0` sets the speed of mouse zooming (mousewheel). +- `mouse_rotationspeed = 1.0` sets the speed of mouse rotations. +- `mouse_translationspeed = 0.5` sets the speed of mouse translations. +- `mouse_zoomspeed = 1.0` sets the speed of mouse zooming (mousewheel). - `circular_rotation = (true, true, true)` enables circular rotations for (fixed x, fixed y, fixed z) rotation axis. (This means drawing a circle with your mouse around the center of the scene will result in a continuous rotation.) There are also a few generally applicable controls: @@ -72,12 +72,12 @@ There are also a few generally applicable controls: - `fix_x_key = Keyboard.x` sets the key for fixing translations and rotations to the (world/plot) x-axis. - `fix_y_key = Keyboard.y` sets the key for fixing translations and rotations to the (world/plot) y-axis. - `fix_z_key = Keyboard.z` sets the key for fixing translations and rotations to the (world/plot) z-axis. -- `reset = Keyboard.home` sets the key for fully resetting the camera. This equivalent to setting `lookat = Vec3f(0)`, `upvector = Vec3f(0, 0, 1)`, `eyeposition = Vec3f(3)` and then calling `center!(scene)`. +- `reset = Keyboard.home` sets the key for fully resetting the camera. This equivalent to setting `lookat = Vec3e(0)`, `upvector = Vec3e(0, 0, 1)`, `eyeposition = Vec3e(3)` and then calling `center!(scene)`. You can also make adjustments to the camera position, rotation and zoom by calling relevant functions: - `translate_cam!(scene, v)` will translate the camera by the given world/plot space vector `v`. -- `rotate_cam!(scene, angles)` will rotate the camera around its axes with the corresponding angles. The first angle will rotate around the cameras "right" that is the screens horizontal axis, the second around the up vector/vertical axis or `Vec3f(0, 0, +-1)` if `fixed_axis = true`, and the third will rotate around the view direction i.e. the axis out of the screen. The rotation respects the current `rotation_center` of the camera. +- `rotate_cam!(scene, angles)` will rotate the camera around its axes with the corresponding angles. The first angle will rotate around the cameras "right" that is the screens horizontal axis, the second around the up vector/vertical axis or `Vec3e(0, 0, +-1)` if `fixed_axis = true`, and the third will rotate around the view direction i.e. the axis out of the screen. The rotation respects the current `rotation_center` of the camera. - `zoom!(scene, zoom_step)` will change the zoom level of the scene without translating or rotating the scene. `zoom_step` applies multiplicatively to `cam.zoom_mult` which is used as a multiplier to the fov (perspective projection) or width and height (orthographic projection). """ function Camera3D(scene::Scene; kwargs...) @@ -113,14 +113,14 @@ function Camera3D(scene::Scene; kwargs...) fix_z_key = Keyboard.z, reset = Keyboard.home, # Settings - keyboard_rotationspeed = 1f0, - keyboard_translationspeed = 0.5f0, - keyboard_zoomspeed = 1f0, - mouse_rotationspeed = 1f0, - mouse_translationspeed = 1f0, - mouse_zoomspeed = 1f0, + keyboard_rotationspeed = 1.0, + keyboard_translationspeed = 0.5, + keyboard_zoomspeed = 1.0, + mouse_rotationspeed = 1.0, + mouse_translationspeed = 1.0, + mouse_zoomspeed = 1.0, circular_rotation = (true, true, true), - fov = 45f0, # base fov + fov = 45.0, # base fov near = automatic, far = automatic, rotation_center = :lookat, @@ -135,14 +135,14 @@ function Camera3D(scene::Scene; kwargs...) end cam = Camera3D( - pop!(attr, :eyeposition, Vec3f(3)), - pop!(attr, :lookat, Vec3f(0)), - pop!(attr, :upvector, Vec3f(0, 0, 1)), + pop!(attr, :eyeposition, Vec3e(3)), + pop!(attr, :lookat, Vec3e(0)), + pop!(attr, :upvector, Vec3e(0, 0, 1)), - Observable(1f0), + Observable(1.0), Observable(attr[:fov][]), - Observable(attr[:near][] === automatic ? 0.1f0 : attr[:near][]), - Observable(attr[:far][] === automatic ? 100f0 : attr[:far][]), + Observable(attr[:near][] === automatic ? 0.1 : attr[:near][]), + Observable(attr[:far][] === automatic ? 100.0 : attr[:far][]), Observable(-1.0), attr @@ -154,7 +154,7 @@ function Camera3D(scene::Scene; kwargs...) # ticks every so often to get consistent position updates. on(cam.pulser) do prev_time current_time = time() - active = on_pulse(scene, cam, Float32(current_time - prev_time)) + active = on_pulse(scene, cam, Float64(current_time - prev_time)) @async if active && attr.selected[] sleep(attr.update_rate[]) cam.pulser[] = current_time @@ -214,9 +214,9 @@ function Camera3D(scene::Scene; kwargs...) # center keeps the rotation of the camera so we reset that here # might make sense to keep user set lookat, upvector, eyeposition # around somewhere for this? - cam.lookat[] = Vec3f(0) - cam.upvector[] = Vec3f(0,0,1) - cam.eyeposition[] = Vec3f(3) + cam.lookat[] = Vec3e(0) + cam.upvector[] = Vec3e(0,0,1) + cam.eyeposition[] = Vec3e(3) center!(scene) return Consume(true) end @@ -256,12 +256,12 @@ function add_translation!(scene, cam::Camera3D) function compute_diff(delta) if cam.attributes[:projectiontype][] == Orthographic - aspect = Float32((/)(widths(scene.px_area[])...)) - aspect_scale = Vec2f(1f0 + aspect, 1f0 + 1f0 / aspect) + aspect = Float64((/)(widths(scene.px_area[])...)) + aspect_scale = Vec2f(1.0 + aspect, 1.0 + 1.0 / aspect) return cam.zoom_mult[] * delta .* aspect_scale ./ widths(scene.px_area[]) else viewdir = cam.lookat[] - cam.eyeposition[] - return 0.002f0 * cam.zoom_mult[] * norm(viewdir) * delta + return 0.002 * cam.zoom_mult[] * norm(viewdir) * delta end end @@ -278,7 +278,7 @@ function add_translation!(scene, cam::Camera3D) diff = compute_diff(last_mousepos[] .- mousepos) last_mousepos[] = mousepos dragging[] = false - translate_cam!(scene, cam, translationspeed[] .* Vec3f(diff[1], diff[2], 0f0)) + translate_cam!(scene, cam, translationspeed[] .* Vec3e(diff[1], diff[2], 0.0)) return Consume(true) end return Consume(false) @@ -290,7 +290,7 @@ function add_translation!(scene, cam::Camera3D) mousepos = screen_relative(scene, mp) diff = compute_diff(last_mousepos[] .- mousepos) last_mousepos[] = mousepos - translate_cam!(scene, cam, translationspeed[] * Vec3f(diff[1], diff[2], 0f0)) + translate_cam!(scene, cam, translationspeed[] * Vec3e(diff[1], diff[2], 0.0)) return Consume(true) end return Consume(false) @@ -298,7 +298,7 @@ function add_translation!(scene, cam::Camera3D) on(camera(scene), scene.events.scroll) do scroll if is_mouseinside(scene) && ispressed(scene, scroll_mod[]) - zoom_step = (1f0 + 0.1f0 * zoomspeed[]) ^ -scroll[2] + zoom_step = (1.0 + 0.1 * zoomspeed[]) ^ -scroll[2] zoom!(scene, cam, zoom_step, shift_lookat[], cad[]) return Consume(true) end @@ -325,9 +325,9 @@ function add_rotation!(scene, cam::Camera3D) mousepos = mouseposition_px(scene) dragging[] = false rot_scaling = rotationspeed[] * (e.window_dpi[] * 0.005) - mp = (last_mousepos[] .- mousepos) .* 0.01f0 .* rot_scaling + mp = (last_mousepos[] .- mousepos) .* 0.01 .* rot_scaling last_mousepos[] = mousepos - rotate_cam!(scene, cam, Vec3f(-mp[2], mp[1], 0f0), true) + rotate_cam!(scene, cam, Vec3e(-mp[2], mp[1], 0.0), true) return Consume(true) end return Consume(false) @@ -338,9 +338,9 @@ function add_rotation!(scene, cam::Camera3D) if dragging[] && ispressed(scene, button[]) mousepos = screen_relative(scene, mp) rot_scaling = rotationspeed[] * (e.window_dpi[] * 0.005) - mp = (last_mousepos[] .- mousepos) * 0.01f0 * rot_scaling + mp = (last_mousepos[] .- mousepos) * 0.01 * rot_scaling last_mousepos[] = mousepos - rotate_cam!(scene, cam, Vec3f(-mp[2], mp[1], 0f0), true) + rotate_cam!(scene, cam, Vec3e(-mp[2], mp[1], 0.0), true) return Consume(true) end return Consume(false) @@ -363,7 +363,7 @@ function on_pulse(scene, cam, timestep) if translating # translation in camera space x/y/z direction translation = attr[:keyboard_translationspeed][] * timestep * - Vec3f(right - left, up - down, backward - forward) + Vec3e(right - left, up - down, backward - forward) viewdir = cam.lookat[] - cam.eyeposition[] _translate_cam!(scene, cam, cam.zoom_mult[] * norm(viewdir) * translation) end @@ -380,7 +380,7 @@ function on_pulse(scene, cam, timestep) if rotating # rotations around camera space x/y/z axes angles = attr[:keyboard_rotationspeed][] * timestep * - Vec3f(up - down, left - right, counterclockwise - clockwise) + Vec3e(up - down, left - right, counterclockwise - clockwise) _rotate_cam!(scene, cam, angles) end @@ -391,14 +391,14 @@ function on_pulse(scene, cam, timestep) zooming = zoom_out || zoom_in if zooming - zoom_step = (1f0 + attr[:keyboard_zoomspeed][] * timestep) ^ (zoom_out - zoom_in) + zoom_step = (1.0 + attr[:keyboard_zoomspeed][] * timestep) ^ (zoom_out - zoom_in) _zoom!(scene, cam, zoom_step, false) end stretch = ispressed(scene, attr[:stretch_view_key][]) contract = ispressed(scene, attr[:contract_view_key][]) if stretch || contract - zoom_step = (1f0 + attr[:keyboard_zoomspeed][] * timestep) ^ (stretch - contract) + zoom_step = (1.0 + attr[:keyboard_zoomspeed][] * timestep) ^ (stretch - contract) cam.eyeposition[] = cam.lookat[] + zoom_step * (cam.eyeposition[] - cam.lookat[]) end zooming = zooming || stretch || contract @@ -435,7 +435,7 @@ function _translate_cam!(scene, cam, t) fix_y = ispressed(scene, cam.attributes[:fix_y_key][]) fix_z = ispressed(scene, cam.attributes[:fix_z_key][]) if fix_x || fix_y || fix_z - trans = Vec3f(fix_x, fix_y, fix_z) .* trans + trans = Vec3e(fix_x, fix_y, fix_z) .* trans end cam.eyeposition[] = eyepos + trans @@ -459,7 +459,7 @@ function _rotate_cam!(scene, cam::Camera3D, angles::VecTypes, from_mouse=false) right = cross(viewdir, up) # +x x_axis = right - y_axis = cam.attributes[:fixed_axis][] ? Vec3f(0, 0, ifelse(up[3] < 0, -1, 1)) : up + y_axis = cam.attributes[:fixed_axis][] ? Vec3e(0, 0, ifelse(up[3] < 0, -1, 1)) : up z_axis = -viewdir fix_x = ispressed(scene, cam.attributes[:fix_x_key][]) @@ -478,14 +478,14 @@ function _rotate_cam!(scene, cam::Camera3D, angles::VecTypes, from_mouse=false) # recontextualize the (dy, dx, 0) from mouse rotations so that # drawing circles creates continuous rotations around the fixed axis mp = mouseposition_px(scene) - past_half = 0.5f0 .* widths(scene.px_area[]) .> mp - flip = 2f0 * past_half .- 1f0 + past_half = 0.5 .* widths(scene.px_area[]) .> mp + flip = 2.0 * past_half .- 1.0 angle = flip[1] * angles[1] + flip[2] * angles[2] - angles = Vec3f(-angle, angle, -angle) + angles = Vec3e(-angle, angle, -angle) # only one fix is true so this only rotates around one axis rotation *= qrotation( - Vec3f(fix_x, fix_z, fix_y) .* Vec3f(sign(right[1]), viewdir[2], sign(up[3])), - dot(Vec3f(fix_x, fix_y, fix_z), angles) + Vec3e(fix_x, fix_z, fix_y) .* Vec3e(sign(right[1]), viewdir[2], sign(up[3])), + dot(Vec3e(fix_x, fix_y, fix_z), angles) ) else # restrict total quaternion rotation to one axis @@ -534,9 +534,9 @@ function _zoom!(scene::Scene, cam::Camera3D, zoom_step, shift_lookat = false, ca viewdir = lookat - eyepos # -z right = cross(viewdir, up) # +x - rel_pos = 2f0 * mouseposition_px(scene) ./ widths(scene.px_area[]) .- 1f0 + rel_pos = 2.0 * mouseposition_px(scene) ./ widths(scene.px_area[]) .- 1.0 shift = rel_pos[1] * normalize(right) + rel_pos[2] * normalize(up) - shifted = eyepos + 0.1f0 * sign(1f0 - zoom_step) * norm(viewdir) * shift + shifted = eyepos + 0.1 * sign(1.0 - zoom_step) * norm(viewdir) * shift cam.eyeposition[] = lookat + norm(viewdir) * normalize(shifted - lookat) elseif shift_lookat lookat = cam.lookat[] @@ -551,19 +551,19 @@ function _zoom!(scene::Scene, cam::Camera3D, zoom_step, shift_lookat = false, ca # translate both eyeposition and lookat to more or less keep data # under the mouse in view fov = cam.attributes[:fov][] - before = tan(clamp(cam.zoom_mult[] * fov, 0.01f0, 175f0) / 360f0 * Float32(pi)) - after = tan(clamp(cam.zoom_mult[] * zoom_step * fov, 0.01f0, 175f0) / 360f0 * Float32(pi)) + before = tan(clamp(cam.zoom_mult[] * fov, 0.01, 175.0) / 360.0 * Float64(pi)) + after = tan(clamp(cam.zoom_mult[] * zoom_step * fov, 0.01, 175.0) / 360.0 * Float64(pi)) - aspect = Float32((/)(widths(scene.px_area[])...)) - rel_pos = 2f0 * mouseposition_px(scene) ./ widths(scene.px_area[]) .- 1f0 + aspect = Float64((/)(widths(scene.px_area[])...)) + rel_pos = 2.0 * mouseposition_px(scene) ./ widths(scene.px_area[]) .- 1.0 shift = rel_pos[1] * u_x + rel_pos[2] * u_y shift = -(after - before) * norm(viewdir) * normalize(aspect .* shift) else - mx, my = 2f0 * mouseposition_px(scene) ./ widths(scene.px_area[]) .- 1f0 - aspect = Float32((/)(widths(scene.px_area[])...)) - w = 0.5f0 * (1f0 + aspect) * cam.zoom_mult[] - h = 0.5f0 * (1f0 + 1f0 / aspect) * cam.zoom_mult[] - shift = (1f0 - zoom_step) * (mx * w * u_x + my * h * u_y) + mx, my = 2.0 * mouseposition_px(scene) ./ widths(scene.px_area[]) .- 1.0 + aspect = Float64((/)(widths(scene.px_area[])...)) + w = 0.5 * (1.0 + aspect) * cam.zoom_mult[] + h = 0.5 * (1.0 + 1.0 / aspect) * cam.zoom_mult[] + shift = (1.0 - zoom_step) * (mx * w * u_x + my * h * u_y) end cam.lookat[] = lookat + shift @@ -581,15 +581,15 @@ function update_cam!(scene::Scene, cam::Camera3D) @extractvalue cam (lookat, eyeposition, upvector) near = cam.near[]; far = cam.far[] - aspect = Float32((/)(widths(scene.px_area[])...)) + aspect = Float64((/)(widths(scene.px_area[])...)) if cam.attributes[:projectiontype][] == Perspective - fov = clamp(cam.zoom_mult[] * cam.attributes[:fov][], 0.01f0, 175f0) + fov = clamp(cam.zoom_mult[] * cam.attributes[:fov][], 0.01, 175.0) cam.fov[] = fov proj = perspectiveprojection(fov, aspect, near, far) else - w = 0.5f0 * (1f0 + aspect) * cam.zoom_mult[] - h = 0.5f0 * (1f0 + 1f0 / aspect) * cam.zoom_mult[] + w = 0.5 * (1.0 + aspect) * cam.zoom_mult[] + h = 0.5 * (1.0 + 1.0 / aspect) * cam.zoom_mult[] proj = orthographicprojection(-w, w, -h, h, near, far) end @@ -602,34 +602,34 @@ end function update_cam!(scene::Scene, camera::Camera3D, area3d::Rect) @extractvalue camera (lookat, eyeposition, upvector) - bb = Rect3f(area3d) + bb = Rect3{Float64}(area3d) width = widths(bb) - half_width = width ./ 2f0 + half_width = width ./ 2.0 middle = maximum(bb) - half_width old_dir = normalize(eyeposition .- lookat) camera.lookat[] = middle neweyepos = middle .+ (1.2*norm(width) .* old_dir) camera.eyeposition[] = neweyepos - camera.upvector[] = Vec3f(0,0,1) + camera.upvector[] = Vec3e(0,0,1) if camera.attributes[:near][] === automatic - camera.near[] = 0.1f0 * norm(widths(bb)) + camera.near[] = 0.1 * norm(widths(bb)) end if camera.attributes[:far][] === automatic - camera.far[] = 3f0 * norm(widths(bb)) + camera.far[] = 3.0 * norm(widths(bb)) end if camera.attributes[:projectiontype][] == Orthographic camera.zoom_mult[] = 0.6 * norm(width) else - camera.zoom_mult[] = 1f0 + camera.zoom_mult[] = 1.0 end update_cam!(scene, camera) return end -function update_cam!(scene::Scene, camera::Camera3D, eyeposition, lookat, up = Vec3f(0, 0, 1)) - camera.lookat[] = Vec3f(lookat) - camera.eyeposition[] = Vec3f(eyeposition) - camera.upvector[] = Vec3f(up) +function update_cam!(scene::Scene, camera::Camera3D, eyeposition, lookat, up = Vec3e(0, 0, 1)) + camera.lookat[] = Vec3e(lookat) + camera.eyeposition[] = Vec3e(eyeposition) + camera.upvector[] = Vec3e(up) update_cam!(scene, camera) return end diff --git a/src/camera/old_camera3d.jl b/src/camera/old_camera3d.jl index 2d5f424cccf..fde16ca4e8b 100644 --- a/src/camera/old_camera3d.jl +++ b/src/camera/old_camera3d.jl @@ -2,14 +2,14 @@ @enum ProjectionEnum Perspective Orthographic struct OldCamera3D <: AbstractCamera - rotationspeed::Observable{Float32} - translationspeed::Observable{Float32} - eyeposition::Observable{Vec3f} - lookat::Observable{Vec3f} - upvector::Observable{Vec3f} - fov::Observable{Float32} - near::Observable{Float32} - far::Observable{Float32} + rotationspeed::Observable{Float64} + translationspeed::Observable{Float64} + eyeposition::Observable{Vec3e} + lookat::Observable{Vec3e} + upvector::Observable{Vec3e} + fov::Observable{Float64} + near::Observable{Float64} + far::Observable{Float64} projectiontype::Observable{ProjectionEnum} pan_button::Observable{ButtonTypes} rotate_button::Observable{ButtonTypes} @@ -28,12 +28,12 @@ function old_cam3d_cad!(scene::Scene; kw_args...) Attributes( rotationspeed = 0.01, translationspeed = 1.0, - eyeposition = Vec3f(3), - lookat = Vec3f(0), - upvector = Vec3f(0, 0, 1), - fov = 45f0, - near = 0.01f0, - far = 100f0, + eyeposition = Vec3e(3), + lookat = Vec3e(0), + upvector = Vec3e(0, 0, 1), + fov = 45.0, + near = 0.01, + far = 100.0, projectiontype = Perspective, pan_button = Mouse.right, rotate_button = Mouse.left, @@ -64,12 +64,12 @@ function old_cam3d_turntable!(scene::Scene; kw_args...) Attributes( rotationspeed = 0.01, translationspeed = 1.0, - eyeposition = Vec3f(3), - lookat = Vec3f(0), - upvector = Vec3f(0, 0, 1), - fov = 45f0, - near = 0.01f0, - far = 100f0, + eyeposition = Vec3e(3), + lookat = Vec3e(0), + upvector = Vec3e(0, 0, 1), + fov = 45.0, + near = 0.01, + far = 100.0, projectiontype = Perspective, pan_button = Mouse.right, rotate_button = Mouse.left, @@ -151,7 +151,7 @@ function add_translation!(scene, cam, key, button, zoom_shift_lookat::Bool) dragging[] = false diff = (last_mousepos[] - mousepos) * cam.translationspeed[] last_mousepos[] = mousepos - translate_cam!(scene, cam, Vec3f(0f0, diff[1], diff[2])) + translate_cam!(scene, cam, Vec3e(0.0, diff[1], diff[2])) return Consume(true) end end @@ -163,7 +163,7 @@ function add_translation!(scene, cam, key, button, zoom_shift_lookat::Bool) mousepos = screen_relative(scene, mp) diff = (last_mousepos[] .- mousepos) * cam.translationspeed[] last_mousepos[] = mousepos - translate_cam!(scene, cam, Vec3f(0f0, diff[1], diff[2])) + translate_cam!(scene, cam, Vec3e(0.0, diff[1], diff[2])) return Consume(true) end return Consume(false) @@ -173,7 +173,7 @@ function add_translation!(scene, cam, key, button, zoom_shift_lookat::Bool) if ispressed(scene, button[]) && is_mouseinside(scene) cam_res = Vec2f(widths(scene.px_area[])) mouse_pos_normalized = mouseposition_px(scene) ./ cam_res - mouse_pos_normalized = 2*mouse_pos_normalized .- 1f0 + mouse_pos_normalized = 2*mouse_pos_normalized .- 1.0 zoom_step = scroll[2] zoom!(scene, mouse_pos_normalized, zoom_step, zoom_shift_lookat) return Consume(true) @@ -199,7 +199,7 @@ function add_rotation!(scene, cam, button, key, fixed_axis::Bool) rot_scaling = cam.rotationspeed[] * (e.window_dpi[] * 0.005) mp = (last_mousepos[] - mousepos) * rot_scaling last_mousepos[] = mousepos - rotate_cam!(scene, cam, Vec3f(mp[1], -mp[2], 0f0), fixed_axis) + rotate_cam!(scene, cam, Vec3e(mp[1], -mp[2], 0.0), fixed_axis) return Consume(true) end end @@ -212,7 +212,7 @@ function add_rotation!(scene, cam, button, key, fixed_axis::Bool) rot_scaling = cam.rotationspeed[] * (e.window_dpi[] * 0.005) mp = (last_mousepos[] .- mousepos) * rot_scaling last_mousepos[] = mousepos - rotate_cam!(scene, cam, Vec3f(mp[1], -mp[2], 0f0), fixed_axis) + rotate_cam!(scene, cam, Vec3e(mp[1], -mp[2], 0.0), fixed_axis) return Consume(true) end return Consume(false) @@ -226,15 +226,15 @@ Translate the camera by a translation vector given in camera space. """ translate_cam!(scene::Scene, translation::VecTypes) = translate_cam!(scene, cameracontrols(scene), translation) function translate_cam!(scene::Scene, cam::OldCamera3D, _translation::VecTypes) - translation = Vec3f(_translation) - translation == Vec3f(0) && return + translation = Vec3e(_translation) + translation == Vec3e(0) && return @extractvalue cam (projectiontype, lookat, eyeposition, upvector) dir = eyeposition - lookat dir_len = norm(dir) cam_res = Vec2f(widths(scene.px_area[])) z, x, y = translation - z *= 0.1f0 * dir_len + z *= 0.1 * dir_len x, y = (Vec2f(x, y) ./ cam_res) .* dir_len @@ -265,7 +265,7 @@ function zoom!(scene, point::VecTypes, zoom_step, shift_lookat::Bool) # the offset parallel to `eyeposition - lookat` ~ dir ray_eye = inv(scene.camera.projection[]) * Vec4f(point[1],point[2],0,0) ray_eye = Vec4f(ray_eye[Vec(1, 2)]...,0,0) - ray_dir = Vec3f((inv(scene.camera.view[]) * ray_eye)) + ray_dir = Vec3e((inv(scene.camera.view[]) * ray_eye)) dir = eyeposition - lookat @@ -274,13 +274,13 @@ function zoom!(scene, point::VecTypes, zoom_step, shift_lookat::Bool) if projectiontype == Perspective ray_dir *= norm(dir) end - cam.eyeposition[] = eyeposition + (ray_dir - dir) * (1f0 - 0.9f0 ^ zoom_step) - cam.lookat[] = lookat + (1f0 - 0.9f0 ^ zoom_step) * ray_dir + cam.eyeposition[] = eyeposition + (ray_dir - dir) * (1.0 - 0.9 ^ zoom_step) + cam.lookat[] = lookat + (1.0 - 0.9 ^ zoom_step) * ray_dir else # Rotations need more extreme eyeposition shifts step = zoom_step - while abs(step) > 0f0 - cam.eyeposition[] = cam.eyeposition[] + sign(zoom_step) * (ray_dir - dir * 0.1f0) + while abs(step) > 0.0 + cam.eyeposition[] = cam.eyeposition[] + sign(zoom_step) * (ray_dir - dir * 0.1) dir = cam.eyeposition[] - lookat step -= sign(step) end @@ -299,14 +299,14 @@ the camera according to the Euler angles (α, β, γ). rotate_cam!(scene::Scene, theta_v::Number...) = rotate_cam!(scene, cameracontrols(scene), theta_v) rotate_cam!(scene::Scene, theta_v::VecTypes) = rotate_cam!(scene, cameracontrols(scene), theta_v) function rotate_cam!(scene::Scene, cam::OldCamera3D, _theta_v::VecTypes, fixed_axis::Bool = true) - theta_v = Vec3f(_theta_v) - theta_v == Vec3f(0) && return #nothing to do! + theta_v = Vec3e(_theta_v) + theta_v == Vec3e(0) && return #nothing to do! @extractvalue cam (eyeposition, lookat, upvector) dir = normalize(eyeposition - lookat) right_v = normalize(cross(upvector, dir)) upvector = normalize(cross(dir, right_v)) - axis = fixed_axis ? Vec3f(0, 0, sign(upvector[3])) : upvector + axis = fixed_axis ? Vec3e(0, 0, sign(upvector[3])) : upvector rotation = rotate_cam(theta_v, right_v, axis, dir) r_eyepos = lookat + rotation * (eyeposition - lookat) r_up = normalize(rotation * upvector) @@ -322,7 +322,7 @@ function update_cam!(scene::Scene, cam::OldCamera3D) zoom = norm(lookat - eyeposition) # TODO this means you can't set FarClip... SAD! # TODO use boundingbox(scene) for optimal far/near - far = max(zoom * 5f0, 30f0) + far = max(zoom * 5.0, 30.0) proj = projection_switch(scene.px_area[], fov, near, far, projectiontype, zoom) view = Makie.lookat(eyeposition, lookat, upvector) set_proj_view!(camera(scene), proj, view) @@ -331,32 +331,32 @@ end function update_cam!(scene::Scene, camera::OldCamera3D, area3d::Rect) @extractvalue camera (fov, near, lookat, eyeposition, upvector) - bb = Rect3f(area3d) + bb = Rect3{Float64}(area3d) width = widths(bb) - half_width = width/2f0 + half_width = width/2.0 middle = maximum(bb) - half_width old_dir = normalize(eyeposition .- lookat) camera.lookat[] = middle neweyepos = middle .+ (1.2*norm(width) .* old_dir) camera.eyeposition[] = neweyepos - camera.upvector[] = Vec3f(0,0,1) - camera.near[] = 0.1f0 * norm(widths(bb)) - camera.far[] = 3f0 * norm(widths(bb)) + camera.upvector[] = Vec3e(0,0,1) + camera.near[] = 0.1 * norm(widths(bb)) + camera.far[] = 3.0 * norm(widths(bb)) update_cam!(scene, camera) return end """ - update_cam!(scene::Scene, eyeposition, lookat, up = Vec3f(0, 0, 1)) + update_cam!(scene::Scene, eyeposition, lookat, up = Vec3e(0, 0, 1)) Updates the camera's controls to point to the specified location. """ -update_cam!(scene::Scene, eyeposition, lookat, up = Vec3f(0, 0, 1)) = update_cam!(scene, cameracontrols(scene), eyeposition, lookat, up) +update_cam!(scene::Scene, eyeposition, lookat, up = Vec3e(0, 0, 1)) = update_cam!(scene, cameracontrols(scene), eyeposition, lookat, up) -function update_cam!(scene::Scene, camera::OldCamera3D, eyeposition, lookat, up = Vec3f(0, 0, 1)) - camera.lookat[] = Vec3f(lookat) - camera.eyeposition[] = Vec3f(eyeposition) - camera.upvector[] = Vec3f(up) +function update_cam!(scene::Scene, camera::OldCamera3D, eyeposition, lookat, up = Vec3e(0, 0, 1)) + camera.lookat[] = Vec3e(lookat) + camera.eyeposition[] = Vec3e(eyeposition) + camera.upvector[] = Vec3e(up) update_cam!(scene, camera) return end From 75b600ee5dbefb6e8aac16df7cfd983d486e35cf Mon Sep 17 00:00:00 2001 From: ffreyer Date: Fri, 3 Mar 2023 12:22:38 +0100 Subject: [PATCH 35/49] fix axis interactions --- src/camera/projection_math.jl | 13 ++++--------- src/interaction/interactive_api.jl | 2 +- src/makielayout/interactions.jl | 16 ++++++++-------- src/makielayout/mousestatemachine.jl | 8 ++++---- 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/camera/projection_math.jl b/src/camera/projection_math.jl index 6d0edfe8da2..5d34b9dd80a 100644 --- a/src/camera/projection_math.jl +++ b/src/camera/projection_math.jl @@ -240,14 +240,9 @@ end function to_world(scene::Scene, point::T) where T <: StaticVector cam = scene.camera - x = to_world( - point, - inv(transformationmatrix(scene)[]) * - inv(cam.view[]) * - inv(cam.projection[]), - T(widths(pixelarea(scene)[])) - ) - Point2f(x[1], x[2]) + pvm = cam.projectionview[] * transformationmatrix(scene)[] + x = to_world(point, inv(pvm), widths(pixelarea(scene)[])) + return Point2{eltype(point)}(x[1], x[2]) end w_component(x::Point) = 1.0 @@ -266,7 +261,7 @@ function to_world( T(0), w_component(p) ) ws = prj_view_inv * pix_space - ws ./ ws[4] + return ws ./ ws[4] end function to_world( diff --git a/src/interaction/interactive_api.jl b/src/interaction/interactive_api.jl index c0cd678d7b5..655b9074871 100644 --- a/src/interaction/interactive_api.jl +++ b/src/interaction/interactive_api.jl @@ -217,7 +217,7 @@ By default uses the `scene` that the mouse is currently hovering over. """ mouseposition(x) = mouseposition(get_scene(x)) function mouseposition(scene::Scene = hovered_scene()) - return to_world(scene, mouseposition_px(scene)) + return to_world(scene, Float64.(mouseposition_px(scene))) end mouseposition_px(x) = mouseposition_px(get_scene(x)) diff --git a/src/makielayout/interactions.jl b/src/makielayout/interactions.jl index 474a61a1aaa..382cabd6ee8 100644 --- a/src/makielayout/interactions.jl +++ b/src/makielayout/interactions.jl @@ -244,9 +244,9 @@ function process_interaction(s::ScrollZoom, event::ScrollEvent, ax::Axis) if zoom != 0 pa = pixelarea(scene)[] - z = (1f0 - s.speed)^zoom + z = (1.0 - s.speed)^zoom - mp_axscene = Vec4f((e.mouseposition[] .- pa.origin)..., 0, 1) + mp_axscene = Vec4e((e.mouseposition[] .- pa.origin)..., 0, 1) # first to normal -1..1 space mp_axfraction = (cam.pixel_space[] * mp_axscene)[Vec(1, 2)] .* @@ -276,11 +276,11 @@ function process_interaction(s::ScrollZoom, event::ScrollEvent, ax::Axis) timed_ticklabelspace_reset(ax, s.reset_timer, s.prev_xticklabelspace, s.prev_yticklabelspace, s.reset_delay) newrect_trans = if ispressed(scene, xzoomkey[]) - Rectf(newxorigin, yorigin, newxwidth, ywidth) + Rect2(newxorigin, yorigin, newxwidth, ywidth) elseif ispressed(scene, yzoomkey[]) - Rectf(xorigin, newyorigin, xwidth, newywidth) + Rect2(xorigin, newyorigin, xwidth, newywidth) else - Rectf(newxorigin, newyorigin, newxwidth, newywidth) + Rect2(newxorigin, newyorigin, newxwidth, newywidth) end inv_transf = Makie.inverse_transform(transf) @@ -308,8 +308,8 @@ function process_interaction(dp::DragPan, event::MouseEvent, ax) cam = camera(scene) pa = pixelarea(scene)[] - mp_axscene = Vec4f((event.px .- pa.origin)..., 0, 1) - mp_axscene_prev = Vec4f((event.prev_px .- pa.origin)..., 0, 1) + mp_axscene = Vec4e((event.px .- pa.origin)..., 0, 1) + mp_axscene_prev = Vec4e((event.prev_px .- pa.origin)..., 0, 1) mp_axfraction, mp_axfraction_prev = map((mp_axscene, mp_axscene_prev)) do mp # first to normal -1..1 space @@ -347,7 +347,7 @@ function process_interaction(dp::DragPan, event::MouseEvent, ax) timed_ticklabelspace_reset(ax, dp.reset_timer, dp.prev_xticklabelspace, dp.prev_yticklabelspace, dp.reset_delay) inv_transf = Makie.inverse_transform(transf) - newrect_trans = Rectf(Vec2f(xori, yori), widths(tlimits_trans)) + newrect_trans = Rect2(Vec2e(xori, yori), widths(tlimits_trans)) tlimits[] = Makie.apply_transform(inv_transf, newrect_trans) return Consume(true) diff --git a/src/makielayout/mousestatemachine.jl b/src/makielayout/mousestatemachine.jl index 40653697f4a..fda096c0de6 100644 --- a/src/makielayout/mousestatemachine.jl +++ b/src/makielayout/mousestatemachine.jl @@ -47,10 +47,10 @@ Fields: struct MouseEvent type::MouseEventType t::Float64 - data::Point2f + data::Point2e px::Point2f prev_t::Float64 - prev_data::Point2f + prev_data::Point2e prev_px::Point2f end @@ -116,7 +116,7 @@ function addmouseevents!(scene, elements...; priority = 1) is_mouse_over_relevant_area() = isempty(elements) ? Makie.is_mouseinside(scene) : mouseover(scene, elements...) _addmouseevents!(scene, is_mouse_over_relevant_area, priority) end -function addmouseevents!(scene, bbox::Observables.AbstractObservable{<: Rect2}; priority = 1) +function addmouseevents!(scene, bbox::Observables.AbstractObservable{<: Rect2{Float64}}; priority = 1) is_mouse_over_relevant_area() = Makie.mouseposition_px(scene) in bbox[] _addmouseevents!(scene, is_mouse_over_relevant_area, priority) end @@ -127,7 +127,7 @@ function _addmouseevents!(scene, is_mouse_over_relevant_area, priority) dblclick_max_interval = 0.2 mouseevent = Observable{MouseEvent}( - MouseEvent(MouseEventTypes.out, 0.0, Point2f(0, 0), Point2f(0, 0), 0.0, Point2f(0, 0), Point2f(0, 0)) + MouseEvent(MouseEventTypes.out, 0.0, Point2e(0, 0), Point2f(0, 0), 0.0, Point2e(0, 0), Point2f(0, 0)) ) # initialize state variables last_mouseevent = Ref{Mouse.Action}(Mouse.release) From f0fbfaca83b6c7d67a037550e555750b03f6a5d9 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Tue, 28 Mar 2023 17:34:53 +0200 Subject: [PATCH 36/49] back to Float64 meshes --- src/conversions.jl | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/conversions.jl b/src/conversions.jl index ddf0d0c7105..4fc568e9e2d 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -548,13 +548,7 @@ function convert_arguments(::Type{<:Mesh}, mesh::GeometryBasics.Mesh{N}) where { end end # TODO Float64? - # If already correct eltypes for GL, we can pass the mesh through as is - if eltype(metafree(coordinates(mesh))) == Point{N, Float32} && eltype(faces(mesh)) == GLTriangleFace - return (mesh,) - else - # Else, we need to convert it! - return (GeometryBasics.mesh(mesh, pointtype=Point{N, Float32}, facetype=GLTriangleFace),) - end + return (GeometryBasics.mesh(mesh, pointtype=Point{N, Float64}, facetype=GLTriangleFace),) end function convert_arguments( From 2c22614f1709f396a9f69804eba4475a0c6519b9 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Tue, 28 Mar 2023 17:46:21 +0200 Subject: [PATCH 37/49] broaden bbox type --- src/makielayout/mousestatemachine.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/makielayout/mousestatemachine.jl b/src/makielayout/mousestatemachine.jl index 732bfb4aab7..741bd07b739 100644 --- a/src/makielayout/mousestatemachine.jl +++ b/src/makielayout/mousestatemachine.jl @@ -116,7 +116,7 @@ function addmouseevents!(scene, elements...; priority = 1) is_mouse_over_relevant_area() = isempty(elements) ? Makie.is_mouseinside(scene) : mouseover(scene, elements...) _addmouseevents!(scene, is_mouse_over_relevant_area, priority) end -function addmouseevents!(scene, bbox::Observables.AbstractObservable{<: Rect2{Float64}}; priority = 1) +function addmouseevents!(scene, bbox::Observables.AbstractObservable{<: Rect2}; priority = 1) is_mouse_over_relevant_area() = Makie.mouseposition_px(scene) in bbox[] _addmouseevents!(scene, is_mouse_over_relevant_area, priority) end From 26c4dbca848a424b0ca49bda8d23771e3e92324c Mon Sep 17 00:00:00 2001 From: ffreyer Date: Wed, 29 Mar 2023 23:43:49 +0200 Subject: [PATCH 38/49] less Float64 conversions --- src/conversions.jl | 100 +++++++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 45 deletions(-) diff --git a/src/conversions.jl b/src/conversions.jl index 4fc568e9e2d..74e691cf226 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -85,19 +85,19 @@ end Wrap a single point or equivalent object in a single-element array. """ function convert_arguments(::PointBased, x::Real, y::Real) - ([Point2e(x, y)],) + ([Point2(x, y)],) end function convert_arguments(::PointBased, x::Real, y::Real, z::Real) - ([Point3e(x, y, z)],) + ([Point3(x, y, z)],) end -function convert_arguments(::PointBased, position::VecTypes{N, <: Number}) where N - ([convert(Point{N, Float64}, position)],) +function convert_arguments(::PointBased, position::VecTypes{N, T}) where {T <: Number, N} + ([convert(Point{N, T}, position)],) end -function convert_arguments(::PointBased, positions::AbstractVector{<: VecTypes{N, <: Number}}) where N - (elconvert(Point{N, Float64}, positions),) +function convert_arguments(::PointBased, positions::AbstractVector{<: VecTypes{N, T}}) where {T <: Number, N} + (elconvert(Point{N, T}, positions),) end function convert_arguments(::PointBased, positions::SubArray{<: VecTypes, 1}) @@ -110,7 +110,7 @@ Enables to use scatter like a surface plot with x::Vector, y::Vector, z::Matrix spanning z over the grid spanned by x y """ function convert_arguments(::PointBased, x::AbstractVector, y::AbstractVector, z::AbstractMatrix) - (vec(Point3e.(x, y', z)),) + (vec(Point3.(x, y', z)),) end """ convert_arguments(P, x, y, z)::(Vector) @@ -119,7 +119,7 @@ Takes vectors `x`, `y`, and `z` and turns it into a vector of 3D points of the v from `x`, `y`, and `z`. `P` is the plot Type (it is optional). """ -convert_arguments(::PointBased, x::RealVector, y::RealVector, z::RealVector) = (Point3e.(x, y, z),) +convert_arguments(::PointBased, x::RealVector, y::RealVector, z::RealVector) = (Point3.(x, y, z),) """ convert_arguments(P, x)::(Vector) @@ -127,14 +127,14 @@ convert_arguments(::PointBased, x::RealVector, y::RealVector, z::RealVector) = ( Takes an input GeometryPrimitive `x` and decomposes it to points. `P` is the plot Type (it is optional). """ -convert_arguments(p::PointBased, x::GeometryPrimitive) = convert_arguments(p, decompose(Point3e, x)) +convert_arguments(p::PointBased, x::GeometryPrimitive) = convert_arguments(p, decompose(Point3f, x)) function convert_arguments(::PointBased, pos::AbstractMatrix{<: Number}) (to_vertices(pos),) end function convert_arguments(P::PointBased, x::AbstractVector{<:Real}, y::AbstractVector{<:Real}) - (Point2e.(x, y),) + (Point2.(x, y),) end convert_arguments(P::PointBased, x::AbstractVector{<:Real}, y::AbstractVector{<:Real}, z::AbstractVector{<:Real}) = (Point3e.(x, y, z),) @@ -170,12 +170,12 @@ Takes an input `Rect` `x` and decomposes it to points. `P` is the plot Type (it is optional). """ -function convert_arguments(P::PointBased, x::Rect2) +function convert_arguments(P::PointBased, x::Rect2{T}) where T # TODO fix the order of decompose - return convert_arguments(P, decompose(Point2e, x)[[1, 2, 4, 3]]) + return convert_arguments(P, decompose(Point2{T}, x)[[1, 2, 4, 3]]) end -function convert_arguments(P::PointBased, mesh::AbstractMesh) +function convert_arguments(P::PointBased, mesh::AbstractMesh) # TODO return convert_arguments(P, decompose(Point3e, mesh)) end @@ -184,19 +184,19 @@ function convert_arguments(PB::PointBased, linesegments::FaceView{<:Line, P}) wh return convert_arguments(PB, collect(reinterpret(P, linesegments))) end -function convert_arguments(P::PointBased, rect::Rect3) - return (decompose(Point3e, rect),) +function convert_arguments(P::PointBased, rect::Rect3{T}) where T + return (decompose(Point3{T}, rect),) end -function convert_arguments(P::Type{<: LineSegments}, rect::Rect3) +function convert_arguments(P::Type{<: LineSegments}, rect::Rect3{T}) where T f = decompose(LineFace{Int}, rect) - p = connect(decompose(Point3e, rect), f) + p = connect(decompose(Point3{T}, rect), f) return convert_arguments(P, p) end -function convert_arguments(::Type{<: Lines}, rect::Rect3) - points = unique(decompose(Point3e, rect)) - push!(points, Point3e(NaN)) # use to seperate linesegments +function convert_arguments(::Type{<: Lines}, rect::Rect3{T}) where T + points = unique(decompose(Point3{T}, rect)) + push!(points, Point3{T}(NaN)) # use to seperate linesegments return (points[[1, 2, 3, 4, 1, 5, 6, 2, 9, 6, 8, 3, 9, 5, 7, 4, 9, 7, 8]],) end """ @@ -216,8 +216,9 @@ Takes an input `Array{LineString}` or a `MultiLineString` and decomposes it to p """ function convert_arguments(PB::PointBased, linestring::Union{Array{<:LineString}, MultiLineString}) arr = copy(convert_arguments(PB, linestring[1])[1]) + T = eltype(arr) for ls in 2:length(linestring) - push!(arr, Point2e(NaN)) + push!(arr, T(NaN)) append!(arr, convert_arguments(PB, linestring[ls])[1]) end return (arr,) @@ -231,14 +232,15 @@ Takes an input `Polygon` and decomposes it to points. """ function convert_arguments(PB::PointBased, pol::Polygon) arr = copy(convert_arguments(PB, pol.exterior)[1]) + T = eltype(arr) push!(arr, arr[1]) # close exterior if !isempty(pol.interiors) - push!(arr, Point2e(NaN)) + push!(arr, T(NaN)) for interior in pol.interiors inter = convert_arguments(PB, interior)[1] append!(arr, inter) # close interior + separate! - push!(arr, inter[1], Point2e(NaN)) + push!(arr, inter[1], T(NaN)) end end return (arr,) @@ -252,8 +254,9 @@ Takes an input `Array{Polygon}` or a `MultiPolygon` and decomposes it to points. """ function convert_arguments(PB::PointBased, mp::Union{Array{<:Polygon}, MultiPolygon}) arr = copy(convert_arguments(PB, mp[1])[1]) + T = eltype(arr) for p in 2:length(mp) - push!(arr, Point2e(NaN)) + push!(arr, T(NaN)) append!(arr, convert_arguments(PB, mp[p])[1]) end return (arr,) @@ -364,8 +367,8 @@ and stores the `ClosedInterval` to `n` and `m`, plus the original matrix in a Tu `P` is the plot Type (it is optional). """ function convert_arguments(sl::SurfaceLike, data::AbstractMatrix) - n, m = Float64.(size(data)) - convert_arguments(sl, 0.0 .. n, 0.0 .. m, el32convert(data)) + n, m = size(data) + convert_arguments(sl, 0 .. n, 0 .. m, el32convert(data)) end function convert_arguments(ds::DiscreteSurface, data::AbstractMatrix) @@ -429,7 +432,7 @@ and stores the `ClosedInterval` to `n`, `m` and `k`, plus the original array in `P` is the plot Type (it is optional). """ function convert_arguments(::VolumeLike, data::AbstractArray{T, 3}) where T - n, m, k = Float32.(size(data)) + n, m, k = T.(size(data)) return (0f0 .. n, 0f0 .. m, 0f0 .. k, el32convert(data)) end @@ -471,9 +474,9 @@ end # <:Lines # ################################################################################ -function convert_arguments(::Type{<: Lines}, x::Rect2) +function convert_arguments(::Type{<: Lines}, x::Rect2{T}) where T # TODO fix the order of decompose - points = decompose(Point2e, x) + points = decompose(Point2{T}, x) return (points[[1, 2, 4, 3, 1]],) end @@ -485,13 +488,14 @@ end Accepts a Vector of Pair of Points (e.g. `[Point(0, 0) => Point(1, 1), ...]`) to encode e.g. linesegments or directions. """ -function convert_arguments(::Type{<: LineSegments}, positions::AbstractVector{E}) where E <: Union{Pair{A, A}, Tuple{A, A}} where A <: VecTypes{N, T} where {N, T} - (elconvert(Point{N, Float64}, reinterpret(Point{N, T}, positions)),) +function convert_arguments(::Type{<: LineSegments}, positions::AbstractVector{E}) where + E <: Union{Pair{A, A}, Tuple{A, A}} where A <: VecTypes{N, T} where {N, T} + (reinterpret(Point{N, T}, positions),) end -function convert_arguments(::Type{<: LineSegments}, x::Rect2) +function convert_arguments(::Type{<: LineSegments}, x::Rect2{T}) where T # TODO fix the order of decompose - points = decompose(Point2e, x) + points = decompose(Point2{T}, x) return (points[[1, 2, 2, 4, 4, 3, 3, 1]],) end @@ -521,7 +525,7 @@ function convert_arguments( T::Type{<:Mesh}, x::RealVector, y::RealVector, z::RealVector ) - convert_arguments(T, Point3e.(x, y, z)) + convert_arguments(T, Point3.(x, y, z)) end """ convert_arguments(Mesh, xyz::AbstractVector)::GLNormalMesh @@ -547,8 +551,14 @@ function convert_arguments(::Type{<:Mesh}, mesh::GeometryBasics.Mesh{N}) where { mesh = GeometryBasics.pointmeta(mesh, decompose(Vec3f, n)) end end - # TODO Float64? - return (GeometryBasics.mesh(mesh, pointtype=Point{N, Float64}, facetype=GLTriangleFace),) + # TODO only convert face type? + # If already correct eltypes for GL, we can pass the mesh through as is + if eltype(metafree(coordinates(mesh))) == Point{N, Float32} && eltype(faces(mesh)) == GLTriangleFace + return (mesh,) + else + # Else, we need to convert it! + return (GeometryBasics.mesh(mesh, pointtype=Point{N, Float32}, facetype=GLTriangleFace),) + end end function convert_arguments( @@ -563,7 +573,7 @@ function convert_arguments( xyz::Union{AbstractPolygon{2, T}, AbstractVector{<: AbstractPoint{2, T}}} ) where T return (GeometryBasics.mesh( - xyz; pointtype = Point{2, Float64}, facetype = GeometryBasics.GLTriangleFace + xyz; pointtype = Point{2, T}, facetype = GeometryBasics.GLTriangleFace ), ) end @@ -571,7 +581,7 @@ function convert_arguments(MT::Type{<:Mesh}, geom::GeometryPrimitive{N, T}) wher # we convert to UV mesh as default, because otherwise the uv informations get lost # - we can still drop them, but we can't add them later on return (GeometryBasics.mesh( - geom; pointtype = Point{N, Float64}, uv = Vec2f, normaltype = Vec3f, + geom; pointtype = Point{N, T}, uv = Vec2f, normaltype = Vec3f, facetype = GeometryBasics.GLTriangleFace ), ) end @@ -587,7 +597,7 @@ function convert_arguments( x::RealVector, y::RealVector, z::RealVector, indices::AbstractVector ) - return convert_arguments(T, Point3e.(x, y, z), indices) + return convert_arguments(T, Point3.(x, y, z), indices) end """ @@ -743,13 +753,13 @@ Converts a representation of vertices `v` to its canonical representation as a - if `v` has 2 or 3 rows, it will treat each column as a vertex, - otherwise if `v` has 2 or 3 columns, it will treat each row as a vertex. """ -# function to_vertices(verts::AbstractVector{<: VecTypes{3, T}}) where T -# return reinterpret(Point3{Float64}, verts) -# end +function to_vertices(verts::AbstractVector{<: VecTypes{3, T}}) where T + return reinterpret(Point3{T}, verts) +end -# function to_vertices(verts::AbstractVector{<: VecTypes{N, T}}) where {N, T} -# to_vertices(to_ndim.(Point{3, Float64}, verts, 0.0)) -# end +function to_vertices(verts::AbstractVector{<: VecTypes{N, T}}) where {N, T} + to_vertices(to_ndim.(Point{3, T}, verts, 0.0)) +end function to_vertices(verts::AbstractVector{<: VecTypes}) to_ndim.(Point{3, Float64}, verts, 0.0) From c021cfd806d3a00b497311d8bb55ce3a32cb1a84 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 1 May 2023 16:56:30 +0200 Subject: [PATCH 39/49] allow Float32 and Float64 --- src/conversions.jl | 255 +++++++++++++++++++++++++++----------------- test/conversions.jl | 14 +-- 2 files changed, 167 insertions(+), 102 deletions(-) diff --git a/src/conversions.jl b/src/conversions.jl index 74e691cf226..2cd1f5836bb 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -1,10 +1,74 @@ +# For tracing function call order, probably delete later? + +macro trace(expr) + if expr.head in (Symbol("="), :function) + name = _to_typed_name(expr.args[1]) + file = " in " * string(__source__.file) * ':' + line = string(__source__.line) * '\n' + code = quote + begin + printstyled($name, bold = true) + printstyled($file, color = :light_black) + printstyled($line, bold = true) + $(expr.args[2]) + end + end + out = Expr( + expr.head, # function or = + esc(expr.args[1]), # function name w/ args + esc(code) + ) + return out + end + return expr +end + +function _to_typed_name(e::Expr) + if e.head == :where + _to_typed_name(e.args[1]) + elseif e.head == :call + if length(e.args) > 1 && e.args[2] isa Expr && e.args[2].head == :parameters + args = join(_to_type.(e.args[3:end]), ", ") + kwargs = join(_to_type.(e.args[2].args), ", ") + return string(e.args[1]) * "(" * args * "; " * kwargs * ")" + else + args = join(_to_type.(e.args[2:end]), ", ") + return string(e.args[1]) * "(" * args * ")" + end + else + dump(e) + return "ERROR" + end +end + +_to_type(s::Symbol) = "::Any" +function _to_type(e::Expr) + if e.head == Symbol("::") + return "::" * string(e.args[end]) + elseif e.head == Symbol("...") + return _to_type(e.args[1]) * "..." + elseif e.head == :parameters # keyword args + return _to_type(e.args[1]) + elseif e.head == :kw # default value + return _to_type(e.args[1]) + else + dump(e) + error("Failed to parse expression.") + return "" + end +end + + ################################################################################ # Type Conversions # ################################################################################ + const RangeLike = Union{AbstractRange, AbstractVector, ClosedInterval} +const NativeFloat = Union{Float64, Float32} +const NativePoint = Point{N, T} where {N, T <: NativeFloat} # if no plot type based conversion is defined, we try using a trait -function convert_arguments(T::PlotFunc, args...; kw...) +@trace function convert_arguments(T::PlotFunc, args...; kw...) ct = conversion_trait(T) try convert_arguments(ct, args...; kw...) @@ -39,7 +103,7 @@ end # in case no trait matches we try to convert each individual argument # and reconvert the whole tuple in order to handle missings centrally, e.g. -function convert_arguments_individually(T::PlotFunc, args...) +@trace function convert_arguments_individually(T::PlotFunc, args...) # convert each single argument until it doesn't change type anymore single_converted = recursively_convert_argument.(args) # if the type of args hasn't changed this function call didn't help and we error @@ -65,16 +129,24 @@ end ################################################################################ # if no specific conversion is defined, we don't convert -convert_single_argument(x) = x +@trace convert_single_argument(x) = x # replace missings with NaNs -function convert_single_argument(a::AbstractArray{<:Union{Missing, <:Real}}) - [ismissing(x) ? NaN : convert(Float64, x) for x in a] +@trace function convert_single_argument(a::AbstractArray{<:Union{Missing, T}}) where {T <: NativeFloat} + nan = T(NaN) + [ismissing(x) ? nan : x for x in a] +end +@trace function convert_single_argument(a::AbstractArray{<:Union{Missing, <:Real}}) + [ismissing(x) ? NaN32 : convert(Float32, x) for x in a] end # same for points -function convert_single_argument(a::AbstractArray{<:Union{Missing, <:Point{N}}}) where N - [ismissing(x) ? Point{N, Float64}(NaN) : Point{N, Float64}(x) for x in a] +@trace function convert_single_argument(a::AbstractArray{<:Union{Missing, T}}) where {T <: NativePoint} + nan = T(NaN) + [ismissing(x) ? nan : T(x) for x in a] +end +@trace function convert_single_argument(a::AbstractArray{<:Union{Missing, <:Point{N}}}) where N + [ismissing(x) ? Point{N, Float32}(NaN32) : Point{N, Float32}(x) for x in a] end ################################################################################ @@ -84,23 +156,23 @@ end """ Wrap a single point or equivalent object in a single-element array. """ -function convert_arguments(::PointBased, x::Real, y::Real) - ([Point2(x, y)],) +@trace function convert_arguments(::PointBased, x::Real, y::Real) + ([native_type(x, y)],) end -function convert_arguments(::PointBased, x::Real, y::Real, z::Real) - ([Point3(x, y, z)],) +@trace function convert_arguments(::PointBased, x::Real, y::Real, z::Real) + ([native_type(x, y, z)],) end -function convert_arguments(::PointBased, position::VecTypes{N, T}) where {T <: Number, N} - ([convert(Point{N, T}, position)],) +@trace function convert_arguments(::PointBased, position::VecTypes{N, T}) where {T <: Number, N} + ([native_type(position)],) end -function convert_arguments(::PointBased, positions::AbstractVector{<: VecTypes{N, T}}) where {T <: Number, N} - (elconvert(Point{N, T}, positions),) +@trace function convert_arguments(::PointBased, positions::AbstractVector{<: VecTypes{N}}) where N + (native_type.(positions),) end -function convert_arguments(::PointBased, positions::SubArray{<: VecTypes, 1}) +@trace function convert_arguments(::PointBased, positions::SubArray{<: VecTypes, 1}) # TODO figure out a good subarray solution (positions,) end @@ -109,7 +181,7 @@ end Enables to use scatter like a surface plot with x::Vector, y::Vector, z::Matrix spanning z over the grid spanned by x y """ -function convert_arguments(::PointBased, x::AbstractVector, y::AbstractVector, z::AbstractMatrix) +@trace function convert_arguments(::PointBased, x::AbstractVector, y::AbstractVector, z::AbstractMatrix) (vec(Point3.(x, y', z)),) end """ @@ -119,7 +191,7 @@ Takes vectors `x`, `y`, and `z` and turns it into a vector of 3D points of the v from `x`, `y`, and `z`. `P` is the plot Type (it is optional). """ -convert_arguments(::PointBased, x::RealVector, y::RealVector, z::RealVector) = (Point3.(x, y, z),) +@trace convert_arguments(::PointBased, x::RealVector, y::RealVector, z::RealVector) = (Point3.(x, y, z),) """ convert_arguments(P, x)::(Vector) @@ -127,18 +199,16 @@ convert_arguments(::PointBased, x::RealVector, y::RealVector, z::RealVector) = ( Takes an input GeometryPrimitive `x` and decomposes it to points. `P` is the plot Type (it is optional). """ -convert_arguments(p::PointBased, x::GeometryPrimitive) = convert_arguments(p, decompose(Point3f, x)) +@trace convert_arguments(p::PointBased, x::GeometryPrimitive) = convert_arguments(p, decompose(Point3f, x)) -function convert_arguments(::PointBased, pos::AbstractMatrix{<: Number}) - (to_vertices(pos),) +@trace function convert_arguments(::PointBased, pos::AbstractMatrix{<: Number}) + (to_vertices(pos),) # NOTE: This currently ends up as Float32 end -function convert_arguments(P::PointBased, x::AbstractVector{<:Real}, y::AbstractVector{<:Real}) - (Point2.(x, y),) +@trace function convert_arguments(P::PointBased, x::AbstractVector{<:Real}, y::AbstractVector{<:Real}) + (native_type.(x, y),) end -convert_arguments(P::PointBased, x::AbstractVector{<:Real}, y::AbstractVector{<:Real}, z::AbstractVector{<:Real}) = (Point3e.(x, y, z),) - """ convert_arguments(P, y)::Vector Takes vector `y` and generates a range from 1 to the length of `y`, for plotting on @@ -146,7 +216,7 @@ an arbitrary `x` axis. `P` is the plot Type (it is optional). """ -convert_arguments(P::PointBased, y::RealVector) = convert_arguments(P, keys(y), y) +@trace convert_arguments(P::PointBased, y::RealVector) = convert_arguments(P, keys(y), y) """ convert_arguments(P, x, y)::(Vector) @@ -157,10 +227,10 @@ from `x` and `y`. `P` is the plot Type (it is optional). """ #convert_arguments(::PointBased, x::RealVector, y::RealVector) = (Point2f.(x, y),) -function convert_arguments(P::PointBased, x::ClosedInterval, y::RealVector) +@trace function convert_arguments(P::PointBased, x::ClosedInterval, y::RealVector) return convert_arguments(P, LinRange(extrema(x)..., length(y)), y) end -convert_arguments(P::PointBased, x::RealVector, y::ClosedInterval) = convert_arguments(P, x, LinRange(extrema(y)..., length(x))) +@trace convert_arguments(P::PointBased, x::RealVector, y::ClosedInterval) = convert_arguments(P, x, LinRange(extrema(y)..., length(x))) """ @@ -170,31 +240,31 @@ Takes an input `Rect` `x` and decomposes it to points. `P` is the plot Type (it is optional). """ -function convert_arguments(P::PointBased, x::Rect2{T}) where T +@trace function convert_arguments(P::PointBased, x::Rect2{T}) where T # TODO fix the order of decompose return convert_arguments(P, decompose(Point2{T}, x)[[1, 2, 4, 3]]) end -function convert_arguments(P::PointBased, mesh::AbstractMesh) # TODO - return convert_arguments(P, decompose(Point3e, mesh)) +@trace function convert_arguments(P::PointBased, mesh::AbstractMesh) # TODO + return convert_arguments(P, decompose(Point3f, mesh)) end -function convert_arguments(PB::PointBased, linesegments::FaceView{<:Line, P}) where {P<:AbstractPoint} +@trace function convert_arguments(PB::PointBased, linesegments::FaceView{<:Line, P}) where {P<:AbstractPoint} # TODO FaceView should be natively supported by backends! return convert_arguments(PB, collect(reinterpret(P, linesegments))) end -function convert_arguments(P::PointBased, rect::Rect3{T}) where T +@trace function convert_arguments(P::PointBased, rect::Rect3{T}) where T return (decompose(Point3{T}, rect),) end -function convert_arguments(P::Type{<: LineSegments}, rect::Rect3{T}) where T +@trace function convert_arguments(P::Type{<: LineSegments}, rect::Rect3{T}) where T f = decompose(LineFace{Int}, rect) p = connect(decompose(Point3{T}, rect), f) return convert_arguments(P, p) end -function convert_arguments(::Type{<: Lines}, rect::Rect3{T}) where T +@trace function convert_arguments(::Type{<: Lines}, rect::Rect3{T}) where T points = unique(decompose(Point3{T}, rect)) push!(points, Point3{T}(NaN)) # use to seperate linesegments return (points[[1, 2, 3, 4, 1, 5, 6, 2, 9, 6, 8, 3, 9, 5, 7, 4, 9, 7, 8]],) @@ -205,7 +275,7 @@ end Takes an input `LineString` and decomposes it to points. """ -function convert_arguments(PB::PointBased, linestring::LineString) +@trace function convert_arguments(PB::PointBased, linestring::LineString) return convert_arguments(PB, decompose(Point, linestring)) end @@ -214,7 +284,7 @@ end Takes an input `Array{LineString}` or a `MultiLineString` and decomposes it to points. """ -function convert_arguments(PB::PointBased, linestring::Union{Array{<:LineString}, MultiLineString}) +@trace function convert_arguments(PB::PointBased, linestring::Union{Array{<:LineString}, MultiLineString}) arr = copy(convert_arguments(PB, linestring[1])[1]) T = eltype(arr) for ls in 2:length(linestring) @@ -230,7 +300,7 @@ end Takes an input `Polygon` and decomposes it to points. """ -function convert_arguments(PB::PointBased, pol::Polygon) +@trace function convert_arguments(PB::PointBased, pol::Polygon) arr = copy(convert_arguments(PB, pol.exterior)[1]) T = eltype(arr) push!(arr, arr[1]) # close exterior @@ -252,7 +322,7 @@ end Takes an input `Array{Polygon}` or a `MultiPolygon` and decomposes it to points. """ -function convert_arguments(PB::PointBased, mp::Union{Array{<:Polygon}, MultiPolygon}) +@trace function convert_arguments(PB::PointBased, mp::Union{Array{<:Polygon}, MultiPolygon}) arr = copy(convert_arguments(PB, mp[1])[1]) T = eltype(arr) for p in 2:length(mp) @@ -262,7 +332,7 @@ function convert_arguments(PB::PointBased, mp::Union{Array{<:Polygon}, MultiPoly return (arr,) end -function convert_arguments(::PointBased, b::BezierPath) +@trace function convert_arguments(::PointBased, b::BezierPath) b2 = replace_nonfreetype_commands(b) points = Point2f[] last_point = Point2f(NaN) @@ -336,16 +406,12 @@ whether they represent edges or centers of the heatmap bins. If they are centers, convert to edges. Convert eltypes to `Float32` and return outputs as a `Tuple`. """ -function convert_arguments(SL::SurfaceLike, x::AbstractVecOrMat{<: Number}, y::AbstractVecOrMat{<: Number}, z::AbstractMatrix{<: Union{Number, Colorant}}) +@trace function convert_arguments(SL::SurfaceLike, x::AbstractVecOrMat{<: Number}, y::AbstractVecOrMat{<: Number}, z::AbstractMatrix{<: Union{Number, Colorant}}) _x, _y, _z = adjust_axes(SL, x, y, z) - return elconvert(Float64, _x), elconvert(Float64, _y), el32convert(_z) + return convert_single_argument(_x), convert_single_argument(_y), el32convert(_z) # TODO convert_single_argument for z too? end -# function convert_arguments(SL::SurfaceLike, x::AbstractVecOrMat{<: Number}, y::AbstractVecOrMat{<: Number}, z::AbstractMatrix{<:Number}) -# _x, _y, _z = adjust_axes(SL, x, y, z) -# return elconvert(Float64, _x), elconvert(Float64, _y), el32convert(_z) -# end -convert_arguments(sl::SurfaceLike, x::AbstractMatrix, y::AbstractMatrix) = convert_arguments(sl, x, y, zeros(size(y))) +@trace convert_arguments(sl::SurfaceLike, x::AbstractMatrix, y::AbstractMatrix) = convert_arguments(sl, x, y, zeros(size(y))) """ convert_arguments(P, x, y, z)::Tuple{ClosedInterval, ClosedInterval, Matrix} @@ -354,7 +420,7 @@ Takes 2 ClosedIntervals's `x`, `y`, and an AbstractMatrix `z`, and converts the linspaces with size(z, 1/2) `P` is the plot Type (it is optional). """ -function convert_arguments(P::SurfaceLike, x::ClosedInterval, y::ClosedInterval, z::AbstractMatrix) +@trace function convert_arguments(P::SurfaceLike, x::ClosedInterval, y::ClosedInterval, z::AbstractMatrix) convert_arguments(P, to_linspace(x, size(z, 1)), to_linspace(y, size(z, 2)), z) end @@ -366,17 +432,17 @@ and stores the `ClosedInterval` to `n` and `m`, plus the original matrix in a Tu `P` is the plot Type (it is optional). """ -function convert_arguments(sl::SurfaceLike, data::AbstractMatrix) +@trace function convert_arguments(sl::SurfaceLike, data::AbstractMatrix) n, m = size(data) convert_arguments(sl, 0 .. n, 0 .. m, el32convert(data)) end -function convert_arguments(ds::DiscreteSurface, data::AbstractMatrix) - n, m = Float64.(size(data)) - convert_arguments(ds, edges(1.0:n), edges(1.0:m), el32convert(data)) +@trace function convert_arguments(ds::DiscreteSurface, data::AbstractMatrix) + n, m = Float32.(size(data)) + convert_arguments(ds, edges(1:n), edges(1:m), el32convert(data)) end -function convert_arguments(SL::SurfaceLike, x::AbstractVector{<:Number}, y::AbstractVector{<:Number}, z::AbstractVector{<:Number}) +@trace function convert_arguments(SL::SurfaceLike, x::AbstractVector{<:Number}, y::AbstractVector{<:Number}, z::AbstractVector{<:Number}) if !(length(x) == length(y) == length(z)) error("x, y and z need to have the same length. Lengths are $(length.((x, y, z)))") end @@ -409,7 +475,7 @@ Takes vectors `x` and `y` and the function `f`, and applies `f` on the grid that This is equivalent to `f.(x, y')`. `P` is the plot Type (it is optional). """ -function convert_arguments(sl::SurfaceLike, x::AbstractVector{T1}, y::AbstractVector{T2}, f::Function) where {T1, T2} +@trace function convert_arguments(sl::SurfaceLike, x::AbstractVector{T1}, y::AbstractVector{T2}, f::Function) where {T1, T2} if !applicable(f, x[1], y[1]) error("You need to pass a function with signature f(x::$T1, y::$T2). Found: $f") end @@ -431,12 +497,12 @@ and stores the `ClosedInterval` to `n`, `m` and `k`, plus the original array in `P` is the plot Type (it is optional). """ -function convert_arguments(::VolumeLike, data::AbstractArray{T, 3}) where T +@trace function convert_arguments(::VolumeLike, data::AbstractArray{T, 3}) where T n, m, k = T.(size(data)) return (0f0 .. n, 0f0 .. m, 0f0 .. k, el32convert(data)) end -function convert_arguments(::VolumeLike, x::RangeLike, y::RangeLike, z::RangeLike, data::AbstractArray{T, 3}) where T +@trace function convert_arguments(::VolumeLike, x::RangeLike, y::RangeLike, z::RangeLike, data::AbstractArray{T, 3}) where T return (x, y, z, el32convert(data)) end """ @@ -446,7 +512,7 @@ Takes 3 `AbstractVector` `x`, `y`, and `z` and the `AbstractMatrix` `i`, and put `P` is the plot Type (it is optional). """ -function convert_arguments(::VolumeLike, x::AbstractVector, y::AbstractVector, z::AbstractVector, i::AbstractArray{T, 3}) where T +@trace function convert_arguments(::VolumeLike, x::AbstractVector, y::AbstractVector, z::AbstractVector, i::AbstractArray{T, 3}) where T (x, y, z, el32convert(i)) end @@ -459,7 +525,7 @@ spanned by `x`, `y` and `z`, and puts `x`, `y`, `z` and `f(x,y,z)` in a Tuple. `P` is the plot Type (it is optional). """ -function convert_arguments(::VolumeLike, x::AbstractVector, y::AbstractVector, z::AbstractVector, f::Function) +@trace function convert_arguments(::VolumeLike, x::AbstractVector, y::AbstractVector, z::AbstractVector, f::Function) if !applicable(f, x[1], y[1], z[1]) error("You need to pass a function with signature f(x, y, z). Found: $f") end @@ -474,7 +540,7 @@ end # <:Lines # ################################################################################ -function convert_arguments(::Type{<: Lines}, x::Rect2{T}) where T +@trace function convert_arguments(::Type{<: Lines}, x::Rect2{T}) where T # TODO fix the order of decompose points = decompose(Point2{T}, x) return (points[[1, 2, 4, 3, 1]],) @@ -488,12 +554,12 @@ end Accepts a Vector of Pair of Points (e.g. `[Point(0, 0) => Point(1, 1), ...]`) to encode e.g. linesegments or directions. """ -function convert_arguments(::Type{<: LineSegments}, positions::AbstractVector{E}) where +@trace function convert_arguments(::Type{<: LineSegments}, positions::AbstractVector{E}) where E <: Union{Pair{A, A}, Tuple{A, A}} where A <: VecTypes{N, T} where {N, T} (reinterpret(Point{N, T}, positions),) end -function convert_arguments(::Type{<: LineSegments}, x::Rect2{T}) where T +@trace function convert_arguments(::Type{<: LineSegments}, x::Rect2{T}) where T # TODO fix the order of decompose points = decompose(Point2{T}, x) return (points[[1, 2, 2, 4, 4, 3, 3, 1]],) @@ -521,7 +587,7 @@ Takes an input `AbstractString` `x` and converts it to a string. Takes real vectors x, y, z and constructs a mesh out of those, under the assumption that every 3 points form a triangle. """ -function convert_arguments( +@trace function convert_arguments( T::Type{<:Mesh}, x::RealVector, y::RealVector, z::RealVector ) @@ -533,7 +599,7 @@ end Takes an input mesh and a vector `xyz` representing the vertices of the mesh, and creates indices under the assumption, that each triplet in `xyz` forms a triangle. """ -function convert_arguments( +@trace function convert_arguments( MT::Type{<:Mesh}, xyz::AbstractVector ) @@ -542,7 +608,7 @@ function convert_arguments( return convert_arguments(MT, xyz, collect(faces)) end -function convert_arguments(::Type{<:Mesh}, mesh::GeometryBasics.Mesh{N}) where {N} +@trace function convert_arguments(::Type{<:Mesh}, mesh::GeometryBasics.Mesh{N}) where {N} # Make sure we have normals! if !hasproperty(mesh, :normals) n = normals(mesh) @@ -561,29 +627,24 @@ function convert_arguments(::Type{<:Mesh}, mesh::GeometryBasics.Mesh{N}) where { end end -function convert_arguments( +@trace function convert_arguments( MT::Type{<:Mesh}, meshes::AbstractVector{<: Union{AbstractMesh, AbstractPolygon}} ) return (meshes,) end -function convert_arguments( +@trace function convert_arguments( MT::Type{<:Mesh}, xyz::Union{AbstractPolygon{2, T}, AbstractVector{<: AbstractPoint{2, T}}} ) where T - return (GeometryBasics.mesh( - xyz; pointtype = Point{2, T}, facetype = GeometryBasics.GLTriangleFace - ), ) + return convert_arguments(MT, triangle_mesh(xyz)) end -function convert_arguments(MT::Type{<:Mesh}, geom::GeometryPrimitive{N, T}) where {N, T} +@trace function convert_arguments(MT::Type{<:Mesh}, geom::GeometryPrimitive{N, T}) where {N, T} # we convert to UV mesh as default, because otherwise the uv informations get lost # - we can still drop them, but we can't add them later on - return (GeometryBasics.mesh( - geom; pointtype = Point{N, T}, uv = Vec2f, normaltype = Vec3f, - facetype = GeometryBasics.GLTriangleFace - ), ) + return (GeometryBasics.uv_normal_mesh(geom),) end """ @@ -592,7 +653,7 @@ end Takes real vectors x, y, z and constructs a triangle mesh out of those, using the faces in `indices`, which can be integers (every 3 -> one triangle), or GeometryBasics.NgonFace{N, <: Integer}. """ -function convert_arguments( +@trace function convert_arguments( T::Type{<: Mesh}, x::RealVector, y::RealVector, z::RealVector, indices::AbstractVector @@ -607,11 +668,11 @@ Takes `vertices` and `indices`, and creates a triangle mesh out of those. See [`to_vertices`](@ref) and [`to_triangles`](@ref) for more information about accepted types. """ -function convert_arguments(MT::Type{<:Mesh}, vertices::AbstractArray, indices::AbstractArray) +@trace function convert_arguments(MT::Type{<:Mesh}, vertices::AbstractArray, indices::AbstractArray) return convert_arguments(MT, to_vertices(vertices), to_triangles(indices)) end -function convert_arguments( +@trace function convert_arguments( ::Type{<:Mesh}, pos::AbstractVector{VT}, faces::AbstractVector{GLTriangleFace} ) where {N, T, VT <: VecTypes{N, T}} _points = to_ndim.(Point{3, T}, pos, T(0)) @@ -624,12 +685,12 @@ end # Function Conversions # ################################################################################ -function convert_arguments(P::PlotFunc, r::AbstractVector, f::Function) +@trace function convert_arguments(P::PlotFunc, r::AbstractVector, f::Function) ptype = plottype(P, Lines) to_plotspec(ptype, convert_arguments(ptype, r, f.(r))) end -function convert_arguments(P::PlotFunc, i::AbstractInterval, f::Function) +@trace function convert_arguments(P::PlotFunc, i::AbstractInterval, f::Function) x, y = PlotUtils.adapted_grid(f, endpoints(i)) ptype = plottype(P, Lines) to_plotspec(ptype, convert_arguments(ptype, x, y)) @@ -658,7 +719,7 @@ function tryrange(F, vec) end # OffsetArrays conversions -function convert_arguments(sl::SurfaceLike, wm::OffsetArray) +@trace function convert_arguments(sl::SurfaceLike, wm::OffsetArray) x1, y1 = wm.offsets .+ 1 nx, ny = size(wm) x = range(x1, length = nx) @@ -707,6 +768,14 @@ function el32convert(mesh::GeometryBasics.Mesh, positions = mesh.position) end +@trace native_type(x::NativeFloat) = x +# @trace native_type(x::VecTypes{N, T}) where {N, T <: NativeFloat} = reinterpret(Point{N, T}, x) # crashes precompile? +@trace native_type(x::VecTypes{N, T}) where {N, T <: NativeFloat} = Point{N, T}(x) +@trace native_type(x::Real) = Float32(x) +@trace native_type(x::VecTypes{N}) where N = Point{N, Float32}(x) +@trace native_type(x::Real, y::Real) = Point2(native_type(x), native_type(y)) +@trace native_type(x::Real, y::Real, z::Real) = Point3(native_type(x), native_type(y), native_type(z)) + """ to_triangles(indices) @@ -742,7 +811,7 @@ end to_vertices(v) Converts a representation of vertices `v` to its canonical representation as a -`Vector{Point3{T}}`. `v` can be: +`Vector{Point3f}`. `v` can be: - An `AbstractVector` of 3-element `Tuple`s or `StaticVector`s, @@ -754,18 +823,14 @@ Converts a representation of vertices `v` to its canonical representation as a - otherwise if `v` has 2 or 3 columns, it will treat each row as a vertex. """ function to_vertices(verts::AbstractVector{<: VecTypes{3, T}}) where T - return reinterpret(Point3{T}, verts) -end - -function to_vertices(verts::AbstractVector{<: VecTypes{N, T}}) where {N, T} - to_vertices(to_ndim.(Point{3, T}, verts, 0.0)) + return T != Float32 ? Point3f.(verts) : reinterpret(Point3f, verts) end -function to_vertices(verts::AbstractVector{<: VecTypes}) - to_ndim.(Point{3, Float64}, verts, 0.0) +@trace function to_vertices(verts::AbstractVector{<: VecTypes}) + to_ndim.(Point3f, verts, 0.0) end -function to_vertices(verts::AbstractMatrix{<: Real}) +@trace function to_vertices(verts::AbstractMatrix{<: Real}) if size(verts, 1) in (2, 3) to_vertices(verts, Val(1)) elseif size(verts, 2) in (2, 3) @@ -775,23 +840,23 @@ function to_vertices(verts::AbstractMatrix{<: Real}) end end -function to_vertices(verts::AbstractMatrix{T}, ::Val{1}) where T <: Real +@trace function to_vertices(verts::AbstractMatrix{T}, ::Val{1}) where T <: Real N = size(verts, 1) - if N == 3 - reinterpret(Point{N, T}, elconvert(T, vec(verts))) + if T == Float32 && N == 3 + reinterpret(Point3f, elconvert(T, vec(verts))) else let N = Val(N), lverts = verts broadcast(1:size(verts, 2), N) do vidx, n - to_ndim(Point3{T}, ntuple(i-> lverts[i, vidx], n), 0.0) + to_ndim(Point3f, ntuple(i-> lverts[i, vidx], n), 0.0) end end end end -function to_vertices(verts::AbstractMatrix{T}, ::Val{2}) where T <: Real +@trace function to_vertices(verts::AbstractMatrix{T}, ::Val{2}) where T <: Real let N = Val(size(verts, 2)), lverts = verts broadcast(1:size(verts, 1), N) do vidx, n - to_ndim(Point3{T}, ntuple(i-> lverts[vidx, i], n), 0.0) + to_ndim(Point3f, ntuple(i-> lverts[vidx, i], n), 0.0) end end end diff --git a/test/conversions.jl b/test/conversions.jl index 747f67deb36..446ad91e508 100644 --- a/test/conversions.jl +++ b/test/conversions.jl @@ -21,7 +21,7 @@ end @testset "changing input types" begin input = Observable{Any}(decompose(Point2f, Circle(Point2f(0), 2f0))) f, ax, pl = mesh(input) - m = Makie._triangle_mesh(Circle(Point2(0.0), 1.0)) + m = Makie._triangle_mesh(Circle(Point2f(0), 1f0)) input[] = m @test pl[1][] == m end @@ -29,29 +29,29 @@ end @testset "to_vertices" begin X1 = [Point(rand(3)...) for i = 1:10] V1 = to_vertices(X1) - @test X1[7][1] == V1[7][1] + @test Float32(X1[7][1]) == V1[7][1] X2 = [tuple(rand(3)...) for i = 1:10] V2 = to_vertices(X2) - @test X2[7][1] == V2[7][1] + @test Float32(X2[7][1]) == V2[7][1] X4 = rand(2,10) V4 = to_vertices(X4) - @test X4[1,7] == V4[7][1] + @test Float32(X4[1,7]) == V4[7][1] @test V4[7][3] == 0 X5 = rand(3,10) V5 = to_vertices(X5) - @test X5[1,7] == V5[7][1] + @test Float32(X5[1,7]) == V5[7][1] X6 = rand(10,2) V6 = to_vertices(X6) - @test X6[7,1] == V6[7][1] + @test Float32(X6[7,1]) == V6[7][1] @test V6[7][3] == 0 X7 = rand(10,3) V7 = to_vertices(X7) - @test X7[7,1] == V7[7][1] + @test Float32(X7[7,1]) == V7[7][1] end @testset "functions" begin From 8ade21562fa3dc34dedb3d34d03c13676c548b50 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 1 May 2023 17:05:34 +0200 Subject: [PATCH 40/49] cleanup trace, return statements, Number -> Real --- src/conversions.jl | 253 ++++++++++++++----------------------- src/utilities/utilities.jl | 61 +++++++++ 2 files changed, 157 insertions(+), 157 deletions(-) diff --git a/src/conversions.jl b/src/conversions.jl index 2cd1f5836bb..89fc3b3da02 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -1,64 +1,3 @@ -# For tracing function call order, probably delete later? - -macro trace(expr) - if expr.head in (Symbol("="), :function) - name = _to_typed_name(expr.args[1]) - file = " in " * string(__source__.file) * ':' - line = string(__source__.line) * '\n' - code = quote - begin - printstyled($name, bold = true) - printstyled($file, color = :light_black) - printstyled($line, bold = true) - $(expr.args[2]) - end - end - out = Expr( - expr.head, # function or = - esc(expr.args[1]), # function name w/ args - esc(code) - ) - return out - end - return expr -end - -function _to_typed_name(e::Expr) - if e.head == :where - _to_typed_name(e.args[1]) - elseif e.head == :call - if length(e.args) > 1 && e.args[2] isa Expr && e.args[2].head == :parameters - args = join(_to_type.(e.args[3:end]), ", ") - kwargs = join(_to_type.(e.args[2].args), ", ") - return string(e.args[1]) * "(" * args * "; " * kwargs * ")" - else - args = join(_to_type.(e.args[2:end]), ", ") - return string(e.args[1]) * "(" * args * ")" - end - else - dump(e) - return "ERROR" - end -end - -_to_type(s::Symbol) = "::Any" -function _to_type(e::Expr) - if e.head == Symbol("::") - return "::" * string(e.args[end]) - elseif e.head == Symbol("...") - return _to_type(e.args[1]) * "..." - elseif e.head == :parameters # keyword args - return _to_type(e.args[1]) - elseif e.head == :kw # default value - return _to_type(e.args[1]) - else - dump(e) - error("Failed to parse expression.") - return "" - end -end - - ################################################################################ # Type Conversions # ################################################################################ @@ -68,14 +7,14 @@ const NativeFloat = Union{Float64, Float32} const NativePoint = Point{N, T} where {N, T <: NativeFloat} # if no plot type based conversion is defined, we try using a trait -@trace function convert_arguments(T::PlotFunc, args...; kw...) +function convert_arguments(T::PlotFunc, args...; kw...) ct = conversion_trait(T) try - convert_arguments(ct, args...; kw...) + return convert_arguments(ct, args...; kw...) catch e if e isa MethodError try - convert_arguments_individually(T, args...) + return convert_arguments_individually(T, args...) catch ee if ee isa MethodError error( @@ -103,7 +42,7 @@ end # in case no trait matches we try to convert each individual argument # and reconvert the whole tuple in order to handle missings centrally, e.g. -@trace function convert_arguments_individually(T::PlotFunc, args...) +function convert_arguments_individually(T::PlotFunc, args...) # convert each single argument until it doesn't change type anymore single_converted = recursively_convert_argument.(args) # if the type of args hasn't changed this function call didn't help and we error @@ -112,15 +51,15 @@ end end # otherwise we try converting our newly single-converted args again because # now a normal conversion method might work again - convert_arguments(T, single_converted...) + return convert_arguments(T, single_converted...) end function recursively_convert_argument(x) newx = convert_single_argument(x) if typeof(newx) == typeof(x) - x + return x else - recursively_convert_argument(newx) + return recursively_convert_argument(newx) end end @@ -129,24 +68,24 @@ end ################################################################################ # if no specific conversion is defined, we don't convert -@trace convert_single_argument(x) = x +convert_single_argument(x) = x # replace missings with NaNs -@trace function convert_single_argument(a::AbstractArray{<:Union{Missing, T}}) where {T <: NativeFloat} +function convert_single_argument(a::AbstractArray{<:Union{Missing, T}}) where {T <: NativeFloat} nan = T(NaN) - [ismissing(x) ? nan : x for x in a] + return [ismissing(x) ? nan : x for x in a] end -@trace function convert_single_argument(a::AbstractArray{<:Union{Missing, <:Real}}) - [ismissing(x) ? NaN32 : convert(Float32, x) for x in a] +function convert_single_argument(a::AbstractArray{<:Union{Missing, <:Real}}) + return [ismissing(x) ? NaN32 : convert(Float32, x) for x in a] end # same for points -@trace function convert_single_argument(a::AbstractArray{<:Union{Missing, T}}) where {T <: NativePoint} +function convert_single_argument(a::AbstractArray{<:Union{Missing, T}}) where {T <: NativePoint} nan = T(NaN) - [ismissing(x) ? nan : T(x) for x in a] + return [ismissing(x) ? nan : T(x) for x in a] end -@trace function convert_single_argument(a::AbstractArray{<:Union{Missing, <:Point{N}}}) where N - [ismissing(x) ? Point{N, Float32}(NaN32) : Point{N, Float32}(x) for x in a] +function convert_single_argument(a::AbstractArray{<:Union{Missing, <:Point{N}}}) where N + return [ismissing(x) ? Point{N, Float32}(NaN32) : Point{N, Float32}(x) for x in a] end ################################################################################ @@ -156,33 +95,33 @@ end """ Wrap a single point or equivalent object in a single-element array. """ -@trace function convert_arguments(::PointBased, x::Real, y::Real) - ([native_type(x, y)],) +function convert_arguments(::PointBased, x::Real, y::Real) + return ([native_type(x, y)],) end -@trace function convert_arguments(::PointBased, x::Real, y::Real, z::Real) - ([native_type(x, y, z)],) +function convert_arguments(::PointBased, x::Real, y::Real, z::Real) + return ([native_type(x, y, z)],) end -@trace function convert_arguments(::PointBased, position::VecTypes{N, T}) where {T <: Number, N} - ([native_type(position)],) +function convert_arguments(::PointBased, position::VecTypes{N, T}) where {T <: Real, N} + return ([native_type(position)],) end -@trace function convert_arguments(::PointBased, positions::AbstractVector{<: VecTypes{N}}) where N - (native_type.(positions),) +function convert_arguments(::PointBased, positions::AbstractVector{<: VecTypes{N}}) where N + return (native_type.(positions),) end -@trace function convert_arguments(::PointBased, positions::SubArray{<: VecTypes, 1}) +function convert_arguments(::PointBased, positions::SubArray{<: VecTypes, 1}) # TODO figure out a good subarray solution - (positions,) + return (positions,) end """ Enables to use scatter like a surface plot with x::Vector, y::Vector, z::Matrix spanning z over the grid spanned by x y """ -@trace function convert_arguments(::PointBased, x::AbstractVector, y::AbstractVector, z::AbstractMatrix) - (vec(Point3.(x, y', z)),) +function convert_arguments(::PointBased, x::AbstractVector, y::AbstractVector, z::AbstractMatrix) + return (vec(native_type.(x, y', z)),) end """ convert_arguments(P, x, y, z)::(Vector) @@ -191,7 +130,7 @@ Takes vectors `x`, `y`, and `z` and turns it into a vector of 3D points of the v from `x`, `y`, and `z`. `P` is the plot Type (it is optional). """ -@trace convert_arguments(::PointBased, x::RealVector, y::RealVector, z::RealVector) = (Point3.(x, y, z),) +convert_arguments(::PointBased, x::RealVector, y::RealVector, z::RealVector) = (native_type.(x, y, z),) """ convert_arguments(P, x)::(Vector) @@ -199,14 +138,14 @@ from `x`, `y`, and `z`. Takes an input GeometryPrimitive `x` and decomposes it to points. `P` is the plot Type (it is optional). """ -@trace convert_arguments(p::PointBased, x::GeometryPrimitive) = convert_arguments(p, decompose(Point3f, x)) +convert_arguments(p::PointBased, x::GeometryPrimitive) = convert_arguments(p, decompose(Point3f, x)) -@trace function convert_arguments(::PointBased, pos::AbstractMatrix{<: Number}) - (to_vertices(pos),) # NOTE: This currently ends up as Float32 +function convert_arguments(::PointBased, pos::AbstractMatrix{<: Real}) + return (to_vertices(pos),) # NOTE: This currently ends up as Float32 end -@trace function convert_arguments(P::PointBased, x::AbstractVector{<:Real}, y::AbstractVector{<:Real}) - (native_type.(x, y),) +function convert_arguments(P::PointBased, x::AbstractVector{<:Real}, y::AbstractVector{<:Real}) + return (native_type.(x, y),) end """ @@ -216,7 +155,7 @@ an arbitrary `x` axis. `P` is the plot Type (it is optional). """ -@trace convert_arguments(P::PointBased, y::RealVector) = convert_arguments(P, keys(y), y) +convert_arguments(P::PointBased, y::RealVector) = convert_arguments(P, keys(y), y) """ convert_arguments(P, x, y)::(Vector) @@ -227,10 +166,10 @@ from `x` and `y`. `P` is the plot Type (it is optional). """ #convert_arguments(::PointBased, x::RealVector, y::RealVector) = (Point2f.(x, y),) -@trace function convert_arguments(P::PointBased, x::ClosedInterval, y::RealVector) +function convert_arguments(P::PointBased, x::ClosedInterval, y::RealVector) return convert_arguments(P, LinRange(extrema(x)..., length(y)), y) end -@trace convert_arguments(P::PointBased, x::RealVector, y::ClosedInterval) = convert_arguments(P, x, LinRange(extrema(y)..., length(x))) +convert_arguments(P::PointBased, x::RealVector, y::ClosedInterval) = convert_arguments(P, x, LinRange(extrema(y)..., length(x))) """ @@ -240,31 +179,31 @@ Takes an input `Rect` `x` and decomposes it to points. `P` is the plot Type (it is optional). """ -@trace function convert_arguments(P::PointBased, x::Rect2{T}) where T +function convert_arguments(P::PointBased, x::Rect2{T}) where T # TODO fix the order of decompose return convert_arguments(P, decompose(Point2{T}, x)[[1, 2, 4, 3]]) end -@trace function convert_arguments(P::PointBased, mesh::AbstractMesh) # TODO +function convert_arguments(P::PointBased, mesh::AbstractMesh) # TODO return convert_arguments(P, decompose(Point3f, mesh)) end -@trace function convert_arguments(PB::PointBased, linesegments::FaceView{<:Line, P}) where {P<:AbstractPoint} +function convert_arguments(PB::PointBased, linesegments::FaceView{<:Line, P}) where {P<:AbstractPoint} # TODO FaceView should be natively supported by backends! return convert_arguments(PB, collect(reinterpret(P, linesegments))) end -@trace function convert_arguments(P::PointBased, rect::Rect3{T}) where T +function convert_arguments(P::PointBased, rect::Rect3{T}) where T return (decompose(Point3{T}, rect),) end -@trace function convert_arguments(P::Type{<: LineSegments}, rect::Rect3{T}) where T +function convert_arguments(P::Type{<: LineSegments}, rect::Rect3{T}) where T f = decompose(LineFace{Int}, rect) p = connect(decompose(Point3{T}, rect), f) return convert_arguments(P, p) end -@trace function convert_arguments(::Type{<: Lines}, rect::Rect3{T}) where T +function convert_arguments(::Type{<: Lines}, rect::Rect3{T}) where T points = unique(decompose(Point3{T}, rect)) push!(points, Point3{T}(NaN)) # use to seperate linesegments return (points[[1, 2, 3, 4, 1, 5, 6, 2, 9, 6, 8, 3, 9, 5, 7, 4, 9, 7, 8]],) @@ -275,7 +214,7 @@ end Takes an input `LineString` and decomposes it to points. """ -@trace function convert_arguments(PB::PointBased, linestring::LineString) +function convert_arguments(PB::PointBased, linestring::LineString) return convert_arguments(PB, decompose(Point, linestring)) end @@ -284,7 +223,7 @@ end Takes an input `Array{LineString}` or a `MultiLineString` and decomposes it to points. """ -@trace function convert_arguments(PB::PointBased, linestring::Union{Array{<:LineString}, MultiLineString}) +function convert_arguments(PB::PointBased, linestring::Union{Array{<:LineString}, MultiLineString}) arr = copy(convert_arguments(PB, linestring[1])[1]) T = eltype(arr) for ls in 2:length(linestring) @@ -300,7 +239,7 @@ end Takes an input `Polygon` and decomposes it to points. """ -@trace function convert_arguments(PB::PointBased, pol::Polygon) +function convert_arguments(PB::PointBased, pol::Polygon) arr = copy(convert_arguments(PB, pol.exterior)[1]) T = eltype(arr) push!(arr, arr[1]) # close exterior @@ -322,7 +261,7 @@ end Takes an input `Array{Polygon}` or a `MultiPolygon` and decomposes it to points. """ -@trace function convert_arguments(PB::PointBased, mp::Union{Array{<:Polygon}, MultiPolygon}) +function convert_arguments(PB::PointBased, mp::Union{Array{<:Polygon}, MultiPolygon}) arr = copy(convert_arguments(PB, mp[1])[1]) T = eltype(arr) for p in 2:length(mp) @@ -332,7 +271,7 @@ Takes an input `Array{Polygon}` or a `MultiPolygon` and decomposes it to points. return (arr,) end -@trace function convert_arguments(::PointBased, b::BezierPath) +function convert_arguments(::PointBased, b::BezierPath) b2 = replace_nonfreetype_commands(b) points = Point2f[] last_point = Point2f(NaN) @@ -389,7 +328,7 @@ function edges(v::AbstractVector) end end -function adjust_axes(::DiscreteSurface, x::AbstractVector{<:Number}, y::AbstractVector{<:Number}, z::AbstractMatrix) +function adjust_axes(::DiscreteSurface, x::RealVector, y::RealVector, z::AbstractMatrix) x̂, ŷ = map((x, y), size(z)) do v, sz return length(v) == sz ? edges(v) : v end @@ -406,12 +345,12 @@ whether they represent edges or centers of the heatmap bins. If they are centers, convert to edges. Convert eltypes to `Float32` and return outputs as a `Tuple`. """ -@trace function convert_arguments(SL::SurfaceLike, x::AbstractVecOrMat{<: Number}, y::AbstractVecOrMat{<: Number}, z::AbstractMatrix{<: Union{Number, Colorant}}) +function convert_arguments(SL::SurfaceLike, x::AbstractVecOrMat{<: Real}, y::AbstractVecOrMat{<: Real}, z::AbstractMatrix{<: Union{Real, Colorant}}) _x, _y, _z = adjust_axes(SL, x, y, z) return convert_single_argument(_x), convert_single_argument(_y), el32convert(_z) # TODO convert_single_argument for z too? end -@trace convert_arguments(sl::SurfaceLike, x::AbstractMatrix, y::AbstractMatrix) = convert_arguments(sl, x, y, zeros(size(y))) +convert_arguments(sl::SurfaceLike, x::AbstractMatrix, y::AbstractMatrix) = convert_arguments(sl, x, y, zeros(size(y))) """ convert_arguments(P, x, y, z)::Tuple{ClosedInterval, ClosedInterval, Matrix} @@ -420,8 +359,8 @@ Takes 2 ClosedIntervals's `x`, `y`, and an AbstractMatrix `z`, and converts the linspaces with size(z, 1/2) `P` is the plot Type (it is optional). """ -@trace function convert_arguments(P::SurfaceLike, x::ClosedInterval, y::ClosedInterval, z::AbstractMatrix) - convert_arguments(P, to_linspace(x, size(z, 1)), to_linspace(y, size(z, 2)), z) +function convert_arguments(P::SurfaceLike, x::ClosedInterval, y::ClosedInterval, z::AbstractMatrix) + return convert_arguments(P, to_linspace(x, size(z, 1)), to_linspace(y, size(z, 2)), z) end """ @@ -432,17 +371,17 @@ and stores the `ClosedInterval` to `n` and `m`, plus the original matrix in a Tu `P` is the plot Type (it is optional). """ -@trace function convert_arguments(sl::SurfaceLike, data::AbstractMatrix) +function convert_arguments(sl::SurfaceLike, data::AbstractMatrix) n, m = size(data) - convert_arguments(sl, 0 .. n, 0 .. m, el32convert(data)) + return convert_arguments(sl, 0 .. n, 0 .. m, el32convert(data)) end -@trace function convert_arguments(ds::DiscreteSurface, data::AbstractMatrix) +function convert_arguments(ds::DiscreteSurface, data::AbstractMatrix) n, m = Float32.(size(data)) - convert_arguments(ds, edges(1:n), edges(1:m), el32convert(data)) + return convert_arguments(ds, edges(1:n), edges(1:m), el32convert(data)) end -@trace function convert_arguments(SL::SurfaceLike, x::AbstractVector{<:Number}, y::AbstractVector{<:Number}, z::AbstractVector{<:Number}) +function convert_arguments(SL::SurfaceLike, x::AbstractVector{<: Real}, y::AbstractVector{<: Real}, z::AbstractVector{<: Real}) if !(length(x) == length(y) == length(z)) error("x, y and z need to have the same length. Lengths are $(length.((x, y, z)))") end @@ -464,7 +403,7 @@ end j = searchsortedfirst(y_centers, yi) @inbounds zs[i, j] = zi end - convert_arguments(SL, x_centers, y_centers, zs) + return convert_arguments(SL, x_centers, y_centers, zs) end @@ -475,7 +414,7 @@ Takes vectors `x` and `y` and the function `f`, and applies `f` on the grid that This is equivalent to `f.(x, y')`. `P` is the plot Type (it is optional). """ -@trace function convert_arguments(sl::SurfaceLike, x::AbstractVector{T1}, y::AbstractVector{T2}, f::Function) where {T1, T2} +function convert_arguments(sl::SurfaceLike, x::AbstractVector{T1}, y::AbstractVector{T2}, f::Function) where {T1, T2} if !applicable(f, x[1], y[1]) error("You need to pass a function with signature f(x::$T1, y::$T2). Found: $f") end @@ -497,12 +436,12 @@ and stores the `ClosedInterval` to `n`, `m` and `k`, plus the original array in `P` is the plot Type (it is optional). """ -@trace function convert_arguments(::VolumeLike, data::AbstractArray{T, 3}) where T +function convert_arguments(::VolumeLike, data::AbstractArray{T, 3}) where T n, m, k = T.(size(data)) return (0f0 .. n, 0f0 .. m, 0f0 .. k, el32convert(data)) end -@trace function convert_arguments(::VolumeLike, x::RangeLike, y::RangeLike, z::RangeLike, data::AbstractArray{T, 3}) where T +function convert_arguments(::VolumeLike, x::RangeLike, y::RangeLike, z::RangeLike, data::AbstractArray{T, 3}) where T return (x, y, z, el32convert(data)) end """ @@ -512,8 +451,8 @@ Takes 3 `AbstractVector` `x`, `y`, and `z` and the `AbstractMatrix` `i`, and put `P` is the plot Type (it is optional). """ -@trace function convert_arguments(::VolumeLike, x::AbstractVector, y::AbstractVector, z::AbstractVector, i::AbstractArray{T, 3}) where T - (x, y, z, el32convert(i)) +function convert_arguments(::VolumeLike, x::AbstractVector, y::AbstractVector, z::AbstractVector, i::AbstractArray{T, 3}) where T + return (x, y, z, el32convert(i)) end @@ -525,7 +464,7 @@ spanned by `x`, `y` and `z`, and puts `x`, `y`, `z` and `f(x,y,z)` in a Tuple. `P` is the plot Type (it is optional). """ -@trace function convert_arguments(::VolumeLike, x::AbstractVector, y::AbstractVector, z::AbstractVector, f::Function) +function convert_arguments(::VolumeLike, x::AbstractVector, y::AbstractVector, z::AbstractVector, f::Function) if !applicable(f, x[1], y[1], z[1]) error("You need to pass a function with signature f(x, y, z). Found: $f") end @@ -540,7 +479,7 @@ end # <:Lines # ################################################################################ -@trace function convert_arguments(::Type{<: Lines}, x::Rect2{T}) where T +function convert_arguments(::Type{<: Lines}, x::Rect2{T}) where T # TODO fix the order of decompose points = decompose(Point2{T}, x) return (points[[1, 2, 4, 3, 1]],) @@ -554,12 +493,12 @@ end Accepts a Vector of Pair of Points (e.g. `[Point(0, 0) => Point(1, 1), ...]`) to encode e.g. linesegments or directions. """ -@trace function convert_arguments(::Type{<: LineSegments}, positions::AbstractVector{E}) where +function convert_arguments(::Type{<: LineSegments}, positions::AbstractVector{E}) where E <: Union{Pair{A, A}, Tuple{A, A}} where A <: VecTypes{N, T} where {N, T} - (reinterpret(Point{N, T}, positions),) + return (reinterpret(Point{N, T}, positions),) end -@trace function convert_arguments(::Type{<: LineSegments}, x::Rect2{T}) where T +function convert_arguments(::Type{<: LineSegments}, x::Rect2{T}) where T # TODO fix the order of decompose points = decompose(Point2{T}, x) return (points[[1, 2, 2, 4, 4, 3, 3, 1]],) @@ -587,11 +526,11 @@ Takes an input `AbstractString` `x` and converts it to a string. Takes real vectors x, y, z and constructs a mesh out of those, under the assumption that every 3 points form a triangle. """ -@trace function convert_arguments( +function convert_arguments( T::Type{<:Mesh}, x::RealVector, y::RealVector, z::RealVector ) - convert_arguments(T, Point3.(x, y, z)) + return convert_arguments(T, Point3.(x, y, z)) end """ convert_arguments(Mesh, xyz::AbstractVector)::GLNormalMesh @@ -599,7 +538,7 @@ end Takes an input mesh and a vector `xyz` representing the vertices of the mesh, and creates indices under the assumption, that each triplet in `xyz` forms a triangle. """ -@trace function convert_arguments( +function convert_arguments( MT::Type{<:Mesh}, xyz::AbstractVector ) @@ -608,7 +547,7 @@ creates indices under the assumption, that each triplet in `xyz` forms a triangl return convert_arguments(MT, xyz, collect(faces)) end -@trace function convert_arguments(::Type{<:Mesh}, mesh::GeometryBasics.Mesh{N}) where {N} +function convert_arguments(::Type{<:Mesh}, mesh::GeometryBasics.Mesh{N}) where {N} # Make sure we have normals! if !hasproperty(mesh, :normals) n = normals(mesh) @@ -627,21 +566,21 @@ end end end -@trace function convert_arguments( +function convert_arguments( MT::Type{<:Mesh}, meshes::AbstractVector{<: Union{AbstractMesh, AbstractPolygon}} ) return (meshes,) end -@trace function convert_arguments( +function convert_arguments( MT::Type{<:Mesh}, xyz::Union{AbstractPolygon{2, T}, AbstractVector{<: AbstractPoint{2, T}}} ) where T return convert_arguments(MT, triangle_mesh(xyz)) end -@trace function convert_arguments(MT::Type{<:Mesh}, geom::GeometryPrimitive{N, T}) where {N, T} +function convert_arguments(MT::Type{<:Mesh}, geom::GeometryPrimitive{N, T}) where {N, T} # we convert to UV mesh as default, because otherwise the uv informations get lost # - we can still drop them, but we can't add them later on return (GeometryBasics.uv_normal_mesh(geom),) @@ -653,7 +592,7 @@ end Takes real vectors x, y, z and constructs a triangle mesh out of those, using the faces in `indices`, which can be integers (every 3 -> one triangle), or GeometryBasics.NgonFace{N, <: Integer}. """ -@trace function convert_arguments( +function convert_arguments( T::Type{<: Mesh}, x::RealVector, y::RealVector, z::RealVector, indices::AbstractVector @@ -668,11 +607,11 @@ Takes `vertices` and `indices`, and creates a triangle mesh out of those. See [`to_vertices`](@ref) and [`to_triangles`](@ref) for more information about accepted types. """ -@trace function convert_arguments(MT::Type{<:Mesh}, vertices::AbstractArray, indices::AbstractArray) +function convert_arguments(MT::Type{<:Mesh}, vertices::AbstractArray, indices::AbstractArray) return convert_arguments(MT, to_vertices(vertices), to_triangles(indices)) end -@trace function convert_arguments( +function convert_arguments( ::Type{<:Mesh}, pos::AbstractVector{VT}, faces::AbstractVector{GLTriangleFace} ) where {N, T, VT <: VecTypes{N, T}} _points = to_ndim.(Point{3, T}, pos, T(0)) @@ -685,15 +624,15 @@ end # Function Conversions # ################################################################################ -@trace function convert_arguments(P::PlotFunc, r::AbstractVector, f::Function) +function convert_arguments(P::PlotFunc, r::AbstractVector, f::Function) ptype = plottype(P, Lines) - to_plotspec(ptype, convert_arguments(ptype, r, f.(r))) + return to_plotspec(ptype, convert_arguments(ptype, r, f.(r))) end -@trace function convert_arguments(P::PlotFunc, i::AbstractInterval, f::Function) +function convert_arguments(P::PlotFunc, i::AbstractInterval, f::Function) x, y = PlotUtils.adapted_grid(f, endpoints(i)) ptype = plottype(P, Lines) - to_plotspec(ptype, convert_arguments(ptype, x, y)) + return to_plotspec(ptype, convert_arguments(ptype, x, y)) end # The following `tryrange` code was copied from Plots.jl @@ -704,7 +643,7 @@ function tryrange(F::AbstractArray, vec) rets = [tryrange(f, vec) for f in F] # get the preferred for each maxind = maximum(indexin(rets, vec)) # get the last attempt that succeeded (most likely to fit all) rets .= [tryrange(f, vec[maxind:maxind]) for f in F] # ensure that all functions compute there - rets[1] + return rets[1] end function tryrange(F, vec) @@ -719,7 +658,7 @@ function tryrange(F, vec) end # OffsetArrays conversions -@trace function convert_arguments(sl::SurfaceLike, wm::OffsetArray) +function convert_arguments(sl::SurfaceLike, wm::OffsetArray) x1, y1 = wm.offsets .+ 1 nx, ny = size(wm) x = range(x1, length = nx) @@ -768,13 +707,13 @@ function el32convert(mesh::GeometryBasics.Mesh, positions = mesh.position) end -@trace native_type(x::NativeFloat) = x -# @trace native_type(x::VecTypes{N, T}) where {N, T <: NativeFloat} = reinterpret(Point{N, T}, x) # crashes precompile? -@trace native_type(x::VecTypes{N, T}) where {N, T <: NativeFloat} = Point{N, T}(x) -@trace native_type(x::Real) = Float32(x) -@trace native_type(x::VecTypes{N}) where N = Point{N, Float32}(x) -@trace native_type(x::Real, y::Real) = Point2(native_type(x), native_type(y)) -@trace native_type(x::Real, y::Real, z::Real) = Point3(native_type(x), native_type(y), native_type(z)) +native_type(x::NativeFloat) = x +# native_type(x::VecTypes{N, T}) where {N, T <: NativeFloat} = reinterpret(Point{N, T}, x) # crashes precompile? +native_type(x::VecTypes{N, T}) where {N, T <: NativeFloat} = Point{N, T}(x) +native_type(x::Real) = Float32(x) +native_type(x::VecTypes{N}) where N = Point{N, Float32}(x) +native_type(x::Real, y::Real) = Point2(native_type(x), native_type(y)) +native_type(x::Real, y::Real, z::Real) = Point3(native_type(x), native_type(y), native_type(z)) """ @@ -826,11 +765,11 @@ function to_vertices(verts::AbstractVector{<: VecTypes{3, T}}) where T return T != Float32 ? Point3f.(verts) : reinterpret(Point3f, verts) end -@trace function to_vertices(verts::AbstractVector{<: VecTypes}) +function to_vertices(verts::AbstractVector{<: VecTypes}) to_ndim.(Point3f, verts, 0.0) end -@trace function to_vertices(verts::AbstractMatrix{<: Real}) +function to_vertices(verts::AbstractMatrix{<: Real}) if size(verts, 1) in (2, 3) to_vertices(verts, Val(1)) elseif size(verts, 2) in (2, 3) @@ -840,7 +779,7 @@ end end end -@trace function to_vertices(verts::AbstractMatrix{T}, ::Val{1}) where T <: Real +function to_vertices(verts::AbstractMatrix{T}, ::Val{1}) where T <: Real N = size(verts, 1) if T == Float32 && N == 3 reinterpret(Point3f, elconvert(T, vec(verts))) @@ -853,7 +792,7 @@ end end end -@trace function to_vertices(verts::AbstractMatrix{T}, ::Val{2}) where T <: Real +function to_vertices(verts::AbstractMatrix{T}, ::Val{2}) where T <: Real let N = Val(size(verts, 2)), lverts = verts broadcast(1:size(verts, 1), N) do vidx, n to_ndim(Point3f, ntuple(i-> lverts[vidx, i], n), 0.0) diff --git a/src/utilities/utilities.jl b/src/utilities/utilities.jl index 6f6a60edd7b..2d07c53e3f6 100644 --- a/src/utilities/utilities.jl +++ b/src/utilities/utilities.jl @@ -364,3 +364,64 @@ end # Scalar - Vector getindex sv_getindex(v::Vector, i::Integer) = v[i] sv_getindex(x, i::Integer) = x + + +# For tracing function call order, probably delete later? + +macro trace(expr) + if expr.head in (Symbol("="), :function) + name = _to_typed_name(expr.args[1]) + file = " in " * string(__source__.file) * ':' + line = string(__source__.line) * '\n' + code = quote + begin + printstyled($name, bold = true) + printstyled($file, color = :light_black) + printstyled($line, bold = true) + $(expr.args[2]) + end + end + out = Expr( + expr.head, # function or = + esc(expr.args[1]), # function name w/ args + esc(code) + ) + return out + end + return expr +end + +function _to_typed_name(e::Expr) + if e.head == :where + _to_typed_name(e.args[1]) + elseif e.head == :call + if length(e.args) > 1 && e.args[2] isa Expr && e.args[2].head == :parameters + args = join(_to_type.(e.args[3:end]), ", ") + kwargs = join(_to_type.(e.args[2].args), ", ") + return string(e.args[1]) * "(" * args * "; " * kwargs * ")" + else + args = join(_to_type.(e.args[2:end]), ", ") + return string(e.args[1]) * "(" * args * ")" + end + else + dump(e) + return "ERROR" + end +end + +_to_type(s::Symbol) = "::Any" +function _to_type(e::Expr) + if e.head == Symbol("::") + return "::" * string(e.args[end]) + elseif e.head == Symbol("...") + return _to_type(e.args[1]) * "..." + elseif e.head == :parameters # keyword args + return _to_type(e.args[1]) + elseif e.head == :kw # default value + return _to_type(e.args[1]) + else + dump(e) + error("Failed to parse expression.") + return "" + end +end \ No newline at end of file From 75583e9e3dbfcc344e02c931b86fa5c64c7bef4c Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 1 May 2023 18:39:32 +0200 Subject: [PATCH 41/49] fix WGLMakie --- WGLMakie/src/imagelike.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WGLMakie/src/imagelike.jl b/WGLMakie/src/imagelike.jl index 1963b54308f..76f93a1c038 100644 --- a/WGLMakie/src/imagelike.jl +++ b/WGLMakie/src/imagelike.jl @@ -94,8 +94,8 @@ function limits_to_uvmesh(plot) faces = Buffer(lift(rect -> decompose(GLTriangleFace, rect), rect)) uv = Buffer(lift(decompose_uv, rect)) else - grid(x, y, trans, space) = Makie.matrix_grid(p-> apply_transform(trans, p, space), x, y, zeros(length(x), length(y))) - rect = lift((x, y) -> Tesselation(Rect2(0.0, 0.0, 1.0, 1.0), (length(x), length(y))), px, py) + grid(x, y, trans, space) = Makie.el32convert(Makie.matrix_grid(p-> apply_transform(trans, p, space), x, y, zeros(length(x), length(y)))) + resolution = lift((x, y) -> (length(x), length(y)), px, py; ignore_equal_values=true) positions = Buffer(lift(grid, px, py, t, get(plot, :space, :data))) faces = Buffer(lift(fast_faces, resolution)) uv = Buffer(lift(fast_uv, resolution)) From d8599840797ba71ad37639111049b5cf2fd11fd7 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 1 May 2023 19:26:18 +0200 Subject: [PATCH 42/49] loosen some types [skip ci] --- src/conversions.jl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/conversions.jl b/src/conversions.jl index 89fc3b3da02..caf694b4129 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -155,7 +155,7 @@ an arbitrary `x` axis. `P` is the plot Type (it is optional). """ -convert_arguments(P::PointBased, y::RealVector) = convert_arguments(P, keys(y), y) +convert_arguments(P::PointBased, y::AbstractVector{<: Number}) = convert_arguments(P, keys(y), y) """ convert_arguments(P, x, y)::(Vector) @@ -165,11 +165,12 @@ from `x` and `y`. `P` is the plot Type (it is optional). """ -#convert_arguments(::PointBased, x::RealVector, y::RealVector) = (Point2f.(x, y),) -function convert_arguments(P::PointBased, x::ClosedInterval, y::RealVector) +function convert_arguments(P::PointBased, x::ClosedInterval, y::AbstractVector{<: Number}) return convert_arguments(P, LinRange(extrema(x)..., length(y)), y) end -convert_arguments(P::PointBased, x::RealVector, y::ClosedInterval) = convert_arguments(P, x, LinRange(extrema(y)..., length(x))) +function convert_arguments(P::PointBased, x::AbstractVector{<: Number}, y::ClosedInterval) + return convert_arguments(P, x, LinRange(extrema(y)..., length(x))) +end """ From 2ada40e9e03b5fa16c97367d3da05ab4bb136982 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 4 Jun 2023 18:06:39 +0200 Subject: [PATCH 43/49] allow empty inputs --- src/conversions.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/conversions.jl b/src/conversions.jl index 6ec74476158..b70cae607ef 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -225,9 +225,9 @@ end Takes an input `Array{LineString}` or a `MultiLineString` and decomposes it to points. """ function convert_arguments(PB::PointBased, linestring::Union{Array{<:LineString}, MultiLineString}) - arr = convert_arguments(PB, linestring[1])[1] - nan = eltype(arr)(NaN) n = length(linestring) + arr = n > 0 ? convert_arguments(PB, linestring[1])[1] : Point2f[] + nan = eltype(arr)(NaN) for idx in 2:n push!(arr, nan) append!(arr, convert_arguments(PB, linestring[idx])[1]) @@ -266,8 +266,8 @@ end Takes an input `Array{Polygon}` or a `MultiPolygon` and decomposes it to points. """ function convert_arguments(PB::PointBased, mp::Union{Array{<:Polygon}, MultiPolygon}) - arr = convert_arguments(PB, mp[1])[1] n = length(mp) + arr = n > 0 ? convert_arguments(PB, mp[1])[1] : Point2f[] nan = eltype(arr)(NaN) for idx in 2:n push!(arr, nan) From bada567b813493ba92cda3593bfff55f799ddad3 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 4 Jun 2023 18:21:36 +0200 Subject: [PATCH 44/49] remove file from clipping pr --- GLMakie/assets/shader/clipping.vert | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 GLMakie/assets/shader/clipping.vert diff --git a/GLMakie/assets/shader/clipping.vert b/GLMakie/assets/shader/clipping.vert deleted file mode 100644 index 5f223738926..00000000000 --- a/GLMakie/assets/shader/clipping.vert +++ /dev/null @@ -1,23 +0,0 @@ -struct Nothing{ - bool _; -}; - -struct WorldAxisLimits{ - vec3 min, max; -}; - -{{clip_planes_type}} clip_planes; - -void set_clip(Nothing planes, vec4 world_pos){ return; } -void set_clip(WorldAxisLimits planes, vec4 world_pos) -{ - // inside positive, outside negative? - vec3 min_dist = world_pos.xyz - planes.min; - vec3 max_dist = planes.max - world_pos.xyz; - gl_ClipDistance[0] = min_dist[0]; - gl_ClipDistance[1] = max_dist[0]; - gl_ClipDistance[2] = min_dist[1]; - gl_ClipDistance[3] = max_dist[1]; - gl_ClipDistance[4] = min_dist[2]; - gl_ClipDistance[5] = max_dist[2]; -} \ No newline at end of file From ad056b3484484099e52b6a0b41fd2fb7c72ffdc7 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Tue, 6 Jun 2023 14:19:29 +0200 Subject: [PATCH 45/49] remove unused `concrete_type` --- src/utilities/quaternions.jl | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/utilities/quaternions.jl b/src/utilities/quaternions.jl index bcae57f50de..278468be9bc 100644 --- a/src/utilities/quaternions.jl +++ b/src/utilities/quaternions.jl @@ -107,9 +107,6 @@ function Mat4{ET}(q::Quaternion{T}) where {T, ET} ) end -concrete_type(::Type{Any}, ::Type{T}) where T = T -concrete_type(::Type{T}, x) where T = T - function Mat3{ET}(q::Quaternion{T}) where {T, ET} sx, sy, sz = 2q[4]*q[1], 2q[4]*q[2], 2q[4]*q[3] xx, xy, xz = 2q[1]^2, 2q[1]*q[2], 2q[1]*q[3] From e49b2ad9fe20728597da1df8e768c458f73bb53e Mon Sep 17 00:00:00 2001 From: ffreyer Date: Tue, 6 Jun 2023 14:56:54 +0200 Subject: [PATCH 46/49] drop intermediate functions, use Float64, use map --- src/basic_recipes/ablines.jl | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/basic_recipes/ablines.jl b/src/basic_recipes/ablines.jl index 6e3786d82c1..06024020b52 100644 --- a/src/basic_recipes/ablines.jl +++ b/src/basic_recipes/ablines.jl @@ -23,23 +23,16 @@ function Makie.plot!(p::ABLines) limits = lift(projview_to_2d_limits, p, scene.camera.projectionview) - points = Observable(Point2f[]) - - onany(p, limits, p[1], p[2]) do lims, intercept, slope - inv = inverse_transform(transf) - empty!(points[]) - f(x) = x * b + a + points = map(p, limits, p[1], p[2]) do lims, intercept, slope + points = sizehint!(Point2e[], 2length(slope)) broadcast_foreach(intercept, slope) do intercept, slope - f(x) = intercept + slope * x xmin, xmax = first.(extrema(lims)) - push!(points[], Point2f(xmin, f(xmin))) - push!(points[], Point2f(xmax, f(xmax))) + push!(points, Point2e(xmin, slope * xmin + intercept)) + push!(points, Point2e(xmax, slope * xmax + intercept)) end - notify(points) + return points end - notify(p[1]) - linesegments!(p, points; p.attributes...) p end From 84cdab5f7f2270cc0146486a34b422f6fe62ce1d Mon Sep 17 00:00:00 2001 From: ffreyer Date: Tue, 6 Jun 2023 16:18:42 +0200 Subject: [PATCH 47/49] generalize float type & minor reorganization --- src/basic_recipes/stairs.jl | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/basic_recipes/stairs.jl b/src/basic_recipes/stairs.jl index 4d74024c9b1..6693be909a5 100644 --- a/src/basic_recipes/stairs.jl +++ b/src/basic_recipes/stairs.jl @@ -22,45 +22,43 @@ end conversion_trait(::Type{<:Stairs}) = PointBased() -function plot!(p::Stairs{<:Tuple{<:AbstractVector{<:Point2}}}) +function Makie.plot!(p::Stairs{<:Tuple{<:AbstractVector{<:Point2}}}) points = p[1] steppoints = lift(p, points, p.step) do points, step + if !(step in (:pre, :post, :center)) + error("Invalid step $step. Valid options are :pre, :post and :center") + end + + s_points = Vector{eltype(points)}(undef, length(points) * 2 - (step !== :center)) + s_points[1] = point = points[1] + if step === :pre - s_points = Vector{Point2f}(undef, length(points) * 2 - 1) - s_points[1] = point = points[1] for i in 1:length(points)-1 nextpoint = points[i + 1] - s_points[2i] = Point2f(point[1], nextpoint[2]) + s_points[2i] = Point2(point[1], nextpoint[2]) s_points[2i + 1] = nextpoint point = nextpoint end - s_points elseif step === :post - s_points = Vector{Point2f}(undef, length(points) * 2 - 1) - s_points[1] = point = points[1] for i in 1:length(points)-1 - nextpoint = points[i+1] - s_points[2i] = Point2f(nextpoint[1], point[2]) + nextpoint = points[i + 1] + s_points[2i] = Point2(nextpoint[1], point[2]) s_points[2i + 1] = nextpoint point = nextpoint end - s_points elseif step === :center - s_points = Vector{Point2f}(undef, length(points) * 2) - s_points[1] = point = points[1] for i in 1:length(points)-1 nextpoint = points[i+1] halfx = (point[1] + nextpoint[1]) / 2 - s_points[2i] = Point2f(halfx, point[2]) - s_points[2i + 1] = Point2f(halfx, nextpoint[2]) + s_points[2i] = Point2(halfx, point[2]) + s_points[2i + 1] = Point2(halfx, nextpoint[2]) point = nextpoint end s_points[end] = point - s_points - else - error("Invalid step $step. Valid options are :pre, :post and :center") end + + return s_points end lines!(p, steppoints; [x for x in pairs(p.attributes) if x[1] !== :step]...) From a1cfa627a0d3008405795f2ebfc7c8f4e1b32def Mon Sep 17 00:00:00 2001 From: ffreyer Date: Wed, 7 Jun 2023 18:51:05 +0200 Subject: [PATCH 48/49] keep float (element) type through plot! and conversions --- src/basic_recipes/annotations.jl | 8 ++-- src/basic_recipes/arc.jl | 4 +- src/basic_recipes/arrows.jl | 14 +++--- src/basic_recipes/axis.jl | 26 +++++------ src/basic_recipes/band.jl | 2 +- src/basic_recipes/barplot.jl | 8 ++-- src/basic_recipes/bracket.jl | 6 +-- src/basic_recipes/buffers.jl | 27 ++++++------ src/basic_recipes/contourf.jl | 22 +++++----- src/basic_recipes/contours.jl | 55 ++++++++++++------------ src/basic_recipes/error_and_rangebars.jl | 53 +++++++++-------------- src/basic_recipes/hvlines.jl | 19 ++++---- src/basic_recipes/hvspan.jl | 9 ++-- src/basic_recipes/pie.jl | 8 ++-- src/basic_recipes/poly.jl | 16 +++---- src/basic_recipes/series.jl | 6 +-- src/basic_recipes/spy.jl | 4 +- src/basic_recipes/streamplot.jl | 14 +++--- src/basic_recipes/text.jl | 6 +-- src/basic_recipes/timeseries.jl | 4 +- src/basic_recipes/tooltip.jl | 4 +- src/basic_recipes/tricontourf.jl | 9 ++-- src/basic_recipes/waterfall.jl | 4 +- src/basic_recipes/wireframe.jl | 2 +- src/conversions.jl | 17 ++++++++ src/layouting/layouting.jl | 9 ++-- src/stats/boxplot.jl | 19 ++++---- src/stats/crossbar.jl | 3 +- src/stats/density.jl | 24 +++++------ src/stats/distributions.jl | 6 +-- src/stats/hexbin.jl | 15 ++++--- src/stats/hist.jl | 4 +- src/stats/violin.jl | 9 ++-- 33 files changed, 227 insertions(+), 209 deletions(-) diff --git a/src/basic_recipes/annotations.jl b/src/basic_recipes/annotations.jl index 941614d2301..a30daa48943 100644 --- a/src/basic_recipes/annotations.jl +++ b/src/basic_recipes/annotations.jl @@ -10,15 +10,15 @@ $(ATTRIBUTES) default_theme(scene, Text) end -function convert_arguments(::Type{<: Annotations}, +function Makie.convert_arguments(::Type{<: Annotations}, strings::AbstractVector{<: AbstractString}, - text_positions::AbstractVector{<: Point{N}}) where N + text_positions::AbstractVector{<: Point}) return (map(strings, text_positions) do str, pos - (String(str), Point{N, Float32}(pos)) + (String(str), pos) end,) end -function plot!(plot::Annotations) +function Makie.plot!(plot::Annotations) # annotations are not necessary anymore with the different text behavior text!(plot, plot[1]; plot.attributes...) plot diff --git a/src/basic_recipes/arc.jl b/src/basic_recipes/arc.jl index b13042c402d..83a265597d7 100644 --- a/src/basic_recipes/arc.jl +++ b/src/basic_recipes/arc.jl @@ -21,11 +21,11 @@ $(ATTRIBUTES) ) end -function plot!(p::Arc) +function Makie.plot!(p::Arc) args = getindex.(p, (:origin, :radius, :start_angle, :stop_angle, :resolution)) positions = lift(p, args...) do origin, radius, start_angle, stop_angle, resolution return map(range(start_angle, stop=stop_angle, length=resolution)) do angle - return origin .+ Point2f((cos(angle), sin(angle)) .* radius) + return origin .+ Point2((cos(angle), sin(angle)) .* radius) end end attr = Attributes(p) diff --git a/src/basic_recipes/arrows.jl b/src/basic_recipes/arrows.jl index b3f35002e0e..1af61eebea5 100644 --- a/src/basic_recipes/arrows.jl +++ b/src/basic_recipes/arrows.jl @@ -102,11 +102,11 @@ function _circle(origin, r, normal, N) end -convert_arguments(::Type{<: Arrows}, x, y, u, v) = (Point2f.(x, y), Vec2f.(u, v)) +convert_arguments(::Type{<: Arrows}, x, y, u, v) = (Point2.(x, y), Vec2.(u, v)) function convert_arguments(::Type{<: Arrows}, x::AbstractVector, y::AbstractVector, u::AbstractMatrix, v::AbstractMatrix) - (vec(Point2f.(x, y')), vec(Vec2f.(u, v))) + (vec(Point2.(x, y')), vec(Vec2.(u, v))) end -convert_arguments(::Type{<: Arrows}, x, y, z, u, v, w) = (Point3f.(x, y, z), Vec3f.(u, v, w)) +convert_arguments(::Type{<: Arrows}, x, y, z, u, v, w) = (Point3.(x, y, z), Vec3.(u, v, w)) function plot!(arrowplot::Arrows{<: Tuple{AbstractVector{<: Point{N}}, V}}) where {N, V} @extract arrowplot ( @@ -130,9 +130,9 @@ function plot!(arrowplot::Arrows{<: Tuple{AbstractVector{<: Point{N}}, V}}) wher if align in (:head, :lineend, :tailend, :headstart, :center) shift = s .* dir else - shift = Vec2f(0) + shift = zero(dir) end - return Point2f(p1 .- shift) => Point2f(p1 .- shift .+ (dir .* s)) + return Point2(p1 .- shift) => Point2(p1 .- shift .+ (dir .* s)) end end @@ -195,11 +195,11 @@ function plot!(arrowplot::Arrows{<: Tuple{AbstractVector{<: Point{N}}, V}}) wher start = lift(arrowplot, points, directions, align, lengthscale) do points, dirs, align, scales return broadcast(points, dirs, scales) do p, dir, s if align in (:head, :lineend, :tailend, :headstart, :center) - shift = Vec3f(0) + shift = zero(dir) else shift = -s .* dir end - return Point3f(p .- shift) + return Point3(p .- shift) end end marker_tail = lift((at, q) -> arrow_tail(3, at, q), arrowplot, arrowtail, quality) diff --git a/src/basic_recipes/axis.jl b/src/basic_recipes/axis.jl index f9744a8efb5..e962254bfd4 100644 --- a/src/basic_recipes/axis.jl +++ b/src/basic_recipes/axis.jl @@ -208,14 +208,14 @@ end function labelposition(ranges, dim, dir, tgap, origin::StaticVector{N}) where N a, b = extrema(ranges[dim]) - whalf = Float32(((b - a) / 2)) - halfaxis = unit(Point{N, Float32}, dim) .* whalf + whalf = Float64(((b - a) / 2)) + halfaxis = unit(Point{N, Float64}, dim) .* whalf origin .+ (halfaxis .+ (normalize(dir) * tgap)) end _widths(x::Tuple{<: Number, <: Number}) = x[2] - x[1] -_widths(x) = Float32(maximum(x) - minimum(x)) +_widths(x) = Float64(maximum(x) - minimum(x)) to3tuple(x::Tuple{Any}) = (x[1], x[1], x[1]) to3tuple(x::Tuple{Any, Any}) = (x[1], x[2], x[2]) @@ -245,7 +245,7 @@ function draw_axis3d(textbuffer, linebuffer, scale, limits, ranges_labels, fonts mini, maxi = first.(limits), last.(limits) - origin = Point{N, Float32}(min.(mini, first.(ranges))) + origin = Point{N, Float64}(min.(mini, first.(ranges))) limit_widths = max.(last.(ranges), maxi) .- origin % = minimum(limit_widths) / 100 # percentage tfontsize = (%) .* tfontsize @@ -258,8 +258,8 @@ function draw_axis3d(textbuffer, linebuffer, scale, limits, ranges_labels, fonts tgap = 0.01limit_widths[offset_indices] .* tgap for i in 1:N - axis_vec = unit(Point{N, Float32}, i) - width = Float32(limit_widths[i]) + axis_vec = unit(Point{N, Float64}, i) + width = Float64(limit_widths[i]) stop = origin .+ (width .* axis_vec) if showaxis[i] append!(linebuffer, [origin, stop], color = axiscolors[i], linewidth = axislinewidth[i]) @@ -267,14 +267,14 @@ function draw_axis3d(textbuffer, linebuffer, scale, limits, ranges_labels, fonts if showticks[i] range = ranges[i] j = offset_indices[i] - tickdir = unit(Vec{N, Float32}, j) - offset2 = Float32(limit_widths[j] + tgap[i]) * tickdir + tickdir = unit(Vec{N, Float64}, j) + offset2 = Float64(limit_widths[j] + tgap[i]) * tickdir for (j, tick) in enumerate(range) labels = ticklabels[i] if length(labels) >= j str = labels[j] if !isempty(str) - startpos = (origin .+ ((Float32(tick - origin[i]) * axis_vec)) .+ offset2) + startpos = (origin .+ ((Float64(tick - origin[i]) * axis_vec)) .+ offset2) push!( textbuffer, str, startpos, color = ttextcolor[i], rotation = trotation[i], @@ -301,10 +301,10 @@ function draw_axis3d(textbuffer, linebuffer, scale, limits, ranges_labels, fonts thickness = gridthickness[i] for _j = (i + 1):(i + N - 1) j = mod1(_j, N) - dir = unit(Point{N, Float32}, j) + dir = unit(Point{N, Float64}, j) range = ranges[j] for tick in range - offset = Float32(tick - origin[j]) * dir + offset = Float64(tick - origin[j]) * dir append!( linebuffer, [origin .+ offset, stop .+ offset], color = c, linewidth = thickness @@ -321,9 +321,9 @@ function plot!(scene::SceneLike, ::Type{<: Axis3D}, attributes::Attributes, args axis = Axis3D(scene, attributes, args) # Disable any non linear transform for the axis plot! axis.transformation.transform_func[] = identity - textbuffer = TextBuffer(axis, Point3, transparency = true, markerspace = :data, + textbuffer = TextBuffer(axis, Point3e, transparency = true, markerspace = :data, inspectable = axis.inspectable, visible = axis.visible) - linebuffer = LinesegmentBuffer(axis, Point3, transparency = true, inspectable = axis.inspectable, + linebuffer = LinesegmentBuffer(axis, Point3e, transparency = true, inspectable = axis.inspectable, visible = axis.visible) tstyle, ticks, frame = to_value.(getindex.(axis, (:names, :ticks, :frame))) diff --git a/src/basic_recipes/band.jl b/src/basic_recipes/band.jl index b0434868c1a..bdd476e7a70 100644 --- a/src/basic_recipes/band.jl +++ b/src/basic_recipes/band.jl @@ -17,7 +17,7 @@ $(ATTRIBUTES) attr end -convert_arguments(::Type{<: Band}, x, ylower, yupper) = (Point2f.(x, ylower), Point2f.(x, yupper)) +convert_arguments(::Type{<: Band}, x, ylower, yupper) = (Point2.(x, ylower), Point2.(x, yupper)) function band_connect(n) ns = 1:n-1 diff --git a/src/basic_recipes/barplot.jl b/src/basic_recipes/barplot.jl index b62164c1f15..05cb205ebf9 100644 --- a/src/basic_recipes/barplot.jl +++ b/src/basic_recipes/barplot.jl @@ -57,7 +57,7 @@ function bar_rectangle(x, y, width, fillto, in_y_direction) ymin = min(fillto, y) ymax = max(fillto, y) w = abs(width) - rect = Rectf(x - (w / 2f0), ymin, w, ymax - ymin) + rect = Rect(x - (w / 2), ymin, w, ymax - ymin) return in_y_direction ? rect : flip(rect) end @@ -173,7 +173,7 @@ function barplot_labels(xpositions, ypositions, bar_labels, in_y_direction, flip if length(bar_labels) == length(xpositions) attributes = text_attributes(ypositions, in_y_direction, flip_labels_at, color_over_background, color_over_bar, label_offset) label_pos = map(xpositions, ypositions, bar_labels) do x, y, l - return (string(l), in_y_direction ? Point2f(x, y) : Point2f(y, x)) + return (string(l), in_y_direction ? Point2(x, y) : Point2(y, x)) end return (label_pos, attributes...) else @@ -185,8 +185,8 @@ function barplot_labels(xpositions, ypositions, bar_labels, in_y_direction, flip end function Makie.plot!(p::BarPlot) - - labels = Observable(Tuple{String, Point2f}[]) + FT = floattype(p[1]) + labels = Observable(Tuple{String, Point2{FT}}[]) label_aligns = Observable(Vec2f[]) label_offsets = Observable(Vec2f[]) label_colors = Observable(RGBAf[]) diff --git a/src/basic_recipes/bracket.jl b/src/basic_recipes/bracket.jl index 3260a54c24c..0ad354945b0 100644 --- a/src/basic_recipes/bracket.jl +++ b/src/basic_recipes/bracket.jl @@ -31,11 +31,11 @@ $(ATTRIBUTES) ) end -Makie.convert_arguments(::Type{<:Bracket}, point1::VecTypes, point2::VecTypes) = ([(Point2f(point1), Point2f(point2))],) -Makie.convert_arguments(::Type{<:Bracket}, x1::Real, y1::Real, x2::Real, y2::Real) = ([(Point2f(x1, y1), Point2f(x2, y2))],) +Makie.convert_arguments(::Type{<:Bracket}, point1::VecTypes, point2::VecTypes) = ([(Point2(point1), Point2(point2))],) +Makie.convert_arguments(::Type{<:Bracket}, x1::Real, y1::Real, x2::Real, y2::Real) = ([(Point2(x1, y1), Point2(x2, y2))],) function Makie.convert_arguments(::Type{<:Bracket}, x1::AbstractVector{<:Real}, y1::AbstractVector{<:Real}, x2::AbstractVector{<:Real}, y2::AbstractVector{<:Real}) points = broadcast(x1, y1, x2, y2) do x1, y1, x2, y2 - (Point2f(x1, y1), Point2f(x2, y2)) + (Point2(x1, y1), Point2(x2, y2)) end (points,) end diff --git a/src/basic_recipes/buffers.jl b/src/basic_recipes/buffers.jl index 823ddbcae32..05d41fee024 100644 --- a/src/basic_recipes/buffers.jl +++ b/src/basic_recipes/buffers.jl @@ -4,17 +4,17 @@ efficiently append + push new values to them =# function LinesegmentBuffer( - scene::SceneLike, ::Type{Point{N}} = Point{2}; + scene::SceneLike, ::Type{PT} = Point2f; color = RGBAf[], linewidth = Float32[], kw_args... - ) where N + ) where PT <: Point linesegments!( - scene, Point{N, Float32}[]; color = color, + scene, PT[]; color = color, linewidth = linewidth, kw_args... ) end -function append!(lsb::LineSegments, positions::Vector{Point{N, Float32}}; color = :black, linewidth = 1.0) where N +function append!(lsb::LineSegments, positions::Vector{<: Point}; color = :black, linewidth = 1.0) thickv = same_length_array(positions, linewidth, key"linewidth"()) colorv = same_length_array(positions, color, key"color"()) append!(lsb[1][], positions) @@ -23,7 +23,7 @@ function append!(lsb::LineSegments, positions::Vector{Point{N, Float32}}; color return end -function push!(tb::LineSegments, positions::Point{N, Float32}; kw_args...) where N +function push!(tb::LineSegments, positions::Point; kw_args...) append!(tb, [positions]; kw_args...) end @@ -43,16 +43,16 @@ function finish!(lsb::LineSegments) end function TextBuffer( - scene::SceneLike, ::Type{Point{N}} = Point{2}; + scene::SceneLike, ::Type{PT} = Point2f; rotation = [Quaternionf(0,0,0,1)], color = RGBAf[RGBAf(0,0,0,0)], fontsize = Float32[0], font = [defaultfont()], align = [Vec2f(0)], kw_args... - ) where N + ) where PT <: Point annotations!( - scene, String[" "], [Point{N, Float32}(0)]; + scene, String[" "], [PT(0)]; rotation = rotation, color = color, fontsize = fontsize, @@ -82,17 +82,20 @@ function finish!(tb::Annotations) end -function push!(tb::Annotations, text::String, position::VecTypes{N}; kw_args...) where N - append!(tb, [(String(text), Point{N, Float32}(position))]; kw_args...) +function push!( + tb::Annotations{Tuple{Vector{Tuple{String, Point{N, T}}}}}, + text::String, position::VecTypes{N}; kw_args... + ) where {N, T} + append!(tb, [(String(text), Point{N, T}(position))]; kw_args...) end -function append!(tb::Annotations, text::Vector{String}, positions::Vector{Point{N, Float32}}; kw_args...) where N +function append!(tb::Annotations, text::Vector{String}, positions::Vector{<: Point}; kw_args...) text_positions = convert_argument(Annotations, text, positions)[1] append!(tb, text_positions; kw_args...) return end -function append!(tb::Annotations, text_positions::Vector{Tuple{String, Point{N, Float32}}}; kw_args...) where N +function append!(tb::Annotations, text_positions::Vector{Tuple{String, PT}}; kw_args...) where PT <: Point append!(tb[1][], text_positions) kw = Dict(kw_args) for key in (:color, :rotation, :fontsize, :font, :align) diff --git a/src/basic_recipes/contourf.jl b/src/basic_recipes/contourf.jl index 60eb88ec6e6..02613d20660 100644 --- a/src/basic_recipes/contourf.jl +++ b/src/basic_recipes/contourf.jl @@ -48,24 +48,24 @@ end # _computed_extendhigh function _get_isoband_levels(levels::Int, mi, ma) - edges = Float32.(LinRange(mi, ma, levels+1)) + return collect(LinRange(mi, ma, levels+1)) end function _get_isoband_levels(levels::AbstractVector{<:Real}, mi, ma) - edges = Float32.(levels) + edges = convert_single_argument(levels) @assert issorted(edges) - edges + return edges end conversion_trait(::Type{<:Contourf}) = ContinuousSurface() function _get_isoband_levels(::Val{:normal}, levels, values) - _get_isoband_levels(levels, extrema_nan(values)...) + return _get_isoband_levels(levels, extrema_nan(values)...) end function _get_isoband_levels(::Val{:relative}, levels::AbstractVector, values) mi, ma = extrema_nan(values) - Float32.(levels .* (ma - mi) .+ mi) + return convert_single_argument(levels .* (ma - mi) .+ mi) end @@ -93,29 +93,31 @@ function Makie.plot!(c::Contourf{<:Tuple{<:AbstractVector{<:Real}, <:AbstractVec c.attributes[:_computed_extendhigh] = highcolor is_extended_high = lift(!isnothing, c, highcolor) - PolyType = typeof(Polygon(Point2f[], [Point2f[]])) + PolyType = typeof(Polygon(Point2e[], [Point2e[]])) polys = Observable(PolyType[]) colors = Observable(Float64[]) - function calculate_polys(xs, ys, zs, levels::Vector{Float32}, is_extended_low, is_extended_high) + function calculate_polys(xs, ys, zs, levels::Vector{<:Real}, is_extended_low, is_extended_high) empty!(polys[]) empty!(colors[]) levels = copy(levels) @assert issorted(levels) + is_extended_low && pushfirst!(levels, -Inf) is_extended_high && push!(levels, Inf) lows = levels[1:end-1] highs = levels[2:end] # zs needs to be transposed to match rest of makie - isos = Isoband.isobands(xs, ys, zs', lows, highs) + # this converts each input to Float64 and always returns Float64's + isos = Isoband.isobands(xs, ys, zs', lows, highs) levelcenters = (highs .+ lows) ./ 2 for (i, (center, group)) in enumerate(zip(levelcenters, isos)) - points = Point2f.(group.x, group.y) + points = Point2.(group.x, group.y) polygroups = _group_polys(points, group.id) for polygroup in polygroups outline = polygroup[1] @@ -180,7 +182,7 @@ function _group_polys(points, ids) # each group has first an outer polygon, and then its holes # TODO: don't specifically type this 2f0? - groups = Vector{Vector{Point2f}}[] + groups = Vector{Vector{Point2e}}[] # a dict that maps index in `polys` to index in `groups` for outer polys outerindex_groupdict = Dict{Int, Int}() diff --git a/src/basic_recipes/contours.jl b/src/basic_recipes/contours.jl index e0a9d98e748..df5b578090f 100644 --- a/src/basic_recipes/contours.jl +++ b/src/basic_recipes/contours.jl @@ -56,49 +56,49 @@ $(ATTRIBUTES) default_theme(scene, Contour) end -angle(p1::Union{Vec2f,Point2f}, p2::Union{Vec2f,Point2f})::Float32 = +angle(p1::VecTypes{2, T}, p2::VecTypes{2, T}) where T = atan(p2[2] - p1[2], p2[1] - p1[1]) # result in [-π, π] -function label_info(lev, vertices, col) +function label_info(level, vertices::Vector{<: VecTypes{N, FT}}, color) where {N, FT} mid = ceil(Int, 0.5f0 * length(vertices)) - pts = (vertices[max(firstindex(vertices), mid - 1)], vertices[mid], vertices[min(mid + 1, lastindex(vertices))]) - ( - lev, - map(p -> to_ndim(Point3f, p, lev), Tuple(pts)), - col, + pts = ( + to_ndim(Point3{FT}, vertices[max(firstindex(vertices), mid - 1)], level), + to_ndim(Point3{FT}, vertices[mid], level), + to_ndim(Point3{FT}, vertices[min(mid + 1, lastindex(vertices))], level) ) + return (level, pts, color) end -function contourlines(::Type{<: Contour}, contours, cols, labels) - points = Point2f[] +function contourlines(::Type{<: Contour}, contours, cols, labels, FT::Type) + points = Point2{FT}[] colors = RGBA{Float32}[] - lev_pos_col = Tuple{Float32,NTuple{3,Point2f},RGBA{Float32}}[] + lev_pos_col = Tuple{FT, NTuple{3, Point2{FT}}, RGBA{Float32}}[] for (color, c) in zip(cols, Contours.levels(contours)) for elem in Contours.lines(c) append!(points, elem.vertices) - push!(points, Point2f(NaN32)) + push!(points, Point2{FT}(NaN)) append!(colors, fill(color, length(elem.vertices) + 1)) labels && push!(lev_pos_col, label_info(c.level, elem.vertices, color)) end end - points, colors, lev_pos_col + return points, colors, lev_pos_col end -function contourlines(::Type{<: Contour3d}, contours, cols, labels) - points = Point3f[] +function contourlines(::Type{<: Contour3d}, contours, cols, labels, FT::Type) + points = Point3{FT}[] colors = RGBA{Float32}[] - lev_pos_col = Tuple{Float32,NTuple{3,Point3f},RGBA{Float32}}[] + lev_pos_col = Tuple{FT, NTuple{3, Point3{FT}}, RGBA{Float32}}[] for (color, c) in zip(cols, Contours.levels(contours)) for elem in Contours.lines(c) for p in elem.vertices - push!(points, to_ndim(Point3f, p, c.level)) + push!(points, to_ndim(Point3{FT}, p, c.level)) end - push!(points, Point3f(NaN32)) + push!(points, Point3{FT}(NaN)) append!(colors, fill(color, length(elem.vertices) + 1)) labels && push!(lev_pos_col, label_info(c.level, elem.vertices, color)) end end - points, colors, lev_pos_col + return points, colors, lev_pos_col end to_levels(x::AbstractVector{<: Number}, cnorm) = x @@ -207,15 +207,16 @@ function plot!(plot::T) where T <: Union{Contour, Contour3d} @extract plot (labels, labelsize, labelfont, labelcolor, labelformatter) args = @extract plot (color, colormap, colorrange, alpha) level_colors = lift(color_per_level, plot, args..., levels) + FT = floattype(x, y, z, levels) + cont_lines = lift(plot, x, y, z, levels, level_colors, labels) do x, y, z, levels, level_colors, labels - t = eltype(z) # Compute contours - xv, yv = to_vector(x, size(z, 1), t), to_vector(y, size(z, 2), t) - contours = Contours.contours(xv, yv, z, convert(Vector{t}, levels)) - contourlines(T, contours, level_colors, labels) + xv, yv = to_vector(x, size(z, 1), FT), to_vector(y, size(z, 2), FT) + contours = Contours.contours(xv, yv, z, convert(Vector{FT}, levels)) + contourlines(T, contours, level_colors, labels, FT) end - P = T <: Contour ? Point2f : Point3f + P = T <: Contour ? Point2{FT} : Point3{FT} scene = parent_scene(plot) space = plot.space[] @@ -238,7 +239,7 @@ function plot!(plot::T) where T <: Union{Contour, Contour3d} col = texts.color.val; empty!(col) lbl = texts.text.val; empty!(lbl) for (lev, (p1, p2, p3), color) in lev_pos_col - rot_from_horz::Float32 = angle(project(scene, p1), project(scene, p3)) + rot_from_horz = Float32(angle(project(scene, p1), project(scene, p3))) # transition from an angle from horizontal axis in [-π; π] # to a readable text with a rotation from vertical axis in [-π / 2; π / 2] rot_from_vert::Float32 = if abs(rot_from_horz) > 0.5f0 * π @@ -270,7 +271,7 @@ function plot!(plot::T) where T <: Union{Contour, Contour3d} bb = bboxes[n] nlab = length(bboxes) masked = copy(segments) - nan = P(NaN32) + nan = P(NaN) for (i, p) in enumerate(segments) if isnan(p) && n < nlab bb = bboxes[n += 1] # next segment is materialized by a NaN, thus consider next label @@ -305,8 +306,8 @@ end function point_iterator(x::Contour{<: Tuple{X, Y, Z}}) where {X, Y, Z} axes = (x[1], x[2]) extremata = map(extrema∘to_value, axes) - minpoint = Point2f(first.(extremata)...) + minpoint = Point2(first.(extremata)...) widths = last.(extremata) .- first.(extremata) - rect = Rect2f(minpoint, Vec2f(widths)) + rect = Rect2(minpoint, Vec2(widths)) return unique(decompose(Point, rect)) end diff --git a/src/basic_recipes/error_and_rangebars.jl b/src/basic_recipes/error_and_rangebars.jl index edb5fd6564e..66b18be943a 100644 --- a/src/basic_recipes/error_and_rangebars.jl +++ b/src/basic_recipes/error_and_rangebars.jl @@ -63,48 +63,48 @@ end function Makie.convert_arguments(::Type{<:Errorbars}, x, y, error_both) xyerr = broadcast(x, y, error_both) do x, y, e - Vec4f(x, y, e, e) + Vec4(x, y, e, e) end (xyerr,) end function Makie.convert_arguments(::Type{<:Errorbars}, x, y, error_low, error_high) - xyerr = broadcast(Vec4f, x, y, error_low, error_high) + xyerr = broadcast(Vec4, x, y, error_low, error_high) (xyerr,) end function Makie.convert_arguments(::Type{<:Errorbars}, x, y, error_low_high::AbstractVector{<:VecTypes{2}}) xyerr = broadcast(x, y, error_low_high) do x, y, (el, eh) - Vec4f(x, y, el, eh) + Vec4(x, y, el, eh) end (xyerr,) end function Makie.convert_arguments(::Type{<:Errorbars}, xy::AbstractVector{<:VecTypes{2}}, error_both) xyerr = broadcast(xy, error_both) do (x, y), e - Vec4f(x, y, e, e) + Vec4(x, y, e, e) end (xyerr,) end function Makie.convert_arguments(::Type{<:Errorbars}, xy::AbstractVector{<:VecTypes{2}}, error_low, error_high) xyerr = broadcast(xy, error_low, error_high) do (x, y), el, eh - Vec4f(x, y, el, eh) + Vec4(x, y, el, eh) end (xyerr,) end function Makie.convert_arguments(::Type{<:Errorbars}, xy::AbstractVector{<:VecTypes{2}}, error_low_high::AbstractVector{<:VecTypes{2}}) xyerr = broadcast(xy, error_low_high) do (x, y), (el, eh) - Vec4f(x, y, el, eh) + Vec4(x, y, el, eh) end (xyerr,) end function Makie.convert_arguments(::Type{<:Errorbars}, xy_error_both::AbstractVector{<:VecTypes{3}}) xyerr = broadcast(xy_error_both) do (x, y, e) - Vec4f(x, y, e, e) + Vec4(x, y, e, e) end (xyerr,) end @@ -112,13 +112,13 @@ end ### conversions for rangebars function Makie.convert_arguments(::Type{<:Rangebars}, val, low, high) - val_low_high = broadcast(Vec3f, val, low, high) + val_low_high = broadcast(Vec3, val, low, high) (val_low_high,) end function Makie.convert_arguments(::Type{<:Rangebars}, val, low_high) val_low_high = broadcast(val, low_high) do val, (low, high) - Vec3f(val, low, high) + Vec3(val, low, high) end (val_low_high,) end @@ -143,8 +143,8 @@ function Makie.plot!(plot::Errorbars{T}) where T <: Tuple{AbstractVector{<:VecTy linesegpairs = lift(plot, x_y_low_high, is_in_y_direction) do x_y_low_high, in_y return map(x_y_low_high) do (x, y, l, h) in_y ? - (Point2f(x, y - l), Point2f(x, y + h)) : - (Point2f(x - l, y), Point2f(x + h, y)) + (Point2(x, y - l), Point2(x, y + h)) : + (Point2(x - l, y), Point2(x + h, y)) end end @@ -169,8 +169,8 @@ function Makie.plot!(plot::Rangebars{T}) where T <: Tuple{AbstractVector{<:VecTy linesegpairs = lift(plot, val_low_high, is_in_y_direction) do vlh, in_y return map(vlh) do (v, l, h) in_y ? - (Point2f(v, l), Point2f(v, h)) : - (Point2f(l, v), Point2f(h, v)) + (Point2(v, l), Point2(v, h)) : + (Point2(l, v), Point2(h, v)) end end @@ -234,32 +234,21 @@ function _plot_bars!(plot, linesegpairs, is_in_y_direction) plot end -function scene_to_screen(pts, scene) - p4 = to_ndim.(Vec4f, to_ndim.(Vec3f, pts, 0.0), 1.0) - p1m1 = Ref(scene.camera.projectionview[]) .* p4 - projected = Ref(inv(scene.camera.pixel_space[])) .* p1m1 - [Point2.(p[Vec(1, 2)]...) for p in projected] -end - -function screen_to_scene(pts, scene) - p4 = to_ndim.(Vec4f, to_ndim.(Vec3f, pts, 0.0), 1.0) - p1m1 = Ref(scene.camera.pixel_space[]) .* p4 - projected = Ref(inv(scene.camera.projectionview[])) .* p1m1 - [Point2.(p[Vec(1, 2)]...) for p in projected] -end +scene_to_screen(pts::AbstractArray, scene) = scene_to_screen.(pts, (scene,)) +screen_to_scene(pts::AbstractArray, scene) = screen_to_scene.(pts, (scene,)) -function scene_to_screen(p::T, scene) where T <: Point - p4 = to_ndim(Vec4f, to_ndim(Vec3f, p, 0.0), 1.0) +function scene_to_screen(p::Point{N, T}, scene) where {N, T} + p4 = to_ndim(Vec4{T}, to_ndim(Vec3{T}, p, 0.0), 1.0) p1m1 = scene.camera.projectionview[] * p4 projected = inv(scene.camera.pixel_space[]) * p1m1 - T(projected[Vec(1, 2)]...) + return Point{2, T}(projected[1], projected[2]) end -function screen_to_scene(p::T, scene) where T <: Point - p4 = to_ndim(Vec4f, to_ndim(Vec3f, p, 0.0), 1.0) +function screen_to_scene(p::Point{N, T}, scene) where {N, T} + p4 = to_ndim(Vec4{T}, to_ndim(Vec3{T}, p, 0.0), 1.0) p1m1 = scene.camera.pixel_space[] * p4 projected = inv(scene.camera.projectionview[]) * p1m1 - T(projected[Vec(1, 2)]...) + return Point{2, T}(projected[1], projected[2]) end # ignore whiskers when determining data limits diff --git a/src/basic_recipes/hvlines.jl b/src/basic_recipes/hvlines.jl index a7ead9e9d09..c4ef760c508 100644 --- a/src/basic_recipes/hvlines.jl +++ b/src/basic_recipes/hvlines.jl @@ -41,8 +41,8 @@ end function projview_to_2d_limits(pv) xmin, xmax = minmax((((-1, 1) .- pv[1, 4]) ./ pv[1, 1])...) ymin, ymax = minmax((((-1, 1) .- pv[2, 4]) ./ pv[2, 2])...) - origin = Vec2f(xmin, ymin) - return Rect2f(origin, Vec2f(xmax, ymax) - origin) + origin = Vec2(xmin, ymin) + return Rect2(origin, Vec2(xmax, ymax) - origin) end function Makie.plot!(p::Union{HLines, VLines}) @@ -50,9 +50,10 @@ function Makie.plot!(p::Union{HLines, VLines}) transf = transform_func_obs(scene) limits = lift(projview_to_2d_limits, p, scene.camera.projectionview) - - points = Observable(Point2f[]) - + + ET = floattype(p[1]) + points = Observable(Point2{ET}[]) + mi = p isa HLines ? p.xmin : p.ymin ma = p isa HLines ? p.xmax : p.ymax @@ -67,15 +68,15 @@ function Makie.plot!(p::Union{HLines, VLines}) x_ma = min_x + (max_x - min_x) * ma x_mi = _apply_x_transform(inv, x_mi) x_ma = _apply_x_transform(inv, x_ma) - push!(points[], Point2f(x_mi, val)) - push!(points[], Point2f(x_ma, val)) + push!(points[], Point2{ET}(x_mi, val)) + push!(points[], Point2{ET}(x_ma, val)) elseif p isa VLines y_mi = min_y + (max_y - min_y) * mi y_ma = min_y + (max_y - min_y) * ma y_mi = _apply_y_transform(inv, y_mi) y_ma = _apply_y_transform(inv, y_ma) - push!(points[], Point2f(val, y_mi)) - push!(points[], Point2f(val, y_ma)) + push!(points[], Point2{ET}(val, y_mi)) + push!(points[], Point2{ET}(val, y_ma)) end end notify(points) diff --git a/src/basic_recipes/hvspan.jl b/src/basic_recipes/hvspan.jl index 18ac06bdae4..c038981596b 100644 --- a/src/basic_recipes/hvspan.jl +++ b/src/basic_recipes/hvspan.jl @@ -44,8 +44,9 @@ function Makie.plot!(p::Union{HSpan, VSpan}) limits = lift(projview_to_2d_limits, scene.camera.projectionview) - rects = Observable(Rect2f[]) - + ET = floattype(p[1], p[2]) + rects = Observable(Rect2{ET}[]) + mi = p isa HSpan ? p.xmin : p.ymin ma = p isa HSpan ? p.xmax : p.ymax @@ -60,13 +61,13 @@ function Makie.plot!(p::Union{HSpan, VSpan}) x_ma = min_x + (max_x - min_x) * ma x_mi = _apply_x_transform(inv, x_mi) x_ma = _apply_x_transform(inv, x_ma) - push!(rects[], Rect2f(Point2f(x_mi, low), Vec2f(x_ma - x_mi, high - low))) + push!(rects[], Rect2{ET}(Point2(x_mi, low), Vec2(x_ma - x_mi, high - low))) elseif p isa VSpan y_mi = min_y + (max_y - min_y) * mi y_ma = min_y + (max_y - min_y) * ma y_mi = _apply_y_transform(inv, y_mi) y_ma = _apply_y_transform(inv, y_ma) - push!(rects[], Rect2f(Point2f(low, y_mi), Vec2f(high - low, y_ma - y_mi))) + push!(rects[], Rect2{ET}(Point2(low, y_mi), Vec2(high - low, y_ma - y_mi))) end end notify(rects) diff --git a/src/basic_recipes/pie.jl b/src/basic_recipes/pie.jl index e13033d39e9..44346080d10 100644 --- a/src/basic_recipes/pie.jl +++ b/src/basic_recipes/pie.jl @@ -22,7 +22,7 @@ $(ATTRIBUTES) ) end -function plot!(plot::Pie) +function Makie.plot!(plot::Pie) values = plot[1] @@ -46,18 +46,18 @@ function plot!(plot::Pie) # curve points points = map(LinRange(sta, en, nvertices)) do rad - Point2f(cos(rad + offset), sin(rad + offset)) .* radius + Point2(radius * cos(rad + offset), radius * sin(rad + offset)) end # add inner points (either curve or one point) if inner_radius != 0 inner_points = map(LinRange(en, sta, nvertices)) do rad - Point2f(cos(rad + offset), sin(rad + offset)) .* inner_radius + Point2(inner_radius * cos(rad + offset), inner_radius * sin(rad + offset)) end append!(points, inner_points) else - push!(points, Point2f(0, 0)) + push!(points, eltype(points)(0, 0)) end points diff --git a/src/basic_recipes/poly.jl b/src/basic_recipes/poly.jl index 308bed0e5ca..463379201b7 100644 --- a/src/basic_recipes/poly.jl +++ b/src/basic_recipes/poly.jl @@ -67,21 +67,19 @@ to_lines(polygon) = convert_arguments(Lines, polygon)[1] to_lines(polygon::GeometryBasics.Mesh) = convert_arguments(PointBased(), polygon)[1] function to_lines(meshes::AbstractVector) - line = Point2f[] - for (i, mesh) in enumerate(meshes) + # TODO: handle empty inputs better + line = isempty(meshes) ? Point2f[] : to_lines(meshes[1]) + PT = eltype(line) + for mesh in view(meshes, 2:length(meshes)) points = to_lines(mesh) + push!(line, PT(NaN)) append!(line, points) - # push!(line, points[1]) - # dont need to separate the last line segment - if i != length(meshes) - push!(line, Point2f(NaN)) - end end return line end -function to_lines(polygon::AbstractVector{<: VecTypes}) - result = Point2f.(polygon) +function to_lines(polygon::AbstractVector{<: VecTypes{2, T}}) where T + result = Point2{T}.(polygon) push!(result, polygon[1]) return result end diff --git a/src/basic_recipes/series.jl b/src/basic_recipes/series.jl index a0375a0790a..9e441de2465 100644 --- a/src/basic_recipes/series.jl +++ b/src/basic_recipes/series.jl @@ -44,13 +44,13 @@ end function convert_arguments(::Type{<: Series}, x::AbstractVector, ys::AbstractMatrix) return (map(1:size(ys, 1)) do i - Point2f.(replace_missing.(x), replace_missing.(view(ys, i, :))) + Point2.(replace_missing.(x), replace_missing.(view(ys, i, :))) end,) end function convert_arguments(::Type{<: Series}, arg::AbstractVector{<: Tuple{X, Y}}) where {X, Y} return (map(arg) do (x, y) - Point2f.(replace_missing.(x), replace_missing.(y)) + Point2.(replace_missing.(x), replace_missing.(y)) end,) end @@ -60,7 +60,7 @@ end function convert_arguments(::Type{<: Series}, arg::AbstractVector{<: AbstractVector{<:Point2}}) return (map(arg) do points - Point2f.(replace_missing.(first.(points)), replace_missing.(last.(points))) + Point2.(replace_missing.(first.(points)), replace_missing.(last.(points))) end,) end diff --git a/src/basic_recipes/spy.jl b/src/basic_recipes/spy.jl index 199867dd9fc..e57649df328 100644 --- a/src/basic_recipes/spy.jl +++ b/src/basic_recipes/spy.jl @@ -36,7 +36,7 @@ end function calculated_attributes!(::Type{<: Spy}, plot) end -function plot!(p::Spy) +function Makie.plot!(p::Spy) rect = lift(p, p.x, p.y) do x, y xe = extrema(x) ye = extrema(y) @@ -56,7 +56,7 @@ function plot!(p::Spy) xycol = lift(p, rect, p.z, markersize) do rect, z, markersize x, y, color = SparseArrays.findnz(z) points = map(x, y) do x, y - (((Point2f(x, y) .- 1) ./ Point2f(size(z) .- 1)) .* + (((Point2(x, y) .- 1) ./ Point2(size(z) .- 1)) .* widths(rect) .+ minimum(rect)) end points, convert(Vector{Float32}, color) diff --git a/src/basic_recipes/streamplot.jl b/src/basic_recipes/streamplot.jl index f26b4b9a9e6..b49ca7ffd02 100644 --- a/src/basic_recipes/streamplot.jl +++ b/src/basic_recipes/streamplot.jl @@ -43,8 +43,8 @@ function convert_arguments(::Type{<: StreamPlot}, f::Function, xrange, yrange, z xmin, xmax = extrema(xrange) ymin, ymax = extrema(yrange) zmin, zmax = extrema(zrange) - mini = Vec3f(xmin, ymin, zmin) - maxi = Vec3f(xmax, ymax, zmax) + mini = Vec3(xmin, ymin, zmin) + maxi = Vec3(xmax, ymax, zmax) return (f, Rect(mini, maxi .- mini)) end @@ -76,9 +76,9 @@ Links: function streamplot_impl(CallType, f, limits::Rect{N, T}, resolutionND, stepsize, maxsteps=500, dens=1.0) where {N, T} resolution = to_ndim(Vec{N, Int}, resolutionND, last(resolutionND)) mask = trues(resolution...) # unvisited squares - arrow_pos = Point{N, Float32}[] + arrow_pos = Point{N, T}[] arrow_dir = Vec{N, Float32}[] - line_points = Point{N, Float32}[] + line_points = Point{N, T}[] colors = Float64[] line_colors = Float64[] dt = Point{N, Float32}(stepsize) @@ -121,7 +121,7 @@ function streamplot_impl(CallType, f, limits::Rect{N, T}, resolutionND, stepsize n_linepoints = 1 x = x0 ccur = c - push!(line_points, Point{N, Float32}(NaN), x) + push!(line_points, Point{N, T}(NaN), x) push!(line_colors, 0.0, pnorm) while x in limits && n_linepoints < maxsteps point = apply_f(x, CallType) @@ -158,9 +158,9 @@ function streamplot_impl(CallType, f, limits::Rect{N, T}, resolutionND, stepsize ) end -function plot!(p::StreamPlot) +function Makie.plot!(p::StreamPlot) data = lift(p, p.f, p.limits, p.gridsize, p.stepsize, p.maxsteps, p.density) do f, limits, resolution, stepsize, maxsteps, density - P = if applicable(f, Point2f(0)) || applicable(f, Point3f(0)) + P = if any(p -> applicable(f, p), (Point2f(0), Point3f(0), Point2e(0), Point3e(0))) Point else Number diff --git a/src/basic_recipes/text.jl b/src/basic_recipes/text.jl index 4441dd082a9..70fe5c1b552 100644 --- a/src/basic_recipes/text.jl +++ b/src/basic_recipes/text.jl @@ -141,13 +141,13 @@ function plot!(plot::Text{<:Tuple{<:AbstractArray{<:AbstractString}}}) end # overload text plotting for a vector of tuples of a string and a point each -function plot!(plot::Text{<:Tuple{<:AbstractArray{<:Tuple{<:Any, <:Point}}}}) +function plot!(plot::Text{<:Tuple{<:AbstractArray{<:Tuple{<:Any, <:Point{N, T}}}}}) where {N, T} strings_and_positions = plot[1] strings = Observable{Vector{Any}}(first.(strings_and_positions[])) positions = Observable( - Point3f[to_ndim(Point3f, last(x), 0) for x in strings_and_positions[]] # avoid Any for zero elements + Point3{T}[to_ndim(Point3{T}, last(x), 0) for x in strings_and_positions[]] # avoid Any for zero elements ) attrs = plot.attributes @@ -158,7 +158,7 @@ function plot!(plot::Text{<:Tuple{<:AbstractArray{<:Tuple{<:Any, <:Point}}}}) # update both text and positions together on(strings_and_positions) do str_pos strs = first.(str_pos) - poss = to_ndim.(Ref(Point3f), last.(str_pos), 0) + poss = to_ndim.(Ref(Point3{T}), last.(str_pos), 0) strings.val != strs && (strings[] = strs) positions.val != poss && (positions[] = poss) diff --git a/src/basic_recipes/timeseries.jl b/src/basic_recipes/timeseries.jl index 7e7fc9ca8ed..ab9cf240d2a 100644 --- a/src/basic_recipes/timeseries.jl +++ b/src/basic_recipes/timeseries.jl @@ -27,7 +27,7 @@ end ) end -signal2point(signal::Number, start) = Point2f(time() - start, signal) +signal2point(signal::Number, start) = Point2(time() - start, signal) signal2point(signal::Point2, start) = signal signal2point(signal, start) = error(""" Signal needs to be of type Number or Point. Found: $(typeof(signal)) @@ -37,7 +37,7 @@ Found: $(typeof(signal)) function Makie.plot!(plot::TimeSeries) # normal plotting code, building on any previously defined recipes # or atomic plotting operations, and adding to the combined `plot`: - points = Observable(fill(Point2f(NaN), plot.history[])) + points = Observable(fill(Point2e(NaN), plot.history[])) buffer = copy(points[]) lines!(plot, points) start = time() diff --git a/src/basic_recipes/tooltip.jl b/src/basic_recipes/tooltip.jl index ae0a516f04c..83d33d86f75 100644 --- a/src/basic_recipes/tooltip.jl +++ b/src/basic_recipes/tooltip.jl @@ -70,8 +70,8 @@ Creates a tooltip pointing at `position` displaying the given `string` ) end -convert_arguments(::Type{<: Tooltip}, x::Real, y::Real, str::AbstractString) = (Point2f(x, y), str) -convert_arguments(::Type{<: Tooltip}, x::Real, y::Real) = (Point2f(x, y),) +convert_arguments(::Type{<: Tooltip}, x::Real, y::Real, str::AbstractString) = (Point2(x, y), str) +convert_arguments(::Type{<: Tooltip}, x::Real, y::Real) = (Point2(x, y),) function plot!(plot::Tooltip{<:Tuple{<:VecTypes, <:AbstractString}}) plot.attributes[:text] = plot[2] tooltip!(plot, plot[1]; plot.attributes...) diff --git a/src/basic_recipes/tricontourf.jl b/src/basic_recipes/tricontourf.jl index 9b98a876cbb..748e3e949cd 100644 --- a/src/basic_recipes/tricontourf.jl +++ b/src/basic_recipes/tricontourf.jl @@ -46,7 +46,7 @@ $(ATTRIBUTES) end function Makie.convert_arguments(::Type{<:Tricontourf}, x::AbstractVector{<:Real}, y::AbstractVector{<:Real}, z::AbstractVector{<:Real}) - map(x -> elconvert(Float32, x), (x, y, z)) + return map(convert_single_argument, (x, y, z)) end function compute_contourf_colormap(levels, cmap, elow, ehigh) @@ -112,12 +112,13 @@ function Makie.plot!(c::Tricontourf{<:Tuple{<:AbstractVector{<:Real},<:AbstractV c.attributes[:_computed_extendhigh] = highcolor is_extended_high = lift(!isnothing, c, c.extendhigh) - PolyType = typeof(Polygon(Point2f[], [Point2f[]])) + FT = floattype(xs, ys, zs) + PolyType = typeof(Polygon(Point2{FT}[], [Point2{FT}[]])) polys = Observable(PolyType[]) colors = Observable(Float64[]) - function calculate_polys(xs, ys, zs, levels::Vector{Float32}, is_extended_low, is_extended_high, triangulation) + function calculate_polys(xs, ys, zs, levels::Vector{<:AbstractFloat}, is_extended_low, is_extended_high, triangulation) empty!(polys[]) empty!(colors[]) @@ -138,7 +139,7 @@ function Makie.plot!(c::Tricontourf{<:Tuple{<:AbstractVector{<:Real},<:AbstractV for (fc, lc) in zip(filledcontours, levelcenters) pointvecs = map(fc.polylines) do vecs - map(Point2f, vecs) + map(Point2{FT}, vecs) end if isempty(pointvecs) continue diff --git a/src/basic_recipes/waterfall.jl b/src/basic_recipes/waterfall.jl index 0d83e40221f..52aa3cd2b6a 100644 --- a/src/basic_recipes/waterfall.jl +++ b/src/basic_recipes/waterfall.jl @@ -47,8 +47,8 @@ function Makie.plot!(p::Waterfall) for (grp, inds) in StructArrays.finduniquesorted(groupby) fromto = stack_from_to_final(i_stack[inds], y[inds]) fillto[inds] .= fromto.from - xy[inds] .= Point2f.(x[inds], fromto.to) - final[inds] .= Point2f.(x[inds], fromto.final) + xy[inds] .= Point2.(x[inds], fromto.to) + final[inds] .= Point2.(x[inds], fromto.final) end return (xy=xy, fillto=fillto, final=final) end diff --git a/src/basic_recipes/wireframe.jl b/src/basic_recipes/wireframe.jl index bbf6d271e0d..97acdf2a01f 100644 --- a/src/basic_recipes/wireframe.jl +++ b/src/basic_recipes/wireframe.jl @@ -29,7 +29,7 @@ yvector(x::AbstractMatrix, len) = x function plot!(plot::Wireframe{<: Tuple{<: Any, <: Any, <: AbstractMatrix}}) points_faces = lift(plot, plot[1:3]...) do x, y, z M, N = size(z) - points = vec(Point3f.(xvector(x, M), yvector(y, N), z)) + points = vec(Point3.(xvector(x, M), yvector(y, N), z)) # Connect the vetices with faces, as one would use for a 2D Rectangle # grid with M,N grid points faces = decompose(LineFace{GLIndex}, Tesselation(Rect2(0, 0, 1, 1), (M, N))) diff --git a/src/conversions.jl b/src/conversions.jl index b70cae607ef..150a3f88ef7 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -6,6 +6,23 @@ const RangeLike = Union{AbstractRange, AbstractVector, ClosedInterval} const NativeFloat = Union{Float64, Float32} const NativePoint = Point{N, T} where {N, T <: NativeFloat} +floattype(::Type{Float64}) = Float64 +floattype(::Type{<: Real}) = Float32 +floattype(::T) where T <: Real = floattype(T) +floattype(::VecTypes{N, T}) where {N, T <: Real} = floattype(T) +floattype(::AbstractArray{T}) where T <: Real = floattype(T) +floattype(::AbstractArray{VT}) where {N, T <: Real, VT <: VecTypes{N, T}} = floattype(T) +floattype(::Rect{N, T}) where {N, T <: Real} = floattype(T) +floattype(x::Observable) = floattype(x[]) +function floattype(a, others...) + if floattype(a) === Float64 + return Float64 + else + return floattype(others...) + end +end + + # if no plot type based conversion is defined, we try using a trait function convert_arguments(T::PlotFunc, args...; kw...) ct = conversion_trait(T) diff --git a/src/layouting/layouting.jl b/src/layouting/layouting.jl index d71fe598d4e..8c4f4d4f608 100644 --- a/src/layouting/layouting.jl +++ b/src/layouting/layouting.jl @@ -302,9 +302,9 @@ _offset_to_vec(o::Vector) = to_ndim.(Vec3f, o, 0) Base.getindex(x::ScalarOrVector, i) = x.sv isa Vector ? x.sv[i] : x.sv Base.lastindex(x::ScalarOrVector) = x.sv isa Vector ? length(x.sv) : 1 -function text_quads(atlas::TextureAtlas, position::VecTypes, gc::GlyphCollection, offset, transfunc, space) +function text_quads(atlas::TextureAtlas, position::VecTypes{N, T}, gc::GlyphCollection, offset, transfunc, space) where {N, T} p = apply_transform(transfunc, position, space) - pos = [to_ndim(Point3f, p, 0) for _ in gc.origins] + pos = [to_ndim(Point3{T}, p, 0) for _ in gc.origins] pad = atlas.glyph_padding / atlas.pix_per_glyph off = _offset_to_vec(offset) @@ -325,6 +325,7 @@ function text_quads(atlas::TextureAtlas, position::VecTypes, gc::GlyphCollection end # pos is the (space) position given to text (with transfunc applied) + # (keep float type for further processing in the backend) # char_offsets are 3D offsets in marker space, including: # - offsets passed to text # - character origins (relative to the string origin pos) @@ -335,9 +336,9 @@ function text_quads(atlas::TextureAtlas, position::VecTypes, gc::GlyphCollection return pos, char_offsets, quad_offsets, uvs, scales end -function text_quads(atlas::TextureAtlas, position::Vector, gcs::Vector{<: GlyphCollection}, offset, transfunc, space) +function text_quads(atlas::TextureAtlas, position::Vector{<: VecTypes{N, T}}, gcs::Vector{<: GlyphCollection}, offset, transfunc, space) where {N, T} ps = apply_transform(transfunc, position, space) - pos = [to_ndim(Point3f, p, 0) for (p, gc) in zip(ps, gcs) for _ in gc.origins] + pos = [to_ndim(Point3{T}, p, 0) for (p, gc) in zip(ps, gcs) for _ in gc.origins] pad = atlas.glyph_padding / atlas.pix_per_glyph off = _offset_to_vec(offset) diff --git a/src/stats/boxplot.jl b/src/stats/boxplot.jl index 33d11eeeefc..f58849e037a 100644 --- a/src/stats/boxplot.jl +++ b/src/stats/boxplot.jl @@ -75,12 +75,13 @@ conversion_trait(x::Type{<:BoxPlot}) = SampleBased() _cycle(v::AbstractVector, idx::Integer) = v[mod1(idx, length(v))] _cycle(v, idx::Integer) = v -flip_xy(p::Point2f) = reverse(p) +flip_xy(p::Point2) = reverse(p) flip_xy(r::Rect{2,T}) where {T} = Rect{2,T}(reverse(r.origin), reverse(r.widths)) function Makie.plot!(plot::BoxPlot) args = @extract plot (weights, width, range, show_outliers, whiskerwidth, show_notch, orientation, gap, dodge, n_dodge, dodge_gap) + FT = floattype(plot[1], plot[2]) signals = lift( plot, plot[1], @@ -93,14 +94,14 @@ function Makie.plot!(plot::BoxPlot) error("whiskerwidth must be :match or a positive number. Found: $whiskerwidth") end ww = whiskerwidth === :match ? boxwidth : whiskerwidth * boxwidth - outlier_points = Point2f[] - centers = Float32[] - medians = Float32[] - boxmin = Float32[] - boxmax = Float32[] - notchmin = Float32[] - notchmax = Float32[] - t_segments = Point2f[] + outlier_points = Point2{FT}[] + centers = FT[] + medians = FT[] + boxmin = FT[] + boxmax = FT[] + notchmin = FT[] + notchmax = FT[] + t_segments = Point2{FT}[] outlier_indices = Int[] T = color isa AbstractVector ? eltype(color) : typeof(color) boxcolor = T[] diff --git a/src/stats/crossbar.jl b/src/stats/crossbar.jl index 6bcd61abb03..f6768b538b8 100644 --- a/src/stats/crossbar.jl +++ b/src/stats/crossbar.jl @@ -53,6 +53,7 @@ end function Makie.plot!(plot::CrossBar) args = @extract plot (width, dodge, n_dodge, gap, dodge_gap, show_notch, notchmin, notchmax, notchwidth, orientation) + FT = floattype(plot[1], plot[2], plot[3], plot[4]) signals = lift( plot, plot[1], @@ -65,7 +66,7 @@ function Makie.plot!(plot::CrossBar) show_notch = show_notch && (nmin !== automatic && nmax !== automatic) # for horizontal crossbars just flip all components - fpoint, frect = Point2f, Rectf + fpoint, frect = Point2{FT}, Rect{2, FT} if orientation === :horizontal fpoint, frect = flip_xy ∘ fpoint, flip_xy ∘ frect end diff --git a/src/stats/density.jl b/src/stats/density.jl index 2d667196268..ae9685afe91 100644 --- a/src/stats/density.jl +++ b/src/stats/density.jl @@ -4,10 +4,11 @@ function convert_arguments(P::PlotFunc, d::KernelDensity.UnivariateKDE) end function convert_arguments(::Type{<:Poly}, d::KernelDensity.UnivariateKDE) - points = Vector{Point2f}(undef, length(d.x) + 2) - points[1] = Point2f(d.x[1], 0) - points[2:end-1] .= Point2f.(d.x, d.density) - points[end] = Point2f(d.x[end], 0) + # d.density is always Float64 + points = Vector{Point2e}(undef, length(d.x) + 2) + points[1] = Point2e(d.x[1], 0) + points[2:end-1] .= Point2e.(d.x, d.density) + points[end] = Point2e(d.x[end], 0) (points,) end @@ -53,7 +54,7 @@ $(ATTRIBUTES) ) end -function plot!(plot::Density{<:Tuple{<:AbstractVector}}) +function Makie.plot!(plot::Density{<:Tuple{<:AbstractVector}}) x = plot[1] lowerupper = lift(plot, x, plot.direction, plot.boundary, plot.offset, @@ -67,11 +68,11 @@ function plot!(plot::Density{<:Tuple{<:AbstractVector}}) ) if dir === :x - lowerv = Point2f.(k.x, offs) - upperv = Point2f.(k.x, offs .+ k.density) + lowerv = Point2.(k.x, offs) + upperv = Point2.(k.x, offs .+ k.density) elseif dir === :y - lowerv = Point2f.(offs, k.x) - upperv = Point2f.(offs .+ k.density, k.x) + lowerv = Point2.(offs, k.x) + upperv = Point2.(offs .+ k.density, k.x) else error("Invalid direction $dir, only :x or :y allowed") end @@ -90,14 +91,13 @@ function plot!(plot::Density{<:Tuple{<:AbstractVector}}) end end - lower = Observable(Point2f[]) - upper = Observable(Point2f[]) + lower = Observable(first(lowerupper[])) + upper = Observable(last(lowerupper[])) on(plot, lowerupper) do (l, u) lower.val = l upper[] = u end - notify(lowerupper) colorobs = Observable{RGBColors}() map!(plot, colorobs, plot.color, lowerupper, plot.direction) do c, lu, dir diff --git a/src/stats/distributions.jl b/src/stats/distributions.jl index 0e219fb0bd9..ceaed6d290e 100644 --- a/src/stats/distributions.jl +++ b/src/stats/distributions.jl @@ -90,8 +90,8 @@ function fit_qqplot(x, y; qqline = :none) throw(ArgumentError(msg)) end h = qqbuild(x, y) - points = Point2f.(h.qx, h.qy) - qqline === :none && return points, Point2f[] + points = Point2.(h.qx, h.qy) + qqline === :none && return points, eltype(points)[] xs = collect(extrema(h.qx)) if qqline === :identity ys = xs @@ -103,7 +103,7 @@ function fit_qqplot(x, y; qqline = :none) slp = (quanty[2] - quanty[1]) / (quantx[2] - quantx[1]) ys = @. quanty + slp * (xs - quantx) end - return points, Point2f.(xs, ys) + return points, eltype(points).(xs, ys) end # Fit distribution type, otherwise leave first argument unchanged diff --git a/src/stats/hexbin.jl b/src/stats/hexbin.jl index 47150e0c9e9..1ab9e0aba34 100644 --- a/src/stats/hexbin.jl +++ b/src/stats/hexbin.jl @@ -58,21 +58,22 @@ end Makie.conversion_trait(::Type{<:Hexbin}) = PointBased() function data_limits(hb::Hexbin) - bb = Rect3f(hb.plots[1][1][]) - fn(num::Real) = Float32(num) - fn(tup::Union{Tuple,Vec2}) = Vec2f(tup...) + bb = Rect3(hb.plots[1][1][]) + fn(num::Real) = Float64(num) + fn(tup::Union{Tuple,Vec2}) = Vec2(tup...) ms = 2 .* fn(hb.plots[1].markersize[]) nw = widths(bb) .+ (ms..., 0.0f0) no = bb.origin .- ((ms ./ 2.0f0)..., 0.0f0) - return Rect3f(no, nw) + return Rect3(no, nw) end function Makie.plot!(hb::Hexbin{<:Tuple{<:AbstractVector{<:Point2}}}) xy = hb[1] - points = Observable(Point2f[]) + FT = floattype(xy) + points = Observable(Point2{FT}[]) count_hex = Observable(Float64[]) markersize = Observable(Vec2f(1, 1)) @@ -142,7 +143,7 @@ function Makie.plot!(hb::Hexbin{<:Tuple{<:AbstractVector{<:Point2}}}) _x = xoff + 2 * ix * xspacing + (isodd(iy) * xspacing) _y = yoff + iy * yspacing c = get(d, (ix, iy), 0) - push!(points[], Point2f(_x, _y)) + push!(points[], Point2{FT}(_x, _y)) push!(count_hex[], scale(c)) end end @@ -152,7 +153,7 @@ function Makie.plot!(hb::Hexbin{<:Tuple{<:AbstractVector{<:Point2}}}) if value >= threshold _x = xoff + 2 * ix * xspacing + (isodd(iy) * xspacing) _y = yoff + iy * yspacing - push!(points[], Point2f(_x, _y)) + push!(points[], Point2{FT}(_x, _y)) push!(count_hex[], scale(value)) end end diff --git a/src/stats/hist.jl b/src/stats/hist.jl index bf5cd7e5bf8..f0a5f58e49e 100644 --- a/src/stats/hist.jl +++ b/src/stats/hist.jl @@ -63,7 +63,7 @@ function Makie.plot!(plot::StepHist) edges = vcat(edges, phantomedge) z = zero(eltype(weights)) heights = vcat(z, weights, z) - return Point2f.(edges, heights) + return Point2.(edges, heights) end color = lift(plot, plot.color) do color if color === :values @@ -165,7 +165,7 @@ function Makie.plot!(plot::Hist) points = lift(plot, edges, plot.normalization, plot.scale_to, plot.weights) do edges, normalization, scale_to, wgts centers, weights = _hist_center_weights(values, edges, normalization, scale_to, wgts) - return Point2f.(centers, weights) + return Point2.(centers, weights) end widths = lift(diff, plot, edges) color = lift(plot, plot.color) do color diff --git a/src/stats/violin.jl b/src/stats/violin.jl index ef6e6f5ff99..08c3e1bb76d 100644 --- a/src/stats/violin.jl +++ b/src/stats/violin.jl @@ -47,17 +47,18 @@ function getuniquevalue(v::AbstractVector, idxs) return f end -function plot!(plot::Violin) +function Makie.plot!(plot::Violin) x, y = plot[1], plot[2] args = @extract plot (width, side, color, show_median, npoints, boundary, bandwidth, weights, datalimits, max_density, dodge, n_dodge, gap, dodge_gap, orientation) + FT = floattype(x, y) signals = lift(plot, x, y, args...) do x, y, width, vside, color, show_median, n, bound, bw, w, limits, max_density, dodge, n_dodge, gap, dodge_gap, orientation x̂, violinwidth = compute_x_and_width(x, width, gap, dodge, n_dodge, dodge_gap) # for horizontal violin just flip all componentes - point_func = Point2f + point_func = Point2{FT} if orientation === :horizontal point_func = flip_xy ∘ point_func end @@ -93,8 +94,8 @@ function plot!(plot::Violin) max_density end - vertices = Vector{Point2f}[] - lines = Pair{Point2f, Point2f}[] + vertices = Vector{Point2{FT}}[] + lines = Pair{Point2{FT}, Point2{FT}}[] colors = RGBA{Float32}[] for spec in specs From c2daeaf208b942ad2c5e53a8dc3c0086bb6d6ee5 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Thu, 8 Jun 2023 15:48:21 +0200 Subject: [PATCH 49/49] fix test failures --- src/basic_recipes/arrows.jl | 19 +++++++++++++------ src/basic_recipes/bracket.jl | 15 +++++++++++---- src/basic_recipes/error_and_rangebars.jl | 4 ++-- src/basic_recipes/streamplot.jl | 10 ++++++---- src/stats/hexbin.jl | 12 ++++++++---- 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/basic_recipes/arrows.jl b/src/basic_recipes/arrows.jl index 1af61eebea5..22164367f6f 100644 --- a/src/basic_recipes/arrows.jl +++ b/src/basic_recipes/arrows.jl @@ -102,13 +102,20 @@ function _circle(origin, r, normal, N) end -convert_arguments(::Type{<: Arrows}, x, y, u, v) = (Point2.(x, y), Vec2.(u, v)) +function convert_arguments(::Type{<: Arrows}, x, y, u, v) + FT = floattype(x, y, u, v) + return (Point2{FT}.(x, y), Vec2{FT}.(u, v)) +end function convert_arguments(::Type{<: Arrows}, x::AbstractVector, y::AbstractVector, u::AbstractMatrix, v::AbstractMatrix) - (vec(Point2.(x, y')), vec(Vec2.(u, v))) + FT = floattype(x, y, u, v) + return (vec(Point2{FT}.(x, y')), vec(Vec2{FT}.(u, v))) +end +function convert_arguments(::Type{<: Arrows}, x, y, z, u, v, w) + FT = floattype(x, y, u, v) + return (Point3{FT}.(x, y, z), Vec3{FT}.(u, v, w)) end -convert_arguments(::Type{<: Arrows}, x, y, z, u, v, w) = (Point3.(x, y, z), Vec3.(u, v, w)) -function plot!(arrowplot::Arrows{<: Tuple{AbstractVector{<: Point{N}}, V}}) where {N, V} +function plot!(arrowplot::Arrows{<: Tuple{AbstractVector{<: Point{N, T}}, V}}) where {N, T, V} @extract arrowplot ( points, directions, colormap, normalize, align, arrowtail, color, linecolor, linestyle, linewidth, lengthscale, @@ -132,7 +139,7 @@ function plot!(arrowplot::Arrows{<: Tuple{AbstractVector{<: Point{N}}, V}}) wher else shift = zero(dir) end - return Point2(p1 .- shift) => Point2(p1 .- shift .+ (dir .* s)) + return Point2{T}(p1 .- shift) => Point2{T}(p1 .- shift .+ (dir .* s)) end end @@ -199,7 +206,7 @@ function plot!(arrowplot::Arrows{<: Tuple{AbstractVector{<: Point{N}}, V}}) wher else shift = -s .* dir end - return Point3(p .- shift) + return Point3{T}(p .- shift) end end marker_tail = lift((at, q) -> arrow_tail(3, at, q), arrowplot, arrowtail, quality) diff --git a/src/basic_recipes/bracket.jl b/src/basic_recipes/bracket.jl index 0ad354945b0..4a0bf73a47a 100644 --- a/src/basic_recipes/bracket.jl +++ b/src/basic_recipes/bracket.jl @@ -31,13 +31,20 @@ $(ATTRIBUTES) ) end -Makie.convert_arguments(::Type{<:Bracket}, point1::VecTypes, point2::VecTypes) = ([(Point2(point1), Point2(point2))],) -Makie.convert_arguments(::Type{<:Bracket}, x1::Real, y1::Real, x2::Real, y2::Real) = ([(Point2(x1, y1), Point2(x2, y2))],) +function Makie.convert_arguments(::Type{<:Bracket}, point1::VecTypes{2, T1}, point2::VecTypes{2, T2}) where {T1, T2} + FT = floattype(T1, T2) + return ([(Point2{FT}(point1), Point2{FT}(point2))],) +end +function Makie.convert_arguments(::Type{<:Bracket}, x1::Real, y1::Real, x2::Real, y2::Real) + FT = floattype(x1, y1, x2, y2) + return ([(Point2{FT}(x1, y1), Point2{FT}(x2, y2))],) +end function Makie.convert_arguments(::Type{<:Bracket}, x1::AbstractVector{<:Real}, y1::AbstractVector{<:Real}, x2::AbstractVector{<:Real}, y2::AbstractVector{<:Real}) + FT = floattype(x1, y1, x2, y2) points = broadcast(x1, y1, x2, y2) do x1, y1, x2, y2 - (Point2(x1, y1), Point2(x2, y2)) + (Point2{FT}(x1, y1), Point2{FT}(x2, y2)) end - (points,) + return (points,) end function Makie.plot!(pl::Bracket) diff --git a/src/basic_recipes/error_and_rangebars.jl b/src/basic_recipes/error_and_rangebars.jl index 66b18be943a..8b7c759eb1a 100644 --- a/src/basic_recipes/error_and_rangebars.jl +++ b/src/basic_recipes/error_and_rangebars.jl @@ -237,14 +237,14 @@ end scene_to_screen(pts::AbstractArray, scene) = scene_to_screen.(pts, (scene,)) screen_to_scene(pts::AbstractArray, scene) = screen_to_scene.(pts, (scene,)) -function scene_to_screen(p::Point{N, T}, scene) where {N, T} +function scene_to_screen(p::Point{N, T}, scene) where {N, T <: NativeFloat} p4 = to_ndim(Vec4{T}, to_ndim(Vec3{T}, p, 0.0), 1.0) p1m1 = scene.camera.projectionview[] * p4 projected = inv(scene.camera.pixel_space[]) * p1m1 return Point{2, T}(projected[1], projected[2]) end -function screen_to_scene(p::Point{N, T}, scene) where {N, T} +function screen_to_scene(p::Point{N, T}, scene) where {N, T <: NativeFloat} p4 = to_ndim(Vec4{T}, to_ndim(Vec3{T}, p, 0.0), 1.0) p1m1 = scene.camera.pixel_space[] * p4 projected = inv(scene.camera.projectionview[]) * p1m1 diff --git a/src/basic_recipes/streamplot.jl b/src/basic_recipes/streamplot.jl index b49ca7ffd02..c2d92a3872f 100644 --- a/src/basic_recipes/streamplot.jl +++ b/src/basic_recipes/streamplot.jl @@ -36,7 +36,8 @@ end function convert_arguments(::Type{<: StreamPlot}, f::Function, xrange, yrange) xmin, xmax = extrema(xrange) ymin, ymax = extrema(yrange) - return (f, Rect(xmin, ymin, xmax - xmin, ymax - ymin)) + FT = floattype(xmin, xmax, ymin, ymax) + return (f, Rect{2, FT}(xmin, ymin, xmax - xmin, ymax - ymin)) end function convert_arguments(::Type{<: StreamPlot}, f::Function, xrange, yrange, zrange) @@ -45,11 +46,12 @@ function convert_arguments(::Type{<: StreamPlot}, f::Function, xrange, yrange, z zmin, zmax = extrema(zrange) mini = Vec3(xmin, ymin, zmin) maxi = Vec3(xmax, ymax, zmax) - return (f, Rect(mini, maxi .- mini)) + FT = floattype(mini, maxi) + return (f, Rect{3, FT}(mini, maxi .- mini)) end -function convert_arguments(::Type{<: StreamPlot}, f::Function, limits::Rect) - return (f, limits) +function convert_arguments(::Type{<: StreamPlot}, f::Function, limits::Rect{N, T}) where {N, T} + return (f, Rect{N, floattype(T)}(limits)) end scatterfun(N) = N == 2 ? scatter! : meshscatter! diff --git a/src/stats/hexbin.jl b/src/stats/hexbin.jl index 1ab9e0aba34..27b16812e22 100644 --- a/src/stats/hexbin.jl +++ b/src/stats/hexbin.jl @@ -58,15 +58,19 @@ end Makie.conversion_trait(::Type{<:Hexbin}) = PointBased() function data_limits(hb::Hexbin) - bb = Rect3(hb.plots[1][1][]) + data = hb.plots[1][1][] + FT = floattype(data) + bb = Rect3{FT}(data) + fn(num::Real) = Float64(num) fn(tup::Union{Tuple,Vec2}) = Vec2(tup...) ms = 2 .* fn(hb.plots[1].markersize[]) - nw = widths(bb) .+ (ms..., 0.0f0) - no = bb.origin .- ((ms ./ 2.0f0)..., 0.0f0) + nw = widths(bb) .+ (ms..., 0) + no = bb.origin .- ((ms ./ 2)..., 0) - return Rect3(no, nw) + r = Rect3(no, nw) + return r end function Makie.plot!(hb::Hexbin{<:Tuple{<:AbstractVector{<:Point2}}})