Add 1-based indexing syntax for connections kw in :mesh3d

This commit is contained in:
Lukas Hauertmann 2021-09-22 15:28:42 +02:00
parent 3051adfa91
commit 88351f3031
4 changed files with 64 additions and 15 deletions

View File

@ -512,10 +512,26 @@ function pgfx_add_series!(::Val{:heatmap}, axis, series_opt, series, series_func
end end
function pgfx_add_series!(::Val{:mesh3d}, axis, series_opt, series, series_func, opt) function pgfx_add_series!(::Val{:mesh3d}, axis, series_opt, series, series_func, opt)
ptable = join( if opt[:connections] isa Tuple{Array,Array,Array}
[string(i, " ", j, " ", k, "\\\\") for (i, j, k) in zip(opt[:connections]...)], # 0-based indexing
"\n ", ptable = join(
) [string(i, " ", j, " ", k, "\\\\") for (i, j, k) in zip(opt[:connections]...)],
"\n ",
)
elseif typeof(opt[:connections]) <: AbstractVector{NTuple{3, Int}}
# 1-based indexing
ptable = join(
[string(i, " ", j, " ", k, "\\\\") for (i, j, k) in opt[:connections]],
"\n ",
)
else
throw(
ArgumentError(
"Argument connections has to be either a tuple of three arrays (0-based indexing)
or an AbstractVector{NTuple{3,Int}} (1-based indexing).",
),
)
end
push!( push!(
series_opt, series_opt,
"patch" => nothing, "patch" => nothing,

View File

@ -678,6 +678,7 @@ function plotly_series(plt::Plot, series::Series)
if series[:connections] !== nothing if series[:connections] !== nothing
if typeof(series[:connections]) <: Tuple{Array,Array,Array} if typeof(series[:connections]) <: Tuple{Array,Array,Array}
# 0-based indexing
i, j, k = series[:connections] i, j, k = series[:connections]
if !(length(i) == length(j) == length(k)) if !(length(i) == length(j) == length(k))
throw( throw(
@ -689,10 +690,17 @@ function plotly_series(plt::Plot, series::Series)
plotattributes_out[:i] = i plotattributes_out[:i] = i
plotattributes_out[:j] = j plotattributes_out[:j] = j
plotattributes_out[:k] = k plotattributes_out[:k] = k
elseif typeof(series[:connections]) <: AbstractVector{NTuple{3, Int}}
# 1-based indexing
i, j, k = broadcast(i -> [ inds[i]-1 for inds in series[:connections]], (1, 2, 3))
plotattributes_out[:i] = i
plotattributes_out[:j] = j
plotattributes_out[:k] = k
else else
throw( throw(
ArgumentError( ArgumentError(
"Argument connections has to be a tuple of three arrays.", "Argument connections has to be either a tuple of three arrays (0-based indexing)
or an AbstractVector{NTuple{3,Int}} (1-based indexing).",
), ),
) )
end end

View File

@ -700,8 +700,13 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
if st == :mesh3d if st == :mesh3d
polygons = if series[:connections] isa AbstractVector{<:AbstractVector{Int}} polygons = if series[:connections] isa AbstractVector{<:AbstractVector{Int}}
# Combination of any polygon types
broadcast(inds -> broadcast(i -> [x[i], y[i], z[i]], inds), series[:connections])
elseif series[:connections] isa AbstractVector{NTuple{N, Int}} where N
# Only N-gons - connections have to be 1-based (indexing)
broadcast(inds -> broadcast(i -> [x[i], y[i], z[i]], inds), series[:connections]) broadcast(inds -> broadcast(i -> [x[i], y[i], z[i]], inds), series[:connections])
elseif series[:connections] isa NTuple{3,<:AbstractVector{Int}} elseif series[:connections] isa NTuple{3,<:AbstractVector{Int}}
# Only triangles - connections have to be 0-based (indexing)
ci, cj, ck = series[:connections] ci, cj, ck = series[:connections]
if !(length(ci) == length(cj) == length(ck)) if !(length(ci) == length(cj) == length(ck))
throw( throw(

View File

@ -1180,16 +1180,12 @@ end
_document_argument(S::AbstractString) = _document_argument(S::AbstractString) =
_fmt_paragraph("`$S`: " * _arg_desc[Symbol(S)], leadingspaces = 6 + length(S)) _fmt_paragraph("`$S`: " * _arg_desc[Symbol(S)], leadingspaces = 6 + length(S))
function mesh3d_triangles(x, y, z, cns) function mesh3d_triangles(x, y, z, cns::Tuple{Array,Array,Array})
if typeof(cns) <: Tuple{Array,Array,Array} ci, cj, ck = cns
ci, cj, ck = cns if !(length(ci) == length(cj) == length(ck))
if !(length(ci) == length(cj) == length(ck)) throw(
throw( ArgumentError("Argument connections must consist of equally sized arrays."),
ArgumentError("Argument connections must consist of equally sized arrays."), )
)
end
else
throw(ArgumentError("Argument connections has to be a tuple of three arrays."))
end end
X = zeros(eltype(x), 4length(ci)) X = zeros(eltype(x), 4length(ci))
Y = zeros(eltype(y), 4length(cj)) Y = zeros(eltype(y), 4length(cj))
@ -1214,6 +1210,30 @@ function mesh3d_triangles(x, y, z, cns)
end end
return X, Y, Z return X, Y, Z
end end
function mesh3d_triangles(x, y, z, cns::AbstractVector{NTuple{3, Int}})
X = zeros(eltype(x), 4length(cns))
Y = zeros(eltype(y), 4length(cns))
Z = zeros(eltype(z), 4length(cns))
@inbounds for I in 1:length(cns)
i = cns[I][1] # connections are 1-based
j = cns[I][2]
k = cns[I][3]
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
return X, Y, Z
end
# cache joined symbols so they can be looked up instead of constructed each time # cache joined symbols so they can be looked up instead of constructed each time
const _attrsymbolcache = Dict{Symbol,Dict{Symbol,Symbol}}() const _attrsymbolcache = Dict{Symbol,Dict{Symbol,Symbol}}()