Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement Float32 without losing Float64 precision (rebased) #3681

Merged
merged 94 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
7c2344b
implement float64 precision
ffreyer Mar 2, 2024
1026bc1
remove merge conflicts
SimonDanisch Mar 6, 2024
0eaa615
update CairoMakie
ffreyer Mar 6, 2024
ffd2690
move some code around
ffreyer Mar 6, 2024
709e423
simplify syntax
ffreyer Mar 7, 2024
b0bcba1
add non-Observable apply_transform_and_f32_conversion
ffreyer Mar 7, 2024
40ed3a4
clean up convert_arguments
SimonDanisch Mar 7, 2024
3dbdc6b
merge origin
SimonDanisch Mar 7, 2024
1352c88
update WGLMakie
ffreyer Mar 7, 2024
c931058
fix tests
SimonDanisch Mar 7, 2024
e8448af
merge
SimonDanisch Mar 7, 2024
e718f8c
patch model to act after f32convert
ffreyer Mar 7, 2024
61cf827
fix function name
ffreyer Mar 7, 2024
53c0030
update project and plot_to_screen
ffreyer Mar 7, 2024
37cb358
Merge branch 'breaking-0.21' into float64-rebased
SimonDanisch Mar 7, 2024
a1ae057
fix patch_model
ffreyer Mar 8, 2024
6217f1f
add first test
ffreyer Mar 8, 2024
3c29961
rename file
ffreyer Mar 8, 2024
57d35ca
fix type after patch_model
ffreyer Mar 8, 2024
93fec50
fix ticks beyond limits
ffreyer Mar 8, 2024
b5b511a
fix image and heatmap conversion
ffreyer Mar 8, 2024
a1f405e
convert to float types
ffreyer Mar 8, 2024
667daef
update test
ffreyer Mar 8, 2024
67fbc70
Fix CairoMakie not precompiling
asinghvi17 Mar 8, 2024
07ac288
update mesh converts
ffreyer Mar 8, 2024
9d0966f
fix poly convert type
ffreyer Mar 8, 2024
e5596fb
fix dict access
ffreyer Mar 8, 2024
60ff762
fix first test in WGLMakie
ffreyer Mar 8, 2024
c50e1af
don't use triangle_mesh
ffreyer Mar 8, 2024
17607e4
fix incorrect convert_arguments
ffreyer Mar 10, 2024
3911bfa
fix test
ffreyer Mar 10, 2024
f1047ef
fix DataInspector error
ffreyer Mar 10, 2024
5e7c0a4
add meshscatter + surface to tests, fix convert_arguments for poly
SimonDanisch Mar 11, 2024
b72beed
Merge branch 'breaking-0.21' into float64-rebased
ffreyer Mar 11, 2024
d91eb0d
Fix docs + Makie tests
SimonDanisch Mar 11, 2024
2b07862
Fix 1.6!?
SimonDanisch Mar 11, 2024
e099682
fix picking test
SimonDanisch Mar 11, 2024
e441a9d
update DataInspector
ffreyer Mar 11, 2024
9c06ebc
fix indicator rotation for meshscatter in DataInspector
ffreyer Mar 11, 2024
7664ca9
fix Vector{<: Integer}, Vector{Float32} -> Vector{Float32} [skip ci]
ffreyer Mar 11, 2024
b1bbaad
fix stackoverflow on mixed tuple types [skip ci]
ffreyer Mar 11, 2024
08e6dd7
fix tuples correctly [skip ci]
ffreyer Mar 11, 2024
17ca99e
fix geom -> points eltype [skip ci]
ffreyer Mar 11, 2024
3fdf163
fix geom -> PointBased output type
ffreyer Mar 11, 2024
363d24a
fix Rect2 -> points output type [skip ci]
ffreyer Mar 11, 2024
395f2f0
fix PointBased mesh conversion
ffreyer Mar 11, 2024
0e9b343
fix PointBased multi-linestrings type [skip ci]
ffreyer Mar 11, 2024
8837bf8
update bezierpath
ffreyer Mar 11, 2024
51b71ba
split up conversions
ffreyer Mar 11, 2024
1210e4e
fix missing Points convert [skip ci]
ffreyer Mar 11, 2024
53831a1
fix CellGridBased types [skip ci]
ffreyer Mar 11, 2024
9de9f74
always convert volumes to float32
ffreyer Mar 11, 2024
6ceba9a
start adding type tests for every convert_arguments
ffreyer Mar 11, 2024
2b28dab
fix tests
SimonDanisch Mar 12, 2024
5f4c0cd
undo splitting conversions.jl
ffreyer Mar 12, 2024
09d8963
test and cleanup mesh conversions
ffreyer Mar 12, 2024
10f2ad2
fix docs
SimonDanisch Mar 12, 2024
f27161f
update & test Annotations
ffreyer Mar 12, 2024
13a9840
update & test arrows
ffreyer Mar 12, 2024
2e407c4
update and test band and bracket
ffreyer Mar 12, 2024
af999cc
update & test errorbars and rangebars conversions
ffreyer Mar 12, 2024
2a8a076
test & update series converts
ffreyer Mar 12, 2024
4e58b74
make type stable on 1.6
SimonDanisch Mar 13, 2024
7a196a1
update & test remaining convert_arguments
ffreyer Mar 13, 2024
69d8ca0
fix & test model application
ffreyer Mar 13, 2024
b2c32fe
add tests for float32convert
ffreyer Mar 13, 2024
a0a97d5
at floatmin/max refimg test
ffreyer Mar 13, 2024
a2c7112
fix typo
ffreyer Mar 13, 2024
5a96b05
update text bbox test & add backtrace
ffreyer Mar 13, 2024
985b490
avoid Float32 in data_limits
ffreyer Mar 13, 2024
0af4bb4
fix Polygon -> Bezierpath conversion
ffreyer Mar 13, 2024
094da7f
fix WGLMakie meshscatter model patching
ffreyer Mar 13, 2024
0265a26
fix Float64 normals
ffreyer Mar 13, 2024
bee3b6f
fix Float64 matrices in Voxels
ffreyer Mar 13, 2024
cd040f7
test normal and uv types
ffreyer Mar 14, 2024
8d69de0
fix for 1.6
SimonDanisch Mar 14, 2024
b50507a
make new project method more complete
ffreyer Mar 14, 2024
4152923
clean up some TODOs
ffreyer Mar 14, 2024
8095c65
restore text tests
ffreyer Mar 14, 2024
099eae8
restore Polar transform tests
ffreyer Mar 14, 2024
9e1618e
avoid BBox for Axis limits
ffreyer Mar 14, 2024
ceb10e2
fix rectangle zoom, deprecate to_world with matrix inputs
ffreyer Mar 14, 2024
a5e5cf2
fix 1.6
ffreyer Mar 14, 2024
2d6fdf4
fix Float64 latexstrings
ffreyer Mar 14, 2024
57a388b
fix hvlines, hvspan, errorbars, rangebars
ffreyer Mar 14, 2024
3c3712c
fix & test ablines
ffreyer Mar 14, 2024
b8926ba
fix other usage of projview_to_2d_limits
ffreyer Mar 14, 2024
fa04f5d
remove dublicated line
ffreyer Mar 14, 2024
7ddc87d
update changelog + cleanup [skip ci]
ffreyer Mar 14, 2024
c828a1a
fix missing to_value
ffreyer Mar 15, 2024
2e0d076
consider markersize and offset for scatter data_limits
ffreyer Mar 15, 2024
aa6bd2b
fix tests
ffreyer Mar 15, 2024
c23f306
revert BBox -> Rect2d changes
ffreyer Mar 15, 2024
82aaf8e
get hist and barplot working
ffreyer Mar 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
- Remove StableHashTraits in favor of calculating hashes directly with CRC32c [#3667](https://github.com/MakieOrg/Makie.jl/pull/3667).

- **Breaking (sort of)** Added a new `@recipe` variant which allows documenting attributes directly where they are defined and validating that all attributes are known whenever a plot is created. This is not breaking in the sense that the API changes, but user code is likely to break because of misspelled attribute names etc. that have so far gone unnoticed.
- **Breaking** Streamline `data_limits` and `boundingbox` [#3671](https://github.com/MakieOrg/Makie.jl/pull/3671)
- `data_limits` now only considers plot positions, completely ignoring transformations
- `boundingbox(::Text)` is deprecated in favor of `text_boundingbox(::Text)`
- `boundingbox` now always consider `transform_func` and `model` (except for Text for the time being)
- **Breaking** Reworked line shaders in GLMakie and WGLMakie [#3558](https://github.com/MakieOrg/Makie.jl/pull/3558)
- GLMakie: Removed support for per point linewidths
- GLMakie: Adjusted dots (e.g. with `linestyle = :dot`) to bend across a joint
Expand All @@ -17,6 +21,7 @@
- Both: Adjusted handling of thin lines which may result in different color intensities
- Fixed an issue with lines being drawn in the wrong direction in 3D (with perspective projection) [#3651](https://github.com/MakieOrg/Makie.jl/pull/3651).


## [0.20.8] - 2024-02-22

- Fixed excessive use of space with HTML image outputs [#3642](https://github.com/MakieOrg/Makie.jl/pull/3642).
Expand Down
1 change: 1 addition & 0 deletions CairoMakie/src/CairoMakie.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ using Makie: to_value, to_colormap, extrema_nan
using Makie.Observables
using Makie: spaces, is_data_space, is_pixel_space, is_relative_space, is_clip_space
using Makie: numbers_to_colors
using Makie: Mat3f, Mat4f, Mat3d, Mat4d

# re-export Makie, including deprecated names
for name in names(Makie, all=true)
Expand Down
62 changes: 35 additions & 27 deletions CairoMakie/src/primitives.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Unio
# Standard transform from input space to clip space
points = Makie.apply_transform(Makie.transform_func(primitive), positions, space)
res = scene.camera.resolution[]
transform = Makie.space_to_clip(scene.camera, space) * model
clip_points = map(p -> transform * to_ndim(Vec4f, to_ndim(Vec3f, p, 0f0), 1f0), points)
f32convert = Makie.f32_convert_matrix(scene.float32convert, space)
transform = Makie.space_to_clip(scene.camera, space) * model * f32convert
clip_points = map(p -> transform * to_ndim(Vec4d, to_ndim(Vec3d, p, 0), 1), points)

# yflip and clip -> screen/pixel coords
function clip2screen(res, p)
Expand Down Expand Up @@ -374,7 +375,7 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Scat
model = primitive.model[]
positions = primitive[1][]
isempty(positions) && return
size_model = transform_marker ? model : Mat4f(I)
size_model = transform_marker ? model : Mat4d(I)

font = to_font(to_value(get(primitive, :font, Makie.defaultfont())))

Expand All @@ -390,6 +391,9 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Scat
end

function draw_atomic_scatter(scene, ctx, transfunc, colors, markersize, strokecolor, strokewidth, marker, marker_offset, rotations, model, positions, size_model, font, markerspace, space)
# TODO Optimization:
# avoid calling project functions per element as they recalculate the
# combined projection matrix for each element like this
broadcast_foreach(positions, colors, markersize, strokecolor,
strokewidth, marker, marker_offset, remove_billboard(rotations)) do point, col,
markersize, strokecolor, strokewidth, m, mo, rotation
Expand Down Expand Up @@ -630,16 +634,20 @@ function draw_glyph_collection(
strokecolors = glyph_collection.strokecolors

model = _deref(_model)
model33 = transform_marker ? model[Vec(1, 2, 3), Vec(1, 2, 3)] : Mat3f(I)
model33 = transform_marker ? model[Vec(1, 2, 3), Vec(1, 2, 3)] : Mat3d(I)
id = Mat4f(I)

glyph_pos = let
# TODO: f32convert may run into issues here if markerspace is :data or
# :transformed (repeated application in glyphpos etc)
transform_func = transformation.transform_func[]
p = Makie.apply_transform(transform_func, position, space)

Makie.clip_to_space(scene.camera, markerspace) *
Makie.space_to_clip(scene.camera, space) *
model * to_ndim(Point4f, to_ndim(Point3f, p, 0), 1)
Makie.f32_convert_matrix(scene.float32convert, space) *
model *
to_ndim(Point4d, to_ndim(Point3d, p, 0), 1)
end

Cairo.save(ctx)
Expand Down Expand Up @@ -674,8 +682,8 @@ function draw_glyph_collection(
# origin. The resulting vectors give the directions in which the character
# needs to be stretched in order to match the 3D projection

xvec = rotation * (scale3[1] * Point3f(1, 0, 0))
yvec = rotation * (scale3[2] * Point3f(0, -1, 0))
xvec = rotation * (scale3[1] * Point3d(1, 0, 0))
yvec = rotation * (scale3[2] * Point3d(0, -1, 0))

glyphpos = _project_position(scene, markerspace, gp3, id, true)
xproj = _project_position(scene, markerspace, gp3 + model33 * xvec, id, true)
Expand Down Expand Up @@ -767,7 +775,7 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Unio
else
ys = regularly_spaced_array_to_range(ys)
end
model = primitive.model[]::Mat4f
model = primitive.model[]::Mat4d
interpolate = to_value(primitive.interpolate)

# Debug attribute we can set to disable fastpath
Expand Down Expand Up @@ -804,8 +812,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(primitive, space, Point2f(first.(imsize)), model)
xymax = project_position(primitive, space, Point2f(last.(imsize)), model)
xy = project_position(primitive, space, Point2(first.(imsize)), model)
xymax = project_position(primitive, space, Point2(last.(imsize)), model)
w, h = xymax .- xy

can_use_fast_path = !(is_vector && !interpolate) && regular_grid && identity_transform &&
Expand Down Expand Up @@ -835,7 +843,7 @@ 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))
xys = project_position.(scene, (Makie.transform_func(primitive),), space, [Point2f(x, y) for x in xs, y in ys], (model,))
xys = project_position(scene, Makie.transform_func(primitive), space, [Point2(x, y) for x in xs, y in ys], model)
colors = to_color(primitive.calculated_colors[])

# Note: xs and ys should have size ni+1, nj+1
Expand Down Expand Up @@ -901,27 +909,26 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Maki
end

function draw_mesh2D(scene, screen, @nospecialize(plot), @nospecialize(mesh))
vs = decompose(Point2f, mesh)::Vector{Point2f}
# TODO: decompose to type used in mesh
space = to_value(get(plot, :space, :data))::Symbol
transform_func = Makie.transform_func(plot)
model = plot.model[]::Mat4d
vs = project_position(scene, transform_func, space, decompose(Point2d, mesh), model)
fs = decompose(GLTriangleFace, mesh)::Vector{GLTriangleFace}
uv = decompose_uv(mesh)::Union{Nothing, Vector{Vec2f}}
model = plot.model[]::Mat4f
color = hasproperty(mesh, :color) ? to_color(mesh.color) : plot.calculated_colors[]
cols = per_face_colors(color, nothing, fs, nothing, uv)
space = to_value(get(plot, :space, :data))::Symbol
transform_func = Makie.transform_func(plot)
return draw_mesh2D(scene, screen, cols, space, transform_func, vs, fs, model)
return draw_mesh2D(screen, cols, vs, fs)
end

function draw_mesh2D(scene, screen, per_face_cols, space::Symbol, transform_func,
vs::Vector{Point2f}, fs::Vector{GLTriangleFace}, model::Mat4f)
function draw_mesh2D(screen, per_face_cols, vs::Vector{<: Point2}, fs::Vector{GLTriangleFace})

ctx = screen.context
# Priorize colors of the mesh if present
# This is a hack, which needs cleaning up in the Mesh plot type!

for (f, (c1, c2, c3)) in zip(fs, per_face_cols)

t1, t2, t3 = project_position.(scene, (transform_func,), space, vs[f], (model,)) #triangle points
t1, t2, t3 = vs[f] #triangle points

# don't draw any mesh faces with NaN components.
if isnan(t1) || isnan(t2) || isnan(t3)
Expand Down Expand Up @@ -971,7 +978,7 @@ function draw_mesh3D(scene, screen, attributes, mesh; pos = Vec4f(0), scale = 1f

per_face_col = per_face_colors(color, matcap, meshfaces, meshnormals, meshuvs)

model = attributes.model[]::Mat4f
model = attributes.model[]::Mat4d
space = to_value(get(attributes, :space, :data))::Symbol
func = Makie.transform_func(attributes)

Expand Down Expand Up @@ -1003,14 +1010,15 @@ function draw_mesh3D(
i = Vec(1, 2, 3)
normalmatrix = transpose(inv(model[i, i]))

local_model = rotation * Makie.scalematrix(Vec3f(scale))
local_model = rotation * Makie.scalematrix(Vec3d(scale))
# pass transform_func as argument to function, so that we get a function barrier
# and have `transform_func` be fully typed inside closure
model_f32 = model * Makie.f32_convert_matrix(scene.float32convert, space)
vs = broadcast(meshpoints, (transform_func,)) do v, f
# Should v get a nan2zero?
v = Makie.apply_transform(f, v, space)
p4d = to_ndim(Vec4f, to_ndim(Vec3f, v, 0f0), 1f0)
model * (local_model * p4d .+ to_ndim(Vec4f, pos, 0f0))
p4d = to_ndim(Vec4d, to_ndim(Vec3d, v, 0), 1)
return to_ndim(Vec4f, model_f32 * (local_model * p4d .+ to_ndim(Vec4f, pos, 0f0)), NaN32)
end

ns = map(n -> normalize(normalmatrix * n), meshnormals)
Expand Down Expand Up @@ -1167,9 +1175,9 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Maki
view = scene.camera.view[]

zorder = sortperm(pos, by = p -> begin
p4d = to_ndim(Vec4f, to_ndim(Vec3f, p, 0f0), 1f0)
cam_pos = view * model * p4d
cam_pos[3] / cam_pos[4]
p4d = to_ndim(Vec4d, to_ndim(Vec3d, p, 0), 1)
cam_pos = (view * model)[Vec(3,4), Vec(1,2,3,4)] * p4d
cam_pos[1] / cam_pos[2]
end, rev=false)

color = to_color(primitive.calculated_colors[])
Expand Down
39 changes: 32 additions & 7 deletions CairoMakie/src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,35 @@ function project_position(scene::Scene, transform_func::T, space, point, model::
_project_position(scene, space, point, model, yflip)
end

function _project_position(scene::Scene, space, point, model, yflip::Bool)
# much faster than dot-ing `project_position` because it skips all the repeated mat * mat
function _project_position(scene::Scene, space, ps::AbstractArray{<: VecTypes{N, T1}}, model, yflip::Bool) where {N, T1}
transform = let
f32convert = Makie.f32_convert_matrix(scene.float32convert, space)
M = Makie.space_to_clip(scene.camera, space) * model * f32convert
res = scene.camera.resolution[]
px_scale = Vec3d(0.5 * res[1], 0.5 * (yflip ? -res[2] : res[2]), 1)
px_offset = Vec3d(0.5 * res[1], 0.5 * res[2], 0)
M = Makie.transformationmatrix(px_offset, px_scale) * M
M[Vec(1,2,4), Vec(1,2,3,4)] # skip z, i.e. calculate (x, y, w)
end

output = similar(ps, Point2f)

@inbounds for i in eachindex(ps)
p4d = to_ndim(Point4d, to_ndim(Point3d, ps[i], 0), 1)
px_pos = transform * p4d
output[i] = px_pos[Vec(1, 2)] / px_pos[3]
end

return output
end

function _project_position(scene::Scene, space, point::VecTypes{N, T1}, model, yflip::Bool) where {N, T1 <: Real}
T = promote_type(Float32, T1) # always Float, at least Float32
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{T}, to_ndim(Vec3{T}, point, 0), 1)
f32convert = Makie.f32_convert_matrix(scene.float32convert, space)
clip = Makie.space_to_clip(scene.camera, space) * model * f32convert * p4d
@inbounds begin
# between -1 and 1
p = (clip ./ clip[4])[Vec(1, 2)]
Expand All @@ -29,12 +54,12 @@ function project_position(@nospecialize(scenelike), space, point, model, yflip::
project_position(scene, Makie.transform_func(scenelike), space, point, model, yflip)
end

function project_scale(scene::Scene, space, s::Number, model = Mat4f(I))
project_scale(scene, space, Vec2f(s), model)
function project_scale(scene::Scene, space, s::Number, model = Mat4d(I))
project_scale(scene, space, Vec2d(s), model)
end

function project_scale(scene::Scene, space, s, model = Mat4f(I))
p4d = model * to_ndim(Vec4f, s, 0f0)
function project_scale(scene::Scene, space, s, model = Mat4d(I))
p4d = model * to_ndim(Vec4d, s, 0)
if is_data_space(space)
@inbounds p = (scene.camera.projectionview[] * p4d)[Vec(1, 2)]
return p .* scene.camera.resolution[] .* 0.5
Expand Down
Loading