Skip to content
Shapemetry

Model - transforms & modifiers

Every transform / modifier — it consumes the stream flowing into it and returns the stream flowing out. Authored as a step in an objects[] chain, after the producers whose entities it acts on.

MethodDescriptionArgTypeDefaultMeaning
applyAttributeAttributekeystring'type'Attribute name to set (single-quote literal), e.g. 'type' or 'ifcClass'.
valuestring | function''Value to store under that key (single-quote literals), or a callback (entity, index) => value, per entity.
applyLabelLabelnamestring | function''Display/export label tag (single-quote literals), or a callback (entity, index) => string, per entity.
applyLayerLayernamestring | function'Layer1'Layer name to assign (single-quote literals), or a callback (entity, index) => string, per entity.
applyLockedLockedlockedbinary | functiontruetrue shields the entities from every later step of this chain; or a callback (entity, index) => boolean, per entity.
applyMaterialMaterialnamematerial | function''A materials[] record name to assign (single-quote literals), or a callback (entity, index) => string, per entity.
applyViewViewfamilystring | function'plan'View family this entity belongs to (single-quote literal): '3d' (default — the projection/section body), 'plan', 'section', 'elevation', 'pattern', or 'detail'. A views[] entry draws the entity when its family matches (entity view is drawn in view V ⟺ X equals V's family from the head method — VIEW_FAMILY_OF map); non-'3d' content is authored drawing content, never projected or sectioned.
applyVisibleVisiblevisiblebinary | functiontruetrue shows, false hides the entities; or a callback (entity, index) => boolean, per entity.
arrayCurveArray Along NurbsCurvecurvecurveEntityPath curve the copies are distributed along.
copiesnumber4Copies to add along the curve — original at the start, spaced evenly.
angleangle0Extra rotation in degrees applied to each copy about the curve tangent.
arrayDistancesArray by Distances — Copies along Direction at explicit per-gap distances (cumulative — gap 1, then gap 2 after it, …). Use arrayLinear when the spacing is uniform.directionvector[1,0,0]Direction to array along — magnitude ignored, see Distances for spacing.
distanceslength[][300,400,500]Gap after each copy, in order, along Direction. Copy count = number of distances (a partition — no separate Copies arg).
arrayLinearLinear Arrayvectorvector[100,0,0]Per-copy step — magnitude IS the spacing (unlike Array Along Distances, where direction is normalized).
copiesnumber2Copies to add — the original stays, so 1 duplicates once.
arrayRadialRadial Arrayaxisaxis{ origin: [0,0,0], direction: [0,0,1] }Rotation axis: origin = pivot point, direction = spin axis.
copiesnumber5Copies to add around the axis — original + copies spaced evenly over 360°.
bendBendaxisaxis{ origin: [0,0,0], direction: [0,0,1] }Bend spine: the geometry's extent along this axis maps onto a circular arc.
angleangle90Total arc angle in degrees (90 = quarter turn).
resolutionnumber24Tessellation density before deforming.
blockExplodeExplodenestedbinary1Dissolve this node's nested blocks (a placed sub-model / clone) into raw geometry. 1 = recursive; 0 = one level.
curveChamferNurbsCurve Chamferdistancelength5Straight setback from each selected corner (flat cut, not an arc).
filterfunction(p, i) => truePredicate over a corner vertex and its index selecting which to cut; default = all.
curveExtrudeExtrude — Push the chain's curves into solids — a closed loop gets caps, an open one becomes walls.thicknesslength10Extrusion distance along the profile's normal.
capsbinary11 = closed profiles get top/bottom caps (a solid); 0 = walls only (open shell).
curveFillFill — Fill the chain's closed curves into flat faces — a closed curve nested inside another becomes a hole; open curves pass through.
curveFilletNurbsCurve Filletradiuslength5Arc radius rounding each selected corner (curved).
filterfunction(p, i) => truePredicate over a corner vertex and its index selecting which to round; default = all.
curveIntersectNurbsCurve IntersectcurvecurveEntityThe closed curve to keep only the overlap with (2D boolean).
curveLoftLoft — Skin a surface through the chain's curves in order (2 or more) — array a profile into sections, then loft them in one chain.degreenumber3Smoothness across sections: 1 = straight (ruled) between curves, 3 = smooth.
curveOffsetOffset NurbsCurve — Offsets every curve in the chain's own array — coplanar curves are grouped first and offset together (shapes that grow into overlap merge; a shape's holes inset/outset with its outer loop), non-coplanar groups offset independently.distancelength10Offset amount: positive = outward, negative = inward.
curveOvercutNurbsCurve Overcut — CNC corner-clearance relief (dogbone/T-bone): adds an arc extending past selected corners so a round cutting tool still seats a square mating part. Throws if radius/reduction are invalid.radiuslength5Relief arc radius — match the cutting tool radius.
typestring'dogbone''dogbone' bulges into both adjacent edges symmetrically. 'longTbone'/'shortTbone' extend into only the longer/shorter adjacent edge, keeping the other exact.
reductionlength00..radius — pulls the relief toward the vertex; at reduction === radius the arc passes exactly through the vertex.
filterfunction(p, i) => truePredicate over a corner vertex and its index selecting which to relieve; default = all.
curvePatchPatch — Fill the chain's boundary curve(s) with a smooth surface — chains off the boundary, so no separate curve node to hide.
curveProjectProject Onto Mesh — Drape the chain's curve onto a target mesh — each point is cast along the direction and snapped to the nearest surface hit. Mesh-level.targetfaceEntity[][]The mesh (Face[]) to project onto.
directionvector[0,0,-1]Cast direction (default straight down = drape onto terrain).
curveRevolveRevolve — Spin the chain's curve(s) about an axis into a solid — a closed profile yields a solid of revolution. Chains off the profile, so no separate curve node to hide.axisaxis{ origin: [0,0,0], direction: [0,0,1] }Revolution axis (origin on the axis, direction = spin axis).
angleangle360Sweep in degrees: 360 = full solid, under 360 = partial.
curveSelfUnionNurbsCurve Self Union — Fuse all closed curves in the node's own array into one region (2D boolean union, no operand).
curveSimplifySimplify NurbsCurve — Douglas-Peucker vertex reduction: drops points that stay within Tolerance of the simplified polyline. Endpoints are always kept (open curves); closed curves split at 3 well-spread anchor points first so the result never opens up.tolerancelength1Max deviation allowed between a dropped point and the simplified polyline.
curveSmoothSmooth NurbsCurve — Chaikin corner-cutting: rounds every corner by iteratively replacing it with two points partway along its adjacent edges. Closed curves round all the way around; open curves keep their exact endpoints. Output is always a degree-1 polyline.iterationsnumber2Corner-cutting passes: each doubles the vertex count and rounds corners further.
curveSplitNurbsCurve Splitparameternumber0.5Normalized split position from start (0) to end (1).
curveSubtractNurbsCurve SubtractcurvecurveEntityThe closed curve to cut away from this one (2D boolean).
curveSweepSweep — Sweep the chain's profile curve along a path into a solid tube — the profile is this chain, the path is the argument.pathcurveEntity[]Path the profile is swept along (open or closed curve).
capsbinary1Close the two ends of the swept tube (false = open duct).
curveThickenThicken NurbsCurve — Thickens every curve in the chain's own array into a closed strip — coplanar curves are grouped first and thickened together, non-coplanar groups independently.distancelength10Offset applied to EACH side of the curve — the strip is twice this wide.
joinTypestring'miter'How outer corners are joined: 'round' (arc), 'miter' (sharp point), 'square' (clipped).
endTypestring'round'How open ends are capped: 'round' (semicircle), 'square' (half-width), 'butt' (flush).
curveUnionNurbsCurve UnioncurvecurveEntityThe closed curve to merge with this one (2D boolean).
displaceDisplacefieldstring''Key of a textures[] chain to sample (triplanar); 0.5 is the neutral level.
amountlength1Displacement along the surface normal at field value 1 (negative at 0).
tilelength10Physical size (mm) of one field tile on the surface.
resolutionnumber48Tessellation density: vertices available for the field to shape.
edgeFilletEdge Fillet — Rounds selected edges by welding faces to mesh, discretizing the neighborhood into planar facets (segments), then returning face entities. Not a true NURBS fillet (kernel roadmap).filterfunction(p1, p2) => truePredicate over an edge's two endpoints selecting which edges to round; default = all.
radiuslength2Rolling-ball arc radius of the rounded edge (curved).
segmentsnumber12Number of planar facets across the arc; higher = smoother (discretized, not NURBS).
faceContoursFace Contours — Slice the chain's faces at evenly spaced Z levels into iso-elevation contour curves — REPLACES the sliced faces with the contours (reference the previous step's key to keep the surface itself). Non-face entities and nested blocks pass through untouched.spacinglength500Elevation interval between contour levels.
basenumber0Z of the reference contour level; other levels are base ± k*spacing.
faceEdgeDissolveDissolve Edges — Fuse the two coplanar faces sharing each selected edge into one polygon (erase the edge). Merges triangles/quads back into n-gons.filterfunction(p1, p2) => truePredicate over an edge's two endpoints [x,y,z]; default fuses every coplanar shared edge.
faceExtrudeFace Extrudethicknesslength10Distance to push the selected faces along their normal (negative = inward).
filterfunction(points, normal) => truePredicate over a face's points and normal selecting which faces to push; default = all.
faceOffsetOffset Facedistancelength10Inset (positive) or outset (negative) distance.
facePlanarizePlanarize — Nudge shared panel corners until every panel is flat — a warped quad tessellation becomes panels cuttable from flat sheet material, changing the surface as little as possible. Triangles are already planar and act as anchors.pinfunction(point) => falsePredicate over a vertex's ORIGINAL point selecting which ones must not move (e.g. a fixed boundary); default = none.
faceSkeletonBind Skeleton — Bind face vertices to a skeletons[] chain: nearest bone segments, top-4 influences, smooth falloff over Falloff mm, weights sum to 1. Writes geometry.skin. Deterministic. Re-running with a different falloff changes the transition width.skeletonstring''skeletons[] chain key (single-quote literal).
fallofflength80Influence radius in mm — weight falls to 0 beyond this distance from the nearest bone segment.
faceSplitFace SplitcurvescurveEntity[][]Curves drawn on a coplanar face — circle/arc/spline/polyline, one or more. Closed curves = an inner face + the outer carrying them as a hole (nested rings become holes); one open curve with both ends on the boundary = the face splits in two.
faceToMeshFaces → Mesh — Convert the chain's faces into ONE meshEntity — the canonical step onto the mesh track. Planar faces without holes become one n-gon each (design edges preserved for lattice/wireframe); curved faces tessellate and pair into quads. The sanctioned path: parametric body → Faces → Mesh → Mesh Subdivision. One-way: no op converts a mesh back into faces.
faceTrimTrim Face — Trim each planar face by a coplanar curve/face region — keep the part inside the tool, or cut it out. Mesh-level (flat faces).toolcurveEntity[] | faceEntity[][]The coplanar closed region to trim with.
sidebinary1Which side of the tool survives: 1 = inside (intersect); 0 = outside (cut the tool out).
faceUnfoldUnfold — Flatten a curved panel into a 2D cutting pattern — for cutting the material a curved surface represents. Each output triangle carries an attributes.areaDistortion (2D area ÷ 3D area — 1 = undistorted; far from 1 = untrustworthy to cut there). Any curved panel flattens, developable or not.
keepEntitiesKeep Entities — Keep only the entities for which the predicate is truthy — the general delete/filter (by region or type). Nested blocks pass through.keepfunction(center, type, index) => truePredicate over each entity's bbox center [x,y,z], its type (curveEntity/faceEntity/...), and index. Return false to delete it.
looseToBlockLoose to Blocks — Collect loose curves/faces into blocks by connectivity — each connected cluster becomes one nested block (inverse of Explode).
makeBlockMake Block — Wrap the whole entity array into one nested block, unconditionally — no connectivity clustering (unlike Loose to Blocks, which makes one block per connected cluster).
meshLatticeMesh Lattice — Hollow every meshEntity in the stream into a strut frame — each polygon face is inset and the remaining rims thicken into struts along design edges (no triangulation diagonals). Needs the welded shell struts meet across, so it works on meshes: convert first with Faces → Mesh. Meshes only — faces and curves pass through untouched.thicknesslength2Strut/wall thickness of the lattice shell.
boundarybinary1Close the open border edges of the lattice with caps.
meshSubdivisionMesh Subdivision — Catmull-Clark-subdivide every meshEntity in the stream — each pass smooths the surface and turns every n-gon into n quads. Normals are rebuilt smooth; uv/color/skin channels do not survive. Meshes only — faces and curves pass through untouched (convert first with Faces → Mesh).iterationsnumber1Catmull-Clark passes: each smooths the mesh and turns every n-gon into n quads.
mirrorMirrorplaneplane{ point: [0,0,0], normal: [1,0,0] }Mirror plane (point on plane + normal).
clonebinary11 keeps the original and adds the reflection; 0 flips in place.
moveMovevectorvector[0,0,1]Displacement to apply.
resizeResizesizeXlength | function1Target width along X, or a callback (entity, index) => number, per entity.
sizeYlength | function1Target depth along Y, or a callback (entity, index) => number, per entity.
sizeZlength | function1Target height along Z, or a callback (entity, index) => number, per entity.
reverseReverse — Flip direction — curve order / face normal, per entity type.
rotateRotateaxisaxis{ origin: [0,0,0], direction: [0,0,1] }Rotation axis (origin = pivot point, direction = axis; magnitude irrelevant).
angleangle | function0Rotation angle in degrees (CCW about the axis), or a callback (entity, index) => number, per entity.
scatterScatter — Randomly distribute copies across a face's surface — area-weighted, aligned to the face normal, randomly spun. Deterministic: the same Seed always samples the same points.facefaceEntity[][]Surface(s) to scatter across.
copiesnumber20Copies to add — the source is planted at (copies + 1) sampled points, same convention as Array Along NurbsCurve.
seednumber0Change to reshuffle the random placement while staying repeatable.
solidifySolidify (Shell) — Hollows a solid via mesh weld + offset (discretized faces returned). Remove faces first to open a shell.thicknesslength3Hollow the solid to a wall this thick, offset inward from the surface. A closed solid becomes a sealed hollow shell; remove faces first (Face Extrude inward, or delete) to open it.
solidIntersectSolid IntersectsolidfaceEntity[]The closed solid (Face[]); keeps only the volume shared by both (3D CSG).
solidSelfUnionSolid Self Union — Fuse all closed solids (Face[]) in the node's own array into one solid (3D CSG, no operand).
solidSliceSliceplaneplane{ point: [0,0,0], normal: [0,0,1] }Cut everything in the stream (faces + curves) with this plane. Returns the two sides as separate groups — nothing is deleted; drop a side with Visible or a filter.
capbinary11 fills the cross-section so each piece stays closed; 0 leaves the cut open.
solidSubtractSolid SubtractsolidfaceEntity[]The closed solid (Face[]) to carve out of this one (3D CSG).
solidUnionSolid UnionsolidfaceEntity[]The closed solid (Face[]) to fuse with this one (3D CSG).
taperTaperaxisaxis{ origin: [0,0,0], direction: [0,0,1] }Taper axis: scaling shrinks/grows perpendicular to this spine.
factornumber0.5Radial scale at the far end (1 = none, 0 = to a point).
resolutionnumber24Tessellation density before deforming.
textOnPathText On Path — Lay text glyphs ALONG the chain's path curve — the baseline follows the curve, glyphs bending with it. The chain IS the path and is consumed (output is glyphs only, no guide curve).textstring'Hello'The string to render along the path; single-quote the literal.
fontfontFont reference; leave '' to use the built-in fallback font.
fontSizelength10Cap height of the glyphs in model units.
twistTwistaxisaxis{ origin: [0,0,0], direction: [0,0,1] }Twist axis: origin = pivot, direction = spine.
angleangle90Total twist in degrees across the geometry's extent along the axis.
resolutionnumber24Tessellation density before deforming (higher = smoother, heavier).
vertexDeleteDelete Vertices — Delete selected vertices — curves rebuild from survivors; faces use weld-aware mesh delete (input-type dispatch).filterfunction(point) => falsePredicate over a point [x,y,z] to delete; default deletes none.
vertexFilletVertex Fillet — Rounds selected vertices by welding to mesh and discretizing into planar faces (same mesh path as edgeFillet; true NURBS fillet is kernel roadmap).filterfunction(point) => truePredicate over a vertex's point selecting which corners to round; default = all.
radiuslength2Rolling-ball arc radius of the rounded corner (curved). An unselected neighbor vertex is left untouched.
segmentsnumber12Number of facets across the arc; higher = smoother.
vertexMoveMove Vertices — Move selected vertices — curve control points or face mesh vertices (input-type dispatch; welded faces move together).filterfunction(point) => truePredicate over a point [x,y,z]; default selects all.
vectorvector[0,0,0]Translation applied to selected vertices.
vertexRotateRotate Vertices — Rotate selected vertices about an axis — curves and faces (input-type dispatch).filterfunction(point) => truePredicate over a point [x,y,z]; default selects all.
axisaxis{ origin: [0,0,0], direction: [0,0,1] }Rotation axis (origin on the axis, direction = spin axis).
angleangle0Rotation in degrees.
vertexScaleScale Vertices — Scale selected vertices about a center — curves and faces (input-type dispatch).filterfunction(point) => truePredicate over a point [x,y,z]; default selects all.
centerpoint[0,0,0]Fixed point the scale is measured from.
factornumber1Uniform scale factor.
Last updated: 📖 15 min readEdit on GitHub