Makie: Colouring 3D Contours by another Array

Worked out how to do it in Makie, using the MarchingCubes, Meshes and MeshViz packages. Meshes to convert the output of MarchingCubes to a Julia Mesh, and MeshViz to extend the plot() signature to accept the Mesh.

using GLMakie, Interpolations, Meshes, MeshViz, MarchingCubes

function InitConds(x, y, z)
    γ = 1.4; R = 287.15
    vx = sin(x) * cos(y) * cos(z)
    vy = -cos(x) * sin(y) * cos(z)
    vz = 0
    p = 1e5 + ((cos(2 * z) + 2) * (cos(2 * x) + cos(2 * y)) - 2) / 16
    ρ = 1
    T = p / (R * ρ)
    return ρ * sqrt(vx^2 + vy^2 + vz^2), ρ * (log(T^(γ / (γ - 1))) / log(p))
end

# Don't unpack the locations and connections
function mesh_data(fvals::Array{T, 3}; v0 = 0.0) where T <: AbstractFloat
    # Generate the marching cube
    mc = MC(fvals, Int)
    m = march(mc, v0)
    return mc
end

begin
    # Configure the domain
    domain_size = 2π
    npts = 64; dx = domain_size / npts
    points = LinRange(dx / 2, domain_size - dx / 2, npts)

    # Generate the data
    data = [InitConds(x, y, z) for x = points, y = points, z = points]
    KinEnergy = getindex.(data, 1)
    Entropy = getindex.(data, 2)

    # Extract an isosurface of the KinEnergy at 3/4 the maximum value
    meshes = mesh_data(KinEnergy, v0 = 0.75 * maximum(KinEnergy))
    mesh_points = Meshes.Point3[Tuple(pt) for pt = meshes.vertices]
    mesh_tris = Meshes.connect.([Tuple(tri) for tri in meshes.triangles], Meshes.Triangle)
    to_SimpleMesh = Meshes.SimpleMesh(mesh_points, mesh_tris)

    # Interpolate the field to colour by onto the vertex locations
    # Marching cubes uses cell indices starting at 0
    itp = interpolate((0:npts-1, 0:npts-1, 0:npts-1), Entropy, Gridded(Linear()))
    Entropy_at_verts = [itp(pt[1], pt[2], pt[3]) for pt = coordinates.(to_SimpleMesh.points)]

    fig = Figure()
    ax = Axis3(fig[1, 1], title = "Inviscid Taylor Green Vortex")
    plot!(ax, to_SimpleMesh, color = Entropy_at_verts)
    display(fig)
end

Results in this:

2 Likes