Lego Brick

This tutorial will introduce you to the basic concepts of the µCAD language.
Objective
The goal is to create a parametric Lego brick part and provide it as a reusable library.
Needed Skills
Basic programming and CAD knowledge are required to complete this tutorial.
How to construct a Lego brick
Before designing a fully customizable Lego brick, we will first construct a brick of fixed size and make it customizable afterwards.
We will design three components by extrusion of the following 2D sketches:
- Base: A rectangular frame with struts (purple).
- Cap: A rectangular top plate that closes the base structure (cyan).
- Knobs: The knobs of a Lego brick placed on top of the cap (green).

Next, we will use the sketches to create a 3D model of a Lego brick.
Finally, we will compile everything into a proper library.
Preparation
Before we can start, you may need to install µcad itself, as well as some other useful tools.
Install µcad
µcad can be installed with user privileges.
Install rust
First, you may need to install rust as described here rustup.rs:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Install µcad command line tool
Then, execute this command on the shell to install microcad:
cargo install microcad
Install Plugins (VSCode)
µcad brings a VSCode plugin with syntax coloring which you might want to install from our source code repository at github.com.
Other useful plugins
Install SVG Preview
You might want to install Svg Preview for VSCode.
Install STL Viewer extension
Another useful extension is the vscode-stl-viewer.
Create new µcad file
Before we design any geometry, we use the microcad command line tool to create a new µcad project:
microcad create lego_brick
This will create a file lego_brick.µcad.
Let's open this file in VSCode:
// microcad generated file
sketch YourSketch( /* your building plan */ ) {
// your code
}
// create YourSketch
YourSketch();
We can export the file using the following command:
microcad export lego_brick
Nothing will be exported because the sketch does not contain any output geometry. Therefore, let's add some!
Sketch the base
The base sketch will consist of a frame and three rings that will become the struts.
First, we will create the frame...
Creating the frame
The first geometry we want to construct is the frame of the brick's base. It consists of an outer and an inner rectangle.
The outer frame is a rectangle with a width = 31.8mm and a height = 15.8mm.
From that we will derive the inner frame by using thickness = 1.2mm as parameter.
Creating a rectangle
To construct a rectangle in µcad, we use a sketch with the name std::geo2d::Rect.
Open the lego_brick.µcad file you have created before, delete all contents and
replace it with the following single statement:
std::geo2d::Rect(width = 31.8mm, height = 15.8mm);
The above statement calls the built-in sketch std::geo2d::Rect
with the parameters width and height set to our measures.
Like every statement in µcad, it ends with a semicolon (;).
Executing this statement will eventually construct the actual geometry.
As you can see, arguments in µcad are quite explicit. There are no positional parameters in µcad! Instead, arguments must be provided with an identifier or match unambiguously by type.
Also you can see that in µcad all values are attached to a unit (like mm in the above code).
The unit implicitly defines the type (e.g. using mm will lead to a Length type).
If you calculate with those values, units will be calculated too!
So if you multiply a length with another you will get a value of type Area (e.g. mm²).
Creating a second rectangle
Like the outer frame, the inner frame is a std::geo2d::Rect too:
thickness = 1.2mm;
std::geo2d::Rect(width = 31.8mm - 2 * thickness, height = 15.8mm - 2 * thickness);
We have defined a new value thickness = 1.2mm to store the frame's wall thickness.
Then, we construct a rectangle by taking the original width and height and subtracting
twice the thickness from both.
We can now output the inner and outer geometry simultaneously.
Similar to the thickness = 1.2mm, we also assign width and height their respective
values to shorten the code:
thickness = 1.2mm;
width = 31.8mm;
height = 15.8mm;
std::geo2d::Rect(width, height);
std::geo2d::Rect(width = width - 2 * thickness, height = height - 2 * thickness);
Because the arguments we give to the first std::geo2d::Rect() match exactly the parameter
names of it we do not need to write extra parameter names here.
This is called auto-matching.
It prevents us from having to write the argument names twice:
std::geo2d::Rect(width = width, height = height);
Now, we can execute the export command from the command line tool:
microcad export lego_brick.µcad
The export command will produce a Scalable Vector Graphic (SVG) file named lego_brick.svg
next to the lego_brick.µcad file.
By default, all 2D geometries are exported to SVG.
Congratulations, you have exported your first 2D geometry with µcad!
Although the measurements of these rectangles are correct, our intention was to create a frame in which the both rectangles define the boundary of the frame. To achieve this, we will use an operation to combine them.
Subtract
Until now, we have two rectangles which are generated within the same file but to build a frame, we have to combine them.
Grouping statements
The first step is to bundle the rectangles into a group with curly brackets {}.
So let's put some around the frame's rectangles.
thickness = 1.2mm;
width = 31.8mm;
height = 15.8mm;
{
std::geo2d::Rect(width, height);
std::geo2d::Rect(width = width - 2 * thickness, height = height - 2 * thickness);
}
As you can see, there is no ; after the braces.
The visual output did not change by using the group braces. However, now we can combine both rectangles by using an operation.
Manipulate geometry with Operations
In µcad, the operation to subtract a geometry from one another is called subtract.
In our case, we want to subtract the outer part by the inner part in our frame group:
thickness = 1.2mm;
width = 31.8mm;
height = 15.8mm;
{
std::geo2d::Rect(width, height);
std::geo2d::Rect(width = width - 2 * thickness, height = height - 2 * thickness);
}.std::ops::subtract(); // Apply the operation.
Now the semicolon is back, because we added the operation.
Use Statement
You might be wondering why we always have to write std::geo2d:: and std::ops:: in front of Rect and subtract.
This is because builtin sketches (and parts) in µcad are organized within modules in a
standard library.
std is the name of the top module of this library and
geo2d
is a submodule of std and contains all built-in sketches.
Writing std::ops and std::geo2d in front of each element seems redundant and cumbersome.
Luckily, µcad has syntax elements called use statements.
Apart from the shorter code, another useful feature of the statement is that it allows you to explicitly specify which parts of a module you want to use throughout the source file.
This means instead of the previous code, we can simply write:
use std::geo2d::Rect;
use std::ops::subtract;
thickness = 1.2mm;
width = 31.8mm;
height = 15.8mm;
{
Rect(width, height);
Rect(width = width - 2 * thickness, height = height - 2 * thickness);
}.subtract();
As you can see, this makes the code much simpler and clearer.
Naming models
During the design process, we will add more geometry to our design.
Therefore, it is useful to identify each sub-geometry by a name.
In the next we want to give the rectangle a name outer, so we can identify it more easily:
outer = std::geo2d::Rect(width = 31.8mm, height = 15.8mm);
By adding outer = to the call std::geo2d::Rect(..), we have created an assignment.
Now, the output rectangle will be stored in the value outer.
However, when we export the file again via microcad export lego_brick.µcad,
you will notice that nothing is exported.
Why? Because in µcad, assignments are not part of the output geometry.
A second statement outer; is needed to output the geometry stored in the outer value.
outer = std::geo2d::Rect(width = 31.8mm, height = 15.8mm);
outer;
Naming the rectangles leads to some better readability but the code will get quite a bit longer, because for each rectangle we now need a second statement to render them.
This makes more sense, if you use an Operator (-) instead of an Operation (subtract()) to combine them.
use std::geo2d::Rect;
thickness = 1.2mm;
width = 31.8mm;
height = 15.8mm;
// name both rectangles
outer = Rect(width, height);
inner = Rect(width = width - 2 * thickness, height = height - 2 * thickness);
// what was { .. }.subtract() before:
outer - inner;
Now any reader can easily understand what's going on.
As you might have mentioned, we do not need the line use std::ops::subtract; anymore.
This is because µcad brings some builtin binary operators which are hard-linked to builtin operations:
| Operator | Builtin Operation | Description |
|---|---|---|
- | __builtin::subtract | Geometrical difference |
| | __builtin::union | Geometrical union |
& | __builtin::intersect | Geometrical intersection |
Those builtin operations are from the builtin library which can be found within the global module __builtin.
Usually there is no need to use the builtin library directly, because all builtin functionalities are also accessible via the standard library and with a more convenient interface.
Finish the frame
Now we have successfully created a model which describes the frame by the difference of two rectangles.
At first glance, it might seem a bit cumbersome to go through multiple steps just to create a simple frame. However, this example was intentionally designed to introduce you to the fundamental concepts of µcad - such as workbenches, operations and groups. Those foundational steps give you a clearer understanding of how µcad works under the hood.
Fortunately, µcad has a ready-to-go sketch in the std library to construct a frame geometry like
we have constructed: the Frame sketch.
Using it, we can achieve the same result as before but with a much simpler expression:
// Include all from std::geo2d using * (including Frame)
use std::geo2d::*;
thickness = 1.2mm;
width = 31.8mm;
height = 15.8mm;
// Construct a frame
Frame(width, height, thickness);
It looks fine, so let's continue with the struts...
Creating the struts
Now after we have finished the frame, we can start with the struts.
Looking at it,
we find three inner and three outer circles with the measures of 4.8 mm and 6.51 mm.
Quite similar to the rectangles we have used in Frame, but now there are three times more elements.
Creating circles
We now can easily construct a single strut by using std::geo2d::Circle() and repeat the lesson we had before,
but our Lego brick needs three of them.
The shape of each strut remains the same - they’re simply offset horizontally by 8mm to left and right.
From the concept we know already, a first solution could be to write the strut three times
and translate them using std::ops::translate().
use std::geo2d::*;
use std::ops::*;
Circle(d = 6.51mm) - Circle(d = 4.8mm);
(Circle(d = 6.51mm) - Circle(d = 4.8mm)).translate(x = 8mm);
(Circle(d = 6.51mm) - Circle(d = 4.8mm)).translate(x = -8mm);
The code above produces the expected result. However, the code is quite repetitive.
We could improve it slightly by storing the expression Circle(d = 6.51mm) - Circle(d = 4.8mm) in a value, say strut.
But even then, we’d still need to write out each translate(...) call manually.
And more importantly: What if we wanted the number of struts to be flexible or generated dynamically?
To solve this in a clean and scalable way, µcad supports multiplicity, allowing us to generate repeated geometry with minimal, reusable code.
Let’s explore that next.
TODO
- Do we need to explain that we now uses
( .. ).translate()instead of curly brackets?
Multiplicity
To avoid having to call translate multiple times, µcad provides a powerful feature called multiplicity.
Instead of applying translate() separately for each position, you can pass it an array of values.
An array of values is expressed with [] brackets.
µcad then will automatically apply the operation once for each value in the array.
This allows us to shorten the previous example significantly:
use std::geo2d::*;
use std::ops::*;
(Circle(d = 6.51mm) - Circle(d = 4.8mm)).translate(x = [-8mm, 0mm, 8mm]);
With just a single line of code, we've created three struts - each correctly positioned! This approach is not only more concise, but also easier to maintain and scale, especially if you later want to add more positions dynamically.
But we still have to write 8mm twice, but we can change this be multiplying the array with that value:
use std::geo2d::*;
use std::ops::*;
(Circle(d = 6.51mm) - Circle(d = 4.8mm)).translate(x = [-1, 0, 1] * 8mm);
Ranges
The term [-1, 0, 1] can be replaced with a range expression [-1..1], which yields the array we need:
use std::geo2d::*;
use std::ops::*;
(Circle(d = 6.51mm) - Circle(d = 4.8mm)).translate(x = [-1..1] * 8mm);
A range expression has the syntax [m..n] where m and n have to be of type Integer.
As you might have mentioned µcad ranges differ from ranges in other languages (like Rust):
They include the end value - in Rust you would have to write [-1..=1] to achieve the same
if you write [-1..1] in µcad.
Finish the struts
Maybe you already question yourself if there is something similar to std::geo2d::Frame() for our circles?
And yes there is, and it's called std::geo2d::Ring.
So let's shorten our strut code a last time:
use std::geo2d::*;
use std::ops::*;
Ring(outer_d = 6.51mm, inner_d = 4.8mm).translate(x = [-1..1] * 8mm);
At this point, we are almost finished with the base. We just have to find a way to combine frame and structs.
Union operation
We can combine the frame and the struts into a single geometry by using the
union
operation or the | operator.
The code in the lego_brick.µcad with the whole 2D geometry of the brick's base will look like this:
use std::geo2d::*;
use std::ops::*;
thickness = 1.2mm;
width = 31.8mm;
height = 15.8mm;
frame = Frame(width, height, thickness);
struts = Ring(outer_d = 6.51mm, inner_d = 4.8mm)
.translate(x = [-1..1] * 8mm);
frame | struts; // We could also write `{ frame; struts; }.union()` but the `|` operator is more elegant.
If you export the file, you will see a frame and the structs combined into a single object.
Create a sketch for the base
Now, we want to turn the construction of the Lego brick base into a reusable, parametric component. In µcad, a reusable, parametric component that produces or transforms a geometry is called workbench.
There are three kinds of workbenches:
- sketches: produce 2D geometry, e.g.
Rect. - parts: produce 3D geometry, e.g.
Sphere. - op: Turn some input geometry into output geometry, e.g.
translate,unionorsubtract.
Definition of our first sketch
Let's encapsulate the construction of the frame into a sketch workbench called Base.
use std::geo2d::*;
use std::ops::*;
sketch Base(width: Length, height: Length, thickness = 1.2mm) {
frame = Frame(width, height, thickness);
struts = Ring(outer_d = 6.51mm, inner_d = 4.8mm)
.translate(x = [-1..1] * 8mm);
frame | struts;
}
Base(width = 31.8mm, height = 15.8mm);
If we examine the syntax of the above example, we can see the following things:
- Names of sketches are commonly written in
PascalCase, starting with a capital letter. - The sketch
Basehas 3 parameterswidth,heightandthickness. Together they are called the building plan ofBase. widthandheighthave the typeLengthand no default value, they are required.thicknessis also of typeLength, but implicitly, because we have defined a default value1.2mmwhich is aLengthof unitmm.- The body
{ ... }ofBaseconstructs the actual geometry. Base(width = 15.8mm, height = 31.8mm)is a call of the sketch.
And the best part: We don't even need additional value stores for our measures like thickness, width etc.
Every measure has a meaningful name in the parameters.
This makes the code clearer and changes easier.
An analogy to natural language
In the previous sections, we have been introduced to main concepts of µcad. If we draw an analogy to natural language, we can summarize:
- The workbenches
Base,FrameandCircleact like a noun, the subject of the sentence - it's the geometry being described or manipulated. - The operation
translatefunction like verbs, indicating operations being applied to the geometry. - The parameters
x = 20mmand45°serve as adverbs, specifying how the operations are carried out. - Groups
{}serve as subclauses. - Assignments
a = Rect(...)are used to give things a unique name:ais a rectangle.
This analogy helps illustrate how the µcad syntax is designed to be both readable and logical, resembling the structure of natural language in a way that makes the code easier to understand.
Now, we have seen all concepts to actually design our Lego brick in 3D.
Sketch caps & knobs
With the knowledge we have gained in the previous chapter,
the remaining sections of the brick (Cap and Knobs) can be constructed swiftly.
Cap
The Cap is nothing more than a rectangle.
We do not have to define a specific sketch Cap, instead we can use an alias:
// alias Rect as Cap
use std::geo2d::Rect as Cap;
Cap(width = 31.8mm, height = 15.8mm);
std::geo2d::Rect will now also be known as Cap.
Knobs
The knobs of the brick are simple circles with a diameter of 4.8mm.
We can easily construct a grid with circles via multiplicity:
std::geo2d::Circle(d = 4.8mm, c = (
x = ([-1..2] - 0.5) * 8mm,
y = ([0..1] - 0.5) * 8mm)
);
Because ranges can only deal with integers, calculating x and y is a bit tricky here,
because x is [-1..2] (which is [-1, 0, 1, 2]) and y is [0..1], we now have no
element in the middle anymore.
So we have to subtract 0.5 from all the array values before multiplying with 8mm to get a centered result.
To avoid this complication we can use the operation center().
By default, if we do not pass any arguments to operation, it will center the object to origin.
std::geo2d::Circle(d = 4.8mm, c = (
x = [0..3] * 8mm,
y = [0..1] * 8mm)
).std::ops::center();
The code looks clearer now.
Tuples
Notice that we have called the std::geo2d::Circle with an additional argument c.
c is given as a tuple (x = ..., y = ...).
A tuple is a collection of (mostly named) values.
The parameter c of a circle is supposed to be a tuple of type (x: Length, y: Length).
By passing an array of Length to the tuple, we are generating a multiplicity, which eventually creates 2*4 circles.
Let's create a sketch for the knobs:
sketch Knobs(diameter = 4.8mm) {
std::geo2d::Circle(d = 4.8mm, c = (x = [0..3] * 8mm, y = [0..1] * 8mm))
.std::ops::center();
}
Knobs();
We now have all the sketches we need! Let's move on and bring them together...
Putting it together
Below is an intermediate result of the sketches of the three components which we now successfully have defined:
use std::geo2d::*;
use std::ops::*;
const SPACING = 8mm;
sketch Base(width: Length, height: Length) {
thickness = 1.2mm;
frame = Frame(width, height, thickness);
struts = Ring(outer_d = 6.51mm, inner_d = 4.8mm)
.translate(x = [0..2] * SPACING)
.center();
frame | struts;
}
use Rect as Cap;
sketch Knobs() {
Circle(d = 4.8mm, c = (x = [0..3] * SPACING, y = [0..1] * SPACING))
.center();
}
width = 31.8mm;
height = 15.8mm;
Base(width, height);
Cap(width, height);
Knobs();
Across the Lego universe, the spacing of 8mm is used everywhere.
To address this we can store it in a constant named SPACING using the const keyword.
This makes SPACING available in all sketches within that file (or module).
The name of a constant must be in capital letters.
It can be used from within the current module/file and from all sketches and parts within that module.
In the next steps, we want to create a 3D geometry.
Create a part: LegoBrick
Now that we have brought everything together in 2D, we want to create a proper part using the sketches we developed to form a 3D Lego brick.
Extrude into 3D
Now, we want to convert the three 2D sketches into a 3D geometry part.
This can be achieved by extrusion.
The corresponding µcad operation is called std::ops::extrude.
As a first example, let's take the cap of the brick and extrude it by 1.0 mm into 3D:
use std::ops::extrude;
use std::geo2d::Rect as Cap;
width = 15.8mm;
height = 31.8mm;
Cap(width, height)
.extrude(1.0mm);
This will create a box with dimensions 15.8 ⨯ 31.8 ⨯ 1.0 mm.
Note that with std::ops::extrude() we will extrude along Z-axis by default.

