JuliaVTK / WriteVTK.jl

Julia package for writing VTK XML files
Other
151 stars 32 forks source link

Using push! to create MeshCell vector raises a MethodError. #133

Open OndrejKincl opened 8 months ago

OndrejKincl commented 8 months ago

Isn't it strange that in this code, the function test1() raises MethodError, but test2() works normally? I would expect them to do the same thing.

module simple_test

using WriteVTK
using StaticArrays

function test1()
    points = [rand(SVector{3, Float64}) for _ in 1:4]
    cell = MeshCell(PolyData.Polys(), (1, 2, 3, 4))
    polys = []
    push!(polys, cell)
    vtk_grid("my_vtp_file", points, polys)
end

function test2()
    points = [rand(SVector{3, Float64}) for _ in 1:4]
    cell = MeshCell(PolyData.Polys(), (1, 2, 3, 4))
    polys = [cell]
    vtk_grid("my_vtp_file", points, polys)
end

end
jipolanco commented 8 months ago

For completeness I ran your test1 function and I got:

julia> test1()
ERROR: MethodError: no method matching vtk_grid(::String, ::Vector{SVector{3, Float64}}, ::Vector{Any})

Closest candidates are:
  vtk_grid(::AbstractString, ::AbstractVector{T}, ::AbstractVector{T}, ::AbstractVector{T}; kwargs...) where T
   @ WriteVTK ~/.julia/dev/WriteVTK/src/gridtypes/structured/rectilinear.jl:57
  vtk_grid(::AbstractString, ::AbstractVector{T}, ::AbstractVector{T}, ::AbstractVector{<:VTKBase.AbstractMeshCell}, ::Any...; kwargs...) where T
   @ WriteVTK ~/.julia/dev/WriteVTK/src/gridtypes/unstructured/unstructured.jl:213
  vtk_grid(::AbstractString, ::AbstractVector{T}, ::AbstractVector{T}, ::AbstractVector{T}, ::AbstractVector{<:VTKBase.AbstractMeshCell}, ::Any...; kwargs...) where T
   @ WriteVTK ~/.julia/dev/WriteVTK/src/gridtypes/unstructured/unstructured.jl:201
  ...

The issue is that, in test1, your polys vector is a Vector{Any} (which can contain any kind of objects), but vtk_grid expects an AbstractVector{<:AbstractMeshCell}, i.e. a vector whose element type is a kind of MeshCell.

For example, in your test2, if you do typeof(polys) you will get Vector{MeshCell{VTKBase.PolyData.Polys, NTuple{4, Int64}}}, which is accepted by vtk_grid. In the case of test1, you will simply get Vector{Any}, which is not.

For now, in test1 you could initialise your empty polys vector using:

polys = MeshCell{PolyData.Polys, NTuple{4, Int64}}[]

I agree this is not very convenient, and it would be nice to have a friendlier way of creating an empty vector of cells.

OndrejKincl commented 8 months ago

Thank you for your excellent and prompt reply. However, I am still not 100% happy because I want to export a Voronoi mesh, which I have stored in some unusual data structure (that is, why I want push the points one after another). A priori, I do not know the number of edges of each polygon. It could be anything from 4 to 50 and each polygon can have different number of edges. So I cannot use: polys = MeshCell{PolyData.Polys, NTuple{4, Int64}}[] So I tried polys = MeshCell[]. Alas, it raises a different error: "type Polys has no field vtk_id". So what should I do?

EDIT: I found that polys = Vector{MeshCell{PolyData.Polys}}() works as I need, so now I am 100% happy.