Skip to main content

Planes

A plane is a flat reference: the surface a sketch is drawn on, the mirror of a mirror feature, the halfway mark between two faces. Every model starts with the three origin planes, and the Plane tool derives new ones from them or from existing geometry.

The origin planes

Three planes exist in every file without any statement. They are named by the world axes they contain and have an alias each, plus a flipped version whose normal points the other way:

NameAliasNormalFlippedFlipped alias
"xy""top"+Z"-xy""bottom"
"xz""front"−Y"-xz""back"
"yz""right"+X"-yz""left"

In the viewport they show as three small quads at the origin. Clicking a quad while a dialog's plane slot is armed picks that plane; the Sketch tool's Face / Plane slot accepts them the same way.

sketch("xy", () => { ... }) // draw on the ground plane
sketch("front", () => { ... }) // same as "xz"
mirror("yz") // mirror the model across the YZ plane

In the viewport

  1. Click Plane on the toolbar. The Plane dialog docks on the right.
  2. Pick the type at the top: Offset, Mid plane or From edge.
  3. Fill the Base slot from the scene: click a face in the viewport, an origin-plane quad, or a plane row in the timeline. Mid plane takes two bases; From edge takes an edge. Once the slot is full, only the origin planes you chose stay in the viewport, so the ghost reads clearly against them; clicking a chosen quad again, or the chip's ✕, frees the slot and brings the others back.
  4. Enter the Distance (Offset type) or the position along the edge from 0 to 1 (From edge type). Offset and Mid planes also take a rotation per axis — around the plane's own X, Y, or its normal, in degrees.
  5. Click Apply. The plane appears as a translucent quad in the viewport and as a row in the timeline, and a plane() statement is written to the file. Clicking that quad later picks the plane for a sketch or a mirror.

A translucent ghost of the plane follows the fields while the dialog is open. Double-click the plane's timeline row to reopen the dialog and edit it.

Offset planes

The most common plane: an origin plane or a face, shifted along its normal. In the viewport a plane is a translucent square with an arrow at its centre pointing along the normal — the side a sketch on it faces, and the direction a positive offset moves it.

The XY origin plane offset 40: a plane quad floating 40 above the grid

The code behind it
offset.part.js
import { plane } from 'fluidcad/core';

// The ground plane lifted 40 along its normal — the Plane dialog's Offset
// type with the XY origin quad as Base and a Distance of 40. The quad in the
// viewport is the plane; the arrow at its centre shows which way it faces.
const top = plane("xy", 40);

The offset is one of the transform options. The others rotate the plane around its own axes, and they compose — the offset is applied first, then the rotations around the offset origin:

plane("xy", 50) // shorthand: offset only
plane("xy", { offset: 50 }) // same
plane("xz", { rotateX: 45 }) // tilted 45° around the plane's X
plane("xy", { offset: 30, rotateZ: 90 }) // shifted, then spun around its normal

From a face

A face is a plane too. Pick the face as the Base and the plane takes its position and orientation, centred on the face; the Distance offsets it from there:

A block with a plane 20 above its top face

The code behind it
block.part.js
import { sketch, line, extrude, plane } from 'fluidcad/core';
import { coincident, distance, fix, horizontal, vertical } from 'fluidcad/constraints';

// A 120 × 80 × 60 block, drawn with the Rectangle tool and extruded.
sketch("xy", () => {
const b = line([-60, -40], [60, -40]);
const r = line([60, -40], [60, 40]);
const t = line([60, 40], [-60, 40]);
const l = line([-60, 40], [-60, -40]);
coincident(b.end(), r.start());
coincident(r.end(), t.start());
coincident(t.end(), l.start());
coincident(l.end(), b.start());
horizontal(b);
vertical(r);
horizontal(t);
vertical(l);
fix(b.start(), [-60, -40]);
distance(b.start(), b.end(), 120);
distance(r.start(), r.end(), 80);
});
const block = extrude(60);

// The block's top face, shifted 20 along its normal — Offset type with the
// face clicked as Base and a Distance of 20. The plane is centred on the
// face and moves with it if the block changes height.
const above = plane(block.endFaces(), 20);

In code, a number or an options object offsets and rotates the face's plane:

plane(block.endFaces()) // the top face's plane
plane(block.endFaces(), 20) // 20 above the top face
plane(block.endFaces(), { rotateY: 15 }) // tilted around the face's Y

Sketching directly on a face (sketch(e.endFaces(), …)) is the same thing without the separate statement; a plane() feature is worth it when several features share the plane, or when it needs an offset or a tilt.

