Open MathieuMorlighem opened 3 years ago
I'm not sure what exactly you want, but you can generate a mesh fairly easily from that input:
using GeometryBasics
positions = Point2f.(x, y)[:] # colon to convert 1xN Array to Vector
faces = [GLTriangleFace(triangles[i, :]) for i in axes(triangles, 1)]
m = normal_mesh(positions, faces)
Though if you want per-face colors you'll have to seperate them. I.e. duplicate the vertices that are used by both faces
using GLMakie, GeometryBasics
import ColorSchemes.jet
triangles=[1 2 3;5 6 4]
x=[0. 1. 1. 0. 0. 1.]
y=[0. 0. 1. 1. 0. 1.]
positions = Point2f.(x, y)[:] # colon to convert 1xN Array to Vector
faces = [GLTriangleFace(triangles[i, :]) for i in axes(triangles, 1)]
m = normal_mesh(positions, faces)
mesh(m, color = [1,1,1, 2,2,2], colormap=jet, shading = false)
Hello @ffreyer, thanks a lot for your response, this is a much more elegant way to achieve the same result. But I guess I was expecting Makie's mesh to understand something like this:
using GLMakie
import ColorSchemes.jet
Makie.mesh( [0.0 0.0; 1.0 0.0; 1.0 1.0; 0.0 1.0;], [1 2 3;1 3 4], shading = false, elementcolor = [1;2], colormap=jet)
@ffreyer Thanks for the proposal. It works indeed for triangular meshes, but seems to fail on quadrangular ones, any idea why ?
It seems like some point metadata is overwritten, but I do not understand why (maybe that's the issue). In fact, as the goal here is to plot one color per face / element, it does not make much sense to rely on vertex metadata as they may differ for the same vertex linked to multiple faces.
I do agree with @mmorligh, that an interface taking directly a vector of values per element would be useful.
Currently it seems to fail at line 456 of drawing_primitives
(GLMakie v0.5.5)
elseif to_value(color) isa AbstractVector{<: Union{Number, Colorant}}
mesh = lift(mesh, color) do mesh, color
return GeometryBasics.pointmeta(mesh, color=el32convert(color))
end
Since a facemeta
function also exists a quick fix might just be
elseif to_value(color) isa AbstractVector{<: Union{Number, Colorant}}
mesh = lift(mesh, color) do mesh, color
if length(coordinates(mesh) == length(color)
return GeometryBasics.pointmeta(mesh, color=el32convert(color))
elseif length(faces(mesh)) == length(color)
return GeometryBasics.facemeta(mesh, color=el32convert(color))
end
quadrangles =[1 2 3 4 ;5 6 4 1] x=[0. 1. 1. 0. 0. 1.] y=[0. 0. 1. 1. 0. 1.]
positions = Point2f.(x, y)[:] # colon to convert 1xN Array to Vector faces = [QuadFace(quadrangles[i, :]) for i in axes(quadrangles , 1)] m = normal_mesh(positions, faces)
mesh(m, color = [1,1,1,1,2, 2,2,2], colormap=jet, shading = false)
Vertices are basically a zip(positions, color)
(and all other metadata). You have 6 positions and 8 colors here, which can't be combined into vertex data cleanly. That's what GeometryBasics is complaining about. You need unique indices for quads, i.e. [1 2 3 4; 5 6 7 8]
, with a position and color per for each index if you want to have per face colors.
Another way of handling this would be to use meshscatter
. Something like
center = Point2f[(0, 0), (1.5, 0)]
sizes = Vec2f[(1, 1), (2, 1)]
face_colors = [:red, :blue]
meshscatter(centers, marker = Rect2f(-0.5, -0.5, 1, 1), markersize = sizes, color = face_colors, shading = false)
Thanks @ffreyer that makes sense, but for large meshes, it is a bit cumbersome to have to renumber the vertices every time one wants to plot...
That's what GeometryBasics is complaining about. You need unique indices for quads, i.e.
[1 2 3 4; 5 6 7 8]
, with a position and color per for each index if you want to have per face colors.
Hmmm so I guess I understand now
Though if you want per-face colors you'll have to seperate them. I.e. duplicate the vertices that are used by both faces
you mean that one needs to duplicate the actual points, not only the metadata).
As @mmorligh said this indeed feels cumbersome, do you think the facemeta
could be leveraged to improve mesh
?
We do this internally in MeshViz.jl if all you need is plot a field over elements or over vertices. Just pass a color vector of the right size and the package with handle things for you. Take a look at the test suite.
Em ter., 5 de abr. de 2022 04:53, BambOoxX @.***> escreveu:
That's what GeometryBasics is complaining about. You need unique indices for quads, i.e. [1 2 3 4; 5 6 7 8], with a position and color per for each index if you want to have per face colors.
Hmmm so I guess I understand now
Though if you want per-face colors you'll have to seperate them. I.e. duplicate the vertices that are used by both faces
you mean that one needs to duplicate the actual points, not only the metadata).
As @mmorligh https://github.com/mmorligh said this indeed feels cumbersome, do you think the facemeta could be leveraged to improve mesh ?
— Reply to this email directly, view it on GitHub https://github.com/JuliaPlots/Makie.jl/issues/1369#issuecomment-1088379782, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAZQW3L67VN3A2PHFPP5HHDVDPWQRANCNFSM5FPSYFOQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>
@juliohm Unfortunately, for my part, I can't rely on MeshViz, I have other stuff to plot in addition to the mesh
Can you elaborate on why this inhibits the usage of MeshViz.jl? Do you understand that MeshViz.jl are Makie recipes right? You can use any Makie command after the plot of the mesh.
Em ter., 5 de abr. de 2022 05:54, BambOoxX @.***> escreveu:
@juliohm https://github.com/juliohm Unfortunately, for my part, I can't rely on MeshViz, I have other stuff to plot in addition to the mesh
— Reply to this email directly, view it on GitHub https://github.com/JuliaPlots/Makie.jl/issues/1369#issuecomment-1088443007, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAZQW3JTTOJF6PV2PJWNBETVDP5UXANCNFSM5FPSYFOQ . You are receiving this because you were mentioned.Message ID: @.***>
At the moment, it's just that all of my plotting functions use on the GeometryBasics.Mesh
type which doe not seem to be compatible with viz
....
@ffreyer Regarding your advice to use a meshscatter
, it does not seem to work with arbitrary quadrangular shapes
You can make it work as long as the meshes/quads you scatter are just translation, rotation and scaling away from each other. So two quads like
quad1 = Point2f[(0, 0), (0, 1), (1, 1), (1, 0)]
quad2 = Point2f[(0, 0), (0, -1), (-1, -2), (-1, -1)]
wouldn't work in a single meshscatter. But if you want to scattering just quad2 works, you just have to make a mesh out of it first.
I mostly mentioned this because I recently used meshscatter to build a heatmap where row lengths were not uniform.
Hello,
again... this is more a feature request but I generally use Mesh to plot fields of size "number of vertices" or "number of elements". It is easy to do the first one using Makie's Mesh function, but for the second one I had to create multiple polygons and call poly instead:
It works, but it would nice to have this done automatically by Mesh. I admit that I may be expecting too much of Mesh (e.g. to behave like MATLAB's patch function), with other features like edgecolor=true for example...
Thank you! Mathieu