POV-Ray : Newsgroups : povray.binaries.images : smooth csg : Re: smooth csg Server Time
30 Jul 2024 08:28:57 EDT (-0400)
  Re: smooth csg  
From: Florian Siegmund
Date: 3 Mar 2012 11:30:01
Message: <web.4f524634bc71efa997033c3c0@news.povray.org>
clipka <ano### [at] anonymousorg> wrote:
>
> You do care to share those macros, don't you? <drool>

Hi folks!

I also wrote some function macros for building smooth csg objects with
isosurfaces some time ago. The advatage of these macros in opposite to blobby
constructs is that the smooth connection is limited to an adjustable distance
from the surface, so the shape itself does not change, and this makes it easier
to design things more exactly.
There's a also second parameter which I call "roundedness", so you can change
the smoothness of the connection. It should be set in a range from greater than
zero up to one, where "1" means a circular transition in normal cases. ("normal
cases" means that the function value increases linearly along the surface's
normal vector)
And as you can see in the attached image, there are also macros allowing to
create something like a "facet" between the objects.

But enough talk, here's the code:

// smooth union
// fn_smooth_union (FUNCTION, FUNCTION, FLOAT, FLOAT)
// param#3: distance
// param#4: roundedness
#macro fn_smooth_union (fn_1, fn_2, fn_d, fn_r)
    #local c_1 = fn_d/2;
    #local c_2 = 2/fn_r;
    #local c_3 = fn_r/2;
    function {
        select (
            max (fn_1 (x, y, z), fn_2 (x, y, z)) - fn_d,
            -pow (pow (fn_d - fn_1 (x, y, z), c_2) +
            pow (fn_d - fn_2 (x, y, z), c_2), c_3) + fn_d,
            min (fn_1 (x, y, z), fn_2 (x, y, z))
        )
    }
#end

// smooth intersection
// fn_smooth_intersection (FUNCTION, FUNCTION, FLOAT, FLOAT)
// param#3: distance
// param#4: roundedness
#macro fn_smooth_intersection (fn_1, fn_2, fn_d, fn_r)
    #local c_1 = fn_d/2;
    #local c_2 = 2/fn_r;
    #local c_3 = fn_r/2;
    function {
        select (
            max (-fn_1 (x, y, z), -fn_2 (x, y, z)) - fn_d,
            pow (pow (fn_d + fn_1 (x, y, z), c_2) +
            pow (fn_d + fn_2 (x, y, z), c_2), c_3) - fn_d,
            max (fn_1 (x, y, z), fn_2 (x, y, z))
        )
    }
#end

// smooth difference
// fn_smooth_difference (FUNCTION, FUNCTION, FLOAT, FLOAT)
// param#3: distance
// param#4: roundedness
#macro fn_smooth_difference (fn_1, fn_2, fn_d, fn_r)
    #local c_1 = fn_d/2;
    #local c_2 = 2/fn_r;
    #local c_3 = fn_r/2;
    function {
        select (
            max (-fn_1 (x, y, z), fn_2 (x, y, z)) - fn_d,
            pow (pow (fn_d + fn_1 (x, y, z), c_2) +
            pow (fn_d - fn_2 (x, y, z), c_2), c_3) - fn_d,
            max (fn_1 (x, y, z), -fn_2 (x, y, z))
        )
    }
#end

// smooth exclusion loose
// fn_smooth_exclusion (FUNCTION, FUNCTION, FLOAT, FLOAT)
// param#3: distance
// param#4: roundedness
#macro fn_smooth_exclusion_loose (fn_1, fn_2, fn_d, fn_r)
    #local c_1 = fn_d/2;
    #local c_2 = 2/fn_r;
    #local c_3 = fn_r/2;
    function {
        min (
            select (
                max (-fn_1 (x, y, z), fn_2 (x, y, z)) - fn_d,
                pow (pow (fn_d + fn_1 (x, y, z), c_2) +
                pow (fn_d - fn_2 (x, y, z), c_2), c_3) - fn_d,
                max (fn_1 (x, y, z), -fn_2 (x, y, z))
            ),
            select (
                max (-fn_2 (x, y, z), fn_1 (x, y, z)) - fn_d,
                pow (pow (fn_d + fn_2 (x, y, z), c_2) +
                pow (fn_d - fn_1 (x, y, z), c_2), c_3) - fn_d,
                max (fn_2 (x, y, z), -fn_1 (x, y, z))
            )
        )
    }
#end

