-
Notifications
You must be signed in to change notification settings - Fork 25
Motor Mount
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.
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.
motor(){
attach("rotor")
rod(d=30,h=10, $class="wrapper");
attach("screw")
rod(d=10,h=10, $class="wrapper");
}
Then we'll take the hull of the wrappers then subtract out some space for the motors, like so:
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 instance of the children()
operator gets its own copy of the child list you provided. 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 what classes were assigned to its ancestor. If an ancestor matches the selector, then attach()
goes ahead and 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");
}