What is the 3D plotter package closest to the rgl R package?

Hello,

I took a look at the available 3D plotter package in Julia but at first glance they look complicated to me (maybe I mislooked). I’m looking for a package similar to the rgl R package, that is, you just have to enter the vertices coordinates and the indices of the triangle vertices. Is there such a package in Julia? I’m also comfortable with the Pyvista Python package.

isn’t that just GLMakie? with some extra steps if you want with GeometryBasics.jl · GeometryBasics.jl (not needed for basics stuff)

https://juliadatascience.io/glmakie

some extra geometry examples can be found here: https://github.com/lazarusA/100daysOfMakie#21-meshes

1 Like

Sorry but I understand nothing to the docs. Can someone show me a basic example, e.g. a tetrahedron or a cube?

A cube:

using GLMakie
mesh(Rect3f(Vec3f(-0.5), Vec3f(1)); color = :red)

of course you need to install GLMakie first.

Also, a pyramid

using GLMakie, GeometryBasics
mesh(Pyramid(Point3f(0), 1.0f0, 1.0f0); color = :gold, transparency =true)
wireframe!(Pyramid(Point3f(0), 1.0f0, 1.0f0); color=:black, 
    linewidth = 2, transparency = true)
current_figure()

2 Likes

Thanks, and sorry for the late reply.

Here you use built-in functions Pyramid and Rect3f. Is it not possible to simply enter the vertices and the faces (given by vertex indices)?

It is possible to provide the mesh vertices and faces, but I think the interface only supports triangular faces at the moment mesh.
See this issue for additional info `mesh` fails on quadrilateral mesh · Issue #1677 · JuliaPlots/Makie.jl · GitHub

Thank you. There’s an example. Looks like one cannot specify the per-vertex normals.

Wouldn’t this fit your needs, especially this line suggests to me that per-point normals are being passed in:

gb_mesh = GeometryBasics.Mesh(meta(points; uv=uv_buff, normals), faces)

https://makie.juliaplots.org/stable/examples/plotting_functions/mesh/#using_geometrybasicsmesh_and_buffersampler_type

The code below plots a mesh defined by vertices and faces. Is there a way to have automatic normals? By “automatic normals” I mean for example the per-vertex normals obtained by averaging the normals of the incident faces of the vertices.

using GLMakie

function HopfTorusMeshHelper(u, cos_v, sin_v, nlobes, A)
    B = pi/2 - (pi/2 - A)*cos(u*nlobes)
    C = u + A*sin(2*u*nlobes)
    y1 = 1 + cos(B)
    y23 = sin(B) .* [cos(C), sin(C)]
    y2 = y23[1]
    y3 = y23[2]
    x1 = y3 .* cos_v + y2 .* sin_v
    x2 = y2 .* cos_v - y3 .* sin_v
    x3 = y1 .* sin_v
    x4 = y1 .* cos_v
    yden = sqrt(2*y1)
    return vcat(x1 ./ (yden .- x4), x2 ./ (yden .- x4), x3 ./ (yden .- x4)) 
end

function HopfTorusMesh(nu, nv; nlobes = 3, A = 0.44)
  vs    = Array{Float64}(undef, nu*nv, 3)
  tris1 = Array{Int64}(undef, nu*nv, 3)
  tris2 = Array{Int64}(undef, nu*nv, 3)
  u_ = range(0, stop = 2*pi, length = nu+1)[2:(nu+1)]
  v_ = range(0, stop = 2*pi, length = nv+1)[2:(nv+1)]
  cos_v = cos.(v_)
  sin_v = sin.(v_)
  jp1_ = [(2:nv)..., 1]
  j_ = [(1:nv)...]
  for i in 1:(nu-1)
    i_nv = i*nv
    vs[(i_nv - nv + 1):i_nv, :] =
      HopfTorusMeshHelper(u_[i], cos_v, sin_v, nlobes, A)
    k1 = i_nv - nv
    k_ = k1 .+ j_
    l_ = k1 .+ jp1_
    m_ = i_nv .+ j_
    tris1[k_, :] = hcat(k_, l_, m_)
    tris2[k_, :] = hcat(l_, i_nv .+ jp1_, m_)
  end
  i_nv = nu*nv
  vs[(i_nv - nv + 1):i_nv, :] =
    HopfTorusMeshHelper(2*pi, cos_v, sin_v, nlobes, A)
  k1 = i_nv - nv
  k_ = k1 .+ j_
  l_ = k1 .+ jp1_
  tris1[k_, :] = hcat(k_, l_, j_)
  tris2[k_, :] = hcat(l_, jp1_, j_)
  return (vertices = vs, faces = vcat(tris1, tris2))
end

ht = HopfTorusMesh(200, 200)
mesh(ht.vertices, ht.faces)

I think I found:

using GeometryBasics
vertices = map(Point3f, eachrow(ht.vertices))
faces = map(TriangleFace, eachrow(ht.faces))
nrmls = normals(vertices, faces)
gb_mesh = GeometryBasics.Mesh(meta(vertices; normals = nrmls), faces)

mesh(gb_mesh, color = "green")

But I don’t see any difference regarding the smoothness. It seems that Makie automatically adds the normals.