# Meshes.Vec is ambiguous

Hello,

When I run the code above, I get:

`ERROR: LoadError: MethodError: Meshes.Vec(::Vector{Float64}) is ambiguous.`

However I only import (not using) Meshes, and there’s no `Meshes.Vec` in my code. What should I do?

``````using Printf
import Makie
import Meshes

A = 4
B = 32

# construction of the vertices
duoprismVertices = Array{Float64,3}(undef, A, B, 4)
for i = 1:A
v1 = [cospi(2 * i / A), sinpi(2 * i / A)]
for j = 1:B
v2 = [cospi(2 * j / B), sinpi(2 * j / B)]
duoprismVertices[i, j, :] = vcat(v1, v2)
end
end

# construction of the edges
function dominates(c1, c2)
c2[1] > c1[1] || (c2[1] == c1[1] && c2[2] > c1[2])
end

function modulo(x, y)
((x % y) + y) % y
end

function getEdges()
edges = Array{Int64,3}(undef, 2, 2, 2 * A * B)
counter = 1
for i = 0:(A-1)
for j = 0:(B-1)
c1 = [i, j]
candidate = [i, modulo(j - 1, B)]
if dominates(c1, candidate)
edges[:, :, counter] = hcat(c1, candidate) .+ 1
counter = counter + 1
end
candidate = [i, modulo(j + 1, B)]
if dominates(c1, candidate)
edges[:, :, counter] = hcat(c1, candidate) .+ 1
counter = counter + 1
end
candidate = [modulo(i - 1, A), j]
if dominates(c1, candidate)
edges[:, :, counter] = hcat(c1, candidate) .+ 1
counter = counter + 1
end
candidate = [modulo(i + 1, A), j]
if dominates(c1, candidate)
edges[:, :, counter] = hcat(c1, candidate) .+ 1
counter = counter + 1
end
end
end
edges
end

edges = getEdges()

function rotate4d(alpha, beta, xi, vec)
a = cos(xi)
b = sin(alpha) * cos(beta) * sin(xi)
c = sin(alpha) * sin(beta) * sin(xi)
d = cos(alpha) * sin(xi)
x, y, z, w = vec
[
a*x - b*y - c*z - d*w,
a*y + b*x + c*w - d*z,
a*z - b*w + c*x + d*y,
a*w + b*z - c*y + d*x
]
end

# stereographic projection
function stereog(v)
Meshes.Point(v[1:3] / (sqrt(2) - v[4]))
end

function duoprism(xi)
# rotated and projected vertices
vs = [stereog(rotate4d(pi/2, 0, xi, duoprismVertices[i, j, :])) for i = 1:A, j = 1:B]
## edges
function cylinder(k)
p1 = vs[edges[1, 1, k], edges[2, 1, k]]
p2 = vs[edges[1, 2, k], edges[2, 2, k]]
s = Meshes.Segment(p1, p2)
Meshes.Cylinder(0.06, s)
end
tubes = [cylinder(k) for k = 1:(2*A*B)]
function sphere(i, j)
p = vs[i, j]
Meshes.Sphere(p, 0.1)
end
mesh = reduce(merge, tubes)
spheres = [Meshes.discretize(sphere(i, j), Meshes.RegularDiscretization(20)) for i in 1:A, j in 1:B]
merge(mesh, reduce(merge, spheres))
end

nplots = 60
meshes = [duoprism(xi) for xi in LinRange(0, 2*pi/4, nplots+1)[1:nplots]]

function draw(i)
MeshViz.viz!(meshes[i]; color = :green)
end
for i in 1:nplots
figg, axx, pltt = MeshViz.viz(Meshes.Box(Meshes.Point(-2.5, -2.5, -0.5), Meshes.Point(2.5, 2.5, 1.5)); alpha = 0)
axx.show_axis = false
draw(i)
scale!(axx.scene, 1.6, 1.6, 1.6)
Makie.rotate!(axx.scene, 1,0,0)
png = @sprintf "duoprism%02d.png" i
Makie.save(png, figg)
end

comm = @cmd "convert -layers OptimizePlus -delay 1x10 'duoprism*.png' duoprism.gif"
# run(comm)
``````

@juliohm I fixed that. But now, when I run `duoprism(1)`, I get a StackOverflow.

``````using Printf
import Makie
import Meshes
import MeshViz

A = 4
B = 4

# construction of the vertices
duoprismVertices = Array{Float64,3}(undef, A, B, 4)
for i = 1:A
v1 = [cospi(2 * i / A), sinpi(2 * i / A)]
for j = 1:B
v2 = [cospi(2 * j / B), sinpi(2 * j / B)]
duoprismVertices[i, j, :] = vcat(v1, v2)
end
end

# construction of the edges
function dominates(c1, c2)
c2[1] > c1[1] || (c2[1] == c1[1] && c2[2] > c1[2])
end

function modulo(x, y)
((x % y) + y) % y
end

