Documentation / Node reference / geo nodes

geo/M2DOffset

Grows or shrinks a 2D shape by moving its whole outline sideways.

Manifold Operations

Moves the boundary of a cross section outwards by `offset`, or inwards when it is negative. A hole shrinks as the solid around it grows, so this is the flat version of a wall thickness. The result is a cross section again, so it chains.

IT OFFSETS AN AREA, AND IT CANNOT STROKE A CURVE. Its input is already a filled region, so geo/Line into geo/M2DCreate into here FILLS the polyline first and then grows the fill: the middle stays solid however small the offset is. To give a curve a width, use geo/M2DStroke, which follows the curve rather than filling it. That confusion is the single most common thing to hit with this node.

It is the fillet-and-rounding tool as much as the resizing one. Offsetting a shape OUT and then back IN by the same amount rounds off its outside corners and leaves the inside ones; doing it the other way round rounds the inside ones. It is also how you get a wall of even thickness: offset a profile in and subtract it with geo/M2DBoolean.

A corner cannot simply move, because the two edges meeting there pull apart when the outline grows. `joinType` says what fills that gap, and ROUND is the only choice that keeps every point of the result exactly `offset` from the input. On the side where the corner turns inward the edges overlap instead of parting, and that is cleaned up for you whatever `joinType` says, because there is only one right answer to it.

A large negative offset can eat a shape entirely, and an empty result is a legitimate answer rather than an error. Shrinking a shape apart into two is fine too.

geo/M3DOffset is the 3D counterpart and geo/SDFOffset is the signed-distance one. For a 2D NURBS curve, which stays exact rather than being turned into segments, use geo/CADOffset, which takes the same `joinType` and the same `miterMinimumAngle`.

Parameters

Name Type What it does
offset Float How far the outline moves, perpendicular to itself, everywhere. Positive grows the shape and negative shrinks it, and a hole moves the opposite way from the outline around it. Shrink far enough and a thin part of the shape disappears, which is the correct answer rather than an error: a bar thinner than twice this has nothing left of it.
joinType UInt8 What to put at a corner that the offset opens a GAP at, which is every corner the outline grows round the outside of. ROUND puts an arc centred on the corner, which is the only choice that keeps every point of the result exactly `offset` from the input. It is the one to use when the offset is standing in for a fillet. SQUARE cuts the corner off with a flat edge at exactly `offset` from it. BEVEL also cuts it off flat but without that guarantee, which makes it cheaper and slightly blunter. MITER runs the two edges on until they meet, so the corner stays a point, up to `miterMinimumAngle`. It does nothing to a corner the offset cuts the INSIDE of: there the two edges overlap rather than parting, and the overlap is trimmed away whatever this says.
miterMinimumAngle Float The sharpest corner MITER will still bring to a point, measured AT the corner, so a right angle is 90. Anything sharper is squared off instead. That is what stops a sharp corner growing a long thin spike: the sharper the corner, the further out the two edges have to run before they meet, and it grows without bound as the corner closes up. The default of 60 leaves every corner you are likely to draw, a right angle included, coming to a point. It does not depend on `offset`: the spike and the limit grow together, so only the corner's own angle decides.
segments UInt32 How many straight segments a ROUND join uses for a full turn, so a quarter-turn corner gets a quarter of this. Higher is smoother and heavier; the arc is drawn as segments either way, because a manifold shape is polygons. It does nothing under the other three join types, none of which draws a curve.

See also

This page is generated from the engine, so it describes the release you can download. The same text is in the editor's Help panel next to the node itself.