// smooth exclusion connected
// fn_smooth_exclusion (FUNCTION, FUNCTION, FLOAT, FLOAT)
// param#3: distance
// param#4: roundedness
#macro fn_smooth_exclusion_connected (fn_1, fn_2, fn_d, fn_r)
    #local c_1 = fn_d/2;
    #local c_2 = 2/fn_r;
    #local c_3 = fn_r/2;
    function {
        -min (
            -select (
                max (fn_1 (x, y, z), fn_2 (x, y, z)) - fn_d,
                -pow (pow (fn_d - fn_1 (x, y, z), c_2) +
                pow (fn_d - fn_2 (x, y, z), c_2), c_3) + fn_d,
                min (fn_1 (x, y, z), fn_2 (x, y, z))
            ),
            select (
                max (-fn_1 (x, y, z), -fn_2 (x, y, z)) - fn_d,
                pow (pow (fn_d + fn_1 (x, y, z), c_2) +
                pow (fn_d + fn_2 (x, y, z), c_2), c_3) - fn_d,
                max (fn_1 (x, y, z), fn_2 (x, y, z))
            )
        )
    }
#end

// fillet union
// fn_fillet_union (FUNCTION, FUNCTION, FLOAT)
// param#3: distance
#macro fn_fillet_union (fn_1, fn_2, fn_d)
    #local c_1 = fn_d/2;
    function {
        select (
            max (fn_1 (x, y, z), fn_2 (x, y, z)) - fn_d,
            fn_1 (x, y, z) + fn_2 (x, y, z) - fn_d,
            min (fn_1 (x, y, z), fn_2 (x, y, z))
        )
    }
#end

// fillet intersection
// fn_fillet_intersection (FUNCTION, FUNCTION, FLOAT)
// param#3: distance
#macro fn_fillet_intersection (fn_1, fn_2, fn_d)
    #local c_1 = fn_d/2;
    function {
        select (
            max (-fn_1 (x, y, z), -fn_2 (x, y, z)) - fn_d,
            fn_1 (x, y, z) + fn_2 (x, y, z) + fn_d,
            max (fn_1 (x, y, z), fn_2 (x, y, z))
        )
    }
#end

// fillet difference
// fn_fillet_difference (FUNCTION, FUNCTION, FLOAT)
// param#3: distance
#macro fn_fillet_difference (fn_1, fn_2, fn_d)
    #local c_1 = fn_d/2;
    function {
        select (
            max (-fn_1 (x, y, z), fn_2 (x, y, z)) - fn_d,
            fn_1 (x, y, z) - fn_2 (x, y, z) + fn_d,
            max (fn_1 (x, y, z), -fn_2 (x, y, z))
        )
    }
#end

// fillet exclusion loose
// fn_fillet_exclusion_loose (FUNCTION, FUNCTION, FLOAT)
// param#3: distance
#macro fn_fillet_exclusion_loose (fn_1, fn_2, fn_d)
    #local c_1 = fn_d/2;
    function {
        min (
            select (
                max (-fn_1 (x, y, z), fn_2 (x, y, z)) - fn_d,
                fn_1 (x, y, z) - fn_2 (x, y, z) + fn_d,
                max (fn_1 (x, y, z), -fn_2 (x, y, z))
            ),
            select (
                max (-fn_2 (x, y, z), fn_1 (x, y, z)) - fn_d,
                fn_2 (x, y, z) - fn_1 (x, y, z) + fn_d,
                max (fn_2 (x, y, z), -fn_1 (x, y, z))
            )
        )
    }
#end

// fillet exclusion connected
// fn_fillet_exclusion_connected (FUNCTION, FUNCTION, FLOAT)
// param#3: distance
#macro fn_fillet_exclusion_connected (fn_1, fn_2, fn_d)
    #local c_1 = fn_d/2;
    function {
        -min (
            -select (
                max (fn_1 (x, y, z), fn_2 (x, y, z)) - fn_d,
                fn_1 (x, y, z) + fn_2 (x, y, z) - fn_d,
                min (fn_1 (x, y, z), fn_2 (x, y, z))
            ),
            select (
                max (-fn_1 (x, y, z), -fn_2 (x, y, z)) - fn_d,
                fn_1 (x, y, z) + fn_2 (x, y, z) + fn_d,
                max (fn_1 (x, y, z), fn_2 (x, y, z))
            )
        )
    }
#end

Regards,
Florian


Post a reply to this message


Attachments:
Download 'smooth_csg.jpg' (294 KB)

Preview of image 'smooth_csg.jpg'
smooth_csg.jpg


 

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.