algorithmic modeling for Rhino

Marching Cubes: Curve Wrapping & More Metaballs

UPDATE: 30-Jan-2014

I have added breps as an input for wrapping geometry (it also can take lines now), as in the above definition. It has been updated for some you can taper a curve at both ends if you choose, you only need to feed one radius, although you can feed as many as you like (it acts like the longest list component). The definition uses kangaroo, weaverbird and nudibranch, although I ahve also included some internalized geometry...but I highly recommend playing with those! Kangaroo and weaverbird are better-known essentials, but nudibranch is really fantastic too. Enjoy!

Some of the work posted lately by Nick Tyrer has gotten me thinking about marching cubes again...I had done some stuff with marching tetrahedra and cubes a ways back, and with some new inspiration (and a little time I could carve out today) I figured I'd take a stab at trying to make it more flexible and robust. There was a lot of room for improvement...certainly there still is. This is really a work in progress, so all caveats apply to the can probably break, hasn't been thoroughly tested, etc. But I probably won't be able to do too much more with it for a bit, so I figured I'd put it out there if anyone wants to play with it.

The short of it is that the inputs can take any combination of points and curves, along with variable radii of influence for each geometry object. Also, if you're using curves, and want to "taper" the effect of it over its length (from start to finish) you can do so. For example, an untapered curve versus a tapered curve:

The marching cube stuff is derived from the amazing Paul Bourke's work. I'm calculating fields around points and curves using a standard metaball fall-off function. The trick to its (relative) quickness is in using rTrees to determine which sample points should have their fields updated by various geometry objects, and also in ensuring that points aren't sampled more often than they need to be. The use of the rTree has some up-front computational expense, but with larger geometry sets it saves a ton of time.

The definition has some examples in it, as well as a description of the inputs...but here there are again anyway:

G = A list of base Geometry, which can be any combination of curves or points

R = Radius...this is a list of the radius of influence for each geometry object. The number of elements in this HAS TO BE EQUAL to the number of elements in the geometry list

res = resolution...the edge length of each sampling cube, so smaller numbers reflect higher resolutions. Watch out...the lower this number is, it exponentially increases the calculation time!

iso = iso value for cutting the surface...the lower the number, the bigger the mesh will be

smooth = an integer equal to the number of smoothing passes you want to do on the mesh(es) after they've been created

taper = a boolean...if you're using curves, and want the mesh that wraps around the end of the curve to be tapered smaller, then set this equal to true

ratio = the taper ratio, a double between 0 and 1...this is how much of your base radius you want your tapered edge to if your taper = 1, then your tapered edge should have the same radius as the beginning, 0.5 then it'll be half, etc.

run = a boolean to execute the still can be pretty slow with a lot of geometry, so you can toggle this off to adjust your settings

Anyway, I hope you enjoy!

Views: 24321


You need to be a member of Grasshopper to add comments!

Join Grasshopper

Comment by Scott Finlayson on Sunday

Hi David is this a topic relevant to the query below;

Comment by Tim on September 25, 2016 at 8:08am

Woooo, "fingery" looks spooky, thanks.

Comment by GuangYang on September 25, 2016 at 1:45am

thanks for sharing!

Comment by Artc Quang on November 30, 2015 at 1:45am


Comment by Henrique F on November 25, 2015 at 12:42pm

 thanks for sharing!

Comment by Neo on August 4, 2015 at 12:59pm

Thanks for your help Nik, I learned a lot from your post. 

Comment by Nik Willmore on August 4, 2015 at 12:25pm
Neo, the iso value is somewhat redundant with the r (radius or distance assigned to each metaball point or field strength around curves/surfaces) with often barely noticeable differences between varying one or the other bigger or smaller, and yes, it's not just akin to physics, but is identical.
Comment by Neo on August 4, 2015 at 12:18pm

Thanks for your patients Nik, I tried to figure out all these terminology . so "iso" just means one certain surface because within one 3D field, there is a lot of surfaces where all the value at this surface are the same. just like the electric field, at different distance from the center charge there is always a Gaussian Surface where the field strength is the same. so the value only means which surface to choose. am I right?

Comment by Nik Willmore on August 4, 2015 at 11:41am
Neo, there can be no marching cubes without something to act on, something in 3D space that is defined mathematically or via a 3D array of values, so that each test cube of an XYZ stack of them can decide what predetermined variation among dozens it should use to fill itself with one or more little mesh face triangles with. An iso value merely means "same" value and 3D topology has the fact of life that a varying 3D field creates a nice smooth surface if you start with a smoothly varying field instead of something noisy. An alternative I used to rid bulging where geometry clustered in a model was to replace the complex field drop off (usually an electric charge inspired 1/r*r) with an if/or statement in the code that merely switched from adding zero to the overall field below a desired distance of each cube corner test point to adding 1 or 10. That way the field softness was non-existant so fields stopped adding together so badly, if at all. Kind if confusing to me still why it knocked out all bulging, but with standard metaballs, for historical reasons, they usually do bulge since a field falloff (with distance between each test cube corner and closest point on a geometry if its a curve or a surface instead of just a point) of only the distance squared is quite soft.

Each "cube" or "test cube" that has eight test corners run through the field strength function or that just reads a local field value from a 3D scanner file like MRI, is just a little brick due to evenly subdividing the overall bounding box of your geometry or XYZ data. Internally the algorithms play all sorts of tricks to avoid too much full bounding box inclusion of all those little test cubes in mostly "empty" space.
Comment by Neo on August 4, 2015 at 11:33am

Hi Nik, "it samples the eight corners of each sample cube in a big XYZ grid around your object for the overall field value at each of those eight points" here, is the sample cube similar to the bounding box?  "by summing the contribution of all geometric objects or at least the closest point to each one"  is the geometric objects a cube unit or a object ? I don't understand it clearly. Thanks


Search Grasshopper


  • Add Photos
  • View All

© 2016   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service