Hi everyone, I’d like to share a final update on Discourse regarding the Meshes.jl effort. Future updates will be shared on our Zulip channel, which is where we are spending most of our time discussing computational geometry and related topics.
In this latest release, we have various new features including Douglas-Peucker simplification of polygonal chains and areas, a new triangulation algorithm for polygonal areas by Dehn 1899, a new half-edge data structure with efficient topological relations (boundary, coboundary, adjacency), and I have just finished a first subdivision algorithm by Catmull-Clark to refine and smooth meshes, which is what I am gonna illustrate here.
Suppose you are given a mesh of Beethoven:
This mesh is stored in a PLY file, so we will load it with the PlyIO.jl package:
using Meshes
using PlyIO
function readply(fname)
ply = load_ply(fname)
x = ply["vertex"]["x"]
y = ply["vertex"]["y"]
z = ply["vertex"]["z"]
points = Point.(x, y, z)
inds = ply["face"]["vertex_indices"]
connec = [connect(Tuple(ind.+1)) for ind in inds]
SimpleMesh(points, connec)
end
mesh = readply("bethoven.ply")
We can perform the refinement with:
refined = refine(mesh, CatmullClark())
And it looks like this:
The refinement is taking 60ms approximately in this mesh with 5000 elements, but I think we can make it even faster with more optimizations in the half-edge structure.
We can repeat the refinement multiple times and there is a theorem that says that this process converges to a smooth and nice spline surface. Here is a zoom in the statue after 3 refinement steps:
Notice how the surface is much nicer visually compared to the original control mesh. I learned that this method is the same method used by Pixar in the movie Geri’s Game to render Geri’s hands and head.
You can watch it here:
We are still polishing the minor details, but if you would like to give it a try, feel free to checkout the master branch. A new release should come out by the end of the month with more planned features.