Create a first version of the LegoBrick
Let's make a brick out of our Base, the Knobs and the Cap sketches and integrate everything into a part.
We extrude Base, Knobs and Cap and translate them in Z direction if necessary.
Afterwards, we combine the three components using the | operator.
use std::ops::*;
use std::geo2d::*;
const SPACING = 8mm;
sketch Base(width: Length, height: Length) {
thickness = 1.2mm;
frame = Frame(width, height, thickness);
struts = Ring(outer_d = 6.51mm, inner_d = 4.8mm)
.translate(y = [0..2] * SPACING)
.center();
frame | struts;
}
use Rect as Cap;
sketch Knobs() {
center = (x = [0..1] * SPACING, y = [0..3] * SPACING);
Circle(diameter = 4.8mm, center).center();
}
part LegoBrick(base_height = 9.6mm) {
width = 15.8mm;
height = 31.8mm;
top_thickness = 1.0mm;
base = Base(width, height)
.extrude(base_height);
cap = Cap(width, height)
.extrude(top_thickness)
.translate(z = base_height - top_thickness);
knobs = Knobs()
.extrude(1.7mm)
.translate(z = base_height);
// Combine all components
base | cap | knobs;
}
LegoBrick();
When we export the code snippet above, an STL file will be exported instead of an SVG file.

