VTKDataTypes.jl proposed type system - development code

This is some development code for VTKDataTypes.jl. It is not tested yet, so please report any bugs you find while using it in your code. Any suggestions are also welcome. Disclaimer: I am no expert, but I am working on it!

abstract AbstractVTKData

abstract AbstractStaticVTKData <: AbstractVTKData
abstract AbstractTimeSeriesVTKData <: AbstractVTKData

abstract AbstractVTKSimpleData <: AbstractStaticVTKData
abstract AbstractVTKAMRData <: AbstractStaticVTKData
abstract AbstractVTKMultiblockData <: AbstractStaticVTKData

abstract AbstractVTKUnstructuredData <: AbstractVTKSimpleData
abstract AbstractVTKStructuredData <: AbstractVTKSimpleData

abstract AbstractVTKRectilinearData <: AbstractVTKStructuredData

type VTKUnstructuredData <: AbstractVTKUnstructuredData
    id_offset::Int
    point_coords::Matrix{Float64}
    cell_types::Vector{Int}
    cell_connect::Vector{Vector{Int}}
    point_data::Dict{String, Array{Float64}}
    cell_data::Dict{String, Array{Float64}}
end

type VTKPolyData <: AbstractVTKUnstructuredData
    id_offset::Int
    point_coords::Matrix{Float64}
    cell_types::Vector{Int}
    cell_connect::Vector{Vector{Int}}
    point_data::Dict{String, Array{Float64}}
    cell_data::Dict{String, Array{Float64}}
end

type VTKStructuredData <: AbstractVTKStructuredData
    id_offset::Int
    point_coords::Array{Float64}
    point_data::Dict{String, Array{Float64}}
    cell_data::Dict{String, Array{Float64}}
end

type VTKRectilinearData <: AbstractVTKRectilinearData
    id_offset::Int
    point_coords::Vector{Vector{Float64}}
    point_data::Dict{String, Array{Float64}}
    cell_data::Dict{String, Array{Float64}}
end

type VTKUniformRectilinearData <: AbstractVTKRectilinearData
    id_offset::Int
    origin::Union{NTuple{2, Float64}, NTuple{3, Float64}}
    spacing::Union{NTuple{2, Float64}, NTuple{3, Float64}}
    point_data::Dict{String, Array{Float64}}
    cell_data::Dict{String, Array{Float64}}
end

type VTKMultiblockData <: AbstractVTKMultiblockData
    num_of_blocks::Int
    blocks::Vector{AbstractStaticVTKData}
end

type VTKTimeSeriesData{T<:AbstractStaticVTKData} <: AbstractTimeSeriesVTKData
    num_of_timesteps::Int
    timesteps::Vector{Float64}
    data::Array{T}
end

import Base.getindex
getindex{T<:AbstractTimeSeriesVTKData, S<:Integer}(dataset::T, inds::S...) = dataset.data[inds...]

extents(dataset::VTKStructuredData) = size(dataset.point_coords)[2:end]
extents(dataset::VTKRectilinearData) = ([length(dataset.point_coords[i]) for i in 1:length(dataset.point_coords)]...)
extents(dataset::VTKUniformRectilinearData) = dataset.extents

dim(dataset::AbstractVTKUnstructuredData) = length(dataset.point_coords[1,:])
dim(dataset::AbstractVTKStructuredData) = length(extents(dataset))

num_of_points(dataset::AbstractVTKUnstructuredData) = length(dataset.point_coords)
num_of_points(dataset::AbstractVTKStructuredData) = reduce(*, size(extents(dataset)))

num_of_cells(dataset::AbstractVTKUnstructuredData) = length(dataset.cell_types)
num_of_cells(dataset::AbstractVTKStructuredData) = reduce(*, [extents(dataset)...]-1)

num_of_point_vars(dataset::AbstractVTKSimpleData) = length(dataset.point_data)
num_of_cell_vars(dataset::AbstractVTKSimpleData) = length(dataset.cell_data)

function has_var(dataset::AbstractStaticVTKData, var_name::String)
    if haskey(dataset.point_data, var_name)
        true, "Point"
    elseif haskey(dataset.cell_data, var_name)
        true, "Cell"
    else
        false, ""
    end
end

function var_dim(dataset::AbstractVTKUnstructuredData, var_name::String, var_type::String)
    if var_type == "Point" && haskey(dataset.point_data, var_name)
        length(dataset.point_data[var_name][1,:])
    elseif var_type == "Cell" && haskey(dataset.cell_data, var_name)
        length(dataset.cell_data[var_name][1,:])
    else
        throw("Variable $var_name doesn't exist, please use has_var to check if the variable exists before using this function.")
    end
end

function var_dim(dataset::AbstractVTKStructuredData, var_name::String, var_type::String)
    if var_type == "Point" && haskey(dataset.point_data, var_name)
        s = size(dataset.point_data[var_name]); length(s) == dim(dataset) ? 1 : s[1]
    elseif var_type == "Cell" && haskey(dataset.cell_data, var_name)
        s = size(dataset.cell_data[var_name]); length(s) == dim(dataset) ? 1 : s[1]
    else
        throw("Variable $var_name doesn't exist, please use has_var to check if the variable exists before using this function.")
    end
end

Hi,

I’m just wondering what the context is for this package? Do you mean to implement VTK structures completely in Julia? Or is this meant to interface with the VTK C++ library somehow?

I am implementing it in Julia. I would like to separate the VTK data types in Julia from any reader or proxy that wraps an external library, object or function. I am not sure if this is the best move for the future of the Julia-VTK marriage, but then my motivation is slightly more selfish than it may seem.

Wrapping the whole VTK C++ library is surely a tempting idea but is probably too much than I am willing to commit, or probably currently capable of. I am only interested in representing VTK data in Julia (for other engineering purposes), and reading and writing files. There are also a handful of functions from Paraview that I will wrap using PyCall, including some of its reader, filter and visualization functions.

If you have any suggestions or worries please let me know.