Modeling
When to use / when not
Use when the user wants an exact part built from the admitted analytic, thread/helix, spur-gear, finishing/text, path and spline-surface statements. Read their cards below for the constructor and verification limits, and use independent required measurements for each need. Also use it for mesh parts: bounded STL import, exact→mesh tessellation, mesh Booleans/primitive cuts, repair, decimation, rigid placement, cages, deformation and height-map relief, plus bounded field construction/extraction and mesh-input resampling. Read the mesh, surface-edit and Fields cards before choosing the representation. For the strict captured grab profile, read Captured sculpt replay.
Do not use for direct 3MF import, arbitrary sculpt tools or other unadmitted captured organic inputs,
arbitrary unadmitted STEP imports, helical/bevel/worm/internal gears or racks, unadmitted motion, elasticity,
force, print/slicer settings, or unbounded smooth lofts. Curved loft/path consumers remain limited as described in the path card. Use variants[] for named finite override sets
and when only for structure selected by finite-domain parameters; split a family into documents
when its structures cannot be expressed within those bounded rules. Admitted exact text, draft/offset,
spur gears and bounded paths retain
their own cards and limits.
A modelled threaded hole or thread/helix statement builds and carries a typed thread/helix
requirement; full-profile external threads measure finite sections, uncut ends and overhang, and
closed spring ends are refused (VXL-C477). thread_boss, screw and section are not authored
statements. thread, helix, shell, place, multi-target/styled holes, draft,
face_offset, variable_fillet, bounded text, spur_gear, split and imprint use the
authored VXL vocabulary, and so do import with assets[] and the direct-edit statements.
assets[] may declare up to 8 supported input assets, each bound to its Source-domain descriptor
digest and byte length; the shared asset-byte budget is 96 MiB, with tighter per-media and combined
STEP caps below. For model/step, an exact import statement installs exactly one solid under
certified curve-on-surface bound (1e-5 mm) (raw exact, or a bounded same_parameter re-derivation), and everything else is refused. A
source_units asserts the file's own units; the reader converts them to millimetres once.
A delivered exact part may contain N >= 1 enclosed internal voids (one outward outer shell and
N inward closed shells) only when a required: true enclosed_cavity_count on that final
subject declares expect: N. Missing, optional or mismatching declarations
fail closed with VXL-X121; an intermediate void that a later statement opens is fine.
A one-inch side becomes 25.4 mm. Declaring "inch" for a millimetre STEP file refuses the import;
the declaration never scales already converted geometry.
bounded_v1 import requires a required repair_budget requirement. import_admission and
repair_budget are measured kinds: admission compares authenticated original/cold identities,
units, raw/admitted status and complete preservation; repair budget compares actual operations,
entity tolerance, total growth and certified deviation against its caps. Complete evidence can
PASS; a certified excess or contradiction FAILs. Missing or unsupported preservation/cold
context remains typed not-measured/HOLD. Spline descriptor identity does not prove preservation,
and re-derived volume stays HOLD without a finite volume uncertainty certificate.
Revisioned document sessions follow the draft contract below.
Frames
Coordinate-frame recipe
Rank-2 difficulty: sign errors are silent in geometry but caught by check's dry-run only
sometimes.
- Write the request's frame sentence down as your frame (scratch is fine; the compact form omits
notes). - Write the request's coordinates unchanged. Never re-origin a part unless the request does.
- For each feature state "its + side is toward …", then substitute one known point and confirm.
- For a non-XY sketch, list the two world axes and
towardexplicitly (see the table below). - After
check, readsummary.parts[].predicted_boundsand compare every number with the request.
plane |
u ↦ | v ↦ | toward must be |
|---|---|---|---|
xy |
+x | +y | +z / -z |
yz |
+y | +z | +x / -x |
xz |
+x | +z | +y / -y |
Solids and gears
Analytic solids and revolution card
Use analytic_locator_fixture.vxl.json: five separate exact deliveries, required feature/solid/envelope/mesh proofs.
| Author | Verify independently in final part coordinates |
|---|---|
cone: base/top diameter, length; axis +Z and at origin by default |
conical_surface: directed axis/axis_at, station span, endpoint diameters; optional included angle |
wedge: size [dx,dy,dz], ltx; X width at y=dy, extruded through Z |
face_angle between adjacent outward planar normals; slope planar_face and explicit envelope |
sphere: diameter≥0.02, centre at; full only |
spherical_surface: centre, diameter, full trim/poles/seam; sphere rotation is unobservable |
torus: major>minor≥0.01, major-minor≥0.01; full ring |
toroidal_surface: centre, unoriented axis, both radii and full U/V coverage |
revolve: plane, outer loop, up to 64 strictly interior holes, 2D axis {through,direction}; at=0, angle=360 |
revolved_profile: 3D axis/origin/perpendicular radial, outer loop only in [axial,positive radial], angle; partial phase/caps required; verify holes separately where supported |
| full bushing | revolved_profile + outer_diameter + hole through annular ends |
Revolve reuses all seven extrusion profile forms. The outer loop and up to 64 holes have at most
254 total line/arc segments; holes stay strictly inside the outer loop without touching or nesting.
Holed regions with ellipse/Bézier/B-spline segments are refused (G333). Every
point of every loop, including arc interiors, remains at least 0.01 mm from the axis, and all loops
lie on the same side of it. XZ frame is
u=+X,v=+Z,w=-Y. Exactly 360 is full; near-full gaps cannot become full. Direct
arc-revolve fillet/chamfer/shell is refused even after place/rebinding (C454).
Unsupported attached regions, seam-split unions and spline trim laws stay HOLD; the
full spherical revolve patch is currently unsupported.
Sphere/torus selectors (spherical/toroidal) compare actual carriers with native expect;
they do not certify complete trims. Curved names are not planar supports.
face_angle means outward normals (37×19 wedge, ltx13: 141.632514615°), not automatically
the interior material angle. Cone stations mean dot(axis,point), not distance from axis_at.
Use direct statements for arbitrary directions; stock std dir parameters take principal tokens.
See STD.md and analytic verification evidence
for the admitted stock recipes and obtained measurements.
Spur gears
One external spur gear is one spur_gear step (VXL §7.15): a
faceted involute tooth system extruded along axis, with module, teeth, pressure_angle
(20 or 25°), face_width and optional profile_shift, thinning, chord. Only
<bind>.bottom and <bind>.top are selectable; the teeth are not (a name on a gear facet is
VXL-G390). For a bored gear use the sealed recipe std.spur_gear_bored, which adds a centred
through hole and bundles the gear_teeth and hole requirements that verify them. Its bore
must satisfy bore < 2*(rf - module/100 - 0.01) mm so faceting and the cut tolerance leave one connected gear.
Admitted VXL ranges are module [0.25,10] mm, shift [-0.5,0.5], thinning [0,0.15·module] mm, face width (0,200] mm and chord (0,module/10], default module/100. Teeth start at floor(2(1−shift)/sin²(pressure_angle)) and end at 200, with additional radial-edge, tip-land ≥0.25·module and 1024-face admission guards. Passing scalar bounds alone does not establish admission.
The tooth form is a polygon within the stated chord bound, not an analytic involute surface,
and no ISO 1328 / AGMA accuracy grade, load, transmission-error or wear claim is made.
gear_teeth window bounds stay within [-100000,100000] mm; an optional phase angle stays
within [-360,360] degrees. It measures the complete raw-trim prism certificate, count, tip/root diameters,
thickness, pitch, involute form and width. Base diameter and pressure angle are separate
clause demands only when their tolerances are explicitly stated; their enclosures remain
information otherwise. A required not-measured clause keeps the build HOLD.
Use gear_mesh for a pair: name two operands (and in for an assembly), and name their two
required gear_teeth rows in gears, in the same order. Its comparisons are:
| Clause | Comparison and evidence limit |
|---|---|
| parallelism | Angle between observed end-plane normals within the stated tol.angle |
| section centroid distance | Transverse area-centroid separation within centre_distance ± tol.distance; it does not identify a rotation axis |
| common band | Strictly positive overlap of the certified axial bands |
| backlash at each station | First-contact rotational play on B's authored reference circle inside the stated backlash min/max; certified polygon interference FAILs |
State tol.distance, tol.angle, both backlash limits and integer stations (1–16):
none has a default. Incomplete referenced certificates never PASS. Backlash and
interference require exactly parallel section directions; parallelism can PASS its angle
tolerance while planar contact is typed sections_not_certified_coplanar and the build is
HOLD. A failed normal comparison or disjoint common band leaves contact not measured.
Every reported station must pass; the report says whole_cycle_certified: false because
positions between stations are not certified. Whole-part clearance remains a separate
clearance requirement. That relation is measured by the sealed Linux backend; Mac tooth/mesh evidence does not establish whole-part clearance. A whole-part clearance operand includes attached pins and hubs. To measure a plate portion while retaining one connected carrier, declare views: {"plate": {"min": [-20,-40,-5], "max": [82.75,40,-2]}} on the carrier and select carrier_placed.plate. That view is an exact intersection of the final carrier with the stated box, captured for verification without another deliverable.
Clearance's frozen per-operand caps are 256 faces, 512 unique edges and 16,384 vertices; exceeding one produces typed not-measured before native distance acquisition. A finely faceted 40-tooth default gear has 642 faces/1920 edges, and even its coarsest admitted chord still has 720 edges. Preserve the profile and whole-part intent by using a complete set of connected exact views, every piece-pair clearance relation, and whole-body envelope guards whose accepted bounds stay inside the enclosing view boxes. A query of only the mesh neighbourhood establishes only that neighbourhood's clearance.
See the new gear_mesh_carrier.vxl.json and its arithmetic and measurement walkthrough. The older spur_gear_pair.vxl.json shows gears mounted apart with a whole-part clearance demand; it is not the meshing-pair example.
Local imported parts
Generate the exact attachment descriptor with
vextor vxl asset describe stock.step --id stock, copy it into assets[], and build with
vextor vxl build part.vxl.json --asset stock=stock.step --output-dir delivered.
Supply each declared id exactly once. The descriptor digest uses Vextor's Source domain;
regenerate it after any source-byte change. Check the document before building and inspect
the installed summary/GAR afterwards. See the
CLI import/edit recipe.
For face_displacement, principal and tilted planar supports are measured for identity-placed
imports, including signed distance and complete trimmed footprint. A nonidentity pending frame
on the consumed binding (displaced import or built at/center/rotate/place before the edit) is
typed not-measured (before_after_frames_unassociated): source before coordinates are not
associated with the delivered frame. Identity edits remain measured; final independent geometry
requirements remain available. Whole material_region assertions measure complete
planar/cylindrical boundary separation and an obtained interior classifier in final coordinates.
Both use the ordinary final-subject reading profile; a refused raw source obtains neither.
They PASS only with every boundary separated above the requested clearance and the expected
state. Certified boundary/interior contradictions FAIL; incomplete carriers/census, uncertain
classification or exhausted budgets remain typed not-measured/HOLD. A finite set of samples
does not prove the intervening surface. Required rows with these limits give HOLD.
For standalone verify --sources, use the existing kind: "step" locator and an optional
retained_context: {session_root, session_ref, build_ref} when the STEP came from an owned local
session build. Use references actually returned by the session, that build's terminal and
requirement template. Owned cold reopen authenticates subject/STEP/cell, original attachments,
checkpoints and genuine answered node bindings; changed or missing bytes are a typed refusal.
Caller hashes are not provenance. Ordinary raw STEP verification stays strict; omitting context
cannot recover import history. Run the executable
retained-context example with the flags documented in
the reference.
Profiles and SVG
2D profiles, curves and SVG
Curve segments
Path loops and named profiles accept labelled line, arc, spiral, ellipse_arc, quad,
cubic and polynomial bspline segments. Coordinates may be expressions. For example:
{"path":{"from":[0,0],"segments":[
{"label":"base","line":[20,0]},
{"label":"end","arc":{"to":[20,4],"center":[18,2],"dir":"ccw"}},
{"label":"side","line":[0,4]}],"close":true}}
Use spiral for an Archimedean segment. This four-turn, 3 mm wide band runs outward with
8 mm pitch, then returns on the inner boundary:
{"path":{"from":[14,0],"segments":[
{"label":"outer","spiral":{"to":[46,0],"center":[0,0],"dir":"ccw","turns":4}},
{"line":[43,0]},
{"label":"inner","spiral":{"to":[11,0],"center":[0,0],"dir":"cw","turns":4}},
{"line":[14,0]}]}}
turns is an integer expression from 0 through 16. Directional angular travel, including the
extra turns, must be positive; both endpoint radii and their difference must be at least 0.01 mm.
The compiler retains the authored spiral and builds a clamped C2 cubic B-spline carrier with true
endpoint tangents and a proven error of at most 1e-4 mm. A carrier over the
4,096-pole/4,093-span generated-spiral budget is VXL-C462; an authored bspline segment
retains its 256-pole limit.
A loop has at most 254 segments and 64 holes (VXL-C431); invalid segment geometry is
VXL-G424, undecidable topology is VXL-G423. Extrude, revolve, ordinary loft and ruled,
imprint, and profile split retain supported curves as exact edges or, for a spiral, the certified
polynomial carrier. A reopened carrier or segment
ancestry mismatch is VXL-G434. Curved sweep, pipe, and guided_loft still refuse with
VXL-G425. See also VXL profiles.
extrude.holes prefixes generated segment labels with h<k>_ for zero-based hole k
(for example body.h0_-v for a rectangular hole); authored label/labels[] stay unchanged,
and duplicate labels still fail with VXL-G318.
profiles[]: regions and kernel algebra
Use named regions to share a mechanical outline and combine overlapping features in the 2D kernel:
"profiles":[
{"id":"slot","slot":{"from":[0,4],"to":[16,4],"width":"slot_w"}},
{"id":"plate","union":[{"rect":{"min":[0,0],"max":[20,8]}},{"profile":"slot"}]}
]
Supported region forms include loops, union, difference, intersection, offset (distance,
join: round/miter/bevel), stroke (points or path, width, cap, join, closed), placement
(translate/rotate/scale/mirror), and SVG. Reference one with {"profile":"plate"}. Kernel
results are exact regions with source labels/history. Keep at most 254 segments per authored loop,
64 holes, and 1,024 segments in a resolved region (VXL-G433). Consumer segment limits refuse
with VXL-G435. Profile cycles are VXL-G427;
invalid placement/region is VXL-G428; kernel Boolean failure is VXL-G431, and an exact result
curve that cannot be represented is VXL-G432. Profile algebra cannot be combined with point-cloud
observations in one document. See also VXL named regions.
SVG regions
SVG is an import form for fixed artwork, not a parameter-driven mechanical sketch. Supply a frame that maps the SVG view box into millimetres and gives its anchor; the SVG y-axis is flipped into sketch v. A minimal inline form is:
{"id":"mark","svg":{"d":"M 0 0 L 10 0 L 10 8 Z","fill_rule":"nonzero",
"frame":{"view_box":[0,0,10,8],"size":[20,16],"anchor":[0,0]}}}
An asset uses {"asset":"art","element":"logo"} inside svg; group selection needs stable
element ids. SVG assets are limited to 2 MiB. Unsupported SVG elements, attributes, path data or
frames refuse with VXL-C495. Multi-subpath fills (nonzero winding, evenodd parity)
and strokes, including the stroke-miterlimit miter-to-bevel rule, defer to the supervised
kernel profile prefix as exact regions. Dashed strokes refuse with VXL-C495; VXL-C495 also
covers SVG syntax that remains unsupported. Keep SVG
fixed-size; only frame size follows parameters. See also VXL SVG profiles.
Paths and surfaces
Straight paths and section requirements
Use path_component_kit.vxl.json and its walkthrough: a swept rib, lofted transition and filled pin, with a shared requirement fragment for solid count and mesh closure. The components are separate final subjects. Compilation is checked; read every required measurement and the authenticated build label before claiming RELEASE.
| Choose | When it fits | Independent requirement |
|---|---|---|
sweep |
A single simple CCW line polygon, possibly concave, keeps its section along a straight path. Write perpendicular x; the compiler checks it rather than projecting it. |
swept_section with polygon, path and x |
pipe |
A filled circular rod on a straight path. Write diameter; it has no bore or observable in-plane orientation. | swept_section with a centred circle and path; omit x |
loft |
Exactly two sections with equal segment counts, labels and pairwise-compatible kinds. | loft_sections with independent frame, two sections and span:{"law":"linear_vertices"} |
ruled |
The same per-segment correspondence, using the distinct ruled construction operation. | The same loft_sections expectation; matching endpoint profiles alone cannot prove the span |
guided_loft |
Two to eight convex sections with 3–24 corresponding vertices and at least two distinct vertex rails. Fixed frame or bounded arithmetic-vertex-mean twist. | guide_rail for each required real boundary chain; section_frame for station frames and the admitted full-body law |
Path constructors retain CCW vertex zero, order and labels; they never resample, reverse or choose a cyclic correspondence. Guided points are local XY pairs, one per section, at the indexed vertex; section offsets supply Z. Twist requires one signed angle per station, first 0°, absolute values at most 360° and adjacent changes at most 45°. Fixed frames omit angles. G0 uses the explicit ABC/ACD planar facet diagonal. G1/G2 are admitted only for a fixed, constant-section straight translated prism.
All four kinds address the complete final solid named by subject. Author their
expectations from the request in final part coordinates; moving a construction does not
move its requirement. No kind accepts expect. near and locate choose candidates and
never relax comparison tolerances. Boolean attachments or cuts can remove the complete
path-solid proof; independently verify the resulting final shape before making a claim.
| Kind | Finite proof scope |
|---|---|
swept_section |
Both actual caps plus complete side supports/trims over the entire straight span. A circle additionally needs the complete outward cylindrical-wall group. |
loft_sections |
Actual cap correspondence and a full-domain linear-vertex support/trim/coverage certificate for every side. Equal caps or a few matching cuts do not establish the interior. |
guide_rail |
The complete trimmed real boundary chain through the stated points, including coverage between stations. A buried line or a face diagonal is not a boundary rail. |
section_frame |
Obtained station means/bases/signed angles and complete G0 facet or straight-prism body evidence. G1/G2 concern corresponding-side station seams only; polygon-corner jumps are excluded. |
Station measurements prove only their stations. G0 twist is a faceted body, not a continuously twisting smooth section. Unsupported, incomplete, ambiguous or over-budget proof remains nonpass; it cannot authorize RELEASE. None of these rows proves load, physical printability or fit.
Selector limit: a warped loft or ruled side cannot be the selected face target of a
later statement, even when it has a predicted construction name (VXL-S020). Planar caps
and proved planar sides use ordinary planar selection. Predicted station datums and G0
side groups are not single faces (VXL-Q521). A selector count checks the chosen inventory;
it does not replace an independent geometry requirement.
See the path reference and the path evidence index for the corpus and measurement evidence.
Surface construction card
Use surface_skin_and_roof.vxl.json: a height-field skin
thickened along its axis and a height-field roof trimmed from a block, both carrying their wall and
surface requirements. A surfaces[] entry is a construction input, never a delivery (VXL-C529).
Reach for std.skin_panel and std.height_field_roof before hand-writing one; write poles or a
height_field (degree+1..=8 poles per direction, degree 1–3, non-rational/non-periodic) only when no recipe
fits. std.height_field_roof takes grid (5–8 poles per direction, default 6); a fragment body
may pick a generated surface by the literal lookup {"select": "<param>", "from": {…}} on a
surface/nominal field, and the nets no select of that use picked are not emitted. The abscissae of a height field are control abscissae, not points the surface passes
through. A trim_to_surface target face that the trimming surface crosses must be planar; a
section through a curved target face is refused.
| Statement / kind | Write | Pitfall it guards |
|---|---|---|
thicken |
one patch, exactly one of along: <dir> or normal: "+"/"-", distance in (0.1, 100] mm |
both or neither, and a direction not proven transversal to the net, are VXL-C524; write the height-field axis or a direction inside the patch's normal cone |
thicken normal |
also a required thickened_wall of mode normal naming <bind>.base and <bind>.top at the statement's own distance |
a normal offset beyond the smallest radius of curvature folds and still looks valid; the wall requirement's evaluator proves regularity, and its absence is VXL-C528 |
sew_solid |
2–16 distinct patches; one seam for every non-collapsed boundary, pairing identical boundary rows | an open or doubly-used boundary, a count outside 2–16, or unequal rows/knots is VXL-C526; a free edge or several shells is VXL-X117 |
trim_to_surface |
a height-field patch (or separable monotone net) whose plan footprint covers the target with ≥ 0.1 mm; keep is below or above |
the wrong form or an uncovered footprint is VXL-C527; certain no-op is VXL-G410, certain everything-removed is VXL-G411, and a name the trim removed is VXL-G412 |
spline_surface |
face a spline-born name, nominal a surfaces[] id, tol ≥ 1e-4 (default 0.005), trim natural or any |
a geometric query, an unknown nominal, or a small tol is VXL-R750; use trim: "any" for a trimmed face |
surface_probe |
1–16 {from, along, expect} rays, tol ≥ 0 (default 0.02) |
a zero direction or non-finite expect is VXL-R751; it measures the probe points, not the surface between them |
thickened_wall |
faces the base/top of one thicken, mode, thickness, tol (default 0.01) |
faces that are not that pair or a wrong mode are VXL-R752 |
surface_seam |
between two faces of one sewn solid, class g0 or g1, tol.gap/tol.angle |
the same face or two different solid bindings is VXL-R753 |
What each surface requirement can and cannot prove. spline_surface proves the whole
carrier patch, not stations: an affine reparametrized, swapped/reversed or knot-inserted equal net
passes, while a non-affine piecewise reparametrization, an offset/unsupported carrier, and a
net the refinement budget cannot finish are typed not-measured (HOLD) — never FAIL. trim: "natural" also requires the four boundary edges to equal the natural rows (a missing/extra/
moved edge is a FAIL naming it; an unsupported edge curve is HOLD); trim: "any" accepts a
witness only when its rectangle is proven inside the trim loops, so an unsupported pcurve or an
ambiguous ray is HOLD. surface_probe proves the stated probe points only, not the surface
between them: a grazing ray, a ray that hits twice inside the tolerance band, a C0 crease, and
an unsupported/rational carrier are HOLD, not PASS and not FAIL. thickened_wall proves the whole
patch for the directional (along) form and the whole basis regularity for the normal form; a
carrier that is not a matchable offset (OffsetCarrierLost) or a regularity it cannot certify
(OffsetRegularityUnproven) is HOLD. surface_seam proves the whole shared edge set, G0 gap and
(optionally) G1 normal angle; an undecided angle (SeamAngleIndeterminate), an incomplete edge
census, or a carrier it cannot represent is HOLD. A required clause that is not measured makes the
build HOLD; a non-required one is reported without changing the label.
Walkthrough of roof_and_skin_panel.vxl.json.
A 44x36x20 mm stock at [2,2,0] is trimmed below the five-by-five bicubic roof.
The plan poles are uniformly spaced, rather than Greville abscissae, so evaluate the whole
net to choose stations: S(0.25,0.25)=(14.25,11.875,13.56640625),
S(0.5,0.5)=(24,20,14.5) and S(0.75,0.75)=(33.75,28.125,13.07421875) mm.
The three rays start at those x/y coordinates with z=0 and point along +z.
For the extent, every height row peaks at v=0.5; there the height poles are
[11.5,14.5,15,13.5,11.5]. On the left half, t=2u gives
h=11.5+9t-8.25t²+2.25t³, whose maximum is at u=(11-sqrt(13))/18,
with height 14.57328497889526 mm. Its x/y position lies inside the stock's trim footprint.
The stock envelope is therefore [2,2,0]..[46,38,14.57328497889526].
A separate flat +x panel at x=48 is thickened 2 mm, giving its envelope
[48,2,0]..[50,38,10] and a whole-patch wall certificate: every top pole equals the base
pole plus (2,0,0). Requirements target part ids; this version has no subject for a consumed
intermediate body. The example delivers the panel as part panel, with its own wall and
envelope clauses, and leaves a 2 mm gap to the stock. The two bodies' combined box is
[2,2,0]..[50,38,14.57328497889526]; each envelope clause measures its own part.
The trimmed face roofed.surface supplies the spline and station requirements.
A thickened solid names <bind>.base, <bind>.top and side_u0/side_u1/side_v0/side_v1. A side
cannot be selected by name in this version (VXL-S020): reach it through an edge selector
between the base and top predicates. A sewn solid names <bind>.<patch id>; its seam edges are not
named. A trimmed solid names <bind>.surface; a face the trim certainly removed is refused where it
is referenced (VXL-G412). A surface declared and never consumed warns VXL-W976; a net whose cell
normals disagree warns VXL-W975; a curved net whose estimated mesh uses most of the part's budget
warns VXL-W977. A trimmed solid is exact as built, but whether its delivered STEP is admitted is
decided by the build's verification of the reopened file — do not promise RELEASE for it. See the
surface reference and the
surface evidence index.
Curves and instances
Use curve_sweep for a mesh polygon swept along a bounded line/arc/cubic path. Use scatter
for repeat placements of a concrete mesh prototype, then explicitly realize before
editing, Boolean composition, delivery or measurement. Every step writes rep: "mesh" and a
fresh bind. Instances is an opaque binding kind, not an authored representation or mesh;
there is no implicit realization. Convert exact geometry with tessellate or a field with
extract before using it as prototype, support or realization base. All operands are live
bindings in the same part/frame. See the complete reference.
| Need | Author | Check before building |
|---|---|---|
| Curved profile rod | curve_sweep with path, section.region, section.chord_error, frame.normal |
Path starts at start; segment kind is line/end, arc/center+normal+angle, or cubic/control1+control2+end. Joins must be regular and tangent-continuous. The flattened section is simple CCW, 3…32 vertices, with no repeated closing vertex. |
| Variable section | Optional curve_sweep.section_scale.stations with 2–16 {at,scale} rows |
at and both scale components are unitless. Locations increase from exact 0 to exact 1; scales stay in [1/1024,1024]. Closed paths need equal endpoint scale pairs. The largest station scale component times authored section.chord_error must be at most 0.1 mm; larger products refuse with VXL-C593, including after parameter edits. Scaling does not retessellate the section or certify total swept-surface deviation. Omission keeps legacy identity; an explicit all-unit table remains new authored identity. |
| Longitudinal twist | curve_sweep.twist in degrees, default 0 |
±5760 degrees; closed paths require full integral turns and caps: "none". frame.roll is constant roll, not longitudinal twist. Open caps default both; closed caps default none. |
| Fixed count along a curve | scatter.on curve with path and frame; distribution count |
Open count 2…10000 includes endpoints; closed count 3…10000 omits duplicate seam. No curve top-level spacing or reference. |
| Spacing along a curve | Spacing distribution with spacing and optional terminal |
0.0001…100000 mm along the curve; terminal defaults exclude, include is open-only. This is not a minimum geometric gap. |
| Surface placement | Surface on.target, optional constant region and disk exclude; count or density distribution |
Count 1…10000 or positive per_area in instances/mm²; required top-level spacing is minimum center distance. Insufficient domain/spacing or exhausted work refuses, without partial output. |
| Size from position | scale_by height or distance, increasing range, positive endpoint scale |
Height uses signed principal axis and optional at default zero; distance uses center and a nonnegative range. Clamp defaults true; multiply by random uniform scale. These are the only remaps, not arbitrary expressions/channels. |
| Concrete copies with a support/stem | realize with Instances source, fresh bind, optional mesh base |
Base plus copies are concatenated, without welding or Boolean union. Write mesh union separately when required. |
Choose the prototype's origin deliberately: placement transforms its authored coordinates, without automatic centering. Scatter pins that snapshot; rebinding or editing its name later does not change prior sets. A surface support is read at scatter, not retained as delivered geometry; include it explicitly as realization base when intended. Multiple realizations can read the same set.
Required seed is a literal integer 0…4294967295. Optional axes default primary z/secondary y;
use signed x, y, z, -x, -y, -z with distinct unsigned axes. Primary follows curve
tangent or support normal; secondary follows transported normal or reference tangent. Surface
reference defaults x. Uniform scale defaults [1,1] within [0.000001,1000]; degree roll
defaults [0,0] with ordered bounds in [−180,180). A remap has positive endpoint factors ≤1000;
its final random-scale product must stay finite in [0.000001,1000], including extrapolation.
Surface regions keep the all-three-vertices rule and inclusive
selected-vertex expect on each node. Leaves must be constant without width. Disk exclusions
instead remove whole eligible triangles touching/intersecting a principal-plane disk, even
without an inside vertex. Each disk requires center, principal normal, positive radius and
inclusive removed-face expect; at most 16. Eligible faces must all be coplanar within
0.00001 mm of each disk plane; select the planar patch first. Each disk counts from the original
region domain, then removals are unioned. This can exclude more than the disk area and never
proves prototype clearance.
The following complete document uses open-curve spacing and explicit realization. Check it, then build to a fresh output directory. Its requested count and closure need actual final-STL measurements; static admission is not a geometry verdict.
<!-- vxl-example -->{
"schema":"vextor.vxl.v1", "id":"curve_spacing_copies",
"units":{"length":"mm","angle":"deg"},
"needs":[{"id":"n_count","text":"The delivered mesh has three edge-connected face components."},{"id":"n_closed","text":"The delivered mesh has no boundary or nonmanifold edges."}],
"parts":[{"id":"part","rep":"mesh","deliver":"copies","steps":[
{"id":"prototype","op":"curve_sweep","rep":"mesh","bind":"prototype","path":{"start":[0,0,0],"segments":[{"kind":"line","end":[0,0,2]}]},"section":{"region":{"polygon":{"points":[[-0.5,-0.5],[0.5,-0.5],[0,0.5]]}},"chord_error":0.1},"frame":{"normal":"x"}},
{"id":"positions","op":"scatter","rep":"mesh","bind":"placements","prototype":"prototype","seed":1035,"on":{"kind":"curve","path":{"start":[0,0,0],"segments":[{"kind":"line","end":[0,0,40]}]},"frame":{"normal":"x"}},"distribution":{"kind":"spacing","spacing":20,"terminal":"include"}},
{"id":"copies","op":"realize","rep":"mesh","source":"placements","bind":"copies"}
]}],
"requirements":[{"id":"count","kind":"component_count","subject":"part","expect":3,"covers":["n_count"]},{"id":"closed","kind":"closed_delivered_mesh","subject":"part","covers":["n_closed"]}]
}
Use component_count on the realized delivered mesh, never on Instances. It measures
edge-connected faces, not placement count: a prototype may contain multiple components,
a base contributes geometry, and Booleans change topology. A stem with 8 or 12 separate branches
needs measured 9 or 13 components, plus its own closure and dimensional requirements. Neither
centers nor nested arrangements certify clearance or a 44 mm radial gap; retain independent
triangle-based gap measurements where the clearance profile does not admit the arrangement.
Fixed limits include 10,000 rows per set and live per part, 64 MiB placement cache, 1,000 sweep rings / 64,000 sweep triangles, and realized output up to 3,000,000 vertices / 1,000,000 triangles. No limit override is authored. Unknown density/spacing estimates remain unknown; known lower bounds and actual execution counts still enforce budgets. Keep same-cell replay claims distinct from cross-platform trigonometric last-bit identity. Diagnostic repairs are listed under C590–C598, R790–R793, Q555–Q556. A required component or closure nonpass holds the build; no seed, receipt or clean text check substitutes for it.
Finishing and text
Finishing and text card
Four statements change one tracked predecessor's face profile; the predecessor must be a tracked
convex prism (a Boolean or placement result is refused). Use
skill_finishing_labelled_plate.vxl.json:
a plate with 2 mm of +Z stock, a +Y wall drafted 3° about z6 pulling +Z, an untouched front/top
variable fillet run and a planar raised legend, each with its own requirement. Its page says
measured outcomes: see the evidence index; do not quote an outcome the evidence index has not
measured.
| Statement | Author | Independent requirement |
|---|---|---|
draft |
{target, faces:{select,expect:1}, angle, pull, neutral:{through}}; angle magnitude (0,45]°, either sign; pull +z means the neutral-plane normal is the pull |
draft_angle: the undrafted wall normal + through (+ optional near), pull, neutral.through, angle; measures the signed angle and the neutral-line residual |
face_offset |
{target, faces:{select,expect:1}, distance}; outward only, (0,20] mm, one planar convex face |
feature_distance: two operands [before,after] and one between.first/between.second plane each, along, distance; the relation over the two subjects |
variable_fillet |
{target, edges:{select,expect}, run:{from,to}, radii:{start,end}}; straight collinear run, radii [0.01,50] mm, equal endpoints = constant |
variable_fillet_radius: two planar supports between, the same run, measurement:"stations_v1" and 1–16 interior stations:[{at,radius}] |
text |
{target, content, mode:relief|engraving, depth, placement}; depth (0,20] mm; placement planar/paragraph/path/cylinder |
text: content, placement, mode, depth, region in label coordinates (min/max), measurement:"outline_depth_v1", optional checks |
Stroke text: author style:"stroke", stroke:{width} and font:{std:"std_stroke_1"};
repeat them independently in a text requirement with measurement:"stroke_region_depth_v1",
checks:{stroke_width:0.5,min_gap:0.25} and tol:{stroke_width:0.05}. Width/gap are bounded on
final region boundaries; a single component cannot pass a gap demand. See Example 17
vxl/stroke_tag.vxl.json and Example 03 vxl/stroke_text.vxl.json.
Pitfalls the refusal codes guard:
- A paragraph's line pitch is the font's typographic line pitch (ascender − descender + line
gap), not the ink height of the drawn glyphs. Size the box to the whole stack; a too-small box is
VXL-C489and its message names the axis and the per-line pitch. Aplanarlabel is one line. - A
textregionis relative toplacement.anchor, first axis along the baseline and second alongnormal x baseline; it must contain the nominal box (VXL-R716). - On a
pathlabel a contour may meet the boundary of its host face and still be measured: a wall vertex may not lie strictly between the cap and host stations nor beyond the free plane. - Cylinder text is not measured: the statement compiles and the requirement row
is a typed non-pass (
TextCylinderLayoutNotEvaluated), so a required one HOLDs. variable_fillet_radiusmeasures the authored stations only; there is no between-station law (BlendScopeV1::FiniteAuditedStationsOnly). A station's radius is the radius of the blend's cross-section in the plane normal to the run at that station.- A
keep_outoperand offeature_distanceis probed in its own posed frame. A window on its plane reference that cannot be expressed in a non-right-angle keep-out frame is refused withVXL-R712(remove the window, or place the keep-out with right-angle rotations). variable_filletcreates a blend face with no stable name; select a neighbouring face by a planar query, not a name that resolves to the blend.
Threads, coils and springs
Use thread_coil_fixture.vxl.json: an offset block with a
blind M4 hole, a separately placed M4 stud and a plain round-wire coil, each with a typed
sections_v1 requirement. The document compiles; native exact admission of the steps and the
runner rows are still open (see below), so treat the composed example as a checked teaching
document, not as a measured RELEASE.
| Choose | When it fits | Independent requirement |
|---|---|---|
hole + thread:{pitch} |
A right-hand, one-start threaded hole in a target block, cut after the other features of its binding. Any diameter/pitch where pitch <= diameter/2 and 1–64 turns. |
thread with form:"internal", major_diameter, an authored minor_diameter, ends:"blind" or "through", and a floor planar_face for a blind hole |
thread form:"external" |
A metric threaded shaft. ends:"trimmed" for a clipped root or ends:"full_profile" for an uncut profile. |
thread with form:"external"; for full profile write from:-3*pitch/8 and flank length:root_length+3*pitch/4 |
thread form:"internal" |
A separate cylindrical blank with a threaded cavity and a required outer_diameter at least diameter+0.02 mm. |
thread with form:"internal" and ends:"blind" or "through"; a separate outer_diameter for the blank wall |
helix family:"helix" |
A bounded round-wire helix (a solid wire, never a bare curve). | helix with radius, pitch, turns, circular section and ends:"plain" |
helix family:"coil" / family:"spring" |
A plain coil or spring; the family is a label, not an observable difference. | The same helix requirement; do not demand a measured family. Spring stiffness, load and fatigue are never measured. |
The statement rules that bite:
threaddefaults:formhas no default,diameter/pitch/lengthare required,axis:+z,at:[0,0,0],hand:right,starts:1; externalendsdefaultsfull_profileand internaltrimmed. Pitch is[0.1,10]mm,diameter >= sqrt(3)*pitch,lengthgives 1–64 turns. Full-profile external threads are measured with overhang recorded; an uncut end joins the observed constant-radius root return to the terminal flank at the tip and to the body cap with an exact axis root, with overhang bounded by3/8of the measured pitch. Internalfull_profileis refused (VXL-C473).helixdefaults:radius/section/pitch/turnsrequired,family:helix,axis:+z,at:[0,0,0],hand:right,starts:1,ends:plain,end_coils:0. Radius is[0.2,100000]mm and above the wire radius, pitch[0.1,100]mm,starts*turns <= 64. Closed and closed-ground ends (and any nonzeroend_coils) are refused withVXL-C477— this version offers plain ends only. An over-budget coil is refused atturnswithVXL-C478.- Both constructors are terminal: a later Boolean, fillet, chamfer or shell on the threaded
binding is
VXL-C418. A thread/helix requirement must authormeasurement:"sections_v1", an explicitaxis/at(or a matchingfeaturedatum), anauditwindow for a thread,handby default right andstartsby default one.fromdefaults zero. A wrong hand, pitch, starts, length, minor/major or end form is a required geometric failure; a missing or mismatched locator is a typed non-pass (VXL-N101,VXL-R611). - Write the internal thread's
minor_diameterfrom the modelled pilot, not from an ISO formula:D - 5H/4 + 0.06mm withH = sqrt(3)/2*pitch(M4 x 0.7 gives 3.3022277717 mm). The verifier reports the internal flank form as not measured; itstol.profilebounds only the profile repeat. A thread requirement needs one complete repeat per meridian and two complete leads inside itsauditwindow. - The std wrappers
std.threaded_hole(a blind internal hole with its thread and floor),std.thread_stud(a full-profile external stud),std.thread_boss(an internal through thread with its outer wall) andstd.coil(a plain coil) bundle the statement and its requirement; seeSTD.md.
Open at the time of writing. The compiler and the requirement language are in place, and the
STEP admission rule is implemented (a raw exactly-valid solid, or a geometry-untouched copy whose
failing edges get a certified re-derived tolerance U <= 1e-5 mm plus a certified vertex-gap
allowance G <= 1e-5 mm; the combined U_total is carried into every comparison and a
requirement passes only over the whole interval). The complete native observations are not yet
measured RELEASE: the runner pins show every thread row failing at the publish resource limit
(VXL-X110) and every helix row at the export mesh budget (VXL-X107), the internal-thread
runner rows run only on Linux, and the strict external report assertion is not registered. Do not
claim a measured RELEASE for any thread or helix row.
Mesh and organic
Mesh parts card
Choose rep: "mesh" when the delivered triangle geometry is the authority: an STL source,
mesh Boolean/primitive editing, repair, decimation or the surface edits below. Choose exact when required facts need
analytic carriers, selectable exact faces, modelled threads, or a delivered STEP. A mesh terminal
delivers STL, Core 3MF and four renders, with no STEP. The manifest and summary record its
representation. Pair mesh with mesh_conservative_v1 (default for a mesh deliverable); exact
with exact_only_v1. A keep-out has no acceptance profile. Write rep: "mesh" on every mesh
step; a part’s rep alone does not change its exact-default statements.
Use a hybrid chain exact construction → tessellate → mesh operations when source design
facts still matter. See the checked hybrid document:
plate@drill names the exact output immediately after the step id drill. Its hole
requirement is source-geometry evidence only, retained in an evidence STEP checkpoint. It says
nothing about the delivered mesh after conversion or editing. Add independent requirements
on the final mesh; a mesh step cannot be an exact checkpoint and there is no mesh→exact path.
Create analytic control surfaces with surface_grid and cage source refinement.
Use output:"cage" before cage {source}; a mesh binding is refused. See
Parametric mesh and cage sources
for wraps, poles, diagonals, creases and boundary welding.
Start with a checked STL import and its
cube asset, or tessellate.
STL imports need source_units: "mm" or "inch" (scale 1 or 25.4), accept ASCII or binary
STL and never repair implicitly. Regenerate assets[].digest and bytes after changing bytes;
use the Source-domain descriptor, not a raw file SHA. Supply each declared id once with
--asset id=file.stl. Caps: 64 MiB per STL or PNG, 32 MiB per cage JSON, 96 MiB across all media, 8 attachments total;
External STEP inputs remain capped at 8 MiB each and combined; STEP produced from the build's
own result may be up to 32 MiB. Text checking cannot inspect source geometry.
Mesh request headers are capped at 1 MiB and retained session frames at 64 MiB. Probe families
that use the shared probe cap allow at most 32 probes per subject.
| Author | Limits and result |
|---|---|
tessellate |
Exact source, mesh bind; 0 < deflection <= 0.05 mm. Optional angular is degrees, >0 and ≤28.64788975654116, default 5.729577951308233. Sampled deviation receipt is provenance, not certification. |
mesh union / cut / intersect |
Both operands mesh; optional tool_place is rigid. Fixed manifold tolerance 0 and triangle area 1e-12 mm²; no authored tolerance or construction alias. |
primitive cut |
Box centre/size, principal-axis 64-segment cylinder with at, diameter, span, or plane with at, normal. Box/cylinder keep outside (default) or inside; plane requires positive/negative. |
repair |
Cleanup always; optional weld→cleanup, orient, fill all boundary loops→orient, internal-shell removal. Fill is all-or-refuse, not partial. Internal shells need complete containment and material-preservation proof or typed refusal. No component ordinals or keep_components. |
decimate |
Positive max_deviation mm; preserves boundaries and seams, no authored locks/implicit repair. Receipt records sampled measured deviation; it is not a global certified bound. |
mesh place |
Rigid rotations in order, then translation; requirements locate the resulting part frame. |
Require closure and independent topology/dimensional claims as appropriate. The material kinds
(volume_range, minimum_wall, opening, mesh–mesh clearance) internally require a completely
inspected closed, consistently material-oriented, two-manifold, defect-free solid. The ordinary
admission requires one edge-connected component; a certified cavity inventory admits one outward
outer shell plus its inward cavity shells where the individual material query supports that profile,
even without explicit closure/count rows. Missing/incomplete inspection is inspection_unavailable;
invalid closed-solid admission is not_complete_closed_solid; extra components give
multiple_components with the count. These are Unknown; they cannot pass by cancellation of
uncertified inward and outward signed volumes. After containment and orientation admission,
volume_range subtracts certified inward void volumes. Component count and envelope remain
decoded-topology facts.
| Requirement | Proves / evidence | Cannot prove |
|---|---|---|
closed_delivered_mesh |
Complete delivered-STL closure, material orientation and two-manifold/defect inspection; one outer plus declared inward cavity shells is allowed; Exact | Dimensions, cavity count without its matching declaration, or printability |
component_count |
Literal edge-connected topology count; one outer plus N inner shells counts as 1 + N; Exact |
Closure, valid material, containment or intersection freedom |
envelope |
Delivered vertex bounds; Exact | Material fills the bounding box |
volume_range |
Admitted mesh material volume in mm³, subtracting certified inward voids; Exact | Analytic source volume or material location |
mass_range |
Explicit positive density (g/cm³), inclusive min?/max? (g); exact properties Exact, delivered-mesh moments Estimate |
Infill, nonuniform density or physical mass; required Estimates keep HOLD |
center_of_mass |
Exactly one within: {min,max} or near: {at,radius} in subject-frame mm; Exact / mesh Estimate |
Assembly occurrence balance or certified centroid error bounds; unavailable bounds keep HOLD |
self_intersection_free |
Completed whole-mesh bounded scan; Exact | Closure; exhausted scan budgets never pass |
minimum_wall |
Safe-side ConservativeBound on material depth under one planar disk, threshold min - tol |
Local by contract: never the global/whole-feature minimum; no region form |
opening |
Safe-side ConservativeBound on a void cylinder over the written directed span | Nominal bore diameter, measured floor/depth or general accessibility |
mesh–mesh clearance |
ConservativeBound only with disjoint axis-aligned bounds and sufficient certified separation | Overlapping bounds, nested arrangements or designed exact contact |
mixed mesh/exact clearance |
Typed not-measured mixed_representation_unqualified |
A qualified separation proof; a required row holds |
For opening, give a diameter below the nominal bore, allowing for facets, the circumscribed
64-gon radius (diameter/2)/cos(pi/64) and rounding. Its entire prism must miss every triangle
and at least one whole end cap must lie strictly outside the mesh bounds. Both caps outside
certify the written through span; one outside certifies only the written blind/part-through span.
End a blind span short of its floor by the allowance you accept. Contact or neither end outside
is Unknown. Sampled rays never establish the proof. Use principal-axis disk locators for mesh
minimum_wall, keep the continuous disk strictly within its planar patch and its centre
strictly inside one source triangle (avoid triangulation seams), and write 0 <= tol < min.
Under mesh_conservative_v1, Exact PASS or a safe-side ConservativeBound may pass; an Estimate
never does. Required Unknown, incomplete admission and exhausted budgets hold. A mixed generation
still
has one report and one label; each deliverable must pass under its own profile. macOS arm64
development builds stay HOLD. Enforce ≤1,000,000 triangles per mesh terminal and ≤4,000,000 live
across one part’s chain; unknown asset counts are checked at execution. The optional
limits.self_intersection_tests is 1–100,000,000, default/ceiling 100,000,000.
See Mesh statements for a complete checked JSON example of each operation, its editable limits and typed-refusal conditions. A clean check does not imply a measured RELEASE.
Editable semantic sculpt paths
Use sculpt_path for editable brush parameters and current-predecessor semantic selection. Follow the grammar: explicit target, bind, typed brush, 1–256 points, one surface_query or edge_distance_query selection, and sampling:{} or explicit positive length spacing_mm. Query regions have explicit expectations; edge seeds/barriers/protection require constant weights. Each path resolves on its actual predecessor and freezes its selection; later paths requery after earlier geometry edits.
Edge distance measures actual triangle-edge length, retains the zero-weight radius boundary, rejects seed/barrier overlap, and treats unequal-owner edge endpoints as barriers. Protection has zero weight and remains traversable. Stay within the typed caps in the grammar. Do not author captured ordinals or retag an old capture after a source edit. The six brush kinds and tagged falloffs are editable parameters; captured sculpt keeps its existing source admission and stale-basis contract.
Retain canonical source, literal program, and worker receipts together for cold recompile. Source tests do not qualify scale, workflow delivery or physical print acceptance.
Captured sculpt replay
Use grab/draw_clay/inflate/flatten/crease/smooth with constant/linear/smoothstep. Grab requires a finite explicit nonzero effective direction (sample overrides config); reject invalid shadowed directions. Other brushes must omit/null directions. Clay true is valid only for draw_clay. Refuse Gaussian, embedded masks, symmetry and nonzero tolerance. Selection is tagged none/geometric/indexed, frozen once from the actual host-authenticated checkpoint. Indexed requires exact basis, explicit null or V finite [0,1] weights and strictly increasing unique in-range protected indices. Geometric supports sphere/box/ halfspace/capsule/normal_cone and leaf/all/any; near_face refuses, protect is constant only. Protect-only retains null weights. Hard pins precede weights; zero weights still participate in brush plane/neighborhood statistics. Do not sort/clamp or reselect between applications. Read the verification evidence and local evidence for their measured scope. Local replay and sampled macOS resource diagnostics do not establish Linux/hosted or memory qualification.
Follow the single public command recipe
and grammar, rather than inventing a capture variant.
Capture a current authored deliver mesh subject (analytic or owl, not body or a lowered
name), with all source assets and effective literal JSON overrides. The strict options file
requires both stroke: NormalizedStroke and one strict tagged selection; use the exact
selection grammar. Capture resamples
once; replay consumes one canonical ordered path and compact receipt, not one VXL step per
application. Append the public sculpt descriptor to assets[], add sculpt with explicit
target, bind, asset, and update the delivered binding. Do not override brush or strength
in the statement or synthesize final sculpted geometry outside the product.
Authenticate canonical source bytes with the Source-domain descriptor, then require the actual explicit target's exact f64 ordered indexed basis at M0. Seed/native UUID/whole-document identity or visually identical f32 STL does not grant replay permission. Metadata or renaming can preserve the basis; a geometry edit to an earlier prefix requires recapture there in the intended execution cell. Do not soften a stale basis with a tolerance or promise cross-cell bit identity. macOS development remains HOLD; Linux sealed/hosted acceptance is separate.
For S1 → S2 → S3, capture every stroke against its actual predecessor with all prior Source assets supplied. After changing S1, require old S2 to refuse X160/no install, recapture S2, require old S3 to refuse, then recapture S3 and the remaining suffix in order. Do not capture every stroke against M0 or reuse old suffix bases after an edit.
Use capture --attribute-policy geometry_projection and independently set replay
geometry_projection: true when recognized extra channels must be removed, including all-zero
STL attribute words. Derived F64 face/arity-3 normals are recomputed without permission/loss;
unknown or unsafe channels refuse. The source itself grants no target projection permission.
Keep the unchanged ceilings: 2 MiB source, 64 KiB raw input/path each, 256 raw samples/applications
each, 50,000 vertices/triangles each, plus shared asset budgets. These are admission bounds,
not RSS/latency or manufacturing qualification. Hosted uses canonical sculpt_capture on the
existing upload/ref/pin/build/download flow; there is no capture service or --after evaluator.
Indexed checkpoint output is for inspection; ordinary sculpt asset describe/hosted do not admit
unused indexed media. export-sources authenticates and restores inputs; a real fresh rebuild
must pass all restored assets and the contents of overrides JSON into a new build/output.
Use the analytic replay and
owl brow slice for independent
actual final STL/Core 3MF checks and wrong-build controls. The public recipe above also
contains run_b.py matrix/chain commands, Example 26 strokes_b.py and Example 30
vxl_replay/prepare.py → run.py commands. Use genuine pre-sculpt sources and preserve
the frozen ROI/footprint/interface checks; keep recapture and fresh rebuild enabled.
The owl's 36×28 mm base bounds contain the centered 26×20 mm required rectangle.
For scale, run_scale_b.py takes --case one, many, caps or all, a fresh
--output-dir and optional genuine input --source-dir. Keep its oracle enabled and
rerun only an affected case after a fix. Sampled debug RSS is not allocation/SLA evidence;
valid-JSON source padding probes byte caps without proving canonical-size reachability.
Ordinary terminal Core 3MF must match the exact f32 projection of independent f64 math,
with exact indexed topology/pins; this never relaxes native basis equality.
Receipt/render agreement alone cannot establish brush intent. Preserve required
unobserved intent as Unknown/HOLD; do not
infer full artistic, slicing, physical or manufacturing acceptance.
Static named pose rigs
Use the admitted named-rig pose profile for fixed-topology mesh variants. Follow the
public recipe and
grammar; bounded native/hosted and recovery results
are in the native evidence and
hosted and recovery evidence. Capture the actual current deliver mesh subject,
author strict binds/weights using that indexed vertex order, then call
vxl prepare-pose --basis INDEXED --spec RAW --output NEW.pose-rig.json. Pure indexed
preparation has no attribute-policy flag. Use the actual asset describe --id descriptor;
never guess a digest or publish a positive fixture with mismatched bytes.
Append pose with explicit target, bind, static rig and named joints using existing
Placement expressions and parameter units. Omitted joints are identity. No inline binds or
weights, normalization, new Euler convention, auto-rig/auto-weight, IK, retarget or animation.
Each variant starts at the same rest basis. Unknown names require the authenticated rig;
asset-free check cannot prove membership. An exact-basis mismatch requires recapture and
preparation. Target projection defaults false and separately permits recognized extra channel
loss; derived face normals are recomputed. Hosted uses exact pose_rig on ordinary REST
upload/ref/pin/build/download. Preserve source 64 MiB, joint 64/depth 32,
row/pair and shared 8-ID/96-MiB bounds. Recovery includes sources/pose/; fresh rebuild passes
all restored source mappings and literal override contents in a new process/output. Validate
actual final STL/Core 3MF independently; receipts/renders do not qualify an angle domain or
artistic, physical or manufacturing intent.
The connected figurine recipe observed the finite [-20,-10,0,10,20]² degree grid,
an effective 25/75→50/50 shoulder-weight edit through public re-prepare, and an exact
retained-only fresh STL after moving the whole original staging. A separate Linux
hosted/cold/fresh run observed the three named cases. Never infer continuous validity:
fully inspect each actual custom-angle build. Keep STL 2e-5 mm and projected-Core
1e-9 mm budgets, already-exact-f32 observations and exact neutral/source-basis checks.
Use the public recipe's portable package/cell variables and a new output directory;
package installation/default availability is not implied.
Cages, deformation and relief
Use these statements for bounded edits of delivered mesh geometry. Every step writes
rep: "mesh"; exact inputs need tessellate first. Target edits have target and optional
bind defaulting to target; cage creates a fresh bind from either an external asset or a prior
surface_grid step with output: "cage" via source. Start with the
checked surface examples and the
full reference.
| Need | Author | Check before building |
|---|---|---|
| Bend, twist or taper | deform, kind plus frame, axial range and angle, turns or scale |
Angle −180…180 degrees, turns −16…16, positive scales ≤100. Frame at defaults zero; axis is a principal direction or nonzero vector. |
| Box-cage deformation | deform, kind: "lattice", physical bounds, eight vector offsets in mm |
Positive box extents, x-bit-fastest corner order. All selected vertices must lie inside, including protected or zero-weight ones. |
| Texture or formula relief | displace, map, mapping, amplitude |
Map is one PNG asset or an expression with integer raster size 2…4096. Expression locals x/y span [0,1]; every result must be finite in [0,1]. No clipping or source UV. |
| Refine triangles | subdivide, rule, levels 1…8 |
midpoint, loop or adaptive; positive target_edge only and required for adaptive; constant creases only for Loop. Budget input faces × 4^levels. |
| Relax or redistribute triangles | smooth or remesh |
Smooth rule Laplacian/Taubin, lambda default 0.12; mu default −0.13 for Taubin only. Remesh requires positive target_edge. Iterations 1…16, default 1. Boundaries/seams stay fixed; constant protection locks incident edges and can pin neighbours too. |
| Authored triangle/quad cage | cage, asset, rule, levels 0…8 |
Triangle → Loop; quad → Catmull–Clark. Level 0 validates then triangulates. Asset owns crease edges; no step override. |
Mapping uses a tagged planar (two-component size), cylindrical (length) or triplanar
(three-component size, sharpness default 4) object. All lengths are positive mm. Rotation is
mapping.frame.rotate, in degrees, alongside axis and optional at; it is not a step-level
rotation. A +Z frame with 90 degrees gives planar +X/+Y orientation. Seam policies are shared
for planar, wrapped/cut for cylindrical, blended/priority for triplanar. Displacement defaults:
normal direction, chord error 0.05 mm, minimum edge 0.25 mm, depth 3 (1…8), profile
linear/clamp/linear/neutral 0. Signed displacement is amplitude × (sample − neutral) × weight;
fixed directions are also admitted. sRGB linearization is PNG-only. Large rasters/refinement
may still exceed bounded work/report limits; a decode cap is not a scale guarantee.
Regions are current geometric predicates: sphere, box, positive halfspace, capsule,
normal cone (fixed or radial axis), and the bounded retained-exact-face near-face profile.
Near-face is limited to the six retained same-part exact box construction faces, captured
before later edits; other carriers or unavailable inventory refuse. Every leaf writes falloff and inclusive selected
vertex expect: [min,max]. Constant forbids width; linear/smoothstep require positive
inward width, in mm except normal-cone degrees. Boundary membership counts even at weight zero.
all/any compose membership and product/maximum weights, each with its own expect and no
outer falloff. Limit 16 leaves, depth 8; protect/crease arrays have at most 16 constant selectors.
Identity edits still check counts. A triangle belongs only when all three vertices match;
creases need both endpoints. Moving shared vertices also moves partially selected triangles,
so use protect when a boundary must stay fixed. No arbitrary evaluated-mesh index masks.
PNG assets use image/png, at most 64 MiB; only noninterlaced/nonanimated grayscale 8/16-bit,
at most 4096 per edge. Cage assets use application/vnd.vextor.cage.v1+json, at most 32 MiB.
Their closed schema is vextor.cage.v1, with triangle/quad topology, ordered numeric-mm
positions, matching three-/four-index faces, and a creases array of actual edge pairs into
that asset's own positions. Caps: 65,536 faces, 262,144 used positions and unique edges.
Duplicate/unknown keys, unused vertices and invalid/degenerate/nonmanifold topology refuse.
See the schema and bound asset; refresh descriptors after byte changes.
Require independent final-STL measurements. flat_region takes a constant axis-aligned box
or principal-halfspace composition, a principal plane and nonnegative mm tolerance. It reruns
selection on delivered decoded STL, including expect counts, requires a nonempty triangle union
with a certified nondegenerate face, and bounds every selected corner. PASS proves only the
flatness of that selected triangle union: no contact-area, footprint-coverage or global-flatness
claim. Missing/decode evidence, unsupported/uncertain selection, empty/degenerate region,
count mismatch, exhausted budget, cancellation or an inconclusive threshold bound remain
Unknown; a required Unknown holds. See exact reasons.
Receipts and a clean text check do not substitute for measured RELEASE.
Print delivery
Use split_print on a concrete mesh for one named pair, or hollow with explicit drains for a
bounded drained shell. Exact sources need tessellate; fields need extract; Instances needs
realize. Write rep: "mesh" on the statement. Start from the checked
split/drain documents and read the
complete field/default/refusal reference.
| Need | Author | Require on the delivered STL |
|---|---|---|
| Integral pin/socket pair | split_print with principal by.plane, exactly one negative and one positive fresh pieces[].bind, homogeneous connectors.kind: "pin_socket" |
Closure/dimensions independently, plus connector_clearance on the two delivered subjects. Recipe clearance is not evidence. |
| Loose dowels | connectors.kind: "dowel_pin", required fresh statement pins binding |
Deliver the two pieces plus grouped pins. Require closure and any needed measured component count; do not infer count or insertion fit from placements. |
| Drained shell | Existing hollow, positive wall, bounded grid, 1–32 explicit drains with at, principal axis, positive diameter |
enclosed_cavity_count and separately located continuous opening requirements. Count zero alone cannot locate a drain or prove flow. |
| Several mesh deliverables | Object deliver maps subject keys to live bindings; independent parts also work |
Each subject gets its own requirements, STL/Core3MF/four renders and no STEP. One required nonpass holds the shared generation. |
For pin/socket, required positive diameter, clearance, edge_margin, depth, embed;
socket_depth defaults to depth+0.5 mm and must be ≥depth+clearance. Omit pins. For dowels,
use positive length and hole_depth≥length/2+clearance instead of depth/embed/socket_depth,
and name pins. Placements are 1–32 finite points on the principal plane within0.000001 mm.
The split consumes its source, has no generic bind, and returns all children atomically.
Each split writes one pair; more pieces need explicit named repeats within the slot/work
limits. Repeated splitting may exhaust the fixed256KiB Boolean-report cap.
There is no cap override, arbitrary-piece count, component ordinal or automatic printer layout.
Object delivery has2–8subjects; delivered and evidence exports share16slots.
Drains must start in the intended cavity and point out through an admitted locally constant-depth
wall. Unsupported curved crossings refuse with the editable at/axis/grid; no automatic
lowest-point placement is selected. Field sample-count and work limits still apply. A D4 cutter
needs an independent conservative opening, e.g. D3.5 over the full required span. This complete
document checks clean; its three requirements still need obtained final-STL measurements:
{
"schema": "vextor.vxl.v1",
"id": "print_drained_hollow",
"units": {"length": "mm", "angle": "deg"},
"needs": [
{"id":"n_closed","text":"The shell is a closed delivered mesh."},
{"id":"n_traps","text":"The shell contains no enclosed cavity."},
{"id":"n_open","text":"A 3.5 mm bottom opening stays clear along Z from -1 to 4 mm."}
],
"parts": [
{
"id": "shell",
"rep": "mesh",
"deliver": "shell",
"steps": [
{"id":"stock","op":"box","bind":"exact","size":[24,24,20],"at":[-12,-12,0]},
{"id":"mesh","op":"tessellate","rep":"mesh","source":"exact","bind":"body","deflection":0.05},
{"id":"hollow","op":"hollow","rep":"mesh","target":"body","bind":"shell","wall":2.4,"grid":{"voxel":[0.5,0.5,0.5],"margin_cells":8},"drains":[{"at":[0,0,4],"axis":"-z","section":{"region":{"circle":{"center":[0,0],"diameter":4}},"chord_error":0.1}}]}
]
}
],
"requirements": [
{"id":"closed","kind":"closed_delivered_mesh","subject":"shell","covers":["n_closed"]},
{"id":"cavity","kind":"enclosed_cavity_count","subject":"shell","expect":0,"covers":["n_traps"]},
{"id":"opening","kind":"opening","subject":"shell","at":[0,0,0],"axis":"+z","diameter":3.5,"span":[-1,4],"covers":["n_open"]}
]
}
Cavity inventory is Exact only after complete topology/containment evidence; a completed wrong count fails, unsupported/incomplete evidence is Unknown. It can certify nested closed boundary shells without the ordinary single-component material gate, but does not certify void volume or gravity emptyability. The separately located opening keeps its own material admission.
On an exact delivered subject, an intentional positive inventory is also the delivery declaration:
write a required: true row with expect: N. Omitting it, making it optional or declaring the
wrong count produces VXL-X121. Mesh component_count remains the literal edge-connected surface
count, so one outer shell with N inner shells has an evaluated count of 1 + N.
Connector evidence is a ConservativeBound on principal-shaft radial and tip separation.
It allows intentional split-plane contact, requires complete nonvacuous pin containment in all
authored shaft envelopes plus continuously expanded void in the socket, and rejects uncovered or ambiguously assigned
protrusions. For nominal D6/depth4, the positive example uses independent D6.01/depth4.01 envelopes,
planeZ10, construction clearance0.4 and required bounds0.2 mm. The socket must additionally have strict entering-face witnesses in (R,2R) at three axial
stations and four opposed radial directions per shaft, with R = diameter/2 + min_radial.
A far-away socket, an unengaged block or unresolved edge/rounding witness is named Unknown
socket_material_missing. This finite bracketing proves local material only, not a continuous
wall or full engagement; an oversized bore can conservatively remain Unknown.
Bounds below the requirement or an
unsupported proof stay Unknown/HOLD, never an invented measured gap failure. This does not prove
nominal dimensions, insertion, motion, physical fit, friction, retention or whole-part clearance.
Ordinary mesh clearance still needs disjoint AABBs. Do not change a threshold after measurement.
Build to a fresh directory with a matching authenticated package and worker; read every GAR
value class/reason, then run the retained adapter named in the example README. The alongside
shell+lid family uses independent cages and
inherit_creases, preserving the original two-part Example20 and all its geometry thresholds.
All macOS development builds stay HOLD even when every geometry item passes.
Printability stays CLI-only provenance: no VXL statement, requirement or top-level key.
Optional existing vextor mesh printability reports require a captured native mesh and explicit
profile/revision; they never cover a need, decide orientation or grant acceptance. A selected
authenticated terminal Core3MF can separately feed vextor 3mf create-bambu-project; that does
not automatically combine all subjects or prove a slice/physical print. See the
print-delivery evidence and Bambu prerequisite limit.
Fixed multires source recipe
Use import_indexed and explicit multires_apply mode:reconstruct|transfer. Reconstruct
requires immutable exact old==target; transfer permits only position edits with unchanged full
ordered connectivity, vertex count, identity part-local frame and mm units. Old authenticates
exactly in both modes. Read the prepare/finalize recipe
and transfer prefix.
Prepare Loop levels 1–8 through ordinary capture, then author complete normal+tangent rows from
actual old/fine checkpoints. Finalize with --template, explicit --old-base-id and ordered
--layer NAME=ROWS; preserve actual stdout descriptors and root/old/sorted chunk ID maps.
Finalize recaptures and compares full saved/current fine arrays, rule, level and layout.
triangle_loop_detail_v1, indexed_frame_transport_v1 and triangle_loop_layout_v1 are closed
profiles. Later absolute composites replace earlier layers; authenticate every layer even when
overridden. Keep source fit not_measured without desired geometry. Receipt fine_basis binds
the reconstructed final mesh. Cold verification retains exact binary sources and recompiles.
Respect 8 IDs/96MiB by ID including STEP/aliases, root 64KiB, old 64MiB, chunks 262144 rows and 24+56×rows bytes intersected with 16MiB raw JSON, and NODE/compact receipt 64KiB. Existing+whole batch ledger admission is transactional. Strict failures do not install; GAR HOLD is excluded from release. REST accepts indexed/detail/chunk sources. Inspect the evidence for measured source-edit and recovery results before asserting delivery.
Edited-target transfer
Finalize still emits mode:"reconstruct"; explicitly change only that mode after ordinary
import_indexed(old) → deform(lattice/bend) authoring. Reuse its actual root/old/sorted chunks
and exact descriptors. No transfer capture flag or new media/profile/schema exists. Keep old
immutable; refinalize actual edited normal+tangent rows against the same old/template and update
affected descriptors. Pure indexed targets need no geometry-projection loss flag; permission
applies only to actual target channels, and final derived normals recompute.
Use q_new = p_new + unitF_new * c with barycentric target anchors, orthonormal target triangle
frames and full fixed-mm normal/tangent coefficients. Proper 180-degree rotation is valid;
stretch never scales detail. Intended frame motion may be zero while anchors move and is only
a diagnostic, not a legacy residual or motion/error gate. Roundtrip stays at most 1e-8 mm;
source fit is separate and not_measured without an independent desired reference.
Old/target/final must pass closed, outward, one-component and complete intersection admission; exhaustion, degeneracy or self-intersection refuses before install. Supported requirement nonpass installs HOLD/excluded release. Do not nearest-search, reanchor, approximate/snap basis, apply a normal-dot veto or automatically recover. Endpoint admission proves no continuous path.
The prepared examples/detail_replay/run_b.py usage in the public recipe covers translation,
proper180, nonrigid 18-degree bend, nonuniform stretch, one effective row edit, typed negatives,
HOLD, cold export and whole-staging-moved retained-only fresh builds. Require independent all
ordered STL/Core corner formula checks, gross fine movement, nonzero detail and observable wrong
effect controls; archive/source recovery alone is insufficient. Grammar and focused tests
do not establish public delivery, artistic/physical or million-face acceptance.
- Quad loop history: select a closed ring with
loop_cut.ring {source,cell:[u,v],axis:"u"|"v"}on an attribute-free quad cage;edge_slideandloop_removename the original cut binding inloop. Fractions are absolute rail positions in[0.000001,0.999999]; removal restores the authenticated original cage digest. Seedocs/VXL.md#quad-loop-history.
Fields
Fields card
Use a field for a bounded implicit construction or smooth blend, then explicitly extract to a
mesh deliverable. Steps write op: "field", rep: "field", bind, expr; parts still write
rep: "mesh", and extraction writes op: "extract", rep: "mesh", source, bind, grid.
Fields cannot be delivered or used directly in mesh Booleans. Choose the closed AST vocabulary:
sphere, box, capsule, torus (about Y), affine transform, ordered hard/smooth CSG, or hard-clipped
TPMS. Keep operand order and commit literal precomputed rotation matrices. Smooth/CSG fields
are not automatically exact-distance fields.
extract requires explicit grid: {origin, voxel, dims}. Dims are sample counts, each ≥2;
cell counts are (dx-1)(dy-1)(dz-1). Keep finite positive voxel components and exterior margin.
Dense and sparse share a 16,777,216-sample ceiling; sparse also has 65,536 potential 64³ blocks,
iso zero, dense materialization and an eight-layer truncation refusal. Dense iso defaults to
zero; nonzero iso requires exact-distance authority. AST limits: 256 nodes, depth 32, 64 KiB;
JSON nesting limit 96. A clean check cannot guarantee coverage or a nonempty extracted surface.
Mesh-input offset (signed nonzero distance), hollow, mesh thicken, shell_mesh and
reinforce (positive wall) resample under bounded work. They require target and grid;
optional bind replaces target by default. Only these resamplers accept the auto-grid form
{voxel:[vx,vy,vz], margin_cells:N} with integer N≥2. shell_mesh also requires an opening
point/normal and can return open geometry. Hollow's inner/outer shells may make material
admission Unknown; reinforce receipts may record discarded features. Conversion residuals,
realized-wall values and sampled field analysis are Estimates, never a global wall certificate.
To bound an edit, add deviation_from on the final mesh with reference: "part@mesh_step_id"
and finite nonnegative max. The immediate reference output is retained as authenticated STL before
later edits. Only the symmetric ConservativeBound upper U <= max can PASS. A loose upper
U > max, an exhausted query budget or unsupported evidence is Indeterminate/HOLD, not a
measured excess. Open surfaces are eligible if finite/nondegenerate in the same frame.
Reference exports share 16 slots with delivered exports; evidence STL is capped at 96 MiB,
deduplicated. Never substitute a sampled residual for the bound or change a threshold after
measurement to obtain PASS.
Start from 25's stand and companions,
28's field source, or
37's smooth handle and retained coarse reference.
Use vextor vxl check, then build to a fresh directory; read the GAR's actual item classes and
run python3 examples/_shared/vxl_mesh_geometry.py --example 37 BUILD_DIR
(select 25, 28 or 37) (25 requires
all named companions listed in its README). See Fields
for complete payloads and budgets. Exact/Mesh acceptance profiles still govern delivery;
macOS development builds stay HOLD. Geometry acceptance does not qualify slicing, a physical
print, or whole-part minimum wall; same-cell sealed Linux replay is separate evidence.
Composition
Split, multi-body delivery and imprint card
Use split_and_imprint.vxl.json: a hollow box split at
z = 20 into a base with a registration lip and a lid with its matching 0.1 mm clearance groove,
a label imprinted on the lid top, and both bodies delivered as subjects (a deliver object),
with a partition, two section_contour, a planar_face, an imprint_region and a clearance
contact requirement. Compilation is checked.
Cut a body into every piece it makes. split takes a by cutter — an authored plane
({normal, through}, negative side n·x < n·p) or one planar face of another live binding
({of, face}, read not consumed) — and a pieces entry per side. A side writes either
bind (one piece) or count 2–4 with order and exactly count names; exactly two sides,
both present, at most eight pieces. Every piece must be delivered (§2.5) or read later, else
C514. A cutter that is not statically planar is C511; a missing side or bind with count
is C512; a missing or parallel order is C513; count > 1 on a convex primitive is G404.
Each piece Q gets Q.cut only for an authored plane or one construction face name whose
plane the compiler knows (outward +n on the negative piece, -n on the positive). A face query
or any_of defines no .cut names: a later reference is Q501; select the cut face by a
planar query on the piece. The cut role belongs to the current split. Other target face names
keep their carriers as Q.<face>; extents are
clipped when the cutter plane is statically known, and a face wholly on the other side is
G400. A non-analytic portion is G401. When Q.cut exists, put a hole's at on that face and
its axis along the inward normal (for the negative piece, -z when the normal is +z).
Deliver several bodies from one part. "deliver": {"<subject>": "<binding>", …} with 2–8
entries gives each binding its own subject, terminal, STEP/STL/3MF and report row. A one-entry
object or one on a keep-out is C517; naming the part id where a subject is needed (a subject,
relation operand or assembly part) is C518 and lists the subjects. One label per build: one
HOLD piece makes the whole generation HOLD, and every piece is still delivered.
Imprint a region, then use it. imprint takes a planar on face (principal normal, else
G405/G409), exactly one of a sketch (the extrude Loop vocabulary in the face frame;
one closed loop, no labels) or a by tool binding, and a region name. It adds edges and splits
the face without changing material. The target gains <target>.<region> (the pad face),
<target>.<region>.outside (the support) and <target>.<region>.boundary (the edges). The old
<target>.<face> is now two faces: a statement that needs one and uses it is G408, as is a
fillet/chamfer on the flat imprinted boundary. A sketch that leaves/touches the face is G406.
Seat a later hole on the region by putting its at on the region face.
Requirements. partition proves a split by its retained checkpoints (one of the target
before, one of each piece after); part names the part id (a delivered subject name there is
R740), split
the step, plane the requirement's own cutter, scope is mandatory (boundary_v1 or
full_v1). section_contour measures one subject's cross-section at its own plane (state at
least one of loops, area, perimeter, or profile; profile compares the authored region
with the measured section in both directions within tol). imprint_region measures the region an imprint left
(on, and optionally near, extent, area, boundary). All three locate by geometry; they
never read the statement. Refusals: R740-R748.
Two bundles ship. std.split_pair takes normal, through and the two piece names
negative/positive; it binds one piece per side and emits the partition requirement
(boundary_v1, 2 pieces, one per side). std.imprint_rect takes on_normal, on_at,
min_x, min_y, max_x, max_y and region; it emits the imprint and its imprint_region
requirement. negative, positive and region are name parameters: the identifiers the use
makes visible to the document, emitted unchanged exactly like the use's bind.
Traps: a split of a body carrying a modelled thread, coil or gear is C516; a section
statement is C519 (write section_contour).
Direct-authoring language features
Each card gives a small syntax pattern and the main static limits/refusals. The referenced checked examples show complete documents.
each, templated names and n-ary tools
Use each for repeated array entries, at_each for repeated statements, and interpolate integer
variables in names. Boolean tools[] lets one operation combine 2–64 tools after expansion.
{"tools":[{"each":[{"var":"i","range":[0,2]}],"emit":{"binding":"tool_${i}"}}]}
Each expansion product is 1–64 items (VXL-N112); Boolean tools needs 2–64 entries
(VXL-C404). Use the checked array example.
functions[]
Declare a typed pure expression once and call it wherever an expression is accepted:
{"functions":[{"id":"twice","params":[{"id":"x","type":"length"}],
"expr":"x * 2","returns":"length"}]}
Return/parameter types are length, angle, unitless, count. Bodies retain the 256-node,
depth-32 authored limits; expanded expression DAGs cap at 4,096 nodes. Cyclic functions or lets
refuse with VXL-N105. Pass field coordinates as parameters; functions do not capture x/y/z.
Checked function example.
when, variants[] and --variant
Use finite-domain bool, enum, or count parameters for structural conditions; declare family
choices as override sets:
{"params":[{"id":"lid","type":"bool","value":false,"domain":["false","true"]}],
"variants":[{"id":"open","overrides":{"lid":false}},{"id":"closed","overrides":{"lid":true}}]}
Gate a step with "when":"lid". Count domains contain at most 16 values; exhaustive checking
allows at most 64 conditional structures (VXL-C422). References to names gated by a condition
must be under an implying condition (VXL-N130). Select a family with
vextor vxl build DOC --variant closed (or check the same way). Wrong-build and stage controls
remain separate small documents. Checked when/variants example.
Fragment reads and typed list/profile parameters
Declare document values a fragment body may capture, then pass varying data as typed arguments:
{"id":"post","category":"step","reads":["height"],
"params":[{"id":"outline","type":"profile"},{"id":"sites","type":"points"}],
"steps":[{"id":"boss","op":"extrude","bind":"boss","plane":"xy","toward":"+z",
"length":"height","profile":{"profile":"$outline"}}]}
reads can name document params, lets, tables or functions. Fragment parameter types include
points, profile, and bindings alongside scalar, point, direction, part, name and font. An
undeclared capture or argument type mismatch refuses with VXL-F121. Checked
fragment example.
boundary selector
Select every edge bounding a named face, regardless of curve kind:
{"edges":{"select":{"boundary":"body.start"},"expect":8}}
Optional class narrows to convex or concave only for edges between two planar faces; edges
whose other adjacent face is curved do not match a class. expect is 1–64. A malformed
selector/count refuses statically (VXL-Q502); a build count mismatch is VXL-X101. Check can
infer the count only for an intact construction face with a known segment count, such as an
untouched extrude cap; otherwise author the count. Segment side names from native paths and
profiles[] provenance (including split suffixes and join_<k>/cap_<k>), plus SVG element
labels, are construction names for selectors when their predicted bounds are available.
surface_grid and boundary weld
To preserve authored shell normals through realize, declare a corner normal
channel with explicit unitless unit-vector value:[nx,ny,nz] expressions on each
surface_grid, and matching polyhedron.channels normal values (36 triangle-corner
vectors for box, 24 for octahedron). Realize preserves base vectors and transforms
prototype vectors; inspect bounded attribute_readback rows, never STL normals.
Use declarative functions of u and v to generate a mesh or a cage, then combine patches and weld matching boundaries:
{"id":"sheet","op":"surface_grid","rep":"mesh","bind":"sheet",
"u":{"range":[0,10],"intervals":10},"v":{"range":[0,5],"intervals":5},
"position":["u*1mm","v*1mm","0mm"],"topology":"quad","output":"cage"}
{"id":"joined","op":"combine_meshes","rep":"mesh","bind":"joined",
"sources":["sheet_a","sheet_b"],"weld":{"tolerance":"0.00001mm"},"closed":true}
At most 262,144 evaluated grid samples and 64 million formula visits; bad ranges/topology or
sample bounds refuse with VXL-C600/VXL-C601, bad creases with VXL-C605, and quad poles
with VXL-C606. Weld tolerance must be in (0, 0.01] mm; closed requires an explicit weld
(VXL-C604). A rejected weld is VXL-C608; unmatched boundaries with closed:true are
VXL-C609. each may expand surface_grid.creases and combine_meshes.sources; keep each
expanded array within its consumer limit. See the checked cage example.
Declare grid attributes in channels, using fixed names and domain:"corner":
{"name":"uv","domain":"corner","value":["u","v"],"seam":{"u":0}},
{"name":"mask","domain":"corner","value":"v"}, and
{"name":"material_group","domain":"corner","value":"if(v < 0.5, 2, 7)"}.
Here u/v ranges are [0,1]; normalize other ranges explicitly. UV/mask are f64 in
[0,1]; group is a u32 integer, evaluated at each cell centre. UV seam indices name
grid edges: each wrapped axis requires an index in [0,intervals), while an unwrapped
axis accepts boundary 0 or intervals. UV chart u/v start at the wrapped seam and
span the authored range. Masks use physical corner u/v. All welded patches must
carry identical corner channel layouts; their values remain separate at shared
vertices and migrate through cage refinement and displacement. See the
complete channel contract, including
VXL-C634–VXL-C639 refusals. Do not generate channel buffers or cage assets in a script.
Field union.nodes and intersect.nodes also accept each. Field expressions are limited to
256 authored nodes, depth 32 and 128 KiB serialized size. Field ellipsoid, quad_capsule and
offset nodes are supported; offsets require an amplitude bound, and band-limited zero
extraction has a 350 million formula-visit budget. These approximate or formula-offset fields do
not gain exact-distance authority.
Curved-side surface_probe
Use finite ray stations to measure an in-budget degree 1–3 B-spline extrusion side. The observation
table also identifies plane, cylinder, cone, elliptic-cylinder, ruled-B-spline and revolution
surfaces, but those curved surface types are not all measurable by surface_probe in this build.
This proves only the listed points, never the surface between them:
{"id":"r_probe","kind":"surface_probe","subject":"p","face":"roof.surface",
"probes":[{"from":[3,3,20],"along":"-z","expect":16}],"tol":0.02}
Use 1–16 probes; a zero direction, negative/nonfinite expectation or wrong count is VXL-R751.
The face must be an eligible labelled B-spline extrusion side (currently degree 1–3 and at most 8
poles); revolution, ellipse and over-budget curve sides are typed not-measured. Grazing, multiple
or unresolved roots, C0 creases, unsupported carriers and exhausted refinement also remain
not-measured. A probe proves the stated points, not the surface between them.
section_contour
A section requirement can check loops, area, perimeter, and/or compare the section with a named
profiles[] region. Profile matching requires the same loop count and nesting and a two-sided
boundary distance no greater than tol. Use {"profile":{"ref":"region_id","tol":0.001}};
profile alone is sufficient. The compiler resolves shape profiles directly and algebra profiles
through the authenticated profile prefix. Line, circle and ellipse distances are analytic;
Bézier and B-spline boundaries use Bernstein hull subdivision. A certified bound at or below
tol/4 is labelled Exact. Budget-limited estimates may pass geometrically but are labelled Estimate
and cannot satisfy exact_only_v1.
{"schema":"vextor.vxl.v1","id":"section_profile_rect","units":{"length":"mm","angle":"deg"},
"profiles":[{"id":"plate_rect","rect":{"min":[0,0],"max":[8,6]}}],
"parts":[{"id":"p","deliver":"body","steps":[
{"id":"sketch","op":"extrude","bind":"body","plane":"xy","toward":"+z","length":1,
"profile":{"rect":{"min":[0,0],"max":[8,6]}}}]}],
"requirements":[{"id":"n_solid","kind":"solid_count","subject":"p"},
{"id":"r_section","kind":"section_contour","subject":"p",
"plane":{"normal":"+z","through":[0,0,0.5]},
"profile":{"ref":"plate_rect","tol":0.001}}]}
{"id":"r_section","kind":"section_contour","subject":"p",
"plane":{"normal":"+z","through":[0,0,5]},"loops":[{"role":"outer"}]}
At least one of loops, area, perimeter, or profile is required (VXL-R744); section
planes cap at 16 per subject/64 per build (VXL-R748). Measured section inventory may be
unsupported or incomplete and then remains not-measured.
Composition cookbook
Reach for a fragment when a shape repeats with different arguments, when a standard feature should carry its own requirement, or when a hole and its tool must stay aligned. Do not reach for one to avoid writing two unrelated steps.
| Want | Write |
|---|---|
| A screw hole plus its verification | {"id":"h1","use":"std.mount_hole","target":"body","args":{"d":"hole_d","at":[...],"axis":"-z","thick":"plate"},"covers":["n_mount"]} |
| The matching tool keep-out | {"id":"t1","use":"std.tool_access","args":{"of":"bracket","d":9,"l":20,"at":[...],"axis":"-z"},"covers":["n_tool"]} (same at, same axis) |
| A flat datum face | {"id":"d1","use":"std.datum_plane","args":{"of":"bracket","normal":"-z","at":0},"covers":["n_datums"]} |
| A bored spur gear plus its tooth and bore requirements | {"id":"g1","use":"std.spur_gear_bored","bind":"body","args":{"module":1.5,"teeth":17,"face_width":8,"bore":6.3,"pressure_angle":20,"thinning":0.05},"covers":["n_gear"]} |
| A plane split into two named pieces with its partition | {"id":"s2","use":"std.split_pair","target":"body","args":{"normal":"+z","through":[0,0,20],"negative":"base","positive":"lid"},"covers":["n_partition"]} |
| A rectangular imprint with its region requirement | {"id":"s2","use":"std.imprint_rect","target":"body","args":{"on_normal":"+z","on_at":10,"min_x":15,"min_y":15,"max_x":45,"max_y":25,"region":"label"}} |
| Repeat a hole/fragment over points | put at_each on the use; the count must be fixed by literals, or by in_table |
| Define your own repeated shape | a defs[] entry with category step, part or requirement, exactly one primary self statement (no at_each on it), and a use where its category belongs |
| A step fragment with a precondition | add checks to the definition: {"id":"d_pos","expr":"d > 0","message":"..."}; a failed check is VXL-E230 with that message |
Repeat a part fragment |
the repeated part is a group p__0, p__1, … with no statement named p; give each its own named use if a document requirement must select one (VXL-N101 otherwise) |
Rules that bite (the reference states each one in full; §3.4 and §3.5 are authoritative):
- Declare
"std": "vxl-std-2"before anystd.*use orstd_*table (VXL-F103); the sealed signatures and the value conventions are inSTD.md. - A
use'sat_eachcount must be static: integerrange(3or"3"),in, orin_table(VXL-F110; a bad count isVXL-E221). Plain steps may use expression bounds; ausemay not. - Arguments become typed generated lets, so a formal keeps its declared type whatever the
spelling; an ill-typed argument is reported at
<use>/args/<name>(…/<i>for a point, and<use>@k/…when the argument reads anat_eachvariable). A failed fragmentcheckisVXL-E230at<use>!<definition>/checks/<i>. - An error caused by an argument is reported at the argument (
<use>/args/<name>,<use>/target,<use>/bind) even when the body field is what rejects it, and messages never print a generated__/std_name.VXL-F114rejects auseat_eachvariable that no argument reads (exempt when the use'sbind/aliaswrites${k});$bindmay be read in a body only after a body step defined it (VXL-F123). Full rules: VXL §3.4. - A document needs at least one requirement after expansion (
VXL-R600); a fragment use can emit it. Adefs[]definition adds none by itself. A table cell is a decimal string ("4.5"), never a JSON number. enumparams take adomain. A fragmentargs/defaultis an expression, so an enum value there is quoted ("'M4'"); a documentparams[].valueis the bare literal token ("M4") — the quoted form there isVXL-E223. No other type takesdomain. Full rule: VXL §3.4.- A non-repeated
useid is the primary statement's id; a repeated use is a groupp__0with no statementp(VXL-N101if a document requirement names it). Private__ids are not writable;--expandedoutput is not input. parts[]cannot carryat_each(VXL-S002); repeat a part through a repeated part-fragment use.- Every string position in a body has a role (id, binding, construction name, face, part, direction,
expression, prose); §3.4's role table says what may be written. Never write
x,yorz(reserved iteration variables), function reserved words, or an id starting withstd_; usepx,py,pz(M2). A reservedat_eachvariable isVXL-N103with a name hint.
Selector cookbook
Selectors are queries, not identities. They are re-evaluated immediately before the consuming step
and must match exactly expect (mandatory, 1–64). Names: box.+z, cyl.-z, extrude labelled
segments tool.<label>, <hole>.wall, <hole>.rim, a multi-target hole's <step>_<k>.wall /
.rim, styled-hole names <hole>.cbore / .shoulder / .cone / .floor, instance i_0.<face>.
Face queries are planar, cylindrical and conical ({"conical":{"axis","angle","axis_through?","near?"}},
included angle in degrees, unoriented axis).
| Intent | Write | Count |
|---|---|---|
| One straight edge at a known place | {"line":{"direction":"+x","through":[15,4,4],"near":{"z":[4,4.5]}}} |
expect: 1 |
| Several known edges | {"any_of":[{"edge":["base.+z","base.+y"]},{"edge":["wall.+z","wall.+y"]}]} |
expect = member total |
| All concave edges where a listing meets a base | {"class":"concave","adjacent_to":["base.+z","wall.+y"]} |
count by listing, e.g. 9 |
| Edges between two named faces | {"edge":["box.+y","box.+z"]} |
1 on an unchanged box; establish the count on the current shape |
| Entry edges of a cut tool on one face | label the tool profile, then {"edge":["block.-x","groove.floor"]} (one per edge) |
1 each |
| Circular rim of a hole | {"circle":{"axis":"+z","diameter":4.5,"center":[15,14,4]}} |
expect: 1 |
An any_of member may carry its own expect; the member counts must sum to the step's expect.
class needs exactly two planar neighbours and at least one listed face; between needs
both neighbours, one per listed face. Anti-patterns: counting Boolean-result edges by
imagination; class without adjacent_to; naming a Boolean result (name the creator or a labelled
tool face instead). A same-count wrong selection is not caught by a selector — only by a
requirement.
Op table
op |
Required fields | Optional |
|---|---|---|
box |
bind, size |
at or center (not both), rotate |
cylinder |
bind, diameter, length |
axis (default +z), at (base-disk centre) |
spur_gear |
bind, module, teeth, pressure_angle, face_width |
profile_shift (0), thinning (0), chord (m/100), axis (+z), at ([0,0,0]); external, 20/25°, faceted involute |
extrude |
bind, plane, toward, length, profile |
at (plane position, default 0), holes |
sweep |
bind, path:{from,to}, perpendicular x, line-only polygon profile |
— |
pipe |
bind, path:{from,to}, diameter |
— (filled rod) |
loft / ruled |
bind, exactly two sections:[{offset,profile},…] |
at, rotate |
guided_loft |
bind, 2–8 sections, at least two guides:[{id,vertex,points},…] |
at, rotate, frame, continuity |
union / cut / intersect |
target, tool |
tool_place, bind (default target), alias, tolerance (0.01) |
hole |
target (or targets 2–8), diameter, at, axis (the inward normal of the face at is on) |
depth (default "through"), one style: counterbore:{diameter,depth}, countersink:{diameter,angle} (angle default 90), thread:{pitch} (modelled internal thread) |
thread |
bind, form, diameter, pitch, length |
outer_diameter (internal), axis (+z), at (origin), hand (right), starts (1), ends (external full_profile, internal trimmed) |
helix |
bind, radius, section:{circle:{diameter}}, pitch, turns |
family (helix), axis (+z), at (origin), hand (right), starts (1), ends (plain only), end_coils (0) |
pattern |
target, exactly one of linear/circular/path/placements |
instances |
mirror |
target, plane |
maps |
fillet |
target, radius, edges:{select,expect} |
— |
chamfer |
target, distance, edges:{select,expect} |
— |
| place | target, place:{translate?,rotate?} | — (rigid re-pose; keeps the binding name) |
| shell | target, thickness (0–20 mm), open:{select,expect} (1–8 faces) | — (hollows inward; open faces lose their names) |
| thicken | bind, surface, exactly one of along / normal, distance (0.1, 100] mm); a normal wall also needs a required thickened_wall (mode normal, same distance) | — (one closed solid) |
| sew_solid | bind, patches (2–16), seams (every non-collapsed boundary once) | — (one closed solid) |
| trim_to_surface | target, bind, surface (height field / separable monotone), keep (below/above) | — (one closed solid) |
| split | target, by (one of plane:{normal,through} or of+face), pieces (one entry per side, both sides) | one side's bind, or count 2–4 + order + names |
| imprint | target, on:{select,expect} (one planar face), region | exactly one of sketch (a closed loop) or by (a tool binding) |
| curve_sweep | rep: "mesh", fresh bind, path, loop section.region with explicit section.chord_error, frame | section_scale, sampling, twist, caps; Curves and instances |
| scatter | rep: "mesh", fresh bind, mesh prototype, on, distribution, literal seed | axes, scale, roll, scale_by; surface requires spacing, may use reference; returns Instances |
| realize | rep: "mesh", Instances source, fresh bind | mesh base; concatenates geometry without welding |
For a chamfer on a straight rim edge, selecting it with boundary alone can still leave
VXL-W920: write the required chamfer_size measurement for the same edge pair (§7.8). Use an
edge selector for that measured pair, for example edges:{select:{edge:["plate.start","plate.+x"]},expect:1}
with between:["plate.start","plate.+x"] in the requirement. Rounded-corner arcs do not have a
supported chamfer measurement (VXL-V811).
Common step fields: id, op, optional notes, at_each. bind defaults to target for
Booleans and replaces it. In-place ops rebind target. At most 16 live bindings. After expansion
and lowering a document runs at most 256 session operations across all parts; a multi-target
hole counts once per target, an at_each item counts separately, and a required placement
materializes one operation (VXL-C421; §12).
A steps[] entry may instead be a use of a step fragment: {id, use, target?, bind?, args?, covers?, at_each?}. targetandbindare required exactly when the fragment needs them.usereplaces theop`.
Part fields: id, deliver, steps; role (deliverable/keep_out), rep ("exact"),
acceptance ("exact_only_v1", deliverables only).
Examples
The corpus index — every request, what each document teaches, and the part-2 documents — is in
examples/README.md. Each *.vxl.json there is a complete document checked
by a test; the inline templates above are abbreviated. Never copy a private task.
assemblies[].joints and joint_travel support independent grounded
revolute/prismatic travel through the normal VXL build/session path. Conservative bounds
require all-planar exact faces plus native weld/delivered-f32 allowances; curved faces are
not_measured (required → HOLD).
Examples
- cube
- at_each_grid
- at_each_table
- fragment_step
- fragment_part
- fragment_requirement
- std_plate
- array_each
- function_formula
- fragment_reads
- orthogonal_holes_asymmetric
- hole_styles
- slot_and_chamfer
- outer_diameter
- place_named_body
The delivered StandardPart mesh admits at most 262,144 vertices and 524,288 triangles
(VXL-X107), with an independent 64 MiB mesh-object ceiling and the existing 256-face
construction limit. The build keeps its fixed 0.05 mm linear deflection; reducing
curved detail or splitting a part remains appropriate when the new bound is exceeded.
These are export limits, separate from the clearance limits above.
Protected surface conformance
Use conform_surface when a bounded mesh target must fit an earlier immutable
reference mesh in the same part. Author target, distinct reference, optional
bind, explicit projection, all five thresholds, nonnegative length offset,
boolean no_intersections and frame: "equal_part_local". Both actual frames must
agree; arrange placement before fitting. projection: {"kind":"directional", "direction":"+z"} searches along -Z. nearest_surface is the other mode.
Do not reverse this convention to make a missing hit appear successful.
Use region for weights and constant-falloff protect selectors for hard pins.
Selectors count actual target vertices, including soft-boundary weight zero;
write honest expect ranges at or below 20,000. Protection wins when selectors
overlap. For each positive-weight unprotected vertex, a unique compatible hit is
mandatory: no candidate, ambiguity, reverse-side normal and thin-sheet outcomes
refuse. The blend is P + w * (Q + offset * N - P), not an absolute displacement.
The reference stays unchanged. Select the intended oriented reference side; a
positive offset follows its geometric normal and cannot be used as a negative inset.
Keep each operand at or below 50,000 vertices and triangles, and queries and hard
pins at or below 20,000 each. The changed-face one-ring quality gate rejects
collapsed or inverted faces. Set no_intersections: true when that bounded
conclusive scan is required; never interpret a budget refusal as a pass.
Topology and admitted channels are retained, with existing normals recomputed.
Vertex conformance does not certify continuous triangle-to-reference clearance,
wall thickness, fit or print performance. Add independent delivered requirements.
Start from the closed plate in
the conformance fixtures, supplying its
plate.cage.json asset via --asset plate=PATH. Its top vertices genuinely move,
its protected bottom has positive region weight 1/6 (region plane Z=-2, width 6),
and offset, soft-weight and reference
counterfactuals have independent numeric output checks. A nearest-surface pair
differs only by protection and explicitly sets reverse_normal_cos: -1 to admit
both sides: the unprotected bottom must move to Z=-19/24, while the protected
bottom stays at Z=-1. This is an intentional side-policy control, not the
default reverse-normal threshold. Do not claim that an internal development-cell HOLD
proves public RELEASE. This recipe does not provide an indexed-selector API or
establish exact-basis selector integration or retained public session edits.