🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Marching Cubes and Dual Contouring Tutorial

Started by
35 comments, last by Boris The Brave 6 years ago

I've put together some tutorials that explain the ideas behind Marching Cubes and Dual Contouring. Maybe it'll be useful to some of the forum-goers.
 


Each tutorial comes with sample code in Python.

Let me know what you think. This is the first time I've written a tutorial, but may do more if people want them.

Advertisement

Just quickly skimmed through the articles (will read them fully later), but they look really good visually, these topics are sometimes hard to understand conceptually without a proper visualisations and what I see in these tutorials there is quite impressive :) Good job and thanks for sharing!


Where are we and when are we and who are we?
How many people in how many places at how many times?

Thanks for your code. It's much appreciated.

9 hours ago, Boris The Brave said:

Let me know what you think.

Really like how it builds up, starting with the very easy to do 2D and moving to the complexer 3D only after explaining the basic concept. Fantastic tutorials.

I altered the file dual_contour_3d.py to calculate a quaternion Julia set. Any ideas on why it creates a blank obj file? The functions in question are qmul, qadd, and quat_function.

https://gist.github.com/sjhalayka/bac147602440e689a9bab27d889fa2bd

 

Cow, your evaluation function returns only positive numbers, but I've configured the code to treat anything positive as solid. Try subtracting a constant, like I've done in circle_function, so you get some positive and some negative values. 

Ok, thank you for straightening it all out regarding the negative/positive values.

I have it generating the basic shape, but the surface is a mess. Have you ever run into that problem?

I changed the XMIN, etc. to -20, and XMAX, etc to 20.

def quat_function(x, y, z):
    Z_x = x*0.1
    Z_y = y*0.1
    Z_z = z*0.1
    Z_w = 0
    C_x = 0.0 # values of 0 for C make for a unit ball
    C_y = 0.0
    C_z = 0.0
    C_w = 0.0
    threshold = 4
    max_iterations = 8
    len_sq = Z_x*Z_x + Z_y*Z_y + Z_z*Z_z + Z_w*Z_w
    threshold_sq = threshold*threshold

    for i in range(0, max_iterations):
        Z_x, Z_y, Z_z, Z_w = qmul(Z_x, Z_y, Z_z, Z_w, Z_x, Z_y, Z_z, Z_w) # Z*Z        
        Z_x, Z_y, Z_z, Z_w = qadd(Z_x, Z_y, Z_z, Z_w, C_x, C_y, C_z, C_w) # + C

        len_sq = Z_x*Z_x + Z_y*Z_y + Z_z*Z_z + Z_w*Z_w
        
        if len_sq > threshold_sq:
            break;

    return threshold - math.sqrt(len_sq)

Screen Shot 2018-04-16 at 8.04.38 AM.png

The link to the 3D tutorial from the 2D tutorial is broken:

http://www.boristhebrave.com/2018/04/08/marching-cubes-3d-tutorial/

should be

http://www.boristhebrave.com/2018/04/15/marching-cubes-tutorial/

Also, I think marching triangles and tetrahedra should be mentioned. They are an attractive alternative because the number of cases is much smaller.

Have you ever tried to print your meshes on Shapeways?

Also, the quat_function works well with the Marching Cubes 3D code, so the problem relates to the vertex interpolation in Dual Contouring?

I can't believe how easy your code is to modify... thank you so much!

I found a solution for the normal function.

def quat_normal_from_function(f, d=0.00001):
    """Given a sufficiently smooth 3d function, f, returns a function approximating of the gradient of f.
    d controls the scale, smaller values are a more accurate approximation."""
    def norm(x, y, z):
        return V3(
            (f(x + d, y, z) - f(x - d, y, z)),
            (f(x, y + d, z) - f(x, y - d, z)),
            (f(x, y, z + d) - f(x, y, z - d))
        )
    return norm

This topic is closed to new replies.

Advertisement