Make a parameterization concept
In this step, we want to make the Lego brick part fully parametric and reusable. Via using parameters, we want to:
-
control the number of knobs in both directions
-
control the brick's height
-
create a reusable Lego brick library so that we can write this:
lego_brick::LegoBrick(rows = 2, columns = 2, base_height = 9.6mm * 2); -
All our sketches shall lay beside that
LegoBrickinside a new modulelego_brick.
First, though, we need to find a way to place elements more generically than before.
Custom operation
The knobs and struts are created using multiplicity by translate and align operations.
To make placing the elements more generic we will create an operation called grid
which arranges elements in a grid which is centered to origin:
use std::ops::*;
const SPACING = 8mm;
op grid(columns: Integer, rows: Integer) {
@input
.translate(x = [0..columns] * SPACING, y = [0..rows] * SPACING)
.center()
}
The grid operation takes rows and columns as parameters.
Operations - as we already know - have not only an output geometry but an input geometry as well.
To be able to access those input geometry we need to use the keyword @input.
With @input we insert the elements that are given by the caller.
In our case that will be a knob or a strut sketch.
We now can rewrite Knobs and Frame sketches by adding rows and columns
as parameter and using the grid operation:
use std::geo2d::*;
use std::ops::*;
const SPACING = 8mm;
op grid(columns: Integer, rows: Integer) {
@input
.translate(x = [1..columns] * SPACING, y = [1..rows] * SPACING)
.center()
}
sketch Base(
columns: Integer,
rows: Integer,
width: Length,
height: Length
) {
thickness = 1.2mm;
frame = Frame(width, height, thickness);
struts = Ring(outer_d = 6.51mm, inner_d = 4.8mm)
.grid(columns = columns-1, rows = rows-1);
frame | struts;
}
sketch Knobs(columns: Integer, rows: Integer) {
Circle(d = 4.8mm)
.grid(columns, rows);
}
use Rect as Cap;
columns = 4;
rows = 2;
width = columns * SPACING - 0.2mm;
height = rows * SPACING - 0.2mm;
Base(rows, columns, width, height);
Cap(width, height);
Knobs(rows, columns);
Additionally, to the grid operation, we compute the overall width and
height in the LegoBrick part, which are:
width = rows * 8mm - 0.2mmheight = columns * 8mm - 0.2mm
Now we are ready to write the final part of a LegoBrick.
The final part
First we add some default values for rows and columns in the building plan and use
them in the last statement where we call LegoBrick().
use std::geo2d::*;
use std::ops::*;
const SPACING = 8mm;
op grid(columns: Integer, rows: Integer) {
@input
.translate(x = [1..columns] * SPACING, y = [1..rows] * SPACING)
.center()
}
sketch Base(
columns: Integer,
rows: Integer,
width: Length,
height: Length
) {
thickness = 1.2mm;
frame = Frame(width, height, thickness);
struts = Ring(outer_d = 6.51mm, inner_d = 4.8mm)
.grid(columns = columns-1, rows = rows-1);
frame | struts;
}
use Rect as Cap;
sketch Knobs(columns: Integer, rows: Integer) {
Circle(d = 4.8mm)
.grid(columns, rows);
}
part LegoBrick(rows = 2, columns = 4, base_height = 9.6mm) {
width = columns * SPACING - 0.2mm;
height =rows * SPACING - 0.2mm;
cap_thickness = 1.0mm;
base = Base(rows, columns, width, height)
.extrude(base_height - cap_thickness);
cap = Cap(width, height)
.extrude(cap_thickness)
.translate(z = base_height - cap_thickness);
knobs = Knobs(rows, columns)
.extrude(1.7mm)
.translate(z = base_height);
base | cap | knobs;
}
// render a brick with default values
LegoBrick();