Mid planes

A plane halfway between two others, oriented like them. Pick two plane rows in the timeline (or two origin-plane quads) as the Bases:

The mid plane between the YZ origin plane and the same plane shifted 60 along X

The code behind it
mid.part.js
import { plane } from 'fluidcad/core';

// Two parallel vertical planes: the YZ origin plane and the same plane
// shifted 60 along X.
const p1 = plane("yz");
const p2 = plane("yz", 60);

// The plane halfway between them, at X = 30 — the Plane dialog's Mid plane
// type with the two plane rows as Bases. The two sources are folded into it:
// only the mid plane stays in the viewport.
const mid = plane(p1, p2);

The two source planes are folded into the result: after Apply only the mid plane shows in the viewport. It keeps tracking its bases — move either one and the mid plane re-centres.

Between two faces

The bases can be faces: click the block's bottom face and its top face and the plane lands at mid-height.

A block with the mid plane between its bottom and top faces

The code behind it
block.part.js
import { sketch, line, extrude, plane } from 'fluidcad/core';
import { coincident, distance, fix, horizontal, vertical } from 'fluidcad/constraints';

// The same 120 × 80 × 60 block.
sketch("xy", () => {
const b = line([-60, -40], [60, -40]);
const r = line([60, -40], [60, 40]);
const t = line([60, 40], [-60, 40]);
const l = line([-60, 40], [-60, -40]);
coincident(b.end(), r.start());
coincident(r.end(), t.start());
coincident(t.end(), l.start());
coincident(l.end(), b.start());
horizontal(b);
vertical(r);
horizontal(t);
vertical(l);
fix(b.start(), [-60, -40]);
distance(b.start(), b.end(), 120);
distance(r.start(), r.end(), 80);
});
const block = extrude(60);

// Halfway between the block's bottom and top faces — Mid plane type with the
// two faces clicked as Bases. Each face is wrapped in plane(…) so the mid
// plane reads two planes. Make the block taller and the plane stays centred.
const mid = plane(plane(block.startFaces()), plane(block.endFaces()));

Both arguments must be planes, so a face selection is wrapped in plane(…) as above. Options apply to the result:

plane("yz", plane("yz", 60)) // same as the first example, inline
plane(p1, p2, { rotateX: 10 }) // the mid plane, then tilted 10°

Planes from an edge

A plane can also stand normal to an edge at a point along it: the edge's tangent becomes the plane normal, so on a curved edge the plane turns with the curve. This is how a profile is positioned for a sweep along a path. The edge can be a solid's edge or an open sketch curve. Pick it as the Base and set the position along it:

An arc drawn on the front plane with a plane standing across its midpoint

The code behind it
path.part.js
import { sketch, arc, plane } from 'fluidcad/core';

// An open path: one quarter-circle arc of radius 80 on the front plane,
// from (80, 80) down to the origin around the centre (80, 0).
const path = sketch("front", () => {
arc([80, 80], [0, 0], [80, 0]);
});

// A plane standing on the arc halfway along it — From edge type with the
// arc as Base and the position 'middle'. The arc's tangent at that point is
// the plane's normal, so a profile sketched here is square to the path; the
// arrow shows the tangent direction.
const onPath = plane(path, 'middle');

The position is a name or a normalised value:

plane(path, 'start') // at the edge start — normal faces outward, like a cap
plane(path, 'middle') // halfway; same as 0.5
plane(path, 'end') // at the end
plane(path, 0.25) // a quarter of the way along
plane(solid.endEdges(0), 'end') // a solid's edge works the same way

A sketch that draws a single curve reads as that curve, which is what the dialog writes when a bare sketch curve is picked. A sketch with several curves is picked by edge instead.

At 'start' (0) the normal faces away from the edge body so both ends read like end caps; 'middle' and 'end' follow the edge's forward direction. On a curved edge the plane turns with the tangent.

Using a plane

UseStatement
Sketch on itsketch(p, () => { ... })
Mirror across itmirror(p) or repeat("mirror", p, feature)
Wrap onto a facethe sketch plane's origin and orientation place the decal — see Wrap
Loft or sweep profileseach profile is a sketch on its own plane — see Loft
Filter by itface().onPlane("xy", 30), edge().parallelTo("xz") — see Selection & Filters

A sketch plane's coordinates are the plane's own 2D frame: [0, 0] is the plane origin, X and Y its in-plane axes. Inside the sketch, xAxis() / yAxis() name those axes — as constraint targets and as directions for the 2D transforms — see Axes.