Graphics in Julia

From David's Wiki
\( \newcommand{\P}[]{\unicode{xB6}} \newcommand{\AA}[]{\unicode{x212B}} \newcommand{\empty}[]{\emptyset} \newcommand{\O}[]{\emptyset} \newcommand{\Alpha}[]{Α} \newcommand{\Beta}[]{Β} \newcommand{\Epsilon}[]{Ε} \newcommand{\Iota}[]{Ι} \newcommand{\Kappa}[]{Κ} \newcommand{\Rho}[]{Ρ} \newcommand{\Tau}[]{Τ} \newcommand{\Zeta}[]{Ζ} \newcommand{\Mu}[]{\unicode{x039C}} \newcommand{\Chi}[]{Χ} \newcommand{\Eta}[]{\unicode{x0397}} \newcommand{\Nu}[]{\unicode{x039D}} \newcommand{\Omicron}[]{\unicode{x039F}} \DeclareMathOperator{\sgn}{sgn} \def\oiint{\mathop{\vcenter{\mathchoice{\huge\unicode{x222F}\,}{\unicode{x222F}}{\unicode{x222F}}{\unicode{x222F}}}\,}\nolimits} \def\oiiint{\mathop{\vcenter{\mathchoice{\huge\unicode{x2230}\,}{\unicode{x2230}}{\unicode{x2230}}{\unicode{x2230}}}\,}\nolimits} \)

A guide on making graphics visualizations in Julia

MeshCat

MeshCat.jl is a Julia wrapper around three.js built using WebIO.jl. It creates its own server and opens a webpage to access the server. However, MeshCat.js is a bit lacking in documentation and does not expose all the features of three.js. We may need to extend it for additional features.


Getting Started

  • Install Julia
  • Make a new project
  • Add MeshCat, Colors, GeometryTypes, CoordinateTransformations to your project


Geometry

MeshCat.jl and GeometryTypes.jl both come with a variety of basic geometries such as HyperRectangle and PointCloud.
You can also create your own geometry by calling the HomogenousMesh function with your own vertices, normals, triangles/faces, and uvs/texturecoordinates.

Creating Geometry

Example of how to create a quad:

using MeshCat
using GeometryTypes

vis = Visualizer()
open(vis)

# Load the texture
image = PngImage(joinpath(@__DIR__, "circuit_pattern.png"))
texture = Texture(image=image)

# Make the material from the texture
# TODO: Figure out how to set `mat.transparent = true` from within Julia
material = MeshLambertMaterial(map=texture)

# Make the geometry
# Note that you can also use Array{Float32, 1} instead of Point{3, Float32} for the vertices and the normals.
quadGeometry = HomogenousMesh(
  vertices = [Point(0,0,0), Point(0,1,0), Point(0, 0, 1), Point(0, 1, 1)],
  normals = [Point(1,0,0),Point(1,0,0),Point(1,0,0),Point(1,0,0)],
  faces = [Triangle(1,2,3), Triangle(2,3,4)],
  texturecoordinates = [Point(0.0f0,0), Point(1.0f0,0), Point(0.0f0,1), Point(1.0f0,1)]
);

# Add the object to the scene
setobject!(vis["myquad"], quadGeometry , material)

# Set the position
settransform!(vis["myquad"], Translation(0.5, -0.5, 0.5))


Loading Geometry

using GeometryTypes: GLUVMesh # we need a mesh type that stores texture coordinates
image = PngImage(joinpath(@__DIR__, "..", "data", "HeadTextureMultisense.png"))
texture = Texture(image=image)
material = MeshLambertMaterial(map=texture)
geometry = load(joinpath(MeshCat.VIEWER_ROOT, "..", "data", "head_multisense.obj"), GLUVMesh)
setobject!(vis["robots", "valkyrie", "head"], geometry, material)
settransform!(vis["robots", "valkyrie"], Translation(0.5, -0.5, 0.5))

Updating Geometry

After you update your geometry, say by changing your vertex positions, you need to call setobject! again for it to update.