Skip to content

Commit

Permalink
Update the meshimage recipe to the new syntax (#249)
Browse files Browse the repository at this point in the history
* Update the meshimage recipe to the new syntax

* Update the docstring
  • Loading branch information
asinghvi17 authored Jun 20, 2024
1 parent 4ffb528 commit 7abd210
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 53 deletions.
1 change: 1 addition & 0 deletions src/GeoMakie.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ using Reexport
using GeometryBasics, Colors, ImageIO

using Makie
using Makie.MakieCore

import Makie: convert_arguments, convert_attribute, to_value, automatic
using Makie, Makie.FileIO, Makie.GridLayoutBase, Makie.DocStringExtensions
Expand Down
36 changes: 20 additions & 16 deletions src/mesh_image.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ This file contains the implementation of the `MeshImage` recipe.
using Makie: GeometryBasics

"""
meshimage([xs, ys,] zs)
meshimage!(ax, [xs, ys,] zs)
meshimage([xs, ys,] img)
meshimage!(ax, [xs, ys,] img)
Plots an image on a mesh.
Expand All @@ -18,23 +18,25 @@ but a smaller mesh can still represent the inherent
nonlinearity of the space.
This basically plots a mesh with uv coordinates, and textures it by
the provided image. Its conversion trait is `Image` (TODO: change this to DiscreteSurfaceLike).
the provided image. Its conversion trait is `ImageLike`.
For now, it only accepts RGB images. This could be changed in the future.
!!! tip
You can control the density of the mesh by the `npoints` attribute.
## Attributes
$(Makie.ATTRIBUTES)
"""
@recipe(MeshImage) do scene
Attributes(
npoints = 100,
space = :data,
)
@recipe MeshImage (x, y, img) begin
"""
The number of points the mesh should have per side.
Can be an Integer or a 2-tuple of integers representing number of points per side.
"""
npoints = 100
MakieCore.mixin_generic_plot_attributes()...
MakieCore.mixin_colormap_attributes()...
end

# this inherits all conversions for `Image`,
# if no specialized conversion for `MeshImage` is found.
Makie.conversion_trait(::Type{<: MeshImage}) = ImageLike()
Makie.conversion_trait(::Type{<: MeshImage}) = Makie.ImageLike()
# There really is no difference between this and Image,
# except the implementation under the hood.

Expand All @@ -58,18 +60,19 @@ function Makie.plot!(plot::MeshImage)
if npoints != old_npoints[]
# We need a new StructArray to hold all the points.
# TODO: resize the old structarray instead!
points_observable.val = Vector{Point2f}(undef, npoints^2)
points_observable.val = Vector{Point2f}(undef, first(npoints) * last(npoints))
# This constructs an efficient triangulation of a rectangle (all images are rectangles).
rect = GeometryBasics.Tesselation(Rect2f(0, 0, 1, 1), (npoints, npoints))
rect = GeometryBasics.Tesselation(Rect2f(0, 0, 1, 1), (first(npoints), last(npoints)))
# This decomposes that Tesselation to actual triangles, with integer index values.
faces_observable.val = GeometryBasics.decompose(Makie.GLTriangleFace, rect)
# This holds the UVs for the mesh. These are reversed, so that the image is plotted correctly.
uv_observable.val = map(x -> Vec2f(x[1], 1f0 - x[2]), GeometryBasics.decompose_uv(rect))
end

# These are the ranges for the points.
xs = LinRange(extrema(x_in)..., npoints)
ys = LinRange(extrema(y_in)..., npoints)
# `first` and `last` are used to get the number of points per side, if that's provided as a tuple.
xs = LinRange(extrema(x_in)..., first(npoints))
ys = LinRange(extrema(y_in)..., last(npoints))
poval = points_observable[]
# The array is in a grid, so we have to update them on a grid as well.
for (linear_ind, cartesian_ind) in enumerate(CartesianIndices((npoints, npoints)))
Expand Down Expand Up @@ -100,6 +103,7 @@ function Makie.plot!(plot::MeshImage)
plot,
final_mesh;
color = plot[3],
MakieCore.colormap_attributes(plot)...,
shading = NoShading,
transformation = Transformation() # since the points are pre transformed, we don't need to transform them again
)
Expand Down
12 changes: 12 additions & 0 deletions test/meshimage.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Test
using Makie, GeoMakie

@testset "Meshimage color attribute passthrough" begin
img = rand(10, 10)
f, a, p = meshimage(0..1, 0..1, img)
@test p.colormap[] == :viridis
@test p.plots[1].colormap[] == :viridis
p.colormap[] = :jet
@test p.colormap[] == :jet
@test p.plots[1].colormap[] == :jet
end
41 changes: 4 additions & 37 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ Makie.set_theme!(Theme(
))

@testset "GeoMakie" begin
@testset "MeshImage" begin
include("meshimage.jl")
end

@testset "Basics" begin
lons = -180:180
lats = -90:90
Expand All @@ -30,41 +34,4 @@ Makie.set_theme!(Theme(
@test GeoMakie.coastlines(ga) isa Observable
@test GeoMakie.coastlines(ga)[][1] isa GeometryBasics.LineString
end

# @testset "Examples" begin
# geomakie_path = dirname(dirname(pathof(GeoMakie)))
# examples = readdir(joinpath(geomakie_path, "examples"); join = true)
# filenames = filter(x-> isfile(x) && endswith(x, ".jl"), examples)

# test_path = mkpath(joinpath(geomakie_path, "test_images"))
# cd(test_path) do
# for filename in filenames
# example_name = splitext(splitdir(filename)[2])[1]
# printstyled("Running ", bold = true, color = :cyan)
# println(example_name)

# @testset "$example_name" begin
# @test begin
# print(rpad("Include: ", 9))
# @time include(filename)
# true
# end
# @test begin
# savepath = "$example_name.png"
# print(rpad("PNG: ", 9))
# @time CairoMakie.save(savepath, Makie.current_figure(); px_per_unit=2);
# isfile(savepath) && filesize(savepath) > 1000

# end
# @test begin
# savepath = "$example_name.pdf"
# print(rpad("PDF: ", 9))
# @time CairoMakie.save(savepath, Makie.current_figure());
# isfile(savepath) && filesize(savepath) > 1000
# end
# haskey(ENV, "CI") && rm("$example_name.pdf")
# end
# end
# end
# end
end

0 comments on commit 7abd210

Please sign in to comment.