function getEdges()
edges = Array{Int64,3}(undef, 2, 2, 2 * A * B)
counter = 1
for i = 0:(A-1)
for j = 0:(B-1)
c1 = [i, j]
candidate = [i, modulo(j - 1, B)]
if dominates(c1, candidate)
edges[:, :, counter] = hcat(c1, candidate) .+ 1
counter = counter + 1
end
candidate = [i, modulo(j + 1, B)]
if dominates(c1, candidate)
edges[:, :, counter] = hcat(c1, candidate) .+ 1
counter = counter + 1
end
candidate = [modulo(i - 1, A), j]
if dominates(c1, candidate)
edges[:, :, counter] = hcat(c1, candidate) .+ 1
counter = counter + 1
end
candidate = [modulo(i + 1, A), j]
if dominates(c1, candidate)
edges[:, :, counter] = hcat(c1, candidate) .+ 1
counter = counter + 1
end
end
end
edges
end

edges = getEdges()

function rotate4d(alpha, beta, xi, vec)
a = cos(xi)
b = sin(alpha) * cos(beta) * sin(xi)
c = sin(alpha) * sin(beta) * sin(xi)
d = cos(alpha) * sin(xi)
x, y, z, w = vec
[
a*x - b*y - c*z - d*w,
a*y + b*x + c*w - d*z,
a*z - b*w + c*x + d*y,
a*w + b*z - c*y + d*x
]
end

# stereographic projection
function stereog(v)
v[1:3]/ (sqrt(2) - v[4])
end

# rotated vertices
function rvs(xi)
[stereog(rotate4d(pi/2, 0, xi, duoprismVertices[i, j, :])) for i = 1:A, j = 1:B]
end

function cylinder(xi, k)
vs = rvs(xi)
p1 = vs[edges[1, 1, k], edges[2, 1, k]]
p2 = vs[edges[1, 2, k], edges[2, 2, k]]
#    s = Meshes.Segment(Meshes.Point(tuple(p1)), Meshes.Point(tuple(p2)))
Meshes.Cylinder(tuple(p1...), tuple(p2...), 0.06)
end

function tubes(xi)
[cylinder(xi, k) for k = 1:(2*A*B)]
end

function duoprism(xi)
# rotated and projected vertices
vs = rvs(xi)
## edges
duoedges = tubes(xi)
function sphere(i, j)
p = vs[i, j]
Meshes.Sphere(tuple(p...), 0.1)
end
mesh = reduce(Meshes.merge, duoedges)
spheres = [Meshes.discretize(sphere(i, j), Meshes.RegularDiscretization(20)) for i in 1:A, j in 1:B]
Meshes.merge(mesh, reduce(Meshes.merge, spheres))
end

nplots = 60
meshes = [duoprism(xi) for xi in LinRange(0, 2*pi/4, nplots+1)[1:nplots]]

function draw(i)
MeshViz.viz!(meshes[i]; color = :green)
end
for i in 1:nplots
figg, axx, pltt = MeshViz.viz(Meshes.Box(Meshes.Point(-2.5, -2.5, -0.5), Meshes.Point(2.5, 2.5, 1.5)); alpha = 0)
axx.show_axis = false
draw(i)
Makie.scale!(axx.scene, 1.6, 1.6, 1.6)
Makie.rotate!(axx.scene, 1,0,0)
png = @sprintf "duoprism%02d.png" i
Makie.save(png, figg)
end

comm = @cmd "convert -layers OptimizePlus -delay 1x10 'duoprism*.png' duoprism.gif"
# run(comm)
``````

Vec is constructed with static vector or tuple. We should probably add a method to catch this error and alert users who try to use dynamic vectors.

It works now, but there’s the Stackoverflow.

By the way, the doc of `Cylinder` is wrong, it doesn’t work with a `Segment`.

Please open an issue on github. That is the place for issues.

For the StackOverflow ? Hard to minimize my code.

StackOverflow can come from anywhere. If you are suspecting that it comes from Meshes.jl then please reduce the example to the specific lines that you have suspicion. I don’t have the time to create the MWE for you.

I have no idea whether it comes from Meshes.jl or from a bad practice. I will try to minimize.

But I’m sure this code worked previously. I posted the animation on Zulip, I remember.

If you update software versions you should expect breaking changes sometimes. There is no guarantee that a code working in previous versions will keep working in the future.

I found the problem but not its solution. If I separate the merges edges (`mesh` below) and the spheres, this works. The problem is this line:

``````Meshes.merge(mesh, reduce(Meshes.merge, spheres))
``````

Nice. Now you need to create the MWE showing this stackoverflow with a specific small `mesh` and `spheres`.

I think I have the solution now: `cat(1, theSpheres(xi), theEdges(xi))`.

Forget that, bullshit, I did a mistake.

I definitely have to separate the spheres and the cylinders, otherwise the merging generates the stackoverflow. Looks like a bug. I will prepare a minimal code.

@juliohm What about a gallery of pictures/animations for Meshes.jl? Could be nice.

2 Likes