Parametric sketcher
Apply dimensional and geometric constraints to section geometry — 19 constraint types including parallel, perpendicular, coincident, tangent, offset and clear distance — with live constraint inference while drawing.
Overview
The parametric sketcher lets you attach dimensional and geometric constraints to your section geometry so it stays correct as you edit. Once a constraint is in place you can change a single dimension and the solver propagates the change through all connected geometry — no need to manually reposition every vertex.
Constraints are additive — you can mix and match any of the 19 supported types on the same section. There are two ways to add a constraint:
- Constraint tools: select a type from the Constraints tab or use a keyboard shortcut, then click the target geometry.
- Selection-driven: click one entity — or Shift-click several — on the canvas. A floating action bar appears showing only the constraint types that are compatible with your selection.
| Selected entities | Available constraints |
|---|---|
| Any number of straight edges | Horizontal, Vertical† |
| One vertex | Fix |
| Two vertices | Distance, Coincident |
| Two straight edges | Parallel, Perpendicular, Equal length, Offset*, and Horizontal, Vertical |
| Two arc edges | Equal radius, Tangent (arc-arc), Clear distance |
| One straight edge + one arc | Tangent (line-arc), Clear distance |
| Two cross-ring vertices | Coincident |
| One vertex + one edge | Midpoint, Symmetric |
:::note ** Offset only appears while a parallel relation is already live between the two selected edges — an explicit Parallel constraint between them, or both independently pinned Horizontal, or both pinned Vertical. This is a constraint test, not a check of the edges’ current angle: two edges that merely look parallel on the canvas do not offer Offset until a parallel relation actually holds them there. See Offset below. :::
:::note † Horizontal and Vertical take a whole selection. Shift-click as many straight edges as you like and one click levels all of them, creating one separate constraint per edge — individually badged, individually deletable, identical to having applied them one at a time. A two-edge selection offers them alongside Parallel / Perpendicular / Equal length rather than instead of them.
The result does not depend on the order you selected the edges in: all of the constraints are solved together, in one step, from the geometry as it stood before you clicked. Two faces 4 mm out of level each move about 2 mm, rather than one face absorbing the whole error because it happened to be clicked second.
An arc anywhere in the selection hides both — there is no axis to align an arc to. And a selection that cannot be levelled without flattening the shape is refused whole, with nothing applied: select every face of a closed ring and ask for Horizontal and you get a refusal, not a section collapsed to a line. :::
Arc centres are selectable, and count as a vertex everywhere in this table. Every arc edge carries a small cross-shaped centre handle at the arc’s centre, off the ring itself — the centre is not a point on the ring, so it is drawn away from the outline and shaped differently from the round vertex dots. Selecting a centre together with a vertex (or another centre) makes Distance available, so you can dimension a hole or curved feature from its true centre rather than from a point on its boundary. A full circle drawn as two semicircle arcs has two centre handles, one per arc; they coincide as the sketch solves, so dimensioning either moves the whole circle.
A centre handle appears and disappears with its element’s vertex dots, and only for an arc — a straight edge has no centre to select. Unlike a vertex, a centre cannot be dragged: it is selection-only, and it stops accepting clicks entirely while hidden.
The Constraints tab in the left sidebar is accessible at any time for inspecting and managing the active constraint set.
Constraint types
Linear dimension
A linear dimension fixes the distance between two vertices (or between a vertex and a line). Click Add Linear in the Constraints tab, then click two vertices on the canvas. The solver places a dimension label on the canvas; type a new value to change the constrained distance.
Linear dimensions can be horizontal, vertical, or aligned (parallel to the chord between the two points). Choose the type from the Add Linear dropdown before clicking.
| Type | Constrains |
|---|---|
| Horizontal | Horizontal separation () |
| Vertical | Vertical separation () |
| Aligned | Full chord distance |
Equality constraint
An equality constraint forces two edges to have identical lengths. Select two edges (hold Shift to select the second) then click Add Equality. Equality marks appear on both edges (double tick marks). When you resize one edge, the other follows.
Equality constraints are useful for symmetric sections where you want opposite flanges or legs to stay the same size without adding two independent linear dimensions.
Tangent constraint
A tangent constraint forces an arc segment and an adjacent straight segment to be tangent at their shared vertex — no kink at the join. Select the arc and the adjacent edge, then click Add Tangent. The solver adjusts the straight edge’s endpoint to lie on the arc’s tangent line, and thereafter the two stay tangent as you resize the arc.
Tangent constraints are essential for smooth fillet-corner sections (hollow circular, lipped channel, rounded rectangle).
Symmetry constraint
A symmetry constraint mirrors two vertices or two edges about a selected axis. Click Add Symmetry, pick the axis (horizontal, vertical, or an existing edge), then click the two vertices or edges to mirror. The solver keeps both sides equidistant from the axis in perpetuity.
Coincident
A coincident constraint forces two vertices to occupy exactly the same position. Shift-click two vertices on the canvas and choose Coincident from the floating action bar.
Cross-ring coincident: when the two vertices belong to different element rings (for example, an outer solid ring and a void cutout ring), the constraint couples both rings through a constraint-linked group (union-find). Both rings move as a single rigid body whenever either constrained vertex is relocated. The coupling appears in the Constraint List Panel with a chain-link glyph and differs from same-ring coincident in that the solver propagates translations across the ring boundary.
Parallel
A parallel constraint forces two straight edges to be parallel. Shift-click both edges and choose Parallel from the action bar. The solver adjusts the edge directions to match; which edge is treated as the reference and which moves is determined by the existing constraint priority in the DOF count.
Perpendicular
A perpendicular constraint forces two straight edges to intersect at 90°. Shift-click both edges and choose Perpendicular. The same priority logic as parallel applies.
Equal length
An equal-length constraint forces two straight edges to have the same length. Shift-click both straight edges and choose Equal Length from the action bar. Resizing either edge propagates to the other. Equal-length and equal-radius constraints both appear under “equality” in the Constraint List Panel.
Offset
An offset constraint (point-line-distance) dimensions one vertex of a straight edge against the infinite line through a second straight edge — a void’s near face held a fixed clear gap off the section’s face is the motivating case. Its datum is the reference edge’s line, extended; the measured point is the vertex the offset edge starts at.
Offset only appears once a parallel relation between the two edges is already live — an explicit Parallel constraint between them, or both independently pinned Horizontal, or both pinned Vertical. This is deliberate: it is a test of an actual constraint record, never of the edges’ current angle. Two edges that merely look parallel on the canvas — even a fraction of a degree off — do not offer Offset, because nothing would then hold them parallel and a later edit could widen that gap silently while the dimension kept reading as if the faces were still square to one another.
Applying Parallel to two edges offers a shortcut. Once Parallel succeeds, a toast appears — “Faces are now parallel. Set the offset?” — with a Set offset button. Clicking it creates the Offset dimension immediately, at the current measured gap. Parallel and Offset are always two separate actions and two separate constraint records — applying Parallel never creates an Offset on its own, and the toast is only a convenience for the very next click, not a bundle.
Creating an Offset asks for its value. However you create one — the action bar’s Offset button, the Set offset follow-on, or Clear distance on an arc pair — the value box opens straight away, pre-filled with the gap as measured, because the reason to add one is almost always that the gap should be a different number. Dismissing it changes nothing: the constraint is created at the measurement first and the box opened on it, so cancelling leaves the dimension exactly as it was.
While the parallel relation holds, the on-canvas annotation draws witness ticks at both faces, reading as a genuine face-to-face dimension. If the parallel relation is later deleted, the annotation re-labels itself — the witness ticks disappear and it reads as what it has fallen back to actually measuring: one vertex to one line. It never keeps claiming face-to-face once that stops being true, whether or not the Offset’s own value or driven state changed.
An offset value is always entered as a positive clear distance. Which side of the reference line it measures from is captured once, when the constraint is created, from the geometry as it stood that moment — it is not re-derived on every solve. If later edits elsewhere in the sketch pull the measured vertex through to the far side of that datum, the dimension does not silently start reporting a shorter distance from the near side instead: a driven reading shows the true signed value with an explicit “past datum” suffix, never a bare minus sign, so it cannot be misread as a typo; a driving edit to a value that would force that crossing is refused rather than accepted and quietly reinterpreted.
Clear distance
A clear-distance constraint dimensions the gap between an arc and a second entity — line-arc-distance for a straight edge and an arc, arc-arc-distance for two arcs. Shift-click the pair and choose Clear Distance; unlike Offset it needs no prior Parallel relation, since an arc’s own geometry (its centre and radius) already fixes what “clear” means without help from another constraint.
- Line + arc — the datum is the arc’s surface nearest the line; the value is the perpendicular gap between that surface and the line.
- Arc + arc — covers two physical families from the same constraint type: two separate arcs (the ordinary case), and one nested inside the other. A duct inside a curved outline is the nested case, and it is exactly as authorable as two side-by-side arcs — select the pair, in either order, and Clear Distance measures whichever family the current geometry is actually in. Which of the two arcs is inside the other never matters to which arc you clicked first.
As with Offset, the value is a positive clear distance and a reading pulled through its datum by other constraints shows the “past datum” suffix instead of a bare minus sign.
Equal radius
An equal-radius constraint forces two arc edges to share the same radius. Shift-click both arcs and choose Equal Radius. Useful for maintaining identical fillet radii across a symmetric section without entering a specific value.
Midpoint
A midpoint constraint pins a vertex to the midpoint of an edge. Shift-click the vertex then the edge (order matters: vertex first) and choose Midpoint. The vertex stays equidistant from both endpoints of the edge as the rest of the sketch is modified.
Tangent (line-arc, non-adjacent)
A tangent-line-arc constraint enforces tangency between a straight edge and an arc where the two entities are not adjacent at a shared vertex. Shift-click one straight edge and one arc, then choose Tangent from the action bar. The solver repositions the straight edge so it lies along the tangent to the arc at the nearest point.
This is distinct from the existing Tangent constraint above, which enforces tangency at a shared vertex between adjacent entities — that type remains available from the Constraints tab and is required for fillet joins.
Tangent (arc-arc)
A tangent-arc-arc constraint forces two arc edges to be tangent at their shared endpoint — no kink at the join. Shift-click both arcs and choose Tangent. The solver adjusts arc positions so their centres and the shared endpoint are collinear, eliminating any angular discontinuity.
Symmetric
A symmetric constraint keeps two vertices equidistant from a reference axis. Shift-click the two vertices and an axis edge (or choose a coordinate axis from the Constraints tab), then choose Symmetric. The Stage-2 symmetric constraint is complementary to the Stage-1 symmetry constraint: it operates through the multi-select workflow and can reference any straight edge as the axis, not only the horizontal and vertical axes.
Driven vs. driving dimensions
Every linear dimension is either driving or driven:
- Driving (blue label) — the dimension controls the geometry. Typing a new value moves the constrained vertices to match.
- Driven (grey label, lock icon) — the dimension reports the current value but is controlled by other constraints or by the geometry directly.
Typing an edge length or an interior angle makes it driving. On an edge or corner that carried no dimension, the number you type becomes a driving constraint at exactly that value, and its padlock lights up in the same step — so a later edit elsewhere cannot solve it away. On one that already carries a driving dimension, typing changes that dimension; no unlock step. On a driven length or angle, typing promotes it to driving at the typed value, because typing a number states an intent where a driven dimension only reports one. Where the constraint cannot be created — the ring is already dimensioned to the point of conflict — the geometry still takes the typed value and a notice names what it conflicts with, rather than leaving you to discover later that nothing was holding it.
A dimension becomes driven automatically when the solver determines its value is fully determined by other constraints. For example, if you constrain the total width of a section with one linear dimension and then add an equality constraint between the two halves, the per-half dimension becomes driven (it will always equal total width ÷ 2).
Click a driven dimension’s lock icon to promote it to driving — this removes one other constraint to avoid over-constraining the sketch.
Conflict dialog
The sketcher detects constraint conflicts before applying them. A conflict occurs when a new constraint is incompatible with the existing set — for example, adding a horizontal dimension of 100 mm when an equality constraint and an existing 50 mm dimension together already fix the same distance to 100.5 mm.
When a conflict is detected the Conflict dialog opens:
- The conflicting constraint is highlighted in the canvas and listed at the top of the dialog.
- The existing constraints that conflict with it are shown below, with their values.
- You can choose to Remove one of the existing constraints to make room for the new one, or Cancel to discard the new constraint without changing anything.
No constraint is ever silently discarded. Every conflict requires an explicit user decision.
Constraints are identified in the dialog by type and affected geometry — for example, Parallel on E1 and E3 or Linear dimension 80 mm between V2 and V5. Edge and vertex labels are 1-based — E1, E2, … for edges and V1, V2, … for vertices — matching the labels the canvas element-numbers overlay draws.
Managing constraints
Constraint list panel
Every active constraint is listed in the Constraint List Panel, accessible from the General tab in the left sidebar. Each row shows:
- A type glyph (parallel arrows, right-angle mark, equals sign, chain link, etc.)
- A state badge: satisfied (green), driven (grey), or conflicting (red)
- A delete button — removes the constraint; the constrained geometry is freed
- A driven toggle (dimensional constraints only) — click to demote a driving dimension to driven, or to promote a driven dimension to driving (removing one other constraint to maintain consistency)
Clickable canvas badges
Each constraint shows a badge directly on the affected edge or arc. Clicking a badge:
- Selects that constraint in the Constraint List Panel.
- Highlights all geometry entities participating in the constraint.
- Opens the constraint’s detail row for editing the value (dimensional) or deletion.
Badge labels reference affected edges and vertices using 1-based labels — E1 for the first edge, V2 for the second vertex, and so on — consistent with the conflict dialog and the canvas element-numbers overlay.
Cascade on topology changes
When you delete a vertex, split an edge, or switch an arc to a straight segment, the sketcher identifies constraints that are no longer satisfiable and removes them with a toast notification listing each removed constraint by type. No constraint is silently discarded (§874).
Constraint inference while drawing
The inference engine proposes a constraint for each edge you draw in polygon-draw mode, based on how closely the live draft edge approaches a horizontal, vertical, parallel, perpendicular, or tangent relationship with the committed geometry.
How inference works
-
As you move the pointer, the engine computes the draft edge direction from the last-placed vertex to the current pointer position.
-
It tests the draft bearing against the following candidates, in priority order:
Candidate Tolerance Horizontal or vertical ≤ 2° from the axis Parallel to an existing edge ≤ 2° from that edge’s bearing Perpendicular to an existing edge ≤ 2° from 90° off that edge Tangent to an existing arc ≤ one grid step (linear) -
The top candidate is shown as a live glyph at the cursor (reusing the
ConstraintBadgevocabulary). The draft edge preview snaps to satisfy the inferred constraint exactly — horizontal inference locks the endpoint toy = start.y; parallel inference rotates the endpoint to the matching bearing; and so on. -
On commit (click or Enter), the inferred constraint is added as a real, visible, deletable constraint record through the normal adapter+solver gate — it is never invisible magic. You can see and remove it in the Constraint List Panel.
Inference toggle
A topbar button (toggle state visible via aria-pressed) turns inference on or off. The setting is persisted per-browser in localStorage:
- On (default) — proposals are shown, the edge snaps, and constraints are added on commit.
- Off — the edge is placed exactly as drawn; no inference runs and no constraints are added automatically.
Turn inference off when you intentionally want a freehand edge at an angle not near any existing geometry.
Keyboard shortcuts
| Key | Action |
|---|---|
| C | Open Constraints tab |
| L | Add linear dimension (aligned) |
| H | Add horizontal linear dimension |
| V | Add vertical linear dimension |
| E | Add equality constraint (after selecting two edges) |
| T | Add tangent constraint (after selecting arc + edge) |
| S | Add symmetry constraint (after selecting axis + two vertices) |
| Delete | Remove selected constraint |
| ESC | Cancel in-progress constraint placement |
Tips
- Add constraints after you are happy with the rough geometry — constraints preserve ratios, not specific values, so starting with a close-to-correct sketch gives the solver less to rearrange.
- Use equality on symmetric sections early: it halves the number of driving dimensions you need to maintain.
- If a dimension label is in the way of the canvas, drag it to a convenient position — the label position is independent of the constraint value.
- The DOF count badge in the Constraints tab header shows N constraints (M driving) so you always know how over- or under-constrained the sketch is.
- A fully constrained sketch (all dimensions driven except the position anchor) is ideal for parametric studies — change one driving dimension and all geometry updates instantly.
- Inference + Shift-click work together: inference adds constraints as you draw; Shift-click adds constraints between existing edges after the fact. Combining both workflows is the fastest path to a fully constrained sketch.
Next steps
- Drawing tools — freehand drawing, snapping, vertex editing, region roles
- Section properties — the output reference once your constrained geometry is committed