Feature declarations¶
These constructors create Draftwright IR features from build123d objects or explicit values.
They are useful when supplying a declared PartModel; most applications should prefer the
corresponding Sheet verbs.
hole(obj=None, *, diameter=None, at=None, axis=None, through=True, through_indicator=None, depth=None, cbore=None, spotface=None, csink=None, thread=None, count=1, members=())
¶
A drilled hole. Either hole(tool_cylinder) — read ⌀ / axis / location off the
build123d object you subtracted — or hole(diameter=6, at=(20, 10, 0), axis="z").
cbore / spotface are (diameter, depth) pairs; csink is a
(major_diameter, included_angle) pair (a flat-head seat, callout ⌵ Ø.. × ..°);
thread is a tap/thread spec string (e.g. "M3x0.5"), or a
:class:~draftwright.model.ir.ThreadOperation when an independently addressable tap depth
is required, folded onto the callout (#764/#1360); count + members describe a
machining-spec group drawn as one count×.
An object supplies defaults; any explicit keyword overrides that field (#451).
double_d_bore(obj=None, *, major_diameter=None, across_flats=None, at=None, axis=None, depth=None, through=True, through_indicator=None, profile_direction=None, count=1, members=())
¶
A through double-D bore, from its cutter or explicit geometric values.
major_diameter is the diameter of the parent circle and across_flats is the
distance between its two parallel chords. The object form accepts an extruded cutter
with exactly that boundary; arbitrary line/arc profiles and blind profiles fail closed.
boss(obj=None, *, diameter=None, height=None, at=None, axis=None, span=None, thread=None, knurl=None)
¶
An external cylindrical boss / OD. Either boss(cylinder) or
boss(diameter=6, at=(0, 0, 0), axis="x") (parametric). An object supplies
defaults; any explicit keyword overrides that field (#451).
polygonal_boss(*, side_count, across_flats, height, at, axis, flat_directions, flat_centres, span=None)
¶
A declared regular polygonal-prism boss, sized across flats and by height.
This explicit form carries the physical side-face directions and anchor points used by placement. Geometry-object inference is deliberately absent: a detached prism does not prove that it is an attached boss, while an author calling this verb does.
step(obj=None, *, diameter=None, length=None, at=None, axis=None, span=None, thread=None, knurl=None, profile_group=None)
¶
One axial segment of a turned profile — its OD + length. Either step(segment)
(⌀ from the cylindrical face, length + centre from the bbox along its axis) or
explicit step(diameter=4, length=10, at=(0, 0, 0), axis="x"). span (the two
axial end-points) is derived from at + length when not given. An object supplies
defaults; any explicit keyword overrides that field (#451).
chamfer(obj=None, *, axis=None, leg=None, leg1=None, leg2=None, angle=None, at=None, turned=False, source_ids=(), part21_id='', shape_aspect_ids=(), reference_item_ids=())
¶
A chamfer (bevelled edge, #560/#576). Either chamfer(bevel_face) — the oblique
chamfer face supplies axis, both legs and a leader point on the bevel — or explicit
chamfer(axis="z", leg=6, at=(x, y, z)). leg is an equal-leg 45° chamfer (callout
C{leg}); give both leg1/leg2 for an asymmetric one ({leg} × {angle}°).
Set turned=True when axis is the shaft axis rather than a prismatic bevel-edge
direction; this routes the physical at site through a profile view (#1276).
The angle is always derived from the legs; an explicit angle= is only validated
against them (a one-leg-plus-angle spec is not yet supported — #581). An object supplies
defaults; any explicit keyword overrides (#451).
fillet(obj=None, *, axis=None, radius=None, at=None, turned=False)
¶
A fillet (rounded edge, #561). Either fillet(round_face) — the cylindrical blend
face supplies axis, radius and a leader point on the round — or explicit
fillet(axis="z", radius=3, at=(x, y, z)). Called out R{radius} (grouped n× R
for equal radii). Set turned=True when axis is the shaft axis rather than a
prismatic rounded-edge direction; this routes the physical at site through a profile
view (#1276). An object supplies defaults; any explicit keyword overrides (#451).
flat(obj=None, *, axis=None, across=None, at=None, axis_line=None, stock_span=None, axis_direction=None)
¶
A machined flat on round stock (#148b). Either flat(flat_face) — the planar face
supplies the leader point at (axis= and across= still required, being
unrecoverable from a plane) — or fully explicit flat(axis="z", across=15, at=(x, y,
z)). axis_direction= carries a non-principal stock direction; axis_line= and
stock_span= then complete its geometric identity. Called out {across} A/F (across
flats). An object supplies the at default; any explicit keyword overrides (#451).
groove(obj=None, *, axis=None, width=None, diameter=None, at=None, profile_group=None)
¶
A turned / circlip groove on round stock (#148c). Either groove(floor_face) — the
reduced-OD floor face supplies axis, width, diameter and the leader point at — or
fully explicit groove(axis="z", width=3, diameter=16, at=(x, y, z)). Called out
{width} WIDE × ø{diameter}. An object supplies defaults; any explicit keyword
overrides (#451). profile_group joins the groove to steps carrying the same
authored body-group token when coaxial bodies cannot be distinguished by their
axis lines. It does not add a dimension or require omitted steps to be declared.
rotational(*, od, bores=(), at=None, axis=None)
¶
A turned body's axial furniture — its outer diameter, rotation axis and concentric
bores. Explicit values only: rotational(od=30, bores=(16,), axis="z").
There is deliberately no object form, unlike every sibling verb — the signature is
keyword-only so rotational(shaft) is rejected by Python rather than accepted and then
guessed at. An object form would have to re-derive the OD, the axis AND the concentric
bores from geometry, and detection does not read those off the solid: they come from the
part CLASSIFICATION (analysis._classify_geometry / _sizing_bores), which also decides
which concentric bores are sizing bores. A declare-side reimplementation would be a second
inference path for one fact and could silently drop bores or choose the wrong axis.
A convenient object form that quietly changes the drawing is worse than an explicit one.
An object form needs classification shared by detection and declaration (#950).
bores are concentric bore diameters in display order, each placed as a centred leader,
and are Z-axis only — a rule :class:~draftwright.model.ir.RotationalFeature owns and
states, since every route into the IR needs it. at is a point on the rotation axis
(default the origin); it is carried for round-trip identity and does not itself position
the furniture, which the renderer places from the part's projected centre.
plate(obj=None, *, axis=None, lo=None, hi=None, u=None, v=None)
¶
A thin slab's thickness (#559/#577) — a base plate, an upright wall, a rib. Either
plate(slab_box) — the thin axis, its lo/hi extent, and the u/v slab
centre read off the object's bbox — or explicit plate(axis="z", lo=0, hi=4, u=10, v=5).
hi - lo is the thickness; u/v locate the thickness dim on the other two axes
(in axis order). An object supplies defaults; any explicit keyword overrides (#451).
step_level(obj=None, *, base=None, levels=None, shoulders=None, datum=None, at=None, level_supports=None)
¶
A prismatic height ladder + step-position shoulders (#555/#578) — a rebated / stepped
block. Either step_level(part) — base, the interior levels, the (axis,
position) shoulders, the datum and the frame anchor at read off the part — or
explicit step_level(base=0, levels=(10,), shoulders=(("x", 30),)). levels are the
interior step Z-coords (unique, strictly increasing, each above base); a shoulder is
where a step changes height, its position measured from datum along a horizontal
axis (x/y). at is the IR frame origin (like every sibling constructor); it defaults
to the datum X/Y at base and is inert for step rendering. level_supports may
carry one (level, x_span, y_span) record per level so a dimension retains the face that
established it (#915). An object supplies defaults; any explicit keyword overrides that
field (#451).
slot(obj=None, *, width=None, length=None, long_axis=None, width_axis=None, depth_axis=None, w_center=None, lo=None, hi=None, end_radius=None, at=None)
¶
A milled slot / reduced across-flats section. From an object the depth (through, not
stored) axis defaults to the shortest bbox span; the two remaining axes are read as
long_axis (the longer) / width_axis (the shorter). lo/hi are the extent along the
long axis and w_center the centre across the width axis. end_radius declares two
equal semicircular end caps; leave it unset for a rectangular slot. An object supplies
geometric size defaults, but cannot infer this semantic end shape; pass end_radius=
explicitly. Any explicit keyword overrides the corresponding measured field (#451).
Pass depth_axis= when the cutter's through span is not the shortest — a through-Z
milled slot cut by a tall cutter has Z as its longest span, so the shortest-span default
would mistake Z for the long axis (#490). Naming the depth axis excludes it, so long/width
are read from the two in-plane axes.
pocket(obj=None, *, width=None, length=None, depth=None, long_axis=None, width_axis=None, depth_axis=None, w_center=None, lo=None, hi=None, at=None, edge_anchored=False, open_sign=1, corner_radius=0.0, mouth_axis=None, mouth_radius=None, mouth_at=None)
¶
A blind rectangular recess — a floored slot/pocket, dimensioned width × length ×
depth (#148a). The blind counterpart of :func:slot: unlike a through-slot the depth
IS a stored size, read from the object's span along the depth_axis. From an object
the depth axis defaults to the shortest bbox span (a shallow recess); the two
remaining axes are long_axis (the longer) / width_axis (the shorter). Pass
depth_axis= when the recess is deeper than it is wide (#490-style). lo/hi are
the extent along the long axis and w_center the centre across the width axis. An
object supplies defaults; any explicit keyword overrides that field.
corner_radius= declares four equal tangent corners on a closed profile; it is
retained geometry; use the constituent blend.radius measurements to dimension
those corners. A cylindrical mouth is declared with mouth_axis= (a principal
section-plane axis), mouth_radius= and mouth_at= (a point on its world axis).
For that surface, depth= is the maximum floor-to-mouth distance, and at=
centres that maximum-depth envelope. Its dimension ID is pocket_max_depth.length.
channel(*, width, long_axis, width_axis, w_center, lo, hi, d_lo, d_hi, open_sign=1, at=None)
¶
A full-span floored channel, dimensioned only by wall-to-wall width.
The longitudinal and depth bounds identify the physical channel and preserve recognition/declaration parity; they are not additional dimensions.
pad(obj=None, *, x0=None, x1=None, y0=None, y1=None, z0=None, z1=None, at=None, axis='z', direction=1)
¶
A bounded principal-axis raised pad, dimensioned by footprint and location.
pad(pad_solid) reads its axis-aligned bounding box; the explicit flavour
accepts the six world bounds used by generated Sheet scripts. axis is the
attachment-to-terminal coordinate and direction selects its positive or negative
material-outward end; the defaults preserve the historical +Z declaration.
pattern(member, *, kind, count, at=None, axis=None, members=(), bcd=None, pitch=None, direction=None, grid=None, rows=None, cols=None, angle=None)
¶
A hole pattern = count × a member hole (build one with :func:hole). The
arrangement (bolt_circle / linear / grid) and its defining dims (bcd /
pitch / grid + rows/cols/angle) are supplied, not read.
at (the pattern centre) and axis default to the member's frame. The member
centres are computed from the arrangement so the pattern renders like a detected one
(its count× balloon, BCD centreline and pitch dims anchor on members); pass
members= explicitly to override the computed layout (required for kind="other").
pocket_pattern(member, *, kind='linear', count, at=None, members=(), pitch=None, direction=None, grid=None, rows=None, cols=None, angle=None)
¶
count × an identical blind pocket in a linear / grid array (#841) — the
recess analog of :func:pattern. member is one representative pocket (build it with
:func:pocket); the array renders as ONE grouped N× W × L × D DEEP callout plus the
(n-1)× pitch dim(s), instead of N competing size dims.
The arrangement lies in the pocket's OPENING plane (perpendicular to its depth axis), so
the members are laid out about at (default the member's own centre) in that plane —
pass members= to override the computed layout. pitch (linear) / grid +
rows/cols (grid) define the spacing and are read by the pitch-dim furniture.
slot_pattern(member, *, kind='linear', count, at=None, members=(), pitch=None, direction=None, grid=None, rows=None, cols=None, angle=None)
¶
count × an identical milled slot in a linear / grid array (#841) — the
through-slot analog of :func:pocket_pattern. member is one representative slot (build it
with :func:slot); the array renders as ONE grouped N× SLOT W × L leader plus the
(n-1)× pitch dim(s), instead of N competing size dims (some of which drop for lack of
room, #841 behaviour 1).
A slot has no depth, so the array lies in the face plane perpendicular to the slot's THROUGH
axis (the one that is neither width nor long). Members are laid out about at (default the
member's own centre) in that plane; pitch (linear) / grid + rows/cols (grid)
define the spacing. Explicit members= is rejected — the computed layout is the truthful
one (see :func:pocket_pattern).
envelope(obj)
¶
The overall bounding box of obj as width (X) / height (Z) / depth (Y), matching the detector's prismatic envelope.
Measured on the SOLIDS, not on obj as handed in. An AP242 STEP import is a compound of the part plus its PMI presentation geometry — annotation planes, leader curves — and measuring the compound would include presentation geometry in the envelope.
The frame origin is the bbox centre, matching detection. _solids_body also
supplies the body inspected by _analyse and Sheet.model, so declaration
measures the same physical solid.
datum(letter, ref, part=None, *, view=None, side=None)
¶
A datum feature symbol (ISO 5459) on ref — a feature or a planar face (ADR 4 (was 0011) P2c).
finish(ra, ref, part=None, *, view=None, side=None)
¶
A surface-finish symbol (ISO 1302, Ra) on ref — a feature or a planar face (P2c).
note(text, ref, part=None, *, view=None, side=None, satisfies=())
¶
A free-text manufacturing note (#488) on a leader to ref — a feature or a planar face
(ADR 4 (was 0011) P2c). The shop callouts detection can't infer: thread specs (M3x0.5 TAP),
DEBURR, chip-relief, knurl. Placed like the GD&T items (a first-class ADR 2 (was 0009) corridor
candidate), not the dimension planner. satisfies explicitly names canonical
measurement roles that this note carries; the claim takes effect only if the note is
placed, and is never inferred by parsing its prose (#1351).
control_frame(characteristic, tolerance, ref, part=None, *, datums=(), diameter=False, modifier=None, view=None, side=None)
¶
A geometric-tolerance feature control frame (ISO 1101) on ref — a feature or a planar
face (ADR 4 (was 0011) P2c.2). characteristic is a lowercase ISO 1101 name ("position" …);
datums the referenced datum letters; diameter prefixes the zone with ⌀; modifier
a material-condition symbol ("M"/"L"/"P").
measured_dimension(*, kind, value, label, dominant_axis, ref_pts, ref_bbox=None, at=None, axis=None, upper_tol=None, lower_tol=None, lower_bound=None, upper_bound=None, source='sheet', source_kind=None, source_id='', lowering_blockers=(), rendering_blockers=(), cylindrical_refs=(), circular_refs=(), view=None, side=None, angular_reference=None, angular_references=(), angular_member_ids=(), angular_reference_item_groups=())
¶
A pre-authored drafting dimension from explicit measured values — the IR constructor
behind :meth:Sheet.measured_dimension (#704: extracted so build_drawing(model=…)
callers can author one without the façade). Validates the kind against
:data:~draftwright.model.ir.AUTHORED_DIMENSION_KINDS, needs ≥2 ref_pts, and derives
at (the ref_bbox centre, else the ref_pts centroid) when not given.
lower_bound and upper_bound carry a limit range and must be supplied together; they
are mutually exclusive with deviation tolerances. source_id preserves an external
record identity; ordinary Sheet declarations leave it blank. lowering_blockers retains
why an imported requirement could not safely enrich a canonical feature parameter;
rendering_blockers retains why its source geometry cannot truthfully form a witness.
angular_reference supplies an explicit vertex and two ray witnesses in model space;
it is an AngularReference or a mapping with the same fields. Its points populate
empty ref_pts or must agree with the supplied (first, vertex, second) points.
Sheet-authored three-point angles use that same order automatically. Imported generic
reference stations do not establish this ordering and require an explicit reference.
This retains angular meaning; it does not imply that the renderer supports the case.