4 views

Skip to first unread message

Mar 19, 2021, 11:42:48 AM3/19/21

to Curv

Hi all,

I’m a new user of Curv. Loving the pure functional direction and the SDF basis for geometry.

The following code is giving me trouble. I expect the `use_chamfer`

parameter to allow me to select between two different boolean functions, but instead I get an error. If I replace

```
fun = if use_chamfer chamfer(bevel_distance).union else smooth(.02).union;
```

with

```
fun = if true chamfer(bevel_distance).union else smooth(.02).union;
```

the code compiles.

Here’s the full code:

```
let
cross = {bevel_distance = .02, use_chamfer = false} ->
let
cross_bar = cylinder({d: 1, h:3});
cross_bars = [
cross_bar,
cross_bar >> rotate({angle: 90*deg, axis:[1, 0, 0]}),
cross_bar >> rotate({angle: 90*deg, axis:[0,1,0]})
];
fun = if use_chamfer chamfer(bevel_distance).union else smooth(.02).union;
in
cross_bars.[0] >> into fun [cross_bars.[1]] >> into fun [cross_bars.[2]];
in
parametric
'bevel distance' :: slider[.01,1] = .02;
'use chamfer' :: checkbox = false;
in
cross {bevel_distance:'bevel distance', use_chamfer:'use chamfer'}
```

Mar 19, 2021, 1:59:12 PM3/19/21

to Curv

You have encountered a limitation of Curv's GPU compiler. I don't have a workaround. Right now, checkbox parameters are only really useful for making conditional *numeric* expressions. Conditional functions and conditional shapes don't work yet, if the condition contains a parameter declared using 'parametric'.

The root cause relates to the way that 'parametric' shapes are compiled into GLSL shader code (which runs on the GPU). The 'use chamfer' checkbox is a boolean parameter that is updated every frame, and the shader checks the value of this parameter in each frame. So the definition

fun = if use_chamfer chamfer(bevel_distance).union else smooth(.02).union

must be evaluated inside the shader. But this is an if expression that returns a function value, and in GLSL, there is no concept of a 'function value' or 'function pointer'. So there's no direct translation for this if expression in GLSL, and that is the problem that the GPU compiler has run into. Instead of fixing this problem by transforming the code, or producing a clear error message, it is getting confused and giving an opaque error message.

The planned fix is going to be a new shape compiler that compiles these expressions by rearranging the surrounding code. It requires a rewrite of the GPU compiler because I need a better IR (intermediate representation). I'm working on a roadmap; my aspiration is to have this working "sometime this year".

Doug Moen

--You received this message because you are subscribed to the Google Groups "Curv" group.To unsubscribe from this group and stop receiving emails from it, send an email to curv+uns...@googlegroups.com.To view this discussion on the web, visit https://groups.google.com/d/msgid/curv/6e783dd2-ffa5-4071-8c49-bd064b5eee53n%40googlegroups.com.

Mar 19, 2021, 4:16:50 PM3/19/21

to Curv

hmmm ok. so a workaround for this would be to create a single function that switched between the two methods inside the function i guess.

like this

```
let
chamfer_min[a, b, r] =
let e = max[r - abs(a - b), 0];
in min[a, b] - e*.5;
mychamfersmoothunion = r -> chamfer_int -> smooth_int -> [s1,s2] ->
make_shape {
dist p =
let a = s1.dist p;
b = s2.dist p;
in chamfer_min[a, b, r] * chamfer_int + smooth_min[a, b, r] * smooth_int;
colour p =
let d1 = s1.dist p;
d2 = s2.dist p;
in if (d2 <= 0 || d2 <= d1) s2.colour p else s1.colour p;
bbox = [ min[s1.bbox@MIN, s2.bbox@MIN],
max[s1.bbox@MAX, s2.bbox@MAX] ];
is_2d = s1.is_2d && s2.is_2d;
is_3d = s1.is_3d && s2.is_3d;
};
cross = {bevel_distance = .02, use_chamfer = false} ->
let
cross_bar = cylinder({d: 1, h:3});
cross_bars = [
cross_bar,
cross_bar >> rotate({angle: 90*deg, axis:[1, 0, 0]}),
cross_bar >> rotate({angle: 90*deg, axis:[0,1,0]})
];
use_chamfer_int = (bit use_chamfer);
use_smooth_int = (bit (not use_chamfer));
myunion = mychamfersmoothunion bevel_distance use_chamfer_int use_smooth_int;
in
cross_bars.[0] >> into myunion [cross_bars.[1]] >> into myunion [cross_bars.[2]];
in
parametric
'bevel distance' :: slider[.01,1] = .02;
'use chamfer' :: checkbox = false;
in
cross {bevel_distance:'bevel distance', use_chamfer:'use chamfer'}
```

Reply all

Reply to author

Forward

0 new messages

Search

Clear search

Close search

Google apps

Main menu