Native Metaballs

How about Metaballs?  Isosurfaces? Blobs?

Yah, sure, why not?  Since I’m programming in Lua, there are a couple of ways to do things.  Metaballs, or Blobs, are actually fairly easy to produce, up to a point.  You calculate a bunch of points that define the ‘surface’ of the object.  Then you need to perform some fancy calculations to turn all those points into an actual mesh that can be rendered.  There is one such routine, known as “Marching Cubes”, which is patented, which can perform this operation.  There are other (non-patented) routines, which will do a similar task.  If you’re going to do marching cubes, then you need some cubes…

One thing to notice about the code for this rendering is that it uses an iterator.  Notice in the primary loop here: for v in IterateMetaballs…

That’s a standard Lua iterator pattern.  They come in quite handy for such things.  Of course I could wrap this up in some nice native function like: metaball(balls, resolution), and be done with it.  But, anyone can do that, and besides, by making the iterator available in the raw, you can come up with multiple uses of the points that are generated.

Here, I am using the points to display cubes (with transparency).  The “Blue Bell” tinted spheres ‘inside’ the object are the ‘molecules’ of the shape, which create the isosurface.

In this second picture, I’m doing something a bit different.  The last parameter of the iterator ‘{3,3,3}’ determines the ‘Sample Per Unit’ (spu).  If I were a 3D printer, this might be the ‘layer height’.  So, assuming my “Unit” is 1mm, then having a SPU of ‘3’ would mean a resolution of 1/3 == .3mm.  Again, if I’m a printer, this would essentially be a layer height of .3mm.  Alright, so why do I need a mesh in the first place?

What I could do instead is the following.  Let’s assume my printer is a very dumb pick-n-place machine.  I have these tiny little beads that are .3mm in size.  I have this metaball object I want to construct.  I can just give the printer the metaball description, and it can evaluate the iterator, moving from x-y, layer by layer.  Whenever it receives a ‘positive’ at a position, it places a bead.  No mesh involved.  I’ve essentially ‘sliced’ the geometry and rendered directly to the printer.  The only reason I’d need a mesh is if I wanted to interchange with someone else who needs a mesh.  Well, I won’t take on that burden, I’d rather just send them the description of the geometry, and let some other rendering tool figure out how to turn that into a mesh.

Great, problem solved, and no need for Marching Cubes!

Here’s a final picture with a SPU = {5,5,5}.  That’s essentially a 0.20 mm layer height.  It looks “water tight”.  Again, if you have a printer that can consume this description directly, you don’t ever have to generate the .stl file.  Just “Print”.  It’s a technique similar to sending Postscript to a printer for direct rendering.

At any rate, one step closer to reality.

2 Comments on “Native Metaballs”

  1. juaxix says:

    Could you combine all these combined geometry?
    And, how are you computing the bounding boxes and phyisical bodies without any additional structure?
    I have to try this code, it’s pretty

    • For the boundary, the basic technique is best summed up as “shrink wrapping”. The ‘driver’ if you will is making a spherical traversal around the metaball space at a sufficient distance. That’s where you get the control grid. How far in the mesh goes at any given point is determined by a ray cast towards the center. When it hits the boundary of the isosurface, you stop, and move to the next position.

      So, not a point cloud, so no marching cubes. Rather, a controlled mesh.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s