-
Notifications
You must be signed in to change notification settings - Fork 25
Home
Installation
Primitives
Centering
Alignment
Orientation
Sizing
Styling
Demos
To use the library on your own machine, download "relativity.scad" from the project page on Thingiverse. This will get you the latest stable release. Alternatively, you can download the latest unstable release of relativity.scad from the root folder of the project page on github.
Once you download the file, place it in the OpenSCAD folder on your machine. The location of this folder varies by operating system. Start OpenSCAD and type the following:
include <relativity.scad>
Its important you import relativity using the "include" keyword. relativity.scad needs to declare variables during its initialization. If you import relativity.scad with the "use" keyword, OpenSCAD will not load these variables, and strange behavior will result!
This OpenSCAD library adds functionality to size, position, and orient objects relative to other geometric primitives.
To do so, the library introduces a new set of modules to replace the default geometric primitives in OpenSCAD:
Render | Module | Replaces |
---|---|---|
box | cube | |
rod | cylinder | |
ball | sphere |
All the original geometry primitives are still there if you need them, and you can decide how much or how little to use them. The new primitives have most all the behavior of their old counterparts, but with two important distinctions.
First, in place of center
is a new attribute, anchor
. This attribute specifies where the axis of rotation is to be placed relative to the object. The anchor
attribute is given as a vector whose elements range from -1 (e.g. bottom of axis) to 1 (e.g. top of axis). A value of 0 indicates the anchor is to be centered along an axis.
+1 | 0 | -1 | |
---|---|---|---|
X | anchor = [1,0,0] | anchor = [0,0,0] | anchor = [-1,0,0] |
Y | anchor = [0,1,0] | anchor = [0,0,0] | anchor = [0,-1,0] |
Z | anchor = [0,0,1] | anchor = [0,0,0] | anchor = [0,0,-1] |
The second distinction among these new primitives allows for the creation of child objects. By default, a child object is positioned with its origin at the center of its parent:
box(50, anchor=[0,0,-1])
sphere(d=55);
this however can be changed using of a second operation, align:
box(50, anchor=[0,0,-1])
align([0,0,1])
sphere(d=60);
You can align objects along any axis. The value passed to align()
is a vector whose elements range from -1 (e.g. bottom of axis) to 1 (e.g. top of axis). A value of 0 indicates an object is to be placed at the center of its parent along that axis.
+1 | 0 | -1 | |
---|---|---|---|
X | align([1,0,0]) | align([0,0,0]) | align([-1,0,0]) |
Y | align([0,1,0]) | align([0,0,0]) | align([0,-1,0]) |
Z | align([0,0,1]) | align([0,0,0]) | align([0,0,-1]) |
You can also pass a list of vectors. When you pass a list of vectors, align()
will create duplicates of its children in the locations indicated by your vectors.
box(50, anchor=[0,0,-1])
align([[0,0,1], [0,1,0]])
sphere(d=60);
The examples above use sphere()
as their child object. However, ball()
can also be be used as a child. Using ball()
will allow us to combine align()
and anchor
, making it easy to stack objects end-to-end:
box(50, anchor=[0,0,-1])
align([0,0,1])
ball(50, anchor=[0,0,-1])
align([0,0,1])
rod(50, anchor=[0,0,-1]);
To allow for readable code, relativity.scad comes with a few constants representing commonly used values for the align
operator:
top = [0,0,1];
center=[0,0,0];
bottom = [0,0,-1];
x = [1,0,0];
y = [0,1,0];
z = [0,0,1];
It is also possible to combine this constant with +
or -
operators, since OpenSCAD does (simple) vector calculations.
There are also two special variables that are exposed by the align()
module, $inward
and $outward
. $inward
points towards the center of a parent object, while $outward
points away from it.
The anchor
parameter defaults to $inward
. This is meant to facilitate stacking objects. All told, the code above can be rewritten:
box(50)
align(top)
ball(50)
align(top)
rod(50);
Child objects by default will maintain the same z-axis orientation as their parent objects
box(50, anchor=[0,0,-1])
align([0,1,0])
rod(d=50, h=50, anchor=[0,-1,0]);
This, however, can be changed with the use of another module, orient
. The orient module will redirect the top of a child object to face a given direction. Sometimes rotation using orient
can be more intuitive than using rotate
box(50, anchor=[0,0,-1])
align([0,1,0])
orient([0,1,1])
rod(d=50, h=50, anchor=[0,0,-1]);
You can also pass a list of vectors to orient
. In this case, orient
will create duplicates of its children with their tops facing the directions you specify in the list.
//OpenSCAD logo:
differed("hole", "not(hole)")
ball(50)
orient([x,y,z])
rod(d=25, h=50, $class="hole");
relativity.scad exposes a dynamic variable, $parent_size
, in case there are any unforeseen circumstances where something needs to be done relative to a parent object. This can also be used when setting the size of a child, say, when creating a fractal:
box([50,50,50])
align(top)
box(0.8*$parent_size)
align(top)
box(0.8*$parent_size);
The tree demo provides a good example for the parent()
and $parent_size
functionality.
To ease the use of $parent_size
, geometric primitives for rod
and ball
accept size
as their first parameter argument, much like cube
and box
.
rod([50,50,50])
align(top)
rod(0.8*$parent_size)
align(top)
rod(0.8*$parent_size);
An interesting consequence to this means you can pass rod
and ball
different values for x,y, and z:
rod([50,50,50])
align(top)
rod([$parent_size.x*.5, $parent_size.y*.7, $parent_size.z*.9])
align(top)
rod([$parent_size.x*.5, $parent_size.y*.7, $parent_size.z*.9]);
Another, more unfortunate side effect means rod
does not currently support multiple diameters/radii through the d1
and d2
parameters. This may change as need arises. You can still use the original cylinder
primitive when circumstances call for it, but a better idea might be to perform the hull between two rods, one of infinitesimal height.
hulled() rod(d=30, h=infinitesimal) rod(d=10, h=20);
Relativity.scad transforms the way you work with objects in OpenSCAD. You'll find yourself working a lot more with "tree-like" structures, where geometric primitives nest inside one another. This is similar to the way you write using nested tags in html. Just like html, there is a system for performing operations on the tree-like structure. In html, there's css. In relativity, there's the CSG operations:
Module | Demo | Code |
---|---|---|
differed | differed("hole","not(hole)") |
|
hulled | hulled("hole") |
|
intersected | intersected("hole", "not(hole)") |
|
show | show("hole") |
|
hide | hide("hole") |
|
colored | colored("red", "hole") |
|
scaled | scaled(0.95, "hole") |
|
resized | resized([47,47,47], "hole") |
|
mirrored | mirrored(y) |
|
rotated | rotated(22*z, class="hole") |
|
translated | translated(10*z, class="hole") |
Selectors are the means through which CSG operations specify class. Selectors are strings whose format is meant to resemble a subset of CSS selector syntax.
Illustrations below uses the following code:
colored("blue", ...)
ball(50, $class="parent")
{
align(x)
ball(40, $class="child A")
align(x)
ball(30, $class="grandchild");
align(z)
ball(40, $class="child B")
align(z)
ball(30, $class="grandchild");
align(-x)
ball(40, $class="child C")
align(-x)
ball(30, $class="grandchild");
}
As of version 2015.02.14, selectors support the following syntax:
Selector | Description | Comments |
---|---|---|
* | selects all primitives | |
A,B | Selects all primitives of class "A" or "B" | |
not(A) | Selects all primitives where $class does not contain "A" | |
child.A | Selects all primitives both of class "child" and "A". NOTE: this differs from CSS, where "." indicates a selection based on class | |
parent grandchild | Selects all primitives of class "grandchild" with any ancestor of class "parent" | |
parent>grandchild | Selects all primitives of class "grandchild" whose parent is of class "parent". All "grandchild" objects have "child" objects as their parent, so no object is selected. | |
parent child,B grandchild | Note how operators are applied - operators are applied left to right. There is no order of operation. | |
(parent child),B grandchild | Selects two types of primitives. The first type is of class "grandchild" with ancestor of class "A". The second type is of class "grandchild" with ancestor of class "B". NOTE: Normal operator precedence is overridden by parentheses, unlike CSS. |
Note that syntax shown above may be subject to change. This is particularly the case where incongruities exist with the CSS selector syntax.
Link | Render | Description |
---|---|---|
Tree | A fractal tree rendered using parent() and mirrored()
|
|
Stepper Motor | A high fidelity NEMA-17 stepper motor written in 50 lines of code | |
Motor Mount | A stepper motor mount made easy with attach()
|
|
Human Body | A human body designed using techniques in classical figure drawing. Work in progress. Not for the faint-hearted. | |
Flower | ||
Centipede |