Merge pull request #3612 from t-bltg/mesh3d

GR: add support for mesh3d
This commit is contained in:
t-bltg 2021-07-09 23:15:17 +02:00 committed by GitHub
commit 5d608d1e77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 31 deletions

View File

@ -353,6 +353,7 @@ const _gr_seriestype = [
:scatter3d,
:surface,
:wireframe,
:mesh3d,
:volume,
:shape,
]

View File

@ -524,7 +524,7 @@ function gr_draw_colorbar(cbar::GRColorbar, sp::Subplot, clims, viewport_plotare
levels = _cbar_unique(contour_levels.(series, Ref(clims)), "levels")
# GR implicitly uses the maximal z value as the highest level
if levels[end] < clims[2]
@warn("GR: highest contour level less than maximal z value is not supported.")
@warn "GR: highest contour level less than maximal z value is not supported."
# replace levels, rather than assign to levels[end], to ensure type
# promotion in case levels is an integer array
levels = [levels[1:end-1]; clims[2]]
@ -1682,7 +1682,7 @@ function gr_add_series(sp, series)
end
elseif st === :contour
gr_draw_contour(series, x, y, z, clims)
elseif st in (:surface, :wireframe)
elseif st in (:surface, :wireframe, :mesh3d)
gr_draw_surface(series, x, y, z, clims)
elseif st === :volume
sp[:legend] = :none
@ -1838,7 +1838,7 @@ function gr_draw_contour(series, x, y, z, clims)
h = gr_contour_levels(series, clims)
if series[:fillrange] !== nothing
if series[:fillcolor] != series[:linecolor] && !is_lc_black
@warn("GR: filled contour only supported with black contour lines")
@warn "GR: filled contour only supported with black contour lines"
end
GR.contourf(x, y, h, z, series[:contour_labels] == true ? 1 : 0)
else
@ -1849,7 +1849,8 @@ end
function gr_draw_surface(series, x, y, z, clims)
e_kwargs = series[:extra_kwargs]
if series[:seriestype] === :surface
st = series[:seriestype]
if st === :surface
fillalpha = get_fillalpha(series)
fillcolor = get_fillcolor(series)
# NOTE: setting nx = 0 or ny = 0 disables GR.gridit interpolation
@ -1864,9 +1865,41 @@ function gr_draw_surface(series, x, y, z, clims)
else
GR.gr3.surface(x, y, z, d_opt)
end
else # wireframe
elseif st === :wireframe
GR.setfillcolorind(0)
GR.surface(x, y, z, get(e_kwargs, :display_option, GR.OPTION_FILLED_MESH))
elseif st === :mesh3d
@warn "GR: mesh3d is experimental (no face colors)"
conn = series[:connections]
if typeof(conn) <: Tuple{Array, Array, Array}
ci, cj, ck = conn
if !(length(ci) == length(cj) == length(ck))
throw(ArgumentError("Argument connections must consist of equally sized arrays."))
end
else
throw(ArgumentError("Argument connections has to be a tuple of three arrays."))
end
X = zeros(eltype(x), 4length(ci))
Y = zeros(eltype(y), 4length(cj))
Z = zeros(eltype(z), 4length(ck))
@inbounds for I 1:length(ci)
i = ci[I] + 1 # connections are 0-based
j = cj[I] + 1
k = ck[I] + 1
m = 4(I - 1) + 1; n = m + 1; o = m + 2; p = m + 3
X[m] = X[p] = x[i]
Y[m] = Y[p] = y[i]
Z[m] = Z[p] = z[i]
X[n] = x[j]
Y[n] = y[j]
Z[n] = z[j]
X[o] = x[k]
Y[o] = y[k]
Z[o] = z[k]
end
GR.polyline3d(X, Y, Z)
else
throw(ArgumentError("Not handled !"))
end
end

View File

@ -1007,33 +1007,37 @@ const _examples = PlotExample[
end]
),
PlotExample( # 47
"Mesh3d",
"""
Allows to plot arbitrary 3d meshes. If only x,y,z are given the mesh is generated automatically.
You can also specify the connections using the connections keyword.
The connections are specified using a tuple of vectors. Each vector contains the 0-based indices of one point of a triangle,
such that elements at the same position of these vectors form a triangle.
""",
[
:(
begin
# specify the vertices
x=[0, 1, 2, 0]
y=[0, 0, 1, 2]
z=[0, 2, 0, 1]
"Mesh3d",
"""
Allows to plot arbitrary 3d meshes. If only x,y,z are given the mesh is generated automatically.
You can also specify the connections using the connections keyword.
The connections are specified using a tuple of vectors. Each vector contains the 0-based indices of one point of a triangle,
such that elements at the same position of these vectors form a triangle.
""",
[
:(
begin
# specify the vertices
x=[0, 1, 2, 0]
y=[0, 0, 1, 2]
z=[0, 2, 0, 1]
# specify the triangles
# every column is one triangle,
# where the values denote the indices of the vertices of the triangle
i=[0, 0, 0, 1]
j=[1, 2, 3, 2]
k=[2, 3, 1, 3]
# specify the triangles
# every column is one triangle,
# where the values denote the indices of the vertices of the triangle
i=[0, 0, 0, 1]
j=[1, 2, 3, 2]
k=[2, 3, 1, 3]
# the four triangles gives above give a tetrahedron
mesh3d(x,y,z;connections=(i,j,k))
end
),
],
# the four triangles gives above give a tetrahedron
mesh3d(
x, y, z; connections=(i, j, k),
title="triangles", xlabel="x", ylabel="y", zlabel="z",
legend=:none, margin=2Plots.mm
)
end
),
],
),
PlotExample( # 48
"Vectors of markershapes and segments",
@ -1223,7 +1227,7 @@ const _examples = PlotExample[
# Some constants for PlotDocs and PlotReferenceImages
_animation_examples = [2, 31]
_backend_skips = Dict(
:gr => [25, 30, 47],
:gr => [25, 30],
:pyplot => [2, 25, 30, 31, 47, 49, 55],
:plotlyjs => [2, 21, 24, 25, 30, 31, 49, 51, 55],
:plotly => [2, 21, 24, 25, 30, 31, 49, 50, 51, 55],