Skip to main content

Offset

Offset copies sketch geometry inward or outward by a distance: walls, clearances, margins and the inset pockets that follow an existing outline.

In the viewport

The Offset dialog with the four edges of a stadium picked and a distance of 5
  1. Click Offset on the sketch toolbar. The Offset dialog opens docked on the right with a Selection slot, a Distance field (positive = outward, negative = inward) and a Close ends toggle.
  2. Click a sketch edge. It lands in Selection as a chip that names the primitive and its source line. A plain click replaces the pick; hold Ctrl ( on a Mac) to add more edges, and click a chip's to drop one. A blue preview of the offset follows the picks and the value, and the statement about to be written shows under the dialog.
  3. Apply writes the offset() statement after the geometry and constraints, at the end of the sketch body.

A pocket outline offset outward into a wall

The code behind it

Offset is a derived operation: it consumes the solved geometry, so its statement always comes after the geometry and constraint statements. The tool lists the edges you picked, offset(5, top, right, bottom, left); with every edge picked, offset(5) on its own means the same thing.

plate.part.js
import { sketch, line, arc, offset } from 'fluidcad/core';
import { coincident, tangent, horizontal, fix, distance, radius, equal } from "fluidcad/constraints";

sketch("xy", () => {
// A pocket outline — a stadium — and the wall around it. The region
// between the outline and its offset is the wall.
const top = line([0, 15], [60, 15]);
const right = arc([60, 15], [60, -15], [60, 0]).cw();
const bottom = line([60, -15], [0, -15]);
const left = arc([0, -15], [0, 15], [0, 0]).cw();
coincident(top.end(), right.start());
coincident(right.end(), bottom.start());
coincident(bottom.end(), left.start());
coincident(left.end(), top.start());
tangent(top, right);
tangent(right, bottom);
tangent(bottom, left);
tangent(left, top);
horizontal(top);
fix(left.center(), [0, 0]);
distance(left.center(), right.center(), 60);
radius(left, 15);
equal(left, right);
// Offset every non-guide edge of the sketch outward by 5 — the wall
// thickness. Written after the constraints: offset is a derived op and
// consumes solved geometry.
offset(5)
})

By hand

offset(distance) // every non-guide edge in the sketch
offset(distance, g1, g2, ...) // only the listed geometry

A target-less offset() skips guide geometry; to offset a guide, pass it explicitly.

Keeping only the offset

To use only the offset curve in the profile, make the sources guides with .guide() — guides are left out of the face-building step, so the offset alone survives. Pass the guides to offset() explicitly:

A pocket floor inset from the plate outline

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

sketch("xy", () => {
// A pocket floor inset 10 from the plate's outline. The outline is
// drawn as guides — only the offset contributes to the profile.
const sg1 = line([-50, -30], [50, -30]).guide();
const sg2 = line([50, -30], [50, 30]).guide();
const sg3 = line([50, 30], [-50, 30]).guide();
const sg4 = line([-50, 30], [-50, -30]).guide();
coincident(sg1.end(), sg2.start());
coincident(sg2.end(), sg3.start());
coincident(sg3.end(), sg4.start());
coincident(sg4.end(), sg1.start());
horizontal(sg1);
vertical(sg2);
horizontal(sg3);
vertical(sg4);
fix(sg1.start(), [-50, -30]);
distance(sg1.start(), sg1.end(), 100);
distance(sg2.start(), sg2.end(), 60);
// Explicit targets — a target-less offset() skips guides.
offset(-10, sg1, sg2, sg3, sg4)
})

Closing an open offset

Close ends (.close() in code) connects an open offset back to its original with two straight cap edges, producing a closed loop that can be extruded:

An arched handle: an arc offset and closed

The code behind it
plate.part.js
import { sketch, arc } from "fluidcad/core";
import { offset } from "fluidcad/core";
import { fix, radius } from "fluidcad/constraints";

sketch("xy", () => {
// An arched handle: one open arc …
const a = arc([0, 0], [100, 0], [50, 10]);
fix(a.start(), [0, 0]);
fix(a.end(), [100, 0]);
radius(a, 60);
// … offset by 10 and capped back onto the original with two straight
// edges, so the result is a closed band that can be extruded.
offset(10).close()
})

On a profile that is already closed, .close() does nothing.

Combining with other shapes

Offsets and fresh geometry share one profile:

sketch("xy", () => {
const outer = circle([0, 0], 60)
offset(5, outer) // a clearance ring around the circle
circle([0, 0], 14) // a separate bore in the same profile
})

Outside a sketch, the toolbar's Offset pick tool offsets the outline of picked faces instead — see Selection and filters.