Assemblies built from the LDraw LEGO parts library.
The parts come from the LDraw library, as served by
//pub/universe/lego/ldraw. Nothing is vendored here: this package is the
assemblies, and the geometry is meshed from LDraw's own .dat files on demand.
A gothic castle: spired towers along the curtain wall and at its corners, a twin-towered gatehouse over a pointed arch, buttresses with pinnacles between the bays, and a tall turreted keep.
![]() |
![]() |
731 parts, nine distinct LDraw parts between them:
| part | count | |
|---|---|---|
Brick:3005 |
271 | 1 x 1 brick |
Brick:3004 |
153 | 1 x 2 brick |
Brick:3941 |
122 | 2 x 2 round brick |
Brick:3010 |
114 | 1 x 4 brick |
Cone:4589 |
44 | 1 x 1 cone — the spires |
Cone:3942b |
19 | 2 x 2 cone |
Brick:3009 |
6 | 1 x 6 brick — the keep's floor |
Baseplate:3811 |
1 | 32 x 32 baseplate — what it all stands on |
Cone:3943b |
1 | 4 x 4 cone — the keep's spire |
Everything sits on LEGO's own grid: 8 mm stud pitch, 9.6 mm brick height. The
parts arrive standing upright in PartCAD's Z-up world, so front, top, right
and iso mean what they say.
pc inspect -a castle
pc render -a -t png --view iso castleA castle this size repeats itself: four identical corner towers, nine identical
spires, sixteen identical buttresses. So castle is not 731 parts in one file -
it is ten sub-assemblies under castle/, placed 44 times between them, and the
baseplate. Each one is written once and built once, and every further use of it
is a cache hit rather than a rebuild; 288 parts are described instead of 731.
| sub-assembly | parts | used | |
|---|---|---|---|
castle/buttress |
9 | 16 | a pier stepping out from the wall, capped with a pinnacle |
castle/spire |
4 | 9 | two 2x2 cones flaring off a tower, then two 1x1 cones to a point |
castle/wall |
65 | 3 | a stretch of curtain wall between two corner towers |
castle/wall-gate |
71 | 1 | the same wall with the gateway's pointed arch corbelled through it |
castle/tower-corner |
15 | 4 | the body of a corner tower |
castle/tower-mural |
12 | 3 | the body of a tower standing along a wall |
castle/tower-gate |
13 | 2 | the body of one of the gatehouse pair |
castle/keep-courses |
14 | 3 | two courses of the keep, the second breaking joint against the first |
castle/keep-lancet |
36 | 2 | four courses: a lancet, and the course that closes it |
castle/keep-top |
48 | 1 | the keep's last three courses, its merlons, four bartizans and the spire |
Each is a PartCAD assembly in its own right, so any of them can be looked at, rendered or built alone:
pc inspect -a castle/tower-corner
pc render -a -t png --view iso castle/wallThe keep is cut into pairs of courses rather than left whole because its masonry alternates: an even course and the odd one that breaks joint against it, three kinds of pair covering all of it but the last course and the roof. The walls are not split further - the gate wall differs from a plain one in every course, so there is no band of it the two could share.
A brick placed by coordinates is a brick nothing holds up: the file says where it ended up, not what puts it there. Most of these bricks say the other thing instead — which brick they sit on, and which stud of it:
- part: //pub/universe/lego/ldraw/Brick:3010
name: w_c1_0
connect:
with: //pub/universe/lego:anti-stud
withInstance: c0r0
name: w_c0_0
to: //pub/universe/lego:stud
toInstance: c2r0//pub/universe/lego declares the pair — a stud on top of a part and an
anti-stud underneath — and PartCAD works the coordinates out. Every one of
the 288 part nodes is joined that way, in the order they are put together —
there is not a single location: left on a part or a piece anywhere in the
model.
Which two ports meet is decided by where they are, not by the stud grid the
part's name implies, because for several of these parts the grid is not the
answer: a Cone 2 x 2 x 2 has four anti-studs under it and a single stud on
top, at its centre, and a Cone 3 x 3 x 2 has nine and four. A joint picked by
grid index puts such a part half a stud out.
A brick joins downwards to a stud under it or upwards into an anti-stud over it, and that is what keeps the number of coordinates down. A unit's bottom course does not have to go first: put one brick of it down, add the brick above that bridges it to its neighbour, and the neighbour then snaps up into that bridge. So the order is grown rather than given — take whatever can be joined to what is already down.
Each piece's first brick says nothing at all — no coordinates and no joint. It is the piece's own origin, and where that goes is for whatever places the piece to decide, so saying it here would be saying it twice.
Getting to none of them took four things beyond the joints themselves, and each was a fault in the model rather than a limit of the format:
- The keep's corners did not bond. Every course laid its four sides the same way, so no brick ever spanned a corner and the keep was four stacks that merely touched. The corners alternate now.
- A course over an opening has to reach past it. A lancet capped by two bricks meeting over the hole ties nothing; the capping course is laid whichever way puts one brick across the opening with a bearing either side, which is not the same way for a four-stud stretch as for a six-stud one. The gateway's lintel got the same treatment and now bears a stud into the wall on each side.
- No stretch ends with a single stud. Three cells laid greedily come out a two and a one, and that trailing one sits on the corner with nothing reaching across to it.
- The keep's spire stood on its own open shaft. It has a floor now — the last course laid solid, six bricks the full width, each crossing the ring below at both ends — and a spire built the way the towers' are, since a 3 x 3 cone cannot be centred on a 6 x 6 keep and was sitting half a stud off the grid.
A piece is placed by coordinates for the same reason a brick was: nothing says
what holds it. So each piece externalizes the ports it is joined by, with map::
assemblies:
castle/spire:
type: assy
map:
spire_s0-anti-c0r0: [spire_s0, //pub/universe/lego:anti-stud, c0r0]A name of the piece's choosing, against the node inside it, the interface that node implements, and the instance. The interface is not renamed — it is a contract — but the instance name is the piece's to pick.
The walls, towers and buttresses were the hard case: they all stand on the
ground side by side, and a stud joins what is above to what is below, so edge to
edge there is nothing to join them by. LEGO's own answer is a baseplate, and the
library has one big enough — Baseplate 32 x 32 (3811), 1024 studs against a
castle covering 30 × 30. Every piece that reaches the ground is joined to it.
So the baseplate says nothing at all: where it goes decides nothing, since every other node is placed relative to it, and where the castle as a whole sits is the container's to say.
name: castle
location: [[0, 0, 0], [0, 0, 1], 0] # set the offset to [100.0, -100.0, 0.0] to read coordinates off the stud gridOne location: in the whole model, on the container, and as it stands it does
nothing. It used to be a quarter turn about X: LDraw draws its parts Y-up and
PartCAD's world is Z-up, and no joint can derive that — it is a fact about the
parts library, not about the model. The parts library has since taken it on
itself and serves every part standing upright, and the turn left behind laid the
castle on its side, its baseplate standing up like a wall.
What is left is the offset, and that is a knob rather than a fact, and not free. Left at zero the castle sits at the origin, which is where the default views expect to find it. Set to the figure in the comment it stands where the grid runs on whole studs from a known corner — worth having while reading the numbers by hand, and it costs the rendered views their framing, because they look from a fixed point rather than from one relative to the object.
An ASSY file has to enumerate every step. PartCAD reads the tree it makes to work out the bill of materials, and the assembly instructions are that tree written out a step to a page, so a step that is not in the file is a step nobody is told to take.
The text need not repeat itself, though: every ASSY file is a Jinja2 template, rendered before it is parsed. A run of parts laid out regularly can be written as the loop it is -
{% for i in range(15) %}
- part: //pub/universe/lego/ldraw/Brick:3941
name: t_c{{ i }}
location: [[4.0, {{ (9.6 + i * 9.6) | round(3) }}, 4.0], [0, 1, 0], 0]
{% endfor %}- and reaches the parser as the fifteen separate nodes it always was. The castle used to be written that way, and is not any more: now that every brick is joined to the stud it sits on rather than placed, there is no arithmetic left to loop over - each joint names its own studs. Between them the eleven files are 332 nodes of YAML for a 731-part model, and every one of those 731 parts is still a step of its own.
A Formula 1 car in LEGO Technic that drives, steers and rides on springs, with its Power Functions electrics and the IR remote control beside it.
![]() |
![]() |
![]() |
![]() |
| what does it | how | |
|---|---|---|
| drive | Electric:58121 XL motor |
a 12-tooth double bevel (Technic:32270) on its output turns the crown of a differential (Technic:62821) between two half axles |
| steering | Electric:99498 servo |
stands behind the front axle, output down; an arm on its output pushes a track rod pinned into both knuckles |
| power | Electric:58119 battery box |
across the car between the side frames, pinned into both by the four holes in each of its ends |
| control | Electric:58123 IR receiver |
the airbox, over the motor |
Electric:58122 IR remote control |
beside the car | |
| front suspension | double wishbones | two Technic Beam 5 a side; a cross block (Technic:6536) on the end of each holds an upright kingpin, and a knuckle (Technic:32557) turns on it, carrying the stub axle in a round hole; a shock absorber from the upper wishbone to a crossbeam |
| rear suspension | a swinging subframe | the motor, the differential and both half axles are one subframe, pivoting on an axle across the chassis ahead of the motor and held up by a shock absorber under each of two towers |
213 parts, 31 distinct:
pc inspect -a f1 # the car and its remote
pc inspect -a f1/car # the car alone
pc render -a -t png --view right f1The first picture above is f1's own, drawn from where PartCAD looks at an
assembly when nothing says otherwise: iso, [100, -100, 100], above its
front right corner. The other three are f1-front, f1-right and f1-top
in partcad.yaml: aliases of f1, each looking at it from a direction of
its own ([0, -100, 0] for the front, [100, 0, 0] for the right side,
[0, 0, 100] with [0, 1, 0] up from above) - the same directions --view
names, written down so that pc render -r draws them with everything else.
The castle's two pictures are made the same way: castle's own, and
castle-front, an alias of it looking from in front.
It is not small - 44 cm from the back of the rear tyres to the tip of the nose, 19.5 cm across the rear wheels - and that is what fitting a battery box, an XL motor, a servo and a receiver takes, with suspension at both ends.
f1 is the car and the remote beside it; f1/car is the car. The car is split
the way it would be built on a bench by several people at once: into
sub-systems, each made of blocks that are finished and handled on their own
before they are fitted, so that nobody waits for anybody until the last step.
| stage 1 - the blocks, all at once | parts | stage 2 - the sub-systems | stage 3 |
|---|---|---|---|
f1/side-frame-left, f1/side-frame-right |
7 each | f1/tub: the right frame goes onto the battery box's pins, the box onto the left frame; then the pivot axle and its three bushes (4), and the airbox on the rear posts |
f1/car |
f1/battery - the box and the eight pins in its end holes |
9 | ||
f1/airbox - the IR receiver on a crossbeam, and the cross blocks the posts carry it by |
10 | ||
f1/front-frame - nose rails, bulkheads, shock crossbeam, servo cradle |
43 | f1/front-end: everything hangs on the frame; the four pins that join a piece to another piece of it (the tops of the front shocks, the knuckles to the track rod) are its own (4) |
|
f1/front-right, f1/front-left - wishbones, kingpin, knuckle, wheel, shock |
15 each | ||
f1/steering - servo, arm, track rod |
9 | ||
f1/nose - a cross axle, a crossbeam, the cone |
12 | ||
f1/front-wing - two slats between two endplates, on two pylons |
16 | ||
f1/motor-unit - XL motor, pinion, the bracket across its face, the spacer beam |
13 | f1/drivetrain: the subframe's inner beams around the motor unit, the differential, the half axles and wheels, the shocks (23) |
|
f1/rear-wing - an axle through the towers, slats, endplates, pylons |
19 | ||
f1/sidepod - one panel and its pins |
3, used twice |
That is 37 in the tub, 114 in the front end, 36 in the drivetrain, 19 in the rear wing and 2 x 3 in the sidepods: 212 for the car, and the remote makes 213.
Only the sidepod occurs twice. The car is symmetric, but the two front corners and the two side frames are mirror images, and a mirror image is not the same assembly turned round.
Pieces are joined to each other through mapped ports, never by reaching into
another piece's parts. Each piece's map: in partcad.yaml externalizes the
ports a joint outside it uses, and a port that is several levels deep is mapped
at every level on the way up: the front end's front-frame-pin-nose-1-l-pin-left
is the front frame's pin-nose-1-l-pin-left, which is that pin's left end.
A joint between two pieces is written in the lowest piece that holds both, so
the front corners are joined to the front frame in f1/front-end, and only the
four sub-systems and the sidepods meet in f1/car.
Every part of the car is joined through its ports. Nothing in f1/car is
placed by coordinates: each part names the port of its own and the port of an
earlier part that it is put onto, the way the castle's bricks name the stud they
sit on. The left side frame's lower rail is the car's origin, and the car's own
location: is that beam's pose turned into PartCAD's Z-up world - which is what
puts the ground at z = 0, the nose towards -Y and the car's right towards +X.
(It is also what went wrong first: turning the car into Z-up and nothing else
leaves it lying the way that beam lies.)
The remote control is the one item placed by coordinates, in f1 beside the
car, because nothing joins a handset to the car it drives. PartCAD's
connectivity check would rightly refuse it among parts that connect, which is
why the car is an assembly of its own.
Which parts need a turn or a push along their axis is what the interfaces allow
and nothing else: a pin turns in a round hole (turnZ), an axle slides through
one (moveZ), and a stud turns on an anti-stud. An axle hole takes no turn, so a
part on an axle takes whatever roll the axle has - fine for a bush or a wheel,
and not for a cross block, whose pin hole has to be where the design put it. For
those the axle itself is turned, in the round hole it went into.
Three contacts in f1/drivetrain are true of the geometry without being a
joint that excuses them, and pc test reports them: the pinion's mesh with the
differential's crown (21.979 mm^3; the crown has no gear ports, and the pinion's
describe a spur mesh, not a bevel one), the end of the pinion's shaft against
the differential (4.220 mm^3), and the right half axle inside the differential
that sits on it (11.115 mm^3) - an axle snaps past nothing, so the length of it
inside the differential is reported. The bevel gears inside it, which the two
half axles would turn, are not modelled.
tools/gen_f1.py writes every file of the car and the f1 block of
partcad.yaml; nothing under f1/ is edited by hand. It designs each part at
the pose it should have, then looks for a port of the new part and a port of the
part it goes onto that are at the same point, facing each other, and have
interfaces that mate; that pair becomes the connect:. The pose PartCAD will
compute from it - the target port turned around, offset by the joint's
parameters, the part's own port undone - is computed there with the same rule,
and has to come out exactly where the part was designed to be. A part with no
such pair is an error, and the design changes until it has one. The ports come
from //pub/universe/lego's own index, so a joint the package does not serve
cannot be written.
The result was then checked the way the gen-assembly skill asks: PartCAD
instantiated f1, the tree was walked down to its 213 parts composing every
transform, and each part's world placement was compared with the generator's as a
multiset. All 213 agree, rotations included, through every level of the pieces.
It needed two things from //pub/universe/lego/ldraw that it did not have. One
is the axle hole of a cross block: LDraw draws the bush of a cross block as a
primitive with the hole inside it, which the package's geometry walk never
opens, so Technic:6536, "Cross Block 1 x 2 (Axle/Pin)", came with its pin hole
and not its axle hole - and every kingpin, nose block and wing mount here is
one. The package reads that primitive now, and 47 parts gained an axle hole. The
other is that one end of an axle may carry several parts: a half axle here
carries two beams, two bushes and a wheel, each joined to its end at its own
moveZ, and PartCAD's connectivity test reported them as crowding one port
until technic-axle said multiConnect: true.
Every piece passes pc test -f connect, connectivity, validity,
degenerate, solidity, shell and manufacturability on its own as well as
inside the car.
- The cables. In the real thing the motor's and the servo's leads go to the receiver, and the receiver's to the battery box, routed wherever there is room. Nothing about a port says where that is, and none is placed.
- Travel. It is a static pose: the wheels straight ahead, the suspension
settled. The shocks are LDraw's 10L damped shock compressed (
76320-f2), whose eyes are six studs apart, so that each one lands on the stud grid.
A LEGO stud is meant to occupy the part above it, and a Technic pin the hole
it is in — that interference is what makes the parts grip. So
partcad.test.interference has something true to report about almost every
joint in both models, and nowhere to read that it is intended: an overlap which
is meant to be there is stated on the joint that causes it, and these joints do
not say so.
Nothing here turns the check off. The package is manufacturable: false —
nobody is ordering a castle, or this car — and that is what makes interference
report what it finds rather than fail on it. Giving it a threshold high enough to swallow a
stud would be worse than either: that floor is a rounding tolerance, and making
it carry this would be a number pretending to be one.
What makes the check meaningful is the matings in //pub/universe/lego
declaring snapIn: true, and for a Technic pin in a round hole they do: its
slotted end is squeezed past the lip and springs open behind it. A stud in an
anti-stud is the same kind of fit and does not say so yet. It does not need to
for the castle: as LDraw draws them, a stud's side lies on the inner face of the
wall of the brick above, so stacked bricks touch without overlapping, and with
every brick served as a solid the castle reports no interference at all. An axle
snaps past nothing, so an axle that overlaps the part it goes through is still
reported.
A pin joins two parts, and its connection names one of them; its other end
goes into the second part all the same. tools/gen_f1.py finds those ends - a
pin end and a round hole facing each other at one point, the test it joins
parts by - and says so in interferes:. Within one piece, 15 pins name the
second part on their own joint. 25 more have their second part in a different
piece - the battery's pins in the side frames, the steering's in the front
frame, the sidepods' in the tub - and those are said where the two pieces meet,
on the link of one naming the link of the other: the battery's link in
f1/tub says interferes: [side-frame-left, side-frame-right]. That excuses
any overlap between the two pieces, which is as precise as it can be said
until PartCAD can tell an overlap at the joined port from one elsewhere.
PartCAD checks the car the way it is built. Each piece answers for its own inside with its own verdict, cached against the piece, and an assembly looks only at what crosses between the pieces it holds - comparing the box around each piece first, so two pieces that are apart cost one comparison however many parts are in them. A pair whose joint says it overlaps is not measured at all.
What it measures is only as good as the solids it is given, and a part that is
not a solid is not measured but reported: a boolean against an open shell
returns a number that means nothing - the 12.457 mm^3 once reported between an
axle and its cross block was one, where the hole as LDraw draws it is wider
than the axle at every corner. //pub/universe/lego/ldraw now serves a part
as a solid or not at all. It repairs what LDraw draws as overlapping or short
surfaces, and the friction pin, the cross block, the gears, the wheels and the
shocks come out solid. Eight more of this car's parts - the knuckle, three
panels, the servo, the XL motor, the battery box and the IR remote - have faces
LDraw does not draw or draws twice. The plugin's general repairs close the
knuckle, the servo and one panel; the rest are closed by patches it keeps to
LDraw's own files and applies as it reads them, each pinned to the file it was
written against. One of them is authored rather than corrected: the IR remote's
top half, which LDraw declares "Inside not modelled", is closed across its rim
as a filled envelope. Every part of the car is now served as a solid, and the
car, its pieces and the set pass pc test.
Every part here is a LEGO part, sold as vendor: lego by its LDraw number,
and two stores sell them, which the PartCAD index registers at
//pub/svc/commerce. This package names them as its suppliers, so
pc supply looks for every part of a model at them, in this order, and buys
each part from the first that has it:
| Store | Provider | What it needs |
|---|---|---|
| LEGO's Pick a Brick | //pub/svc/commerce/lego-pick-a-brick:pick-a-brick |
Nothing |
| BrickLink | //pub/svc/commerce/bricklink:bricklink |
An account's four OAuth values |
Each store's README says how to give it what it needs. One that has not been given it says, quietly, that it has nothing.
pc supply quote castle # each part where it is first found
pc supply quote -r --provider //pub/svc/commerce/lego-pick-a-brick:pick-a-brick f1 # everything at one store
pc -q supply quote --json --provider //pub/svc/commerce/bricklink:bricklink f1/front-end
python tools/quote.py -r # every model at every storeA part has no colour - the geometry has none - so a store quotes the cheapest colour it has, unless it is told one:
pc --extra-param '//pub/svc/commerce/lego-pick-a-brick:pick-a-brick.color=Medium Stone Grey' \
supply quote --provider //pub/svc/commerce/lego-pick-a-brick:pick-a-brick castleNo store sells by the LDraw number alone, and each works out what to buy for
it: the LEGO elements Rebrickable's public catalogue says the part has been
made as, and the mould LEGO makes in its place where none of those is on sale -
the friction pin LDraw draws as 2780 is sold as 61332, the 2L axle 3704
as 32062, the 2 x 2 cone 3942b as 3942c. Pick a Brick is asked for those
elements by number, and is not searched. BrickLink sells in lots, each bought
whole, so what it quotes is what the lots cost, the pieces over what was asked
for included.
What LDraw draws as one part and LEGO makes as several - the front wheels,
41896c01, are a rim with its tyre on - is an assembly in the parts library,
with an SKU of its own: the car links its wheels, its shock absorbers, the
servo and the battery box as assemblies. pc supply quote asks for each of
them whole, as a set or a marketplace may sell it; -r asks for its parts
instead, which is how Pick a Brick sells a wheel.
What Pick a Brick's US shop had, asked on 2026-10-18:
| Model | Parts it had | Pieces | Price |
|---|---|---|---|
castle, cheapest colours |
9 of 9 | 731 of 731 | $82.01 |
castle, Medium Stone Grey |
7 of 9: not the two cones in grey | 711 of 731 | $78.00 |
f1 -r, cheapest colours |
25 of 40 | 204 of 237 | $34.24 |
What it did not have for the car is what LEGO no longer makes: the Power Functions battery box, XL motor, servo, IR receiver and remote, the 10L damped shocks, and the large rims and tyres of the rear wheels. Those are the parts BrickLink, a marketplace, is for. It was not asked: this was run without the credentials it needs.
It is generated, and so is every picture in it: the text is the docs: section
of partcad.yaml, and pc render -r writes README.md and the images under
images/ - one for each assembly in the list below, the castle and the car
among them, and one for each of the aliases that look at those two from
elsewhere. They are rendered with reproducible: true, so the same model
gives the same file: drawn exactly, from the surfaces, by OpenCASCADE's
hidden-line removal.
All but the whole castle, the whole car, the four views of them and the car's front end, which are too big to be drawn that way. The exact algorithm sets memory aside for every pair of edges in the picture before it draws any of them, so what it needs grows with the square of the model: the car has 423,000 edges and would need 45 GB, the castle 248,000 and 15 GB, the front end 199,000 and 10 GB. Those are drawn from a triangulation instead, which comes out the same again on the same kind of machine.
CI installs the latest PartCAD from PyPI on the
latest Ubuntu, runs pc test -r and pc render -r, and fails if anything it
rendered differs from what is checked in. So a change to a model, to the parts
library or to how PartCAD draws shows up as a diff rather than as a README that
quietly stopped describing the model. To change this text, edit partcad.yaml
and run pc render -r; an edit to README.md itself is overwritten by the
next render.
![]() |
A gothic castle built from LDraw LEGO parts. |
![]() |
A gothic castle built from LDraw LEGO parts. |
![]() |
A pier stepping out from the wall, capped with a pinnacle |
![]() |
Two courses of the keep's masonry, the second breaking joint against the first |
![]() |
Four courses of the keep, the lancets in them and the course that closes them |
![]() |
What the keep ends with - its last three courses, the merlons, a bartizan at each corner, and the spire |
![]() |
A tower's needle roof - two 2x2 cones flaring off the tower, then two 1x1 cones drawing it to a point |
![]() |
The body of a corner tower, 15 courses of 2x2 round brick |
![]() |
The body of one of the gatehouse pair, 13 courses |
![]() |
The body of a tower standing along the wall, 12 courses |
![]() |
A stretch of curtain wall between two corner towers, with its lancets and crenellations |
![]() |
The same wall with the gateway's pointed arch corbelled through it |
![]() |
A Formula 1 car in LEGO Technic - Power Functions motors, suspension, and the IR remote control. |
![]() |
A Formula 1 car in LEGO Technic - Power Functions motors, suspension, and the IR remote control. |
![]() |
A Formula 1 car in LEGO Technic - Power Functions motors, suspension, and the IR remote control. |
![]() |
A Formula 1 car in LEGO Technic - Power Functions motors, suspension, and the IR remote control. |
![]() |
The Power Functions IR receiver on a crossbeam, and the cross blocks the rear posts carry it by |
![]() |
The Power Functions battery box, with the pins in its end holes that the side frames go onto |
![]() |
The car: every one of its parts joined through its ports, none placed by coordinates |
![]() |
The rear subframe: the motor unit, the differential, the half axles and wheels, and the two shocks it hangs from |
![]() |
Everything ahead of the battery: the front frame, both front corners, the steering, the nose and the front wing |
![]() |
The front frame: the nose rails, the bulkheads the wishbones pivot on, the shock crossbeam and the servo's cradle |
![]() |
The left front corner: double wishbones, a kingpin, the knuckle, the wheel and a shock |
![]() |
The right front corner: double wishbones, a kingpin, the knuckle, the wheel and a shock |
![]() |
The front wing: two slats on edge between two endplates, hung from the nose on two pylons |
![]() |
The XL motor with its pinion, the bracket across its face and the spacer beam beside it |
![]() |
The nose: a cross axle between the nose rails, a crossbeam, and the nose cone |
![]() |
The rear wing: an axle through the shock towers, two slats on edge between two endplates, on two pylons |
![]() |
The left side frame: the two rails, the post at the back and the shock tower over it |
![]() |
The right side frame: the two rails, the post at the back and the shock tower over it |
![]() |
A sidepod: one smooth panel pinned to the upper side rail |
![]() |
The servo, its arm and the track rod |
![]() |
The tub: both side frames, the battery box between them, the pivot the drivetrain swings on, and the airbox |
Generated by PartCAD
































