Skip to content
Carl Davidson edited this page Feb 12, 2015 · 9 revisions

Version 2015.02.14 introduces a neat little module called attach(). attach() enables you to create a module with multiple references to the children() operator. When it comes time to invoke the module, you can pick and choose which of these references will handle the child modules you pass to it.

This might be easier to understand with an example. Let's look at that motor we created earlier :

box(42)
align(top)
{
    rod(d=22,h=10);
    
    translated(31*y, [-1,1]/2) 
    translated(31*x, [-1,1]/2) 
    rod(d=3,h=7);
}

What if we want to make a motor mount? One way we can do it is to wrap some material around the screws and rotor. We'll take the hull of the wrappers then subtract out some space for the motors, like so:

differed("motor")
hulled("wrapper")
box(42, $class="motor")
align(top)
{
    rod(d=22,h=10)
    rod(d=30,h=10, $class="wrapper");
    
    translated(31*y, [-1,1]/2) 
    translated(31*x, [-1,1]/2) 
    rod(d=3,h=10)
    rod(d=10,h=10, $class="wrapper");
}

But now the motor and the mount are mixed in with one another. What if we want to keep them separate?

Enter attach(). First we'll setup a module that just contains parts for the motor. We'll include the children() operator where we think we'll want other parts to interface with the design.

module motor(){
	box(42, $class="motor")
	align(top)
	{
	    rod(d=22,h=10, $class="motor rotor")
	    children();
	    
	    translated(31*y, [-1,1]/2) 
	    translated(31*x, [-1,1]/2) 
	    rod(d=3,h=10, $class="motor screw")
	    children();
	}
}

When we invoke the motor() module, we'll include the wrappers as child modules, then perform differed() and hulled() as we did before.

differed("motor")
hulled("wrapper")
motor(){
	attach("rotor")
	rod(d=30,h=10, $class="wrapper");
	
	attach("screw")
        rod(d=10,h=10, $class="wrapper");
}

Neat, but how does it work? Well, when you execute the code above, every child module that is supply to motor() module upon invocation gets inserted into every instance of the children() operator inside the module. Without attach(), our code is effectively rending this:

box(42, $class="motor")
align(top)
{
    rod(d=22,h=10, $class="motor rotor"){
	rod(d=30,h=10, $class="wrapper");
	rod(d=10,h=10, $class="wrapper");
    }
    
    translated(31*y, [-1,1]/2) 
    translated(31*x, [-1,1]/2) 
    rod(d=3,h=10, $class="motor screw"){
	rod(d=30,h=10, $class="wrapper");
	rod(d=10,h=10, $class="wrapper");
    }
}}

All attach() does is filter which child should render where. It does this by checking its parent's class. If the parent's class matches the selector, then attach() renders its children.

In other words, the above code could be rewritten as follows:

differed("motor")
hulled("wrapper")
motor(){
	show("rotor>*")
	rod(d=30,h=10, $class="wrapper");
	
	show("screw>*")
        rod(d=10,h=10, $class="wrapper");
}
Clone this wiki locally