Search code examples
recursionopenscad

Recursively constructing an object in OpenSCAD


So I'm trying to build a simple stack of scaled cubes using a recursive function:

function stack(levels) = (
  levels <= 0
  ? cube([1,1,1], center=true)
  : union() {
    cube([1,1,1], center=true);
    translate([0, 0, 0.9]) scale([1, 1, 0.9]) stack(levels - 1);
  }
);

stack(5);

Now for some reason I currently don't understand OpenSCAD tells me that I've got a syntax error in line 4, marking the editor like this:

highlighted syntax error in the mentioned code

Sadly the console only yields this output:

ERROR: Parser error in line 4: syntax error

ERROR: Compilation failed!

So it's somewhat hard for me to figure out what exactly I'm doing wrong. I guess there's a way to do this using for, but I would consider a recursive approach more readable.

I'll try to do this with modules, and if that doesn't work I can resort to use for in combination with modules I suppose - it's more that I'd like this to work and find it very readable.


Update: So from the OpenSCAD User Manual I get this snippet: OpenSCAD definition of modules and functions

I would tend to interpret this so that it is not possible to create a recursive structure the way I imagined.

Instead I could:

  • Use a helper function to generate the cube parameters and compute their union afterwards.
  • Rewrite the structure in terms of a for loop.

I'm uncertain whether my conviction is correct, but the reasoning is this:

  1. I cannot create objects in a function because that would have an effect.
  2. I cannot use a module recursively because it doesn't return a result and possibly the way variables work in OpenSCAD would interfere with the idea.

Solution

  • You can make a recursive module, the only problem there is the ternary operator takes values not objects:

    module stack(levels) {
      if(levels) {
        cube([1,1,1], center=true);
        translate([0, 0, 0.9]) scale([1, 1, 0.9]) stack(levels-1);      
      } else {
        cube([1,1,1], center=true);
      }
    }
    
    stack(5);
    

    Here's another example: https://github.com/cashlo/OpenSCAN-Objects/blob/master/xmas-tree.scad