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, helical 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, rack, 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
file of another CAD system with certified "tolerant modelling" gaps up to 0.30 mm takes
"heal":{"mode":"tolerant_v1","max_deviation":<mm>} (optional max_deviation, default 0.05 mm; 0 < d <= 0.30, no allow, no repair_budget): every
edge/face context and the vertex gap must certify at or below d, geometry is never changed, and every
comparison carries U_import (the largest certified bound). Round 1: deliver the import itself (its part has
only the import step); declare the smallest d the file honestly needs; omit it when 0.05 mm is enough.
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). - Read
result.ok,result.errors,result.warnings, andresult.notesaftercheck. Comparesummary.parts[].predicted_boundswith the request when present. Anullprediction means unknown (for example after meshrepair), never a pass; a prediction is not a measurement.
plane |
u ↦ | v ↦ | toward must be |
|---|---|---|---|
xy |
+x | +y | +z / -z |
yz |
+y | +z | +x / -x |
xz |
+x | +z | +y / -y |
Solids and gears
Sheet metal (flat-first sheet)
Use sheet for constant-gauge bent parts authored as a flat outline with straight bend lines.
Use extrude for a constant-section prism, or shell to hollow an existing solid; neither
expresses this flat-first bend layout. See the sheet requirements
for independent bend and gauge checks.
- Required fields:
id,op,bind,plane(xy,yz,xz), perpendiculartoward, positivethickness, positive default innerradius, requiredk_factorin [0, 1], andprofile.atis the missing-axis plane coordinate (default 0). Profile coordinates are the plane's world axes as in the frame table.holesis an optional list of profile loops. - The bottom skin starts on the plane; the top skin is
thicknessalongtoward. These are material identities through bends.direction: "up"turns the child toward sheet +z (top is inner);"down"turns it toward sheet -z (bottom is inner). Angles are degrees from flat. - Each optional
bendsentry needs a uniqueidmatching[a-z][a-z0-9_]*(notbase), alinewith distinctfromandtopoints,anglein (0, 180], anddirection. Optionalradiusandk_factoroverride the sheet defaults;bend_allowanceandbend_deductionare forbidden.fixed: [u,v]is required exactly when bends are nonempty and selects the interior of the unmovingbaseregion; omit it for a flat sheet. In the fold tree, each bend's parent side connects toward this fixed region and its child side lies away from it. - Use closed line/arc loops:
path,polygon,rect,rounded_rect,circle,slot,regular_polygon, or a named line/arc profile. Full circles are supported. Splines, ellipses, spirals, text and open paths are refused. Each bend strip must cross straight outline edges at right angles, stay clear of holes and other boundaries, and not touch or overlap another strip. The bend line'sfromandtomust lie on those crossing edges, with the open segment between them inside the material. The regions and bends must form a tree, withfixedstrictly inside a region. - Each bend line is the centre of its neutral strip. Its flat width is the angle in radians
times
(radius + k_factor * thickness); leave positive margin at both outline crossings and aroundfixed. - Selectable names are
<bind>.base.top,<bind>.base.bottom, and, for each bend,<bind>.<bend>.top,.bottom,.inner,.outer; side walls have no names. The bend.top/.bottomname the child panel and.inner/.outername its bend skins.
Use louver for kind: "cut_tab" (generated U kerf and
root reliefs inside one panel, also beside existing bends) or kind: "hood" (formed-only one-sided capsule with required
positive kerf). The directed line is the root/lance; the cut-tab tongue is on its right, an up
hood on its left. Hood also requires region, height, fillet_radius, crown_radius;
cut-tab requires tongue_length, relief, angle, with optional bend radius/K. Zero kerf
refuses. Use gusset for disjoint symmetric ribs on one
exact (0,180]-degree bend, either direction, at stations that keep every retained band positive
(between neighbouring ribs and at both ends), with equal cap extensions per rib; the gussets of
that one bend are the only forms on their sheet (no gussets on two bends) and share one side.
side: "outside" is a rounded rib over the bend; side: "inside" is the stamped corner gusset
(straight bridge inside the corner, groove outside). For an inside gusset from a drawing, write
crown_radius = punch radius + thickness (R1 punch on 2 mm sheet: 3), fillet_radius = die
radius, height > crown_radius + fillet_radius (rib height at the caps) and extensions that
put each cap centre on its flange; the bridge then follows from the formulas in the reference
(VXL-C895 names an inside rib that collapses). Other bends may sit
elsewhere if every cap stays clear of every other panel boundary. Keep complete caps on both
flanges; give each bend row an explicit span inside one retained band, outside every rib.
Both forms retain sheet capability and require whole-subject cold gauge checks. Hood crown
names exist on the single cylindrical face; split gusset crowns/bends are unnamed. A cut tab
develops fully; hood and gusset develop only with flat_pattern scope developable_regions and
one independent hood/gusset mask per form (locators).
Use dimple or bead with required
kind: "capsule" to append a formed-only stamp to a sheet target in place. Name its containing
region (base or the leading bend id) and use flat sheet coordinates. Dimple diameter is the
tangent footprint diameter; wall_angle is wall to panel, strictly 0–90 degrees. Capsule line
joins the end-circle centres. Dimensions are on bottom skin for up, top skin for down; height
is that skin's displacement. Keep the whole footprint clear of boundaries, holes, strips and other
forms, and leave positive inward-offset margins. Form ids share the bend namespace. Numeric fields
accept expressions. Names are <bind>.<form>.floor.top|bottom (dimple disks) and
<bind>.<form>.crown.top|bottom (capsule straight cylinders). Forms preserve sheet capability and
rigid placement, are not developable, and refuse full flat-pattern acceptance. A through bead
is four ordinary bends and develops fully (bead). Form refusals use
VXL-C890–VXL-C899.
A bounded line/arc strip crossing may include perpendicular line members (at most 16 segments per side); a single perpendicular crossing stays exact. Lines parallel to the bend inside a crossing chain refuse. Each finite bend end needs a free boundary across the full strip width: if a notch edge frees only part of it, move the bend end past the edge or add a relief hole/notch.
Static refusals include missing or forbidden fields and invalid values (VXL-C850–VXL-C860),
unsupported or open profiles (VXL-C861/VXL-C862), invalid placement or line
(VXL-C863–VXL-C865), invalid strip geometry (VXL-C866), invalid fixed region (VXL-C867),
and the shell face/edge budget (VXL-C868, currently 256/768). A clean check is not a native
build or measurement; formed separation and shell admission still occur at build time.
This complete two-bend bracket fixes the centre panel. Its bend locators and gauge are stated
independently in final coordinates; k_factor is a construction input, not a measured property.
The same document is available as sheet_u_bracket.vxl.json.
{"schema":"vextcad.vxl.v1","id":"sheet_u_bracket","units":{"length":"mm","angle":"deg"},
"parts":[{"id":"bracket","deliver":"body","steps":[
{"id":"folded_plate","op":"sheet","bind":"body","plane":"xy","toward":"+z",
"thickness":1,"radius":2,"k_factor":0.44,
"profile":{"rect":{"min":[0,0],"max":[60,80]}},
"bends":[{"id":"left","line":{"from":[0,20],"to":[60,20]},"angle":90,"direction":"up"},
{"id":"right","line":{"from":[0,60],"to":[60,60]},"angle":90,"direction":"up"}],
"fixed":[30,40]}]}],
"requirements":[
{"id":"one_solid","kind":"solid_count","subject":"bracket"},
{"id":"gauge","kind":"sheet_thickness","subject":"bracket","thickness":1},
{"id":"left_bend","kind":"bend","subject":"bracket","axis":{"at":[60,21.91637152,3],"dir":"-x"},"window":{"axial":[1,59],"radial":[1.9,3.1]},"start":[0,0,-1],"radius":2,"thickness":1,"angle":90},
{"id":"right_bend","kind":"bend","subject":"bracket","axis":{"at":[0,58.08362848,3],"dir":"+x"},"window":{"axial":[1,59],"radial":[1.9,3.1]},"start":[0,0,-1],"radius":2,"thickness":1,"angle":90}]}
Use hem for a positive-gap 180° return: supply tangent length, gap, direction
and position (bend_outside or material_inside). Use jog to insert an offset
without shortening the far panel: author a boundary-to-boundary perpendicular crossing
line, angle in (0,90], and same-skin offset. The middle straight must remain positive;
see hem and jog for station formulas.
Use corner for matching 90° flanges on 2 or more consecutive complete outer edges of one
region, listed in loop direction at convex perpendicular vertices. Walls/bends are numbered
<id>_1 through <id>_N in listed order, also for two edges. List every edge of a closed
outline in one statement to notch its closing vertex too; open-chain free ends are not trimmed.
Author exactly one relief dimension, square size or round diameter, and a positive minimum distance between their bounded formed
end faces; the operation trims both ends and refuses incompatible dimensions. See
corner for the relief core, trim arms and feasibility limits.
The round centre is the bend-strip centre-line intersection; diameter > w×√2 + 0.0000008 mm,
w=angle_radians×(R+K×t). For 90°, t=1.4, R=0.74, K=0.4, use diameter > 2.887874710 mm
(e.g. 3.0). For sheet.bends, a smaller circle may suffice with an outline notch: their union
must remove the whole strip overlap with positive margin and free both ends across the full
strip width. Leave a formed gap along the full free wall edges as well; local strip clearance
does not prevent distal wall contact. Material left in the overlap or a proven formed wall
contact refuses; ordinary strip holes remain refused.
Use flange on a sheet binding with an explicit fixed point for formed dimensions. Always
state measure (tangent, inner_sharp, outer_sharp) and position (bend_outside,
material_outside, material_inside); these are VextCAD's own conventions. Select
body.base.+v, then body.lip.tip for a chain. Partial spans require explicit rectangular
relief width/depth, with depth measured from the selected edge and greater than the station
shift. Their finite bend strips retain whole-curve separation guards; ordinary holes crossing
a strip and internal-hole flange edges refuse. Local profiles/holes use the child tangent
frame and are never scaled. See the dimension table and examples before converting a drawing.
Complete sheet-metal chains: Example 39
(flanges, reliefs, holes, full flat), Example 40
(dimples, capsule and through beads, partial flat with masks) and
Example 41 (corner, hem, jog, hoods, partial flat; bounded
side tab, lid_oblique_tab hoods beside it, and the closed four-wall box). Separate corners may
use disjoint, still-complete edges; edges changed by an earlier flange/corner refuse VXL-C906 (list
them in one corner). Hems, jogs, corners (chains too), through beads, dimples, capsule beads and hoods
may sit beside a certified-bounded side: the feature's own bends stay exact (VXL-C866 if it would add
a bounded crossing). A gusset may sit beside other bends but its own bend stays exact (VXL-C914); a
cut tab may hang off one panel of a bent sheet when its U kerf and tongue stay clear of every strip.
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], width_at_y_max; 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,nonnegative 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). A loop clear of the axis, including arc interiors, stays at least 0.01 mm from it.
An outer loop may instead close along the axis or meet it at a pole/apex; it must never
cross the axis. 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.
A generic SurfaceOfRevolution carrier alone is not an admitted analytic law.
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.
Fragment dir parameters, including stock std fragments, accept principal tokens or finite
nonzero 3-vectors. The consuming field retains its own direction restrictions.
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.
Straight racks
One straight rack is one rack step (VXL §7.15.1): a straight-flanked
rack tooth system extruded along axis, with module, teeth (1–62), pressure_angle (20 or
25°), face_width, height (pitch line to back face) and optional profile_shift, thinning.
The flanks are planes, so the section is exact and there is no chord. Only <bind>.back and
the two end faces <bind>.end_a / <bind>.end_b are selectable; tip, root and flank facets are
not (a name on a rack facet is VXL-G390). height_dir is the tooth height direction and must be
perpendicular to axis; the pitch line runs along height_dir x axis.
The tooth bound is 62 because the section is 4·teeth + 4 straight segments of one extruded
profile loop (at most 254 segments). Racks with more teeth are not expressible in this version,
and neither are helical racks, root fillets or rack-pinion gear_mesh clauses. rack_teeth
measures the tooth count, pitch, tooth thickness at the pitch line, addendum, dedendum, flank
angle and face width from the observed planar faces of the reopened STEP; keep the locator box
tight so no other face of the part shares those normals inside it.
Use gear_mesh for a pair: name two subject operands, or occurrence IDs with 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 center_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
vextcad vxl asset describe stock.step --id stock, copy it into assets[], and build with
vextcad vxl build part.vxl.json --asset stock=stock.step --output-dir delivered.
Supply each declared id exactly once. The descriptor digest uses VextCAD'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.
An imported solid admits up to 8,192 faces and 16,384 unique edges. direct_edit, split,
imprint, mirror and trim_to_surface of it export up to 8,192 faces (VXL-X110 beyond);
split also keeps its 1,024-face source and piece cap (VXL-X114).
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 and
reports raw_source_not_admitted, with its exact raw face/wire statuses retained in the GAR.
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. sweep
retains curved profile edges on its straight or line/arc spine; a two-section transition may
use the certified circular-rim representation taught below. Other edges retain exact carrier
checks. Curved guided_loft stations 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. A proven one-to-one offset keeps source
slot labels, order and segment zero. An inserted convex join follows source segment i as
join_<i>; a loft needs matching join slots at its other station. Split, removed, merged or
repeated-source mappings keep the general canonical seam and qualified/indexed names; they do not
establish source-slot correspondence for a loft (VXL-G368). 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
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 |
One exact loop stays constant along an open G1 spine of at most 16 line/circular-arc segments; two corresponding endpoint loops may transition on one primitive, subject to certified-rim admission. Three or more changing loops refuse G369. Write section_x perpendicular to the initial tangent; the compiler checks it rather than projecting it. |
Existing swept_section proves only its admitted straight-span shape; use solid/mesh requirements for a curved or transitioning sweep unless another requirement directly covers the claim. |
rod |
A filled circular rod on the same straight or line/arc spine. Write diameter; it has no bore or observable in-plane orientation. | Existing swept_section proves only a straight rod; volume_range and envelope independently cover supported curved-rod volume and bounds. |
loft |
Exactly two sections with equal segment counts and labels in authored order; corresponding exact kinds may differ, including line and arc. | loft_sections for line-only sections, with independent frame and two sections, using the fixed linear span |
ruled |
The same per-segment correspondence, using the distinct ruled construction operation. | The same line-only loft_sections expectation; matching endpoint profiles alone cannot prove the span |
guided_loft |
Two to eight sections with 3–24 corresponding vertices and at least two distinct vertex rails. Convex: fixed frame or bounded arithmetic-vertex-mean twist. Concave: fixed G0 with forward corresponding edges, consistent lower/upper adjacent turns and separated nonadjacent swept XY boxes (complete limits). | guide_rail for each required real boundary chain; section_frame for station frames and the admitted full-body law |
Path constructors retain CCW segment zero, order and labels; they never resample, reverse or
choose a cyclic correspondence. A sweep chain is open and G1; its three-point arcs are directed
through the authored middle point. A sweep station's at is cumulative spine length, starting at
0 and ending at total length, with at least 0.01 mm between stations. A changing-section sweep
needs a station at every primitive join; a constant profile or rod receives exact RMF join anchors
internally. Each authored station uses the RMF at its at: X stays fixed on a line and rotates
about an arc binormal, while Y remains tangent cross X. Sweep profiles do not select another frame
law.
The current static transition profile permits two changing endpoint profiles on one spine
segment. Three or more changing stations are refused with VXL-G369: adding profiles to
MakePipeShell selects an interpolating section law that can overshoot the authored station hull.
Supporting this requires a certified bound on that law or a piecewise construction with
different side topology; adding profiles alone does not establish conservative bounds. Repeated constant-profile stations may still use 2–8 positions. Exact export
retains exact cap planes. For two changing MakePipeShell sections only, polynomial circular
rims require rigorous Bernstein bounds on radial plus plane error, endpoints and directed arc
coverage, all within the existing 1e-5 mm cap. Per-arc rim_certificates appear in cap evidence
and are recertified after strict STEP reopen matching. Failed or unproved bounds refuse
VXL-G434 with the measured bound/cap; lines and ordinary loft/ruled retain exact carrier checks.
The bounded fallback supports full nonrational Bezier rims through degree 8 and authored arcs
through 90 degrees; split larger arcs into corresponding labelled edges.
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 a planar quad for a coplanar span and the ABC/ACD planar facet diagonal for a noncoplanar span. G1/G2 admit a fixed,
constant-section straight translated prism, or one rigid vertex_mean_twist section under a
uniform screw about one fixed Z axis inferred in XY. An off-axis section mean may follow a helix;
zero twist requires a fixed XY position. A nonlinear angle schedule, drifting inferred axis,
scale change or shape change is VXL-G367.
Measure smooth uniform twist with section_frame, including the law and continuity token;
guide_rail remains limited to straight boundary chains. Native spline certification and
conditioning must pass the unchanged 1e-5 mm cap; an exhausted proof refuses without a
faceted fallback.
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, straight-prism, or admitted uniform-twist 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.
Line and circular-arc spines and authored line/circle section edges are exact. Constant circular rod spans therefore keep cylindrical or toroidal carriers. A changing section's side is a kernel-built transition and may be an approximated B-spline; do not describe that side as an analytic surface. Native validity, reopen admission and existing requirement caps are unchanged, and curved-spine predicted bounds are conservative.
Sweep start/end are exact cap-plane names. Each profile edge label denotes its complete side
carrier group across primitive and station spans; curved rod similarly exposes one complete
side group. These groups can contain several native faces, so their names do not establish a
single selectable or analytic face (VXL-Q531).
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, distance} rays, tol ≥ 0 (default 0.02) |
a zero direction or non-finite distance 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 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":"vextcad.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","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","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","source":"placements","bind":"copies"}
]}],
"requirements":[{"id":"count","kind":"component_count","subject":"part","count":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
Rounds and fillets (choose the robust route)
Choose the construction before trying a 3D blend. Keep the requested radius and tangency; a different construction does not authorize changing either dimension.
- Profile arc first. For an edge parallel to an extrusion, draw the round in the
perpendicular profile, then extrude. Use
rounded_rect, apathwith circulararcsegments, namedoffset/strokewithjoin:"round", or SVGdwith circularAarcs. Use native profiles for dimensioned parts; SVG suits a fixed outline. This handles plan corners, lug/tab roots and tangent pocket transitions when they have constant section. - Revolve meridian next. For an axisymmetric boss root, rim or shoulder, draw its tangent
arc in one continuous meridian and
revolve; avoid assembling separate cones and blends. Statement coordinates are the sketch's world axes; arevolved_profilerequirement instead uses [axial, nonnegative radial]. Arc-revolve bodies cannot take direct fillet/chamfer/shell (VXL-C454), so include those rounds in the meridian. - 3D
filletlast. Complete the sharp stock, unions, cuts and holes first, then select a small, simple edge set on that finished revision.edges:{select,expect}is mandatory; inspect the actual matched edges after Booleans merge or split them. Correct the predicate and justified count together; changingexpectalone does not locate the intended round. Prefer long simple edges over an entire concave pocket/web boundary. Split independent sets when needed. This is a starting order, not a guarantee for intersecting contours; respect terminal operations such as threads.variable_filletis a bounded straight-run feature, not a general fallback for a failed constant fillet. - Omit and disclose if no supported route works. Keep the last valid body, name the
missing round in its need's
unmodeledfield, and report the limitation. A required failed or unavailable measurement remains HOLD; never silently shrink or drop a requested round.
Profile route: a 30 × 20 × 4 plate with R3 vertical corners (statement excerpt):
{"id":"stock","op":"extrude","bind":"body","plane":"xy","toward":"+z","length":4,
"profile":{"rounded_rect":{"min":[0,0],"max":[30,20],"radius":3}}}
Meridian route: base R15, top z4; boss R6, top z14; tangent root R2:
{"id":"stock","op":"revolve","bind":"body","plane":"xz","axis":{"through":[0,0],"direction":[0,1]},
"profile":{"path":{"from":[0,0],"segments":[
{"line":[15,0]},{"line":[15,4]},{"line":[8,4]},
{"arc":{"to":[6,6],"center":[8,6],"dir":"cw"}},
{"line":[6,14]},{"line":[0,14]},{"line":[0,0]}]}}}
Complete measured examples: profile plate and
meridian boss. fillet_radius checks supported final
round geometry even when no fillet step made it; use independent support locators.
| Code or symptom | Cause to inspect | What to do |
|---|---|---|
VXL-X101 selector_cardinality |
Current topology or classification differs from the predicate/count | Read matched/near-miss rows; reselect actual edges after the Boolean. |
VXL-X103 finishing_infeasible, NotDone or walking failure |
Builder failure, invalid live/cold solid, or uncertifiable blend | Read contours, support faces, endpoint landings and exact statuses; simplify the set or use a profile/meridian. |
| Radius reaches a flange width or short landing | Tangency limit or neighbouring contour collision | Keep positive geometric margin; reduce only with authorization. A small reduction is no guarantee. |
VXL-K750 |
Boolean volume monotonicity contradiction, possibly involving a blended operand | Inspect the failing Boolean receipt; prefer sharp tools/stock and finish the joined body. |
VXL-K751 or structural nonpass |
Invalid/open/multiple solids, non-manifold contact, or over-cap cold context | Read solid counts, status/context and bounds; revise the tool or blend, then check cold delivery. |
VXL-G315 on a profile round join |
Degenerate/short segment; minimum edge is 0.01 mm | Revise the join geometry. Round joins become miters only within the certified 1e-7 mm deviation bound. |
VXL-X900, or next place fails VXL-X102 |
Generic failure; nested BRepCheck may implicate the preceding blend | If invalid geometry is identified, revise that blend; reserve the infrastructure retry for an actual infrastructure failure. |
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, 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
thread or helix 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 |
A bounded round-wire helix (a solid wire, never a bare curve). | helix with radius, pitch, turns, circular section and ends:"plain" |
| plain coil or spring | The same helix geometry; intended use is 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,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. The one exception is aunionorcuton an external thread whose tool stays out of the thread band, either axially beyond it (a head on the end plane of anends:trimmedthread; afull_profilerunout extends past the end plane) or nearer the axis than the root (a coaxial bore). A thread/helix requirement must author 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:std_thread_pilot_diameter(major, 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. A step's representation is inferred from its op, its inputs and import media type; write rep only on the part.
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 32 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, optional bind (default target), 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, asset, and an optional bind (default target); update the delivered binding if it changes. 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, static rig and named joints, plus optional bind (default target), 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. 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.vextcad.cage.v1+json, at most 32 MiB.
Their closed schema is vextcad.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
For declarative Bambu delivery, choose machine, matching nozzle, presets and platform;
the host fixes plate center [100,100], drops to Z=0, and pins the slicer identity.
Do not author center_xy, drop_z, version or executable_env in the delivery.
Do not author used on configured slots: it is derived from part assignments; unused slots keep their presets.
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. 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": "vextcad.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","source":"exact","bind":"body","deflection":0.05},
{"id":"hollow","op":"hollow","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","count":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 vextcad 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 vextcad 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
A field box uses center and full size: [x,y,z] dimensions. Each size
component is finite and nonnegative.
Use a field for a bounded implicit construction or smooth blend, then explicitly extract to a
mesh deliverable. Steps write op: "field", bind, expr; parts write
rep: "mesh", and extraction writes op: "extract", 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 vextcad 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. Analytic line, circle and ellipse edges may touch
or share the face boundary when the whole edge remains on the face. A near miss needs at least
0.05 mm clearance; polynomial boundary contact is unsupported. A sketch crossing outside the
face or into a hole must be trimmed: the dry check reports G406 when its bounds prove a
crossing or too-close approach; otherwise native admission can refuse with X115. Contact alone
does not prove the region: retain the imprint_region checks below.
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).
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. - A fragment
dirargument accepts principal tokens ("-z") or a finite nonzero 3-vector of unitless expressions ([3,4,0]), with the same checks and normalization as a direction field. Write"$axis"or"$-axis"in the body; derivedaxis_x,axis_y,axis_zare normalized unitless components. Invalid vectors are reported at the argument even when unused. A field requiring an axis letter still requires a principal token. - 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 numeric table cell is a JSON number (4.5). enumfragment params take adomain. Fragmentargsuse expressions, so an enum argument is quoted ("'M4'"); a fragmentdefaultand a documentparams[].valueuse the plain literal ("M4"). No other fragment param 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–256 for fillet/chamfer edges; shell face selections
remain 1–8). 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_at?","near?"}},
included angle in degrees, unoriented axis). A conical query uses tol.half_angle in degrees for the semi-angle; tol.direction is the unitless axis-component tolerance. When a conical query specifies tol.direction, supply tol.half_angle there too. An enclosing edge selector with tol.direction must supply tol.half_angle itself or on each contained cone query.
Every edge selector considers only manifold boundary edges between two distinct faces, with
one FORWARD/REVERSED use per face. Seams, free boundaries, INTERNAL/EXTERNAL uses and
nonmanifold edges do not contribute to expect.
| 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 distinct neighbours with the requested measured dihedral class and
at least one listed face; this includes eligible circular plane-cylinder/cone rims as well
as plane-plane edges and eligible sampled B-spline intersections. between needs both
neighbours, one per listed face. To keep class
filtering on straight edges, use between two planar faces with the same class.
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 |
hem |
target, edge, direction, gap, length, position |
bind, k_factor, span + relief; see hem |
jog |
target, region, line, offset, angle, direction |
bind, radius, k_factor; see jog |
corner |
target, edges, relief, gap, flange |
bind; see corner |
flange |
target, edge, angle, direction, measure, position |
length (required without profile), bind, radius, k_factor, span + relief, profile, holes; see flange |
dimple |
target, region, center, diameter, height, wall_angle, shoulder_radius, bottom_radius, direction |
Formed-only; see dimple |
bead |
target, region, kind, line, height, direction |
capsule: fillet_radius, crown_radius, formed-only. through: width, flank_angle, optional radius/k_factor, four bends with full development; see bead |
louver |
target, kind, line, kerf, direction; kind-specific fields |
Generated cut tab or formed-only hood; see louver |
gusset |
target, bend, axial_center, height, fillet_radius, crown_radius, parent_extension, child_extension, side: "outside" or "inside" |
Bounded (0°,180°] outside rib or inside stamped corner gusset; see gusset |
unfold |
target, bind (new and different) |
Exact flat extrusion or partial nominal layout for forms; preserves source sheet; see VXL |
sheet |
bind, plane, toward, thickness, radius, k_factor, profile |
at (default 0), holes, bends, fixed (required iff bends nonempty); see sheet metal |
sweep |
bind, straight path:{from,to} or open G1 path:{start,segments} (1–16 line/three-point-arc segments), perpendicular section_x, exactly one of profile or 2–8 length-positioned sections |
— |
rod |
bind, straight path:{from,to} or open G1 path:{start,segments} (1–16 line/three-point-arc segments), 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, exactly one of tool or tools |
tool_place, bind (default target), alias, tolerance (0.01) |
hole |
target (or targets 2–8), diameter, at, axis (the inward normal of the entry face; for a coaxial enlargement, at is the centre of its annulus on that plane) |
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 |
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; same-domain faces and edges crossing the plane merge as for union (strictly valid unsimplified fallback) |
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) |
— |
import |
bind, asset, source_units |
heal, at, rotate |
direct_edit |
target, edit:{kind,...}: move/offset {face:{select},distance}, delete {face:{select}}, or cut {plane:{normal,through},keep} |
face.expect |
cone |
bind, base_diameter, top_diameter, length |
axis, at |
wedge |
bind, size, width_at_y_max |
at, rotate |
sphere |
bind, diameter |
at |
torus |
bind, major_radius, minor_radius |
axis, at |
revolve |
bind, plane, profile, axis |
at, angle, holes |
draft |
target, faces:{select,expect}, angle, pull, neutral:{through} |
— |
face_offset |
target, faces:{select,expect}, distance |
— |
variable_fillet |
target, edges:{select,expect}, run:{from,to}, radii:{start,end} |
— |
text |
target, content, mode, depth, placement |
style, stroke |
curve_sweep |
fresh bind, path, loop section.region with explicit section.chord_error, frame |
section_scale, sampling, twist, caps; Curves and instances |
scatter |
fresh bind, mesh prototype, on, distribution, literal seed |
axes, scale, roll, scale_by; surface requires spacing, may use reference; returns Instances |
realize |
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 32 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 524,288 vertices and 1,048,576 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. Both actual part-local 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.
Mesh edits bridge, region_extrude, region_inset, remove_faces, refine_faces, dyntopo, sculpt, sculpt_path, and pose default an omitted bind to target. Loop edits require fresh bindings.
unfold snapshots a live sheet binding into a distinct exact flat binding; deliver both with
{"formed":"body","flat":"flat"}. A flat_pattern output with of:{"subject":"flat"} writes
layered exact DXF and a canonical JSON bend table (full coverage, world frame, source/spec SHA-256,
per-bend radius, K and allowance). It takes no plane. Unfold before generic source edits; write
flat_pattern before any edit to the flat binding, including place, which removes its claim.