Let's make a library out of it, and use it from another file in the next section.
External module
Let's assume we want to use the LegoBrick from an external file.
Fortunately, this is simple!
We just have to create a second file my_brick.µcad:
microcad create my_brick
The directory structure is supposed to contain these files:
lego_brick.µcad
my_brick.µcad
Let's add the following content to the my_brick.µcad file to
create a few bricks with different parameters:
mod lego_brick;
use lego_brick::*;
// 2x2 double height
double_2x2 = LegoBrick(rows = 2, columns = 2, base_height = 9.6mm * 2);
// 4x2 single height
single_4x2 = LegoBrick(rows = 4, columns = 2);
// 3x2 one-third height
third_3x2 = LegoBrick(rows = 3, columns = 2, base_height = 3.2mm);
// generate geometry placing all elements side by side
use std::ops::translate;
single_4x2;
double_2x2.translate(y = -40mm);
third_3x2.translate(y = 40mm);
As you can see in the first line we use a mod statement to load our external module lego_brick.
Visibility
To make this work, we also need to change one line in our final part:
pub part LegoBrick(rows = 2, columns = 4, base_height = 9.6mm) {
Here we add the keyword pub to make LegoBrick visible from outside modules (like our my_brick.µcad):
Now you can export my_brick.µcad to generate the result of our tutorial.
Control Export
Until now when we export the whole the geometry as an STL this results in a single output file:
microcad export lego_brick
But we also can use the #[export] attribute to export each brick to a different file:
mod lego_brick;
use lego_brick::*;
#[export = "double_2x2.stl"]
double_2x2 = LegoBrick(rows = 2, columns = 2, base_height = 9.6mm * 2);
#[export = "single_4x2.stl"]
single_4x2 = LegoBrick(rows = 4, columns = 2);
#[export = "third_3x2.stl"]
third_3x2 = LegoBrick(rows = 5, columns = 1, base_height = 3.2mm);
When we export the file now, three files with the specified names will be created
and we do not need the translate() operations anymore.
TODO
- It seems unclear why the export attribute is used at assignments when we said before, that assignments will not generate any geometry.
Recap
In this tutorial you should have learned about the following things:
- Installing µcad
- Creating a new µcad file
- Using basic 2D primitives in
std::geo2d:Rect,Circle,Frame - Define and use named values and models
- Combining geometries with
std::ops::subtractandstd::ops::union - Geometrical operators:
|,- - Using the
usestatement - Move geometries with
std::ops::translate - Arrays
- Argument multiplicity
- Ranges
- Constants
- Extruding sketches with
std::ops::extrude - Creating custom sketches, parts and operations
- Separating code into external modules
- Controlling export with attributes
Congratulations, you now have successfully finished this tutorial!
If you could not get enough, try to master the additional exercises...
Additional Exercises
- Play around with the parameters of
LegoBrick, e.g. create a 5x7 brick. - Can you provoke any errors by bad parameters?
- Use multiplicity to create three Lego bricks.
- Make multiple Lego bricks from two arrays of given sizes (rows and columns).
- Our tutorial missed some details of the real Lego brick. Can you add them from these specifications?