Some commands exist only where their library is linked. The gate column below means:
Documents & timeline
Creating, saving and opening documents, and walking the shared undo timeline — yours and any connected AI’s steps sit in one history.
doc.branch
Make a named branch of this document's timeline: a complete copy of the recipe as it stands, kept inside the document and saved in the .cocad beside it, so two ideas for one part can live in one file.
Detail
Make a named branch of this document's timeline: a complete copy of the recipe as it stands, kept inside the document and saved in the .cocad beside it, so two ideas for one part can live in one file. Does not switch to it - you stay on the branch you are on; doc.switch_branch opens it. The copy remembers which branch it was taken from and what that branch's recipe was at the time, which is what a later merge compares against. Names are unique within a document; a document that has never branched is on a branch called main. Not a step in the timeline and not undoable: it changes which recipes the document holds, not the part.
doc.close
Close one open document.
Detail
Close one open document. Unsaved work is discarded without asking, exactly as doc.new discards it: prompting belongs in the window, above the bus, because an AI calling this has no dialog to answer. Closing the last one leaves this core with nothing open, which is the state it starts in. A connection looking at the closed document lands on the one beside it.
doc.create_folder
Make a folder in the browser to organise this document - Fasteners, Frame, Old versions.
Detail
Make a folder in the browser to organise this document - Fasteners, Frame, Old versions. A folder is a way of arranging rows and nothing else: it changes no geometry, no position, no joint, no parts list, no export and no timeline order, so moving a body into one does not move the body. Bodies, sketches, component placements and other folders can be filed into it with doc.move_to_folder, and a filed thing is drawn inside the folder rather than in the Bodies or Sketches folder it would otherwise sit in - which is why the Bodies folder's count goes down when you file something. Name it now or let it be called Folder<n> and rename it later with doc.rename. Give a parent folder to nest it; leave parent out and it sits at the top of the document beside Bodies and Sketches. Saved with the file, and undoable - filing thirty rows in one drag is exactly the thing Ctrl+Z has to reach. Not a timeline feature: organising is not modelling.
doc.create_timeline_group
Group a run of ADJACENT timeline features under one name - base, mounting holes, cosmetics - so a long timeline reads as a handful of named stages.
Detail
Group a run of ADJACENT timeline features under one name - base, mounting holes, cosmetics - so a long timeline reads as a handful of named stages. A group is a way of reading the strip and nothing else: it changes no geometry, no rebuild order and no suppression, and grouping a feature does not move it. The features must sit next to each other in the timeline (query.features order) and not already be in a group - a feature is in one group at a time. Name it now or let it be called Group<n> and rename it later with doc.rename. Saved with the file, and undoable in one step. Not a timeline feature itself: organising is not modelling.
doc.delete
Delete bodies, sketches, construction planes, axes, points and coordinate systems - the modelling entities a person selects and presses Del on.
Detail
Delete bodies, sketches, construction planes, axes, points and coordinate systems - the modelling entities a person selects and presses Del on. One call is one undo, whatever the mix. What was built FROM the thing you delete stays: a rebuild replays the deletion after everything that used it, so deleting the sketch an extrude was made from keeps the extruded body and removes the sketch. The timeline keeps the feature that made a deleted body, having made something that later left; rolling the timeline back past the deletion brings the entity back. Deleting is refused where a saved picture would silently change what it shows - an explode state that offsets the body, a drawing view that draws it - and the refusal names it. Journaled, saved with the file, undoable, and it adds no timeline feature.
doc.delete_branch
Forget one of this document's branches that is not the open one, recipe and all.
Detail
Forget one of this document's branches that is not the open one, recipe and all. The open branch cannot be deleted - switch to another first. Not a step and not undoable; the branch is gone from the document and from its next save.
doc.delete_folder
Remove a browser folder.
Detail
Remove a browser folder. What was in it is NOT deleted: bodies, sketches and placements go back to the Bodies, Sketches and Placements folders they came from, and folders inside it move up to where it was. A folder is organisation, so deleting one must never delete a part - the reply says how many things were released so you can tell somebody where their parts went. Saved with the file, and undoable, which puts the folder and every filing back exactly as they were.
doc.delete_timeline_group
Remove a timeline group.
Detail
Remove a timeline group. The features that were in it are NOT deleted or moved: they stand exactly where they are in the timeline, ungrouped. A group is a way of reading the strip, so deleting one must never change the model - the reply says how many features were released. This is also the way out of a group that a move cannot empty. Saved with the file, and undoable, which puts the group and every membership back exactly as they were.
doc.move_to_folder
File things into a browser folder, or take them out of one.
Detail
File things into a browser folder, or take them out of one. Name what to move - bodies, sketches, component placements, other folders, in any mixture - and the folder they go into, or null to put them back where they would otherwise sit. This says where they now are, not how far to move them, so sending the same call twice files them once and a retry is safe. Nothing about the model changes: a folder is a way of arranging rows, so query.measure, query.tessellate, query.bom and every export answer exactly as before, and a part in a folder is manufactured the same way as a part not in one. A thing is in one folder at a time, so filing it somewhere takes it out of wherever it was, and a thing already there is a success that moves nothing. A folder cannot be filed into itself or into anything already inside it. Saved with the file, and undoable in one step, so a drag that files the wrong thirty rows is one Ctrl+Z.
doc.move_to_timeline_group
File timeline features into a group, or take them out of one.
Detail
File timeline features into a group, or take them out of one. Name the features and the group they go into, or null to take them out of whatever group they are in. This says where they now are, not how far to move them, so sending the same call twice files them once and a retry is safe. Every group must stay one unbroken run of adjacent features - filing something into the middle of another group, or pulling a feature out of the middle of its own, is refused with the group named. A feature already there is a success that moves nothing, and a move that would leave a group empty is refused - delete the group instead, which releases its features. Saved with the file, and undoable in one step.
doc.new
Create a new empty document and make it current.
Detail
Create a new empty document and make it current. Without keepCurrent it REPLACES the document this connection is on, and that document's unsaved work is discarded - the reply's replaced names it. Save it first, or pass keepCurrent: true to keep it open beside the new one.
doc.open
Open a .cocad file, replacing the current document.
Detail
Open a .cocad file, replacing the current document. The file's operations are replayed in order, so the reopened document has the same timeline - undo included - that was saved. Nothing changes unless the whole replay finishes: a file that produces no document leaves the current one exactly as it was. A document saved in an older format version opens unchanged and answers olderFormat true, because the next save will write it in the current one. If the file recorded a fingerprint of the geometry it produced, the replay is checked against it and geometryDigest is present only when that check did not pass, naming the value saved and the value this build computes - null when the check could not be made, which means either that this build computes no fingerprint or that firstFailure is present, because a replay that did not finish produced a different document for a reason already named and comparing it would say the build is at fault when a file is simply missing. Opening a file writes a .lock beside it so a second CoCAD - another window here, or another machine on the same share - is told rather than left to overwrite it: readOnly says whether this open got the lock, and lockedBy names who has it (null when nobody could be named, which includes a lock file CoCAD did not write). A read-only document can still be measured, exported and copied from, and saving it writes beside the original rather than over it. The lock is given up when the document is closed or replaced, or when this core exits; one left behind by a crash on this machine is taken silently by the next open.
doc.pack
Copy this document and every part it links to into one folder, with the copied recipe pointing at the copies - so the whole assembly can be sent to somebody else, or moved to another drive, and still open.
Detail
Copy this document and every part it links to into one folder, with the copied recipe pointing at the copies - so the whole assembly can be sent to somebody else, or moved to another drive, and still open. path names the .cocad to write and its folder is where everything lands; each linked part is copied beside it under its own filename, and the copy's recipe stores that bare filename, which means beside this file on any machine. Parts linked by those parts are copied too, and their recipes are pointed at the copies in the same way, so a two-deep assembly arrives whole. A part linked twice is copied once. Two different parts that happen to share a filename get a -2, -3 suffix, because one folder cannot hold both names. It COPIES and never moves: the originals are left exactly where they are, and this document goes on reading them - a pack is not a save, so it does not change which file this document belongs to, does not clear unsaved changes and does not appear in your recent files. Lock sidecars and .bak files are not copied: a lock describes the machine you are on and a backup is a history that is not travelling. If any linked file is missing the whole pack is refused and nothing is written, because a folder with a part missing from it is worse than no folder at all - call query.links first to see what a document needs. Packing where files of the same names already exist is refused too, unless overwrite is true.
doc.recover
Rebuild the document from a crashed session's recording, replacing the current document.
Detail
Rebuild the document from a crashed session's recording, replacing the current document. The recorded commands are replayed in order, exactly as doc.open replays a saved file, so the recovered document has the same timeline - undo included - that was lost. Nothing changes unless the replay produces a document. The recording is left where it is: it is still the only copy until the recovered document is saved.
doc.redo
Re-apply the change undo last reversed, restoring its original entity IDs.
Detail
Re-apply the change undo last reversed, restoring its original entity IDs.
doc.rename
Give a body, a sketch, a construction plane, a construction axis, a construction point, a coordinate system, a reference mesh, a canvas, a component, a joint, a rigid group, an explode state, a section state, a named view, a browser folder, a timeline group, a drawing or a drawing sheet a new display name.
Detail
Give a body, a sketch, a construction plane, a construction axis, a construction point, a coordinate system, a reference mesh, a canvas, a component, a joint, a rigid group, an explode state, a section state, a named view, a browser folder, a timeline group, a drawing or a drawing sheet a new display name. Renaming a component relabels every placement of it at once. Names are what the browser shows and what a find-in-model search reads; they are NOT identity, so they need not be unique and renaming breaks no reference. Undoable.
doc.save
Write the current document to a .cocad file.
Detail
Write the current document to a .cocad file. A .cocad is the document's operation log - the ordered list of commands that built it - under a version header, so it is readable text and opening it replays them. Saving changes nothing about the document and can be done from any state, including a half-drawn sketch. Overwriting an existing file keeps its previous contents beside it as a stamped .bak, the newest files.backupCount of them (5 by default, 0 to keep none); each one is a complete .cocad that doc.open will open. The file also records a fingerprint of the geometry the log produced, so a later build can say whether replaying it reproduced this model exactly. When this document was opened from a file whose fingerprint this build did not reproduce, geometryDigest is present on the first save that follows, naming the value that file recorded and the value this build computed - the save succeeds and records the new geometry as canonical. Saving over a document another CoCAD has open writes your work beside it under a stamped name rather than over theirs, and says so in message; a save is never refused because somebody else has the file, so read path back for where the bytes actually landed. A document is named by its file: after a save it is called the file's name without its extension, and name in the reply says so.
doc.set_appearance
Say what bodies, faces and component instances LOOK like - a colour as r, g and b fractions between 0 and 1.
Detail
Say what bodies, faces and component instances LOOK like - a colour as r, g and b fractions between 0 and 1. Send null to clear, and a cleared face draws at its body's colour, then its material's own look, then the default. This is what somebody CHOSE for this entity, which is a different fact from what the body is made of (ADR 0324): painting a bracket red changes nothing about what it weighs, and doc.set_material is the other half. A placement's colour is that placement's own, so two copies of one part can differ. Undoable, and it changes no geometry - a colour is never a shape. For see-through use doc.set_opacity: there is no alpha here.
doc.set_canvas_frame
Move, turn, flip, recalibrate or re-plane a canvas - the whole placement in one command, absolute values only.
Detail
Move, turn, flip, recalibrate or re-plane a canvas - the whole placement in one command, absolute values only. Send the canvas and any of mmPerPixel, origin, rotation, flip and support; at least one, and absent fields are left exactly as they are, so a retry is safe and nothing here is ever a nudge. mmPerPixel is what the Calibrate gesture sends after two points and a typed distance, and the reply's calibration field then reads sent. Recalibrating rescales the picture about the image's CENTRE, so the traced half stays under its sketch. Journaled and undoable, minting no feature - a canvas is not in the recipe.
doc.set_material
Say what bodies are MADE OF - a name and a density in g/cm3, optionally the appearance that material came with.
Detail
Say what bodies are MADE OF - a name and a density in g/cm3, optionally the appearance that material came with. Send a query.materials row verbatim, or your own numbers; send null to clear. The numbers are stored on the body, never a reference to the library (ADR 0324), so a saved model's mass can never change because a machine's material table did. Bodies only: density is a property of the stuff, and a face has none of its own. query.mass_properties uses what is assigned here, and query.tree discloses it, the appearance included; a body with no colour of its own draws in its material's. Undoable, and it changes no geometry - a material is never a shape.
Write the part-metadata record a BOM row and a title block read - part number, description, material and revision, an exclude-from-BOM flag, and custom fields for what a schema cannot foresee (supplier, finish, coating).
Detail
Write the part-metadata record a BOM row and a title block read - part number, description, material and revision, an exclude-from-BOM flag, and custom fields for what a schema cannot foresee (supplier, finish, coating). Name a component definition ("cp:1") to write its record, or leave entity out to write the document's own - a part file's part IS the document, so that record is what a title block reads for a part drawing. Occurrences and bodies carry no record: every placement of a part answers its definition's, which is what makes a parts list one row per part. An upsert per field: a field left out is untouched, a field sent as null is cleared, and what you send is stored exactly as sent - so a forgotten field is never an erased value and a retry is safe. Values are one line each; mass is deliberately not a field, because mass is derived from the geometry and a typed mass beside a computed one is two places the same fact lives. Undoable, and not a timeline feature: editing a property creates nothing.
doc.set_opacity
How opaque bodies draw, as a fraction in (0, 1] - 1 is opaque, smaller is more see-through.
Detail
How opaque bodies draw, as a fraction in (0, 1] - 1 is opaque, smaller is more see-through. Sets rather than toggles, so sending the same call twice is not two different requests. Display only: nothing about the geometry, measurement or export moves, and it is NOT undoable - the control that set it is its own undo. An opacity of 0 is refused: a body nobody can see is a hidden one, and doc.set_visible is how to say that.
Say what bodies are FOLDED BY - a thickness, the inside bend radius, the K-factor and the bend relief.
Detail
Say what bodies are FOLDED BY - a thickness, the inside bend radius, the K-factor and the bend relief. Send a query.sheet_metal_rules row verbatim, or your own numbers; send null to clear. Assigning a rule is what makes a body sheet metal and clearing it is what stops it being, so there is no separate flag (ADR 0429), and a body with no rule is not sheet metal at some default thickness - it is a body nobody has said is sheet metal. The numbers are stored on the body, never a reference to the table (ADR 0427), so a saved model's flat pattern can never change because a machine's rule table did. Bodies only: a thickness is a property of the stock, and a face has none of its own. One rule per body, because a second flange folds the same sheet as the first. query.tree discloses it. Undoable. A part its own base or contour flange made is RE-FOLDED at the new rule: that flange's rule is rewritten and the part rebuilt from its recipe, so every bend after it follows the new stock, and refolded names the flange - one such part per call, and never in a group. Any other body's rule is a record and moves no geometry.
doc.set_step
Move the document to the state it was in just after a chosen step.
Detail
Move the document to the state it was in just after a chosen step. Steps after it become the redo tail; step 0 is the empty document.
doc.set_units
Change the unit this document's lengths are shown in and typed in.
Detail
Change the unit this document's lengths are shown in and typed in. Storage is always millimetres, so nothing about the geometry moves - only how a number is written for a person and read back from them. Not undoable: it is a way of reading the drawing, not a change to it.
doc.set_visible
Show or hide bodies, sketches, construction planes, construction axes, construction points, coordinate systems, reference meshes, canvases and the three base planes.
Detail
Show or hide bodies, sketches, construction planes, construction axes, construction points, coordinate systems, reference meshes, canvases and the three base planes. Sets rather than toggles, so sending the same call twice is not two different requests. Hiding changes nothing about the geometry, and it is NOT undoable - the browser's eye is its own undo.
doc.switch_branch
Open one of this document's branches in place of the one that is open: its recipe is replayed in order, exactly as doc.open replays a file, so the part, its timeline and its undo history become that branch's.
Detail
Open one of this document's branches in place of the one that is open: its recipe is replayed in order, exactly as doc.open replays a file, so the part, its timeline and its undo history become that branch's. The branch you leave is kept as it stood, rollback marker included, and the document keeps its name, its file and its tab. Nothing changes unless the replay produces a document; a replay that did not finish is reported in firstFailure and the branch's recipe is kept whole, so a later save loses nothing. Switching to the branch already open answers changed false. Not a step and not undoable - switch back to reverse it; doc.undo after a switch undoes that branch's own newest step. A feature made after a switch takes a number no branch of this document has, so features keep their identity across branches.
doc.undo
Reverse the most recent change.
Detail
Reverse the most recent change. Refuses a step another client made unless confirm is true.
Solid features
Turning sketches into solids and editing the solids: extrudes, revolves, fillets, shells, mirrors and booleans.
feature.align kernel
Move one part so a chosen face of it mates with a face somewhere else - assembly.create_joint's positioning arithmetic as a plain move, with nothing recorded.
Detail
Move one part so a chosen face of it mates with a face somewhere else - assembly.create_joint's positioning arithmetic as a plain move, with nothing recorded. Name what moves (moving: a component placement, which travels as a unit exactly as feature.move's occurrences arm moves it, welded co-members and everything jointed below it included - or one body, which travels alone), the face on it to mate (movingFace), and the face to mate it to (targetFace). A flat face gives its centre and outward normal, a cylindrical one gives its axis at mid-height - so dropping a pin into a bore or a bracket onto a plate is one call each. With no flip the two faces end up facing the SAME way, exactly as an unflipped joint lands its child; send flip to turn the part over first, which is what you want for a face-to-face mate. offset backs it away in millimetres measured in the target face's own axes (z is out of the face), and angle turns it about the mate axis. Everything feature.move promises holds here: nothing is copied, every fc:, eg: and vx: survives, overlap is ordinary, a grounded placement is refused, and it is one undoable feature in the timeline. Unlike a joint, nothing is remembered - the parts are placed and left free - so follow with assembly.create_joint asBuilt if you want the assembly to hold them there. A part already exactly where it was asked to go is a success that records nothing: featureId answers null and no step enters the timeline, so a retry is quiet as well as safe.
feature.base_flange kernel
Make the FIRST wall of a sheet-metal part: a closed sketch profile becomes a flat body as thick as the stock you name, and that body is sheet metal from the moment it exists.
Detail
Make the FIRST wall of a sheet-metal part: a closed sketch profile becomes a flat body as thick as the stock you name, and that body is sheet metal from the moment it exists. Name the region with profile (query.profiles lists them) and the stock with rule - a query.sheet_metal_rules row works verbatim, and its thickness is the wall's thickness, which is why there is no separate thickness argument. side says which side of the sketch plane the metal lies on. It always makes a body of its own: a body is folded by ONE rule, so a base flange joined into an existing body would give that body a second thickness and no flat pattern at all - later flanges bend the wall this one makes. The rule goes on the BODY, where query.tree reports it as sheetMetalRule and every fold after this one reads it; doc.set_sheet_metal_rule on this body re-folds the part at another stock by rewriting this feature's rule and rebuilding. A wall with no stock behind it is a plain extrude: use feature.extrude.
feature.bend kernel
Fold a flat wall of a sheet-metal part about a line drawn on it - the cross-brake in a panel, the step in a bracket, any fold that is not at an edge.
Detail
Fold a flat wall of a sheet-metal part about a line drawn on it - the cross-brake in a panel, the step in a bracket, any fold that is not at an edge. Name the wall with face and the line with line (a straight sketch curve lying over that face; query.sketch lists them), and angle says how far it turns, 90 by default. The line is the bend's CENTRE LINE: the flat it consumes straddles it, half each side, and everything on the moving side is carried round on the end of the bend, flanges and holes and all. fixedSide says which side stays put - "left" or "right" of the line, looking at the face you picked from outside and walking the line from its start to its end - and direction says which way the other side goes. The stock, the bend radius and the K-factor come from the BODY's sheet-metal rule; bendRadius and kFactor override them for this bend only, and the thickness is never overridable because one part is cut from one sheet. The metal the line runs through has to be a plain rectangle of that stock - a hole or another wall inside the bend allowance is refused and says so.
feature.boundary_fill kernel
Fill the volume a set of SHEET bodies encloses: the sheets are intersected and every closed cell they bound becomes a new SOLID body.
Detail
Fill the volume a set of SHEET bodies encloses: the sheets are intersected and every closed cell they bound becomes a new SOLID body. The sheets are NOT consumed - a fill uses only the parts of each sheet that bound a cell, so they keep their IDs and their places (feature.stitch is the door that consumes, when sheets should BECOME one body). The largest cell arrives first, named for the first sheet in bodies; keep narrows the answer to the cells CONTAINING the given points - a point on a wall, or inside no cell, is refused rather than guessed. A set that encloses nothing is refused - there is no cell to fill. One closed sheet (a surface revolve's full torus skin, say) is a legitimate set of one.
feature.bridge_cage kernel
Bridge two ends of a SUBDIV (freeform) body's control cage with a tube of new cage faces, so the body gains a HANDLE (two ends on one side of it) or a TUNNEL (two ends on opposite sides).
Detail
Bridge two ends of a SUBDIV (freeform) body's control cage with a tube of new cage faces, so the body gains a HANDLE (two ends on one side of it) or a TUNNEL (two ends on opposite sides). Each end is either cage faces that make one patch - they are deleted, and the tube starts from the edge round them - or the open cage edges all the way round a hole the cage already has (feature.delete_cage makes one). The two ends' edges must have the same number of points: each point of one is joined to the nearest-matching point of the other. The tube is faces long, and between its ends it arches out along the way each end's faces faced - or runs straight through the body when the other end is behind it. The tube's faces are new ids (cf:), listed under faces; the deleted faces' ids are RETIRED. One step, one undo, a timeline feature. Refused, by name: an id that is not a cage face or edge, ends on two bodies, a body that is not a subdiv body, an end that mixes faces and edges, faces whose edge is not one loop or reaches the cage's open rim, edges that are not one loop round a hole, two ends that touch, and ends whose edges have different numbers of points.
feature.chamfer kernel
Cut a flat across the named edges of one body.
Detail
Cut a flat across the named edges of one body. Each edge carries its own setback, and a setback has two sides: distance is measured on one adjacent face and otherDistance on the other, so an asymmetric chamfer is two numbers and a flip is those two numbers swapped. Omit otherDistance for the ordinary symmetric chamfer. The body keeps its ID, its name and its place in the tree — a chamfer edits the body it was given and creates nothing — and every edge named must belong to that one body.
feature.close_corner kernel
Close the open corner between two flanges of a sheet-metal part - the corner of a box where two sides folded up off edges that meet.
Detail
Close the open corner between two flanges of a sheet-metal part - the corner of a box where two sides folded up off edges that meet. Name the two flange ENDS that face each other across the gap with faces (query.tree lists a body's faces; each end is the flat face that closes a flange's section at the corner, and query.measure reports its normal). Each flange's FLAT is carried on along its own fold line until it reaches the other, and the two ends are cut against each other by type: "overlap" carries the first flange over the second's outside face and stops the second short of the first's inside face; "underlap" is the same the other way round; "butt" mitres both at 45 degrees. gap is the air left between the two ends, 0.1 mm by default. The bends are not carried on - two bends that meet would run into each other - so the bend region stays open under the closed corner, as it does in every sheet-metal package. Both ends must belong to one sheet-metal body, must face each other at a right angle, and both flanges must stand square to the wall; anything else is refused and says why.
feature.combine kernel
Combine existing bodies: join, cut or intersect the target with one or more tool bodies, which act as one tool.
Detail
Combine existing bodies: join, cut or intersect the target with one or more tool bodies, which act as one tool. The target keeps its ID, name and appearance — it is the body that survives — and the tools are removed unless keepTools is true. A cut or intersect that leaves the target in disjoint pieces keeps the target's ID on the largest piece by volume and adds the rest as new bodies; a join never splits, so joining two disjoint bodies is how they become one. Mesh bodies (a scan made with body.from_reference_mesh) combine with mesh bodies the same way and stay mesh bodies, provided each one closes up into a solid (feature.repair_mesh first if not); an exact body and a mesh body cannot be combined in one call - convert the exact one first with body.to_mesh.
feature.configuration
Save a named set of parameter values - a configuration such as "Small", "Large" or "M4 version" - so the part can be switched between them.
Detail
Save a named set of parameter values - a configuration such as "Small", "Large" or "M4 version" - so the part can be switched between them. It is a timeline feature that changes no geometry: name is what the configuration is called, unique in the document, and inputs gives the expression it sets for each parameter it names (only those; the others are left alone). Every name must be a parameter of this document, and the parameters with these expressions installed must evaluate, or the write is refused. query.configurations lists every configuration and says which ones match the parameters now; to switch to one, send param.set_many with its inputs. feature.edit changes one; feature.suppress sets it aside. Undoable.
feature.contour_flange kernel
Make a sheet-metal wall that turns corners: an OPEN run of sketch curves becomes a body as thick as the stock you name, with a bend of that stock's radius at every sharp corner, swept length along the sketch plane's normal.
Detail
Make a sheet-metal wall that turns corners: an OPEN run of sketch curves becomes a body as thick as the stock you name, with a bend of that stock's radius at every sharp corner, swept length along the sketch plane's normal. A channel, a hat section or a U-bracket is one call. Name the run with spine (sketch curves from ONE sketch, query.sketch lists them) and the stock with rule - a query.sheet_metal_rules row works verbatim. The order you name the curves in does not matter; a run that branches, has a gap in it, or closes into a loop is refused. The metal sits half either side of the curves you drew, because an open run has no inside for a side to be measured from - so draw the run down the MIDDLE of the metal. A corner between two straight runs is bent for you; an arc you drew tangentially into both its neighbours is carried through as the bend you drew, at your radius. It always makes a body of its own, and that body is sheet metal from the moment it exists: later flanges bend the walls this one makes.
feature.corner_relief kernel
Cut the corner relief where two bend lines of a sheet-metal part cross - the notch a shop makes in the flat before folding, so the two bends have somewhere to go.
Detail
Cut the corner relief where two bend lines of a sheet-metal part cross - the notch a shop makes in the flat before folding, so the two bends have somewhere to go. Name the two flange ENDS that face each other across the corner with faces, exactly as feature.close_corner does (query.tree lists a body's faces; each end is the flat face that closes a flange's section at the corner). The notch is square or round - whichever the body's sheet-metal rule names - and reaches the rule's relief depth back from each fold line, cutting the wall's corner away and setting both flange ends back with it. Send relief to cut a different shape for this corner only. A rule whose relief is a tear cuts nothing and is refused by name. Both ends must belong to one sheet-metal body and must face each other at a right angle across an open corner; anything else is refused and says why.
feature.crease_cage kernel
Crease or smooth edges of a SUBDIV (freeform) body's control cage.
Detail
Crease or smooth edges of a SUBDIV (freeform) body's control cage. A creased edge stays sharp in the smooth surface - the surface folds along it, so a freeform part can have a hard edge, a seam or a flat-bottomed base - and sharpness 0 smooths a creased edge again (an uncrease). Between 0 and 10 the crease is soft: sharp for that many subdivision levels, then rounding off. Every other edge keeps the sharpness it had, and no face, point or id moves. On a body with a symmetry (feature.symmetry_cage) each edge's partners - its mirror image, or its copies round the axis - get the same sharpness, listed under followed. One step, one undo, a timeline feature; when every edge named already has that sharpness, nothing is recorded and the reply says so (changed is empty). Refused, by name: an id that is not a cage edge, edges of two bodies, a body that is not a subdiv body, an edge the cage no longer has, an edge on the cage's open rim (always sharp), and a soft crease sharp for more levels than the cage can be drawn at (the refusal names the largest that fits).
feature.decimate_mesh kernel
Reduce a MESH body's triangle count where it stands, keeping its shape - the step that makes a dense scan light enough to work with.
Detail
Reduce a MESH body's triangle count where it stands, keeping its shape - the step that makes a dense scan light enough to work with. Edges are collapsed cheapest first by how far each collapse would move the surface (quadric error), so flat regions melt to the few triangles their outline needs while creases and corners are kept. Give the size as targetTriangles or as ratio (the fraction to keep), exactly one. Corners on an open edge or on an edge a repair would call faulty are never moved, so a hole keeps its rim and a fault is left for feature.repair_mesh; no collapse is made that would fold the surface or change whether it closes, so a closed scan stays closed. The target is a ceiling and the reply says whether it was reached. The body keeps its ID, name, material and appearance, and one undo takes the decimation back. If nothing could be collapsed the reply says changed false and NOTHING is recorded. An exact body is refused.
feature.delete_cage kernel
Delete faces of a SUBDIV (freeform) body's control cage, leaving a HOLE: the faces round it keep their shape and their ids, and the edges of the hole become the cage's open rim (the smooth surface ends there), listed under rim - a closed body becomes an open one, as a Freeform Plane is.
Detail
Delete faces of a SUBDIV (freeform) body's control cage, leaving a HOLE: the faces round it keep their shape and their ids, and the edges of the hole become the cage's open rim (the smooth surface ends there), listed under rim - a closed body becomes an open one, as a Freeform Plane is. The way to open a body before bridging two holes into a handle, or to cut away the half of a body you mean to mirror. Every deleted face's id (cf:) is RETIRED and never reused; a cage point no face uses any more is retired too (listed under points). A crease on an edge of the hole goes with it. On a body with a symmetry (feature.symmetry_cage) each face's partners are deleted too, listed under followed - set the symmetry to none first to cut one side away. One step, one undo, a timeline feature. Refused, by name: an id that is not a cage face, faces of two bodies, a body that is not a subdiv body, a face already deleted, every face the cage has (delete the body instead), and a hole that would leave two parts of the cage touching at a point by a corner alone.
feature.delete_face kernel
Remove faces from a SOLID body and heal the openings - the direct edit that defeatures a part.
Detail
Remove faces from a SOLID body and heal the openings - the direct edit that defeatures a part. Name faces of ONE body in faces; the neighbouring faces stretch along their own surfaces to close each opening, so a fillet, a boss or a hole's wall vanishes as if it had never been cut - the natural way to simplify an IMPORTED body that has no feature to suppress (on a native body, feature.suppress is the parametric door and keeps the feature recoverable). No new side wall is ever invented: an opening the neighbours cannot close is refused (a plain box's Top has nothing to close it, for example). The body keeps its ID and name; a removal that severs the body keeps every piece, the largest by volume keeping the ID.
feature.dovetail kernel
Join two pieces of a part with a sliding dovetail: the first piece gains a tail - a wedge-shaped key that widens as it goes - and the second piece takes the matching socket, so the second slides onto the first along one direction and cannot be pulled apart any other way.
Detail
Join two pieces of a part with a sliding dovetail: the first piece gains a tail - a wedge-shaped key that widens as it goes - and the second piece takes the matching socket, so the second slides onto the first along one direction and cannot be pulled apart any other way. The pieces are two exact solids that meet face to face on a plane, as feature.split leaves them; the shared face is found. The key runs straight across the WHOLE shared face along direction (default: the face's long axis), placed where the socket keeps the most wall each side - at least max(1.2 mm, depth / 2), beside it and above it. The tail is the second piece's own material inside the key, moved to the first piece, so its ends follow the part's own outline; the socket is the key grown by clearance on every side. Nothing else is made. Refused, each with details.reason, when the pieces share no flat face (noSharedFace), when the faces do not overlap (noOverlap), when no line across the face has room for the socket and its walls (tooNarrow, with room and needed), when the second piece continues past the face along the slide so it could not slide on (blocked - pass another direction), when it is too thin to hold the socket and its wall (runsOut, with at), and when the socket would cut it in two (severs). One feature, one undo; both bodies keep their IDs. The reply gives the direction used, the key's centre line on the face (line {origin, from, to}, from and to measured along direction), and the tail's width at its root and its widest (topWidth).
feature.dowel kernel
Join two pieces of a part with dowels: drill matching sockets into both pieces across the flat face they share, so they line up when glued or pressed together.
Detail
Join two pieces of a part with dowels: drill matching sockets into both pieces across the flat face they share, so they line up when glued or pressed together. The pieces are two exact solids that meet face to face on a plane, as feature.split leaves them (query.build_fit plans the cuts); the shared face is found, and every face of each piece on that plane counts. Sockets go only where they fit inside both pieces' faces with at least half the dowel's diameter of material round them (never under 1.2 mm) - one dowel where there is most room, two or more spread as far apart as the face allows. Each socket is diameter + 2 x clearance wide and depth deep in each piece. The dowel itself is not made: the reply's dowel {diameter, length} is the pin to print with body.cylinder (it prints best lying down) or to buy - its length is 2 x depth less a clearance at each end. Only material is removed, so both pieces can still print cut face down. Refused when the pieces share no flat face, when the face has no room for a socket, when fewer dowels fit than count asks for (the refusal says how many do), and when a socket would run out of a piece thinner than depth. One feature, one undo; both bodies keep their IDs. Two mesh pieces (a scan split with feature.split) are dowelled the same way, the sockets cut as 48-sided prisms whose flats touch the socket's circle; their reply adds representation, and triangles, volume and closed per body. One mesh and one exact piece are refused.
feature.draft kernel
Taper the named faces of one body about a neutral plane — the draft a moulded or cast part needs so it can leave its tool.
Detail
Taper the named faces of one body about a neutral plane — the draft a moulded or cast part needs so it can leave its tool. Each face carries its own angle, and that angle is the lean the face ENDS UP with rather than an amount added to the lean it already has - so drafting a wall twice at the same angle changes nothing, and a positive angle on a wall that already leans further will take material off. Positive tilts a face so the material grows along the neutral plane's normal and negative shrinks it, and the section where the neutral plane crosses a face keeps its size exactly (a face LYING in the neutral plane has no section to keep and is refused). The body keeps its ID, its name and its place in the tree — a draft edits the body it was given and creates nothing — and every face named must belong to that one body. The taper runs on along any face tangentially continuous with one you name, so a wall joined to its neighbour by a fillet leans the fillet too: draftedFaces in the reply says how many faces were actually leaned. A draft that leans nothing (draftedFaces 0) is a success that records nothing: featureId answers null, no step enters the timeline and no event is emitted, so a retry is quiet as well as safe.
feature.drain_hole kernel
Drill drain holes through the wall of a hollowed body into its sealed void, so resin or powder trapped inside can get out - the step a hollowed part needs before it is printed.
Detail
Drill drain holes through the wall of a hollowed body into its sealed void, so resin or powder trapped inside can get out - the step a hollowed part needs before it is printed. Name the body and, for each hole, a point on the part's OUTSIDE (a point within the hole's radius of the skin is put on the nearest face). Each hole runs along the skin's inward normal there, straight through the wall and half a millimetre into the void, never to the far wall: the wall is measured, so there is no depth to give. A hole must open into the void whole - if its rim would meet the edge of the void rather than open into it, it is refused by position, as is a point whose wall backs onto the outside rather than onto the void. A body with no sealed void is refused: hollow it first with feature.hollow. Holes are measured against the SEALED void, so they go in one call: a body an earlier drain hole already opened is refused naming that feature (undo it and send every hole together). A hollowed MESH body (a scan feature.hollow sealed) is drilled by the same rules; an open or inside-out one is refused naming feature.repair_mesh, and its reply adds representation, triangles, volume and closed. The reply gives each hole's opening, axis and the wall it crossed. One feature, one undo; the body keeps its ID.
feature.edge_flange kernel
Fold a wall off the named edges of a sheet-metal part - the sides of a box, the lip on a bracket.
Detail
Fold a wall off the named edges of a sheet-metal part - the sides of a box, the lip on a bracket. Name the edges with edges (query.edges lists one body's live edge IDs) and how far the flange stands with height, which by default is the FLAT length measured from where the bend ends - heightFrom measures it from the inside or the outside of the wall instead, which is what a drawing dimensions. angle is how far it turns, 90 by default. direction says which way: "up" is toward the side of the wall the edge you picked is on, so picking the top edge of a rim folds upward and picking the bottom edge folds down. The stock and the bend radius come from the BODY's sheet-metal rule - set one with feature.base_flange or doc.set_sheet_metal_rule - and bendRadius overrides it for these bends only; the thickness is never overridable, because one part is cut from one sheet. A flange spans the whole edge unless width says how much of it to span, in which case it is CENTRED on that edge - a tab or a lip rather than a side. A partial flange is NOTCHED at each end with the bend relief the body's rule names, and relief overrides that for these bends only. The bend is added beyond the wall's edge, so the wall itself is not shortened, and every edge named must belong to one body. Two edges that meet at a corner fold into an OPEN corner: the flanges touch along the corner and neither runs into the other.
feature.edit kernel
Change a feature's arguments and rebuild the part from its own recipe.
Detail
Change a feature's arguments and rebuild the part from its own recipe. Everything made after it is re-run against the new shape, so a hole drilled into an extrude moves with it. Send the arguments in full, as query.features reports them - the whole object, never a patch. Nothing changes unless the whole rebuild finishes: a change that breaks a later feature leaves the document exactly as it was and names what refused - the sentence leads with the record that refused ("ft:2 (feature.extrude) refused: ...") and details carries it as failedFeature and failedCommand, so "edit whatever the message names first" is a step, not a search.
feature.emboss kernel
Raise a picture off one face of a body, or sink it in — a logo on a lid, a name round a mug, a part number stamped into a bracket.
Detail
Raise a picture off one face of a body, or sink it in — a logo on a lid, a name round a mug, a part number stamped into a bracket. Draw the picture as closed sketch regions (text included) and name them with profiles; name the face with face; say how far with depth and which way with mode: "emboss" raises it away from the material and joins it on, "deboss" sinks it in and cuts it out. On a FLAT face the sketch's plane must be parallel to the face (the face itself is the usual choice) and the picture is moved straight onto it. On a CYLINDRICAL face — a boss, a pin, or the inside of a bore — the sketch's plane must be parallel to the axis (a plane tangent to the face is the usual choice) and the picture is WRAPPED round it: a width drawn across the axis becomes the same length of arc, a height along the axis stays a height, and the walls stand straight out from the axis. It is centred where the sketch faces the cylinder, may reach up to half a turn either way, and must lie wholly on the named face. The body keeps its ID, name and visibility.
feature.extend kernel
Grow a SHEET body past its boundary.
Detail
Grow a SHEET body past its boundary. Name FREE boundary edges in edges (an edge two faces share is interior and refused) and a distance; each edge is extended by its perpendicular strip - the surface swept from the edge along the sheet's own tangent, straight out. EXACT only: an edge whose perpendicular direction is constant (every edge of an extruded sheet), or a full circle on a flat face (the strip is a concentric band), extends cleanly; an edge with neither closed form is refused whole rather than approximated, because a guess written into the geometry could never be told from the real thing. A strip continuing its own face's surface merges into it seamlessly. The body keeps its ID and its faces keep theirs.
feature.extrude kernel
Sweep closed sketch regions into a solid, along the sketch plane's normal.
Detail
Sweep closed sketch regions into a solid, along the sketch plane's normal. Take the profile IDs from query.profiles. The extent is two ends: end is required and start defaults to the sketch plane itself, and each is decided by a signed distance, by a target to stop at, by the next body in the way, or by going through everything on that side. There is no flip flag — the sign is the direction, and so is the slot. A symmetric extrude of 10 mm is start -5 and end 5; a two-sided one is start -a and end b; one that begins 2 mm off the plane and runs 10 mm is start 2 and end 12; one that goes through everything both ways is through_all in both slots. Every profile must come from the same sketch, and a profile already carries its own holes, so do not name them. operation says what becomes of the swept solid: a body of its own, or joined to / cut from / intersected with the bodies it meets, which keep their IDs and names. A cut or intersect that leaves a body in disjoint pieces keeps its ID on the largest piece by volume and adds the rest as new bodies. thin sweeps only a wall along the profile's boundary rather than its whole area. surface: true sweeps a SURFACE instead of a solid (ADR 0301): the boundary's walls with no caps, answering a SHEET body — sheet: true on the reply and the tree row, and no volume to measure (feature.thicken gives a sheet its thickness and makes it a solid, ADR 0302). Its operand is profiles (one tube-like wall per boundary loop) or curves (an open or closed run of sketch curves from one sketch — a ribbon, or a tube when the run closes), exactly one of the two; both ends must be distances, and operation, thin and taper are refused beside it.
feature.extrude_cage kernel
Extrude faces of a SUBDIV (freeform) body's control cage - the first step of shaping one: the chosen faces move out by distance, and a wall of new cage faces grows from every edge around them, so the smooth surface bulges out into an arm, a leg, a spout.
Detail
Extrude faces of a SUBDIV (freeform) body's control cage - the first step of shaping one: the chosen faces move out by distance, and a wall of new cage faces grows from every edge around them, so the smooth surface bulges out into an arm, a leg, a spout. Faces that share an edge move together as one patch along that patch's own outward direction; faces that do not, each along their own. The extruded faces keep their ids (cf:<body>.<n>), so the same selection can be extruded again; the reply lists the new wall faces under walls. One step, one undo, a timeline feature. Refused, by name: a face that is not a cage face, faces of two bodies, a body that is not a subdiv body, a distance of 0, every face of a closed cage (that would only move the body), faces that point opposite ways, and faces that touch at a point by a corner alone.
feature.fillet kernel
Round the named edges of one body.
Detail
Round the named edges of one body. Each edge carries its own size, so a uniform round is one number repeated and a stepped one costs nothing extra. A round that VARIES along its edge is a stops law instead of a radius — at least two {position, radius} stops, positions running 0 to 1 along the contour — and each edge states exactly one of the two, though different edges in one call may state different ones. The body keeps its ID, its name and its place in the tree — a fillet edits the body it was given and creates nothing — and every edge named must belong to that one body.
feature.finger_joint kernel
Join two plates at a square corner with a finger joint (a box joint): the corner is cut into an odd number of equal fingers that interleave, the first plate taking the two end fingers and every second one between, the second plate keeping the rest - so the two press together like a laser-cut box and both outside faces show the fingers.
Detail
Join two plates at a square corner with a finger joint (a box joint): the corner is cut into an odd number of equal fingers that interleave, the first plate taking the two end fingers and every second one between, the second plate keeping the rest - so the two press together like a laser-cut box and both outside faces show the fingers. The plates are two exact solids where the first's END face lies against the second's SIDE (a butt corner, or a T); the shared face is found. Each finger the first plate gains is the second plate's own material, through its whole thickness, and the second plate's socket is the finger grown by clearance on every side. Give fingers (odd) or fingerWidth, or neither for fingers about twice the second plate's thickness. Nothing else is made. Refused, each with details.reason, when the plates share no flat face (noSharedFace), when the faces do not overlap (noOverlap), when the first's face on the plane is not smaller than the second's - the order is reversed, or the pieces are a plate cut straight across (notACorner), when the shared region is not a full rectangle (notRectangular), when the second plate is not one even thickness behind it (uneven, with at), when a finger would be narrower than 1 mm once the clearance is taken (tooFine, with step and needed), and when the sockets would cut the second plate in two (severs). One feature, one undo; both bodies keep their IDs. The reply gives the direction along the joint, the joint's corner (origin), its length, width and depth (the second plate's thickness), and the fingers and their width.
feature.fit kernel
State what round holes or pins are sized FOR - "this hole is a press fit for a 5 mm pin" - so the fit lives in the model rather than in somebody's head.
Detail
State what round holes or pins are sized FOR - "this hole is a press fit for a 5 mm pin" - so the fit lives in the model rather than in somebody's head. It is a timeline feature that changes no geometry: it records the intent, and query.design_check then judges each named round against it using the fit calibration you name, reporting the diameter the printer is predicted to make, the diameter the fit wants, and suggested - the diameter to DRAW so this machine prints it right. Nothing is ever changed for you: resize the hole yourself (feature.edit on the feature that made it). nominal is the MATING size (the 5 of a 5 mm pin), never read off the drawing, because the drawn size is what you will change to compensate a printer. Give the band as an ISO 286 class in designation ("H7" for a hole, "p6" for a pin; query.fits shows what one means) or as two plain deviations from nominal in lower and upper - an FDM press fit on a hole is typically a little below nominal, a slip fit a little above, and your own printer's numbers are the right ones. Every face must be a round (a cylindrical face that closes on itself) of one body, all holes or all pins - which side a round is on is read off the geometry, never sent. A round carries one fit; feature.edit changes it and feature.suppress switches it off.
feature.flexify kernel
Make a MESH body flexible: cut it along a spine into rigid segments joined by print-in-place ball joints, so a scanned dragon, fish, snake or tentacle prints as one part and moves when it comes off the bed.
Detail
Make a MESH body flexible: cut it along a spine into rigid segments joined by print-in-place ball joints, so a scanned dragon, fish, snake or tentacle prints as one part and moves when it comes off the bed. Joints are spaced pitch apart in a straight line along the spine (path), the first one pitch from its start - or, round a closed spine, evenly round the loop, so a bracelet scan becomes a ring of segments. At each joint the segment before it gets a ball on a neck and the segment after it a hollow socket that holds the ball, clearance all round - body.chain's ball joint, sized by ballDiameter and clearance - and the two are parted by a V-shaped gap that lets the joint turn bend degrees any way from the pose the body was cut in (15 by default, never more than the ball's swing). With joint "hinge" each joint is a knuckle and pin turning in a bored fork instead (sized by pinDiameter), the gap opens in one plane only, and the body bends in that plane - the plane a flat spine lies in. Every joint is checked before anything is cut: the body must have room round it for the socket (refused naming the joint, how much room there is and the largest ball that fits), joints that are not neighbours must not crowd each other (a spine that comes back near itself), and every segment must come out ONE piece - a cut that also passes through a leg or a fin away from the spine would leave it loose, and is refused naming the segment. The body keeps its ID, name, material and appearance and stays a mesh body holding every segment as a separate closed surface, so it exports as one file; one undo takes it back. An exact body is refused - turn it into a mesh with body.to_mesh first. Set preview true to see the plan without cutting.
feature.flip_normal kernel
Reverse which way a SHEET body's surface normals point.
Detail
Reverse which way a SHEET body's surface normals point. The geometry does not move and every face keeps its ID - what changes is what every side word downstream means: feature.thicken's and feature.offset's "front" become the old "back", and a mesh export's winding reverses. The viewport shades sheets from both sides, so the picture looks the same after a flip - that is correct, not a failure; the new feature in query.features is the proof it happened. A solid is refused: its outward normals are what makes it solid.
feature.hem kernel
Fold the edge of a sheet-metal part right back on itself - the safe edge on a panel, the stiffened lip on a tray, the return that hides a raw cut.
Detail
Fold the edge of a sheet-metal part right back on itself - the safe edge on a panel, the stiffened lip on a tray, the return that hides a raw cut. Name the edges with edges (query.edges lists one body's live edge IDs) and how far the return reaches with height, measured back over the wall from the sheet's own edge. A hem is a 180-degree fold, so there is no angle: for any other angle use feature.edge_flange. The GAP between the return and the wall is twice the bend radius, which comes from the BODY's sheet-metal rule - set one with feature.base_flange or doc.set_sheet_metal_rule - and bendRadius overrides it for these bends only, so a 0.5 mm radius is a 1 mm gap. direction says which face the return folds onto: "up" is toward the side of the wall the edge you picked is on. A hem spans the whole edge unless width says how much of it to span, in which case it is CENTRED on that edge, and a partial hem is NOTCHED at each end with the bend relief the body's rule names, which relief overrides. The bend is added beyond the wall's edge, so the wall itself is not shortened. To hem a hem - a double hem - send this command again naming the free edge of the first return.
feature.hole kernel
Drill holes — plain, counterbored or countersunk — at named sketch points, and cut them out of the bodies they meet.
Detail
Drill holes — plain, counterbored or countersunk — at named sketch points, and cut them out of the bodies they meet. The sketch those points belong to is the entry surface: its plane is the one datum every length is measured from and its normal is the axis, so depth's sign is the only direction there is. All the holes act as ONE tool, so a body only some of them reach is still cut by those. A hole only ever removes material, which is why there is no operation to choose.
feature.hollow kernel
Hollow one body out completely, leaving a wall of the given thickness and a sealed void with no way in.
Detail
Hollow one body out completely, leaving a wall of the given thickness and a sealed void with no way in. Nothing is opened: every face of the body keeps its wall. To hollow a body and open it at a face — a cup, a box with a lid off — use feature.shell, which is this command's other half. The body keeps its ID, its name and its place in the tree: a hollow edits the body it was given and creates nothing. A MESH body (a scan, a downloaded or generated model) is hollowed too, all three sides: the new surface is meshed from its distance to the body's triangles, edgeLength apart (half the wall when left out), an inward hollow keeps the outside exactly and leaves any part thinner than twice the wall solid, and a scan that is not closed is refused naming feature.repair_mesh. The void is sealed either way, so a resin or powder print still needs drain holes.
feature.insert_cage_loop kernel
Insert an EDGE LOOP into a SUBDIV (freeform) body's control cage: a new row of cage faces running ACROSS the named edge, so the smooth surface can be shaped there - extruded, creased, pulled - without disturbing it anywhere else, and a loop near an edge holds the surface tighter to it.
Detail
Insert an EDGE LOOP into a SUBDIV (freeform) body's control cage: a new row of cage faces running ACROSS the named edge, so the smooth surface can be shaped there - extruded, creased, pulled - without disturbing it anywhere else, and a loop near an edge holds the surface tighter to it. The loop crosses every four-sided face of the named edge's ring, cutting each in two; it runs all the way round when the ring closes (round a box's waist), and a face where the ring ends that is not four-sided (a sphere's pole triangle) takes the new point as one more corner. Every edge the loop crosses is split, and its id is RETIRED - never reused (the reply lists them under split); the new edges are numbered after every edge that already was, the loop's own listed under loopEdges. Every face keeps its id - the half of each cut face on the side of the named edge's first point keeps it, and the other half is added (under faces). A crease on a split edge stays on both halves. One step, one undo, a timeline feature. Refused, by name: an id that is not a cage edge, edges of two bodies, a body that is not a subdiv body, an edge the cage no longer has, an edge with no four-sided face on either side, a ring that would cross one face twice, and a cut that would leave a soft crease too deep to draw.
feature.jog kernel
Step a flat wall of a sheet-metal part sideways about a line drawn on it - the offset in a bracket, the lap in a panel, any place one part of a wall has to sit parallel to the rest and a fixed distance off it.
Detail
Step a flat wall of a sheet-metal part sideways about a line drawn on it - the offset in a bracket, the lap in a panel, any place one part of a wall has to sit parallel to the rest and a fixed distance off it. Name the wall with face and the line with line (a straight sketch curve lying over that face; query.sketch lists them), and height says how far the moving side steps. It is TWO bends: one turns the metal off the wall by angle, a flat run carries it across, and the second turns it back, so the moving side ends up parallel to the wall it came from. The line is the jog's CENTRE LINE and the flat it consumes straddles it. fixedSide says which side stays put - "left" or "right" of the line, looking at the face you picked from outside and walking the line from its start to its end - and direction says which way the step goes. The stock, the bend radius and the K-factor come from the BODY's sheet-metal rule; bendRadius and kFactor override them for this jog only. The metal the line runs through has to be a plain rectangle of that stock - a hole or another wall inside the strip is refused and says so.
feature.lattice kernel
Turn a MESH body into a decorative, printable strut lattice where it stands: a tube along every edge of its surface (pattern wireframe - triangular cells) or across every edge between the centres of the triangles on either side (pattern voronoi - a six-sided cell round every corner), joined at balls and united into one closed solid.
Detail
Turn a MESH body into a decorative, printable strut lattice where it stands: a tube along every edge of its surface (pattern wireframe - triangular cells) or across every edge between the centres of the triangles on either side (pattern voronoi - a six-sided cell round every corner), joined at balls and united into one closed solid. strutDiameter sets the tubes and nodeDiameter the balls (the struts' own diameter by default). cellSize remeshes the surface to even edges of that length first, so the cells are even and of a size you choose; left out, the surface's own triangles are the cells. An open surface is fine - its rim becomes a strut. Refused before anything is built: more than 10000 struts (naming the cellSize that fits), a node thinner than its struts, and struts so thick they close every cell (naming the cellSize that leaves openings). The body keeps its ID, name, material and appearance and stays a mesh body; one undo takes the lattice back. An exact body is refused - turn it into a mesh with body.to_mesh first. Set preview true to see the plan without building.
feature.living_hinge kernel
Join two pieces that share a flat face with a living hinge: the face is opened length wide (default 2 mm), taken from the second piece, everywhere but a thin web thickness thick (default 0.4 mm) along one edge of the face - so the two fold about that edge and stay ONE part, printed flat in one go.
Detail
Join two pieces that share a flat face with a living hinge: the face is opened length wide (default 2 mm), taken from the second piece, everywhere but a thin web thickness thick (default 0.4 mm) along one edge of the face - so the two fold about that edge and stay ONE part, printed flat in one go. The edge (edgeId) is a straight edge of either piece on the rim of the face they share, where both pieces end; the web runs its whole length, inside the face. The first piece keeps its shape and its ID and gains the second, whose ID retires (removedBodyIds). The reply reports the web's surface strain when folded flat, pi x thickness / (2 x length) (0.3 is 30%), as a number and never a verdict: polypropylene and PETG take a high one, PLA cracks - compare it with the material's. Refused, each with details.reason, when the pieces share no flat face (noSharedFace), when the edge is not on the shared face's rim (notOnRim), when the web would not lie wholly on both faces (offFace, with at), when the second piece is not deeper behind the face than length (runsOut, with depth) and when the opening would cut it in two (severs); a curved edge, or one of a third body, by name. One feature, one undo. The reply gives the hinge's axis (direction) and the web's run along it (from, to), the shared plane, and the strain.
feature.loft kernel
Make a solid that passes through two or more closed sketch regions in the order you name them — a boat hull, a transition duct, a blended handle.
Detail
Make a solid that passes through two or more closed sketch regions in the order you name them — a boat hull, a transition duct, a blended handle. Take each section ID from query.profiles. THE ORDER MATTERS and it is yours: the solid runs from the first section in the list to the last, which is why there is no flip flag, and the sections do not have to march along any one axis — a loft that doubles back on itself is spelled by naming the sections in the order it visits them. Unlike an extrude or a revolve, the sections may come from DIFFERENT sketches, which is the ordinary way a loft is drawn: one profile per plane. The first and last entries may be a POINT rather than a region — a body corner, a construction point or a sketch point — which runs the solid to a tip: a square and a point above it make a pyramid, and a point at each end of one section makes a spindle. centerline names a run of sketch curves — or of edges of one body you already have — that the material travels along, so the solid bends between its sections instead of running straight from one to the next — a swan-neck duct, a curved horn, a handle that sweeps round. guide names a second run beside it — a GUIDE RAIL — that says which way up the sections stay as they travel, so a duct can roll as it bends; it is only meaningful with a centerline. transition says whether the surface is one smooth run through every section or a straight taper between each consecutive pair. closed makes it a RING: the surface carries on from the last section back into the first and the solid has no end caps, which is how a torus-like duct or a handle is made — three sections at least, and never spelled by naming the first section twice. operation says what becomes of the lofted solid: a body of its own, or joined to / cut from / intersected with the bodies it meets, which keep their IDs and names. surface: true lofts a SURFACE instead of a solid (ADR 0301): the skin through the sections with no caps, answering a SHEET body — sheet: true on the reply and the tree row, and no volume to measure until feature.thicken gives it one. The sections, points, closed and transition read exactly as for a solid — a closed skin for a ring, a cone's skin to a tip — and operation and centerline are refused beside it.
feature.match_cage kernel
Match a run of a SUBDIV (freeform) body's open rim to a curve - so a freeform sheet or the edge of a hole meets an exact body's edge or follows a sketch: the named rim points move so that the smooth surface's edge passes through the target at every one of them, keeping the spacing they had along the rim, and the reply's deviation says how far the surface's edge strays from the target between them (more rim points - an edge loop across the rim - tighten it).
Detail
Match a run of a SUBDIV (freeform) body's open rim to a curve - so a freeform sheet or the edge of a hole meets an exact body's edge or follows a sketch: the named rim points move so that the smooth surface's edge passes through the target at every one of them, keeping the spacing they had along the rim, and the reply's deviation says how far the surface's edge strays from the target between them (more rim points - an edge loop across the rim - tighten it). Only the rim's points move, so the surface's slope where it meets the target is whatever its next row of points makes it. A whole rim loop matches a target that closes (a circular edge); a run with two ends matches one with two ends, end to end, whichever way round is nearer. When the body has a symmetry (feature.symmetry_cage) each matched point's partners off the rim follow it, listed under followed. One step, one undo, a timeline feature; every id is kept, and a match that moves nothing records nothing. Refused, by name: an id that is not a cage edge, edges of two bodies or that are not one run, an edge between two faces (only the open rim is matched), a soft crease meeting the rim, a target with a hard corner or no length, and an open run asked to follow a closed target or the reverse.
feature.mirror kernel
Reflect one body in a plane and do something with the image: keep it as a body of its own, or join it to / cut it from / intersect it with the bodies it meets.
Detail
Reflect one body in a plane and do something with the image: keep it as a body of its own, or join it to / cut it from / intersect it with the bodies it meets. The plane is a base plane, a planar face or a construction plane — the same three things a sketch can be drawn on — and the body being mirrored is never modified. There is no geometric refusal: a reflection is an isometry, so a plane straight through the body is fine (the halves swap) and so is the body's own plane of symmetry. A mesh body (a scan made a body) is mirrored too, into a new mesh body whose triangles still face outward; its join, cut and intersect are refused, because combining triangles needs mesh booleans.
feature.move kernel
Move bodies (bodies) or whole component placements (occurrences) where they stand, under one transform -- sliding them (type translate), turning them about an axis (type rotate), or resizing them uniformly (type scale, bodies only).
Detail
Move bodies (bodies) or whole component placements (occurrences) where they stand, under one transform -- sliding them (type translate), turning them about an axis (type rotate), or resizing them uniformly (type scale, bodies only). UNLIKE feature.pattern and feature.mirror nothing is copied and nothing is created: each body you name keeps its ID, its name, its visibility and every face and edge ID on it, and only where it sits changes. So a sketch drawn on one of its faces, a fillet on one of its edges and a construction plane built from it all still refer to the same things afterwards - and the sketch and the plane MOVE WITH the body, carried by the same motion, so a hole sketched on a face is still on that face after the part slides or turns. Every solid can be moved, because a rigid motion maps one exactly onto a solid of the same shape, and there is no geometric refusal at all -- bodies that end up overlapping each other are ordinary, because a move is not a boolean. A scale keeps every ID the same way -- a uniform resize maps each face, edge and vertex one to one -- and is the one motion here that changes size: every length multiplies by factor and the volume by its cube, with center the one point that stays put. The one non-geometric refusal is a body inside a GROUNDED component placement: grounding says a part is fixed in space, so free it with assembly.set_grounded first, or move the other parts around it instead. With occurrences a placement moves as a UNIT -- every body under it, nested sub-assemblies, jointed children and all -- which is how you position an assembly's parts relative to each other; a scale is refused there, because resizing one placement would make it a different SIZE from its siblings -- name its bodies in bodies if that divergence is what you want. To make a COPY somewhere else, use feature.pattern with count 2. A mesh body (a scan made a body with body.from_reference_mesh) moves, turns and resizes the same way: every one of its triangle corners goes through the same transform, it stays a mesh body with the same ID, and nothing is re-meshed.
feature.move_cage kernel
Move points of a SUBDIV (freeform) body's control cage - the way a freeform part is sculpted: the named cage points, edges and faces move under one transform and the smooth surface follows them, bulging where they go out and flattening where they come in.
Detail
Move points of a SUBDIV (freeform) body's control cage - the way a freeform part is sculpted: the named cage points, edges and faces move under one transform and the smooth surface follows them, bulging where they go out and flattening where they come in. translate slides them by delta, rotate turns them about axis by angle, scale moves them toward or away from center by factor (the same arguments feature.move takes for a whole body). Only positions change: every face, edge, crease and id stays as it was, so the same selection can be moved again. When the body has a symmetry (feature.symmetry_cage) every named point's partners move too - the mirror image of the move, or the move turned round the axis - listed under followed, and a point on the mirror plane or the axis stays on it. One step, one undo, a timeline feature; when no point would move (a rotation about an axis through them all, a scale about the one point named) nothing is recorded and moved is empty. Refused, by name: an id that is not a cage point, edge or face, elements of two bodies, a body that is not a subdiv body, a point, edge or face the cage no longer has, a zero or missing motion, and an argument that belongs to another type.
feature.offset kernel
Offset a surface into a NEW sheet body.
Detail
Offset a surface into a NEW sheet body. Name a SHEET body in body to offset its whole surface, or faces of ONE body in faces - a solid's faces work too, which is how a solid's skin becomes a surface to model with. The new sheet lands distance mm along the face normals (side "front", the default) or against them ("back"); the source body is never touched and the answer is always a sheet of its own - feature.thicken gives it material, feature.stitch joins it to other sheets.
feature.paste kernel
Paste bodies copied with query.copy into this document.
Detail
Paste bodies copied with query.copy into this document. Send the content that command answered, unchanged; the bytes are CoCAD's own exact geometry, so a pasted body is identical to the one it was copied from rather than a conversion of it. The bodies join the document you already have rather than replacing it, and arrive at the coordinates they were copied at, as ONE undoable step - move them afterwards with feature.move if you want them somewhere else. Send names to keep what each body was called; omit it and they are named for the body number they get - Paste12 for bd:12, exactly as the twelfth box would be Box12. The bytes are stored in the document, so saving and reopening does not need the document they came from.
feature.patch kernel
Fill a closed boundary with a NEW surface body (ADR 0301 - a sheet, one face).
Detail
Fill a closed boundary with a NEW surface body (ADR 0301 - a sheet, one face). The boundary is exactly one of edges - a sheet body's free boundary edges forming one closed loop, with continuity/continuities saying how the patch meets each edge's owning face (G0 touch, G1 tangent, G2 curvature) - or curves, a closed ring of one sketch's curves (G0 by construction). points and rails add interior constraints the surface passes through and contains. The answer is a new body of its own, born beside the boundary's owner; it is NOT sewn on - feature.stitch joins it when it should become part of the sheet, and a closed set then promotes to a solid.
feature.pattern kernel
Repeat one body (body) or one component placement (occurrence) under a rigid motion — in a line (type rectangular), about an axis (type circular), or along a run of curves (type path, spaced by arc length, each copy carried on the path's own frame or kept parallel with orientation fixed).
Detail
Repeat one body (body) or one component placement (occurrence) under a rigid motion — in a line (type rectangular), about an axis (type circular), or along a run of curves (type path, spaced by arc length, each copy carried on the path's own frame or kept parallel with orientation fixed). count includes the original, so count 4 makes three copies, and what is being patterned is never modified. With body, the copies can be kept as a body of their own or joined to / cut from / intersected with the bodies they meet, and they act as ONE tool, which is what makes a bolt circle of holes a single cut. With occurrence, each copy is another placement of the same component — so a parts list counts one part eight times rather than eight parts — and operation, targets and name do not apply. skipInstances leaves individual copies out without moving the ones that stay, so a row of holes can have a gap in it. There is no geometric refusal: a rigid motion is an isometry, so copies that overlap each other, or the original, are ordinary. A mesh body (a scan made a body) is patterned too, rectangular or circular, into one new mesh body holding the copies; its join, cut and intersect are refused, because combining triangles needs mesh booleans.
feature.press_pull kernel
Press or pull faces of a SOLID body - the direct edit also called offset face.
Detail
Press or pull faces of a SOLID body - the direct edit also called offset face. Name faces of ONE body in faces and a distance in mm; side "front" (the default) moves them along their own normals - a solid's normals point OUT, so front GROWS the body and "back" presses in, removing material. The neighbouring faces stretch or shrink along their own surfaces to stay joined; no new side wall is ever invented, and a press the neighbours cannot close is refused (to add material WITH walls, feature.extrude on the face's profile is the door). The body keeps its ID and name and the pressed faces keep theirs; a press that severs the body keeps every piece, the largest by volume keeping the ID.
feature.project_curve kernel
Project sketch curves straight through a SHEET body and IMPRINT where they land: the sheet's faces split along the projection and the curves become real, nameable edges of the body - the reply's edgeIds, exactly what feature.patch, feature.extend and a draft can then take.
Detail
Project sketch curves straight through a SHEET body and IMPRINT where they land: the sheet's faces split along the projection and the curves become real, nameable edges of the body - the reply's edgeIds, exactly what feature.patch, feature.extend and a draft can then take. The direction is the curves' own sketch plane normal, straight through both ways. The body keeps its ID and loses nothing - feature.trim is the remover. A projection that misses the sheet, or lands only along existing boundaries, is refused: an imprint that changes nothing does not journal. A solid is refused - sketch.project reads model edges INTO a sketch, and the solid split is a later feature on this vocabulary.
feature.rebend kernel
Fold back a bend that feature.unbend opened, so a slot or a hole cut across the flat is carried round the fold with it.
Detail
Fold back a bend that feature.unbend opened, so a slot or a hole cut across the flat is carried round the fold with it. Name the unbend step with feature - its ft: id, from query.features - and nothing else: the angle, the radius, the thickness, the K-factor and the wall that stayed put are all on that step already, and stating any of them again would be a second answer to a question it has answered. A slot that runs right across the flattened bend through the full thickness of the sheet is folded with the metal; a hole inside the bend, or a pocket that does not go through, is refused and says so, because this build carries a cut round a fold only where the cut goes all the way across it. An ft: that is not a feature.unbend, an unbend that is suppressed, and a bend that has already been folded back are each refused by name. Leaving a part unfolded is a perfectly good part; nothing insists you call this.
feature.remesh_mesh kernel
Even out a MESH body's triangles where it stands, keeping its shape - every edge near one length, the way a subdivision cage, a mesh boolean or a clean wireframe wants them.
Detail
Even out a MESH body's triangles where it stands, keeping its shape - every edge near one length, the way a subdivision cage, a mesh boolean or a clean wireframe wants them. Long edges are split, short ones collapsed and edges flipped until each corner has about six neighbours, then every free corner is slid along the surface and put back exactly ON the scan's original surface, so the part does not smooth or drift the way a plain averaging pass would. Every corner is on that surface, but a new triangle's face is a chord: where it spans a fold between the original triangles it cuts across it, so a faceted curve (a scanned or exported cylinder, say) loses a sliver of volume - half a percent on a 48-sided puck evened out at 2 mm. Creases (edges whose triangles meet at creaseAngle or more, 45 degrees by default) are kept exactly. Corners on an open edge or on an edge a repair would call faulty are never moved, so a hole keeps its rim and a fault is left for feature.repair_mesh; nothing is done that would fold the surface or change whether it closes, so a closed scan stays closed. The target length is edgeLength, or the body's own mean edge length when left out, and the reply gives it with the shortest, mean and longest edge before and after. The body keeps its ID, name, material and appearance, and one undo takes the remesh back. If nothing changed the reply says changed false and NOTHING is recorded. An exact body is refused.
feature.reorder kernel
Move a feature earlier or later in the timeline and rebuild the part from its own recipe.
Detail
Move a feature earlier or later in the timeline and rebuild the part from its own recipe. Everything is re-run in the new order, so moving a fillet above the extrude whose edge it rounds is refused and the document does not move. The feature keeps its ft: id and its arguments, and so does every other feature - a reorder renumbers nothing.
feature.repair_mesh kernel
Repair a MESH body's triangles where it stands - the step that makes a real scan printable.
Detail
Repair a MESH body's triangles where it stands - the step that makes a real scan printable. It removes slivers (triangles with two corners in one place) and repeated triangles, turns facets that disagree with their neighbours so the whole surface is wound one way, turns a surface that closes so it faces OUTWARD, and fills holes whose rim is a simple loop with a fan of triangles. Corners at exactly the same coordinates become one corner; nothing is moved, smoothed, decimated or re-meshed. The body keeps its ID, name, material and appearance, and one undo takes the repair back. If nothing needed repairing the reply says changed false and NOTHING is recorded - no timeline step - so it is safe to call on every scan. The reply counts each fix, says how many openings were left and how many edges carry three or more triangles (which no repair here splits), and whether the result now closes up into a solid. An exact body is refused.
feature.require kernel
State a requirement the part must keep meeting - "an M3 passes through this hole", "every wall at least 1.6 mm", "the lid clears the base by 0.5 mm", "fits a 256 mm bed" - as a check CoCAD re-runs against the current model whenever query.requirements is read.
Detail
State a requirement the part must keep meeting - "an M3 passes through this hole", "every wall at least 1.6 mm", "the lid clears the base by 0.5 mm", "fits a 256 mm bed" - as a check CoCAD re-runs against the current model whenever query.requirements is read. It is a timeline feature that changes no geometry: statement is the sentence, and quantity, entities and atLeast/atMost are the check you compiled it into. Six quantities, each measured by the read you would call yourself: diameter of a round (query.measure; "an M3 passes through" is atLeast 3.2, or whatever clearance your shop uses), distance between two things (query.measure's between; "clears by 0.5" is atLeast 0.5), wallThickness of a body (query.wall_thickness), size along an axis (query.build_fit's extent; "fits a 256 mm bed" is two requirements, x and y, atMost 256), volume and mass (query.mass_properties). The reply is the requirement's first check - status pass, fail or unmeasured, the measured number and the read that produced it - so you see at once whether the part already meets it. A requirement may be stated before the part meets it, or before it can be measured at all (a mass before doc.set_material): it is recorded and reported unmeasured with the reason. What is refused is a malformed check and anything the read itself refuses, such as a body that does not exist. Nothing ever refuses because a requirement fails. feature.edit changes one; feature.suppress switches it off.
feature.revolve kernel
Turn a closed sketch region about an axis into a solid.
Detail
Turn a closed sketch region about an axis into a solid. Take the profile ID from query.profiles, and name the axis as a line in the same sketch — an ordinary line, a construction line or a centerline — or as a construction axis (construct.axis), or as a straight edge of a body (query.edges); the last two must lie in the profile's own plane. The whole infinite line is the axis, not just the drawn segment, and the profile must not cross it, though touching it is how a sphere or a cone is made. The extent is two signed angles in degrees: end is required and start defaults to where the profile was drawn, and the sign is the direction, so there is no flip flag. A full turn is start 0 and end 360 and has no end caps at all. operation says what becomes of the turned solid: a body of its own, or joined to / cut from / intersected with the bodies it meets, which keep their IDs and names. thin turns only a wall along the profile's boundary rather than its whole area — a vessel, a tube, a funnel or a lampshade. surface: true turns a SURFACE instead of a solid (ADR 0301): the boundary's swept walls with no caps, answering a SHEET body — sheet: true on the reply and the tree row, and no volume to measure until feature.thicken gives it one. Its operand is profiles (one skin per boundary loop) or curves (an open or closed run of sketch curves from one sketch — a swept band, or a closed skin when the run closes), exactly one of the two; the axis and the angles read exactly as for a solid, and operation and thin are refused beside it.
feature.rib kernel
Stand a thin wall up along an OPEN run of sketch curves until it meets the part it stiffens — a rib inside a moulded housing, a web under a boss.
Detail
Stand a thin wall up along an OPEN run of sketch curves until it meets the part it stiffens — a rib inside a moulded housing, a web under a boss. Name the run with spine (sketch curves from ONE sketch, query.sketch lists them) and how thick the wall is with thickness; the material sits half either side of the curves you drew. The order you name them in does not matter — they are joined end to end by where they actually meet — and a run that branches, has a gap in it, or closes into a loop is refused. There is no depth to give: the rib grows both ways along the sketch plane's normal and stops at the first material it meets each way, and an end that meets nothing stays flat on the plane you drew on. It always joins what it meets, which keeps that body's ID, name and visibility; targets narrows which bodies it may join and which it looks at for its stopping point.
feature.rip kernel
Cut a narrow slit along the named edges of a body, so two walls that are joined along them come apart - the corners of an imported enclosure that somebody else's software modelled closed, which is what stops it developing into one flat blank.
Detail
Cut a narrow slit along the named edges of a body, so two walls that are joined along them come apart - the corners of an imported enclosure that somebody else's software modelled closed, which is what stops it developing into one flat blank. Name the edges with edges (query.edges lists one body's live edge IDs) and how wide the slit is with gap, in millimetres. gap is required and has no default: it is a cut, so a width of nothing would be a split rather than a rip, and it deliberately does NOT come from the body's sheet-metal rule because a body being ripped usually has no rule yet - that is the point. This does not require the body to be sheet metal and it does not make it so; ripping is just a cut, and a body becomes sheet metal when doc.set_sheet_metal_rule gives it one, before or after, in either order. A rip that does not part the body is not an error - a box may need three corners opened and the first two are progress - so check query.flat_pattern's pieces to see whether the part lays out as one blank yet. Only a rip that would take away all the metal is refused. Each edge must be straight.
feature.sculpt_mesh kernel
Sculpt a MESH body with one brush stroke, where it stands - grab, smooth, inflate or crease, the way a sculpting tool's brush works, as one journaled step a person and an AI make alike.
Detail
Sculpt a MESH body with one brush stroke, where it stands - grab, smooth, inflate or crease, the way a sculpting tool's brush works, as one journaled step a person and an AI make alike. The stroke is a path (points, in order) with a ball of radius rolled along it: every corner within radius of the path is moved, most at the path and smoothly less to none at the radius. inflate pushes the surface out along its normal by up to strength x radius; crease pushes it in along the path by up to the same and pinches it into a sharp groove; grab moves the surface under the path's START by its end less its start (times strength, 1 when left out), so it follows the drag; smooth pulls each corner toward its neighbours' middle, 10 x strength passes, keeping an open rim where it is. Corners in one place move together and no triangle changes, so a closed scan stays closed; a stroke deep enough to fold the surface through itself is not refused - the reply says whether the body still closes and its volume. The body keeps its ID, name, material and appearance; one undo takes the stroke back. Refused: an exact body (turn it into a mesh with body.to_mesh first), a grab with one point, a stroke that never comes within radius of the surface, and a brush that reaches fewer than four corners (remesh finer with feature.remesh_mesh first - the refusal names the edge length). If the stroke moved nothing the reply says changed false and NOTHING is recorded.
feature.set_intent
Say WHY a feature is here, in plain language - "this fillet clears the bearing", "3 mm so it prints without supports".
Detail
Say WHY a feature is here, in plain language - "this fillet clears the bearing", "3 mm so it prints without supports". The note sits beside the feature in the timeline and is an input to nothing: it changes no geometry, no rebuild and no dimension, which is what lets it be a sentence rather than a number. It is dated and attributed automatically, so a note an AI wrote can be told from one a person wrote. entities are the ids the sentence is about - the face it clears, the parameter it comes from - and they must exist when the note is written; query.features later reports each one as still alive or not, so a note whose subject was removed can be spotted instead of quietly misleading the next reader. Send intent as null to clear the note - required either way, so a forgotten field never erases something silently. Read them back on query.features. Saved with the file, and undoable in one step. Not a timeline feature itself: writing down a reason is not modelling.
feature.set_rollback kernel
Roll the model back to a point in its timeline, or forward again - the timeline's rollback marker.
Detail
Roll the model back to a point in its timeline, or forward again - the timeline's rollback marker. The part is rebuilt up to and including the feature named, and every feature after it stays in the recipe, keeps its ft: id and builds nothing until it is rolled forward: query.features lists them with rolledBack: true and says where the marker is in rollback. A feature made while rolled back is inserted at the marker. The position is saved with the document and moving it is one undoable step. Rolling forward re-runs what it brings back, and a feature that now refuses leaves the document where it was and names the feature.
feature.shell kernel
Hollow one body out to a wall of the given thickness, opening it at the named faces.
Detail
Hollow one body out to a wall of the given thickness, opening it at the named faces. The faces you name are the ones OPENED — each becomes the mouth, and what is left of it, the rim ring, keeps its face ID unless the wall is a middle one — and every other face of the body acquires the wall. The body keeps its ID, its name and its place in the tree: a shell edits the body it was given and creates nothing. One face can keep a wall of its own thickness — a box open at the top with 1 mm walls and a 3 mm floor is one wallThicknesses entry. If the body is in several separate pieces — which is what a pattern of a solid makes — the faces you name decide which pieces are shelled, and any piece you named no face of is left exactly as it was; the reply's piecesLeftSolid says how many that was, and it is 0 for an ordinary connected body.
feature.snap_fit kernel
Grow a cantilever snap-fit from a flat face: a beam length long standing square to the face, thickness thick the way it bends and width wide, with a hook at its tip that stands hook proud of the beam - a lead-in ramp at insertAngle from the beam's axis (default 30) and a retaining face at retainAngle (default 90, a permanent catch).
Detail
Grow a cantilever snap-fit from a flat face: a beam length long standing square to the face, thickness thick the way it bends and width wide, with a hook at its tip that stands hook proud of the beam - a lead-in ramp at insertAngle from the beam's axis (default 30) and a retaining face at retainAngle (default 90, a permanent catch). The beam is joined to the face's body, at the face's centre unless at says where, its hook pointing across the face's long axis unless direction says which way. With catchBodyId - the mating part, placed where it sits when snapped in - the window the hook catches in is cut through it where the hook is, clearance bigger than the hook on every side. The reply reports the beam's strain when it bends the hook's depth to go in, 1.5 x thickness x hook / length^2 (0.02 is 2%), as a number and never a verdict: compare it with the material's allowable strain - a beam that strains too much is not refused. Refused, each with details.reason, when the beam's footprint is not wholly on the face (offFace, with at), when the hook leaves no beam to bend (tooShort, with needed - the length the beam must exceed), when the window would not reach the catch body (missesCatch) and when it would cut the catch body in two (severs); and a face that is not flat, or a direction square to it, by name. One feature, one undo; both bodies keep their IDs. The reply gives the beam's root (origin, the middle of its footprint), the face's normal, the hook's direction, where the retaining face meets the beam (catchAt, from the root) and the strain.
feature.split kernel
Divide a SOLID body into separate bodies along a cutting tool, keeping every piece.
Detail
Divide a SOLID body into separate bodies along a cutting tool, keeping every piece. Name the body in body and a cutting tool as exactly ONE of plane/face/constructionPlane (an unbounded plane), tool (a sheet body - bounded), or profile (a sketch region extended perpendicular to its sketch into a fence). The largest piece by volume keeps the ID and name; the rest become new bodies in the same step. The tool is never consumed, and a tool that does not pass clean through is refused - a split that leaves one piece would change nothing. To remove solid material instead, use feature.combine with "cut"; to cut pieces off a sheet, feature.trim. A mesh body (a scan made with body.from_reference_mesh) is split by a plane only - plane, face or constructionPlane - provided it closes up into a solid (feature.repair_mesh first if not); every piece stays a mesh body, capped flat where the plane passed.
feature.split_face kernel
Divide the named faces of a SOLID body along a cutting tool, without cutting the body itself - the direct edit that draws a real, nameable boundary onto a face.
Detail
Divide the named faces of a SOLID body along a cutting tool, without cutting the body itself - the direct edit that draws a real, nameable boundary onto a face. Name faces of ONE body in faces and a cutting tool as exactly ONE of plane/face/constructionPlane (an unbounded plane), tool (a sheet body - bounded), or profile (a sketch region extended perpendicular to its sketch into a fence). Each named face is replaced by its pieces and EVERY piece is kept - there is nothing to remove here; the body keeps its ID, its name and its shape, and the new edges come back in edgeIds ready for a fillet, a draft or a press-pull on one piece alone. The tool is never consumed. A tool that crosses none of the named faces is refused - an imprint that changes nothing does not journal. To divide the BODY into separate bodies, use feature.split; to imprint a sketch onto a sheet, feature.project_curve.
feature.stitch kernel
Sew two or more SHEET bodies (ADR 0301 - surfaces with no enclosed material) into ONE body.
Detail
Sew two or more SHEET bodies (ADR 0301 - surfaces with no enclosed material) into ONE body. The FIRST body named survives with its ID and name; the rest are consumed and named in removedBodyIds. Gaps up to tolerance are closed. A result that closes into a shell with no free boundary is promoted to a SOLID automatically - the sheet flag simply disappears, exactly as feature.thicken's does - unless surface: true keeps it a sheet. A stitch that would leave separate shells is refused whole rather than consuming bodies it could not attach. Solids are refused: feature.combine is where solids join, and feature.unstitch is the inverse door.
feature.subdivide_cage kernel
Subdivide a SUBDIV (freeform) body's whole control cage once: every face is split into four-sided faces (a quad into four, an n-sided face into n) and every point moves to where the finer cage needs it, so the smooth surface stays EXACTLY the same shape and there are about four times as many cage points, edges and faces to shape with feature.move_cage, feature.extrude_cage and the rest.
Detail
Subdivide a SUBDIV (freeform) body's whole control cage once: every face is split into four-sided faces (a quad into four, an n-sided face into n) and every point moves to where the finer cage needs it, so the smooth surface stays EXACTLY the same shape and there are about four times as many cage points, edges and faces to shape with feature.move_cage, feature.extrude_cage and the rest. Every point keeps its id (cx:), and every face keeps its id for the piece at its first corner - the other pieces are new faces, listed under faces; every edge is split, so every old edge id (ce:) is RETIRED and never reused. A crease stays a crease (a soft one loses a level, which is what keeps the surface the same). One step, one undo, a timeline feature. Refused, by name: an id that is not a body, a body that is not a subdiv body, and a cage that would have more than 62500 faces.
feature.suppress kernel
Take a feature out of the part without deleting it, or put it back.
Detail
Take a feature out of the part without deleting it, or put it back. Everything made after it is re-run without it, so a fillet on a face a suppressed extrude created is refused and the document does not move. The feature keeps its ft: id and its arguments either way, and a suppression survives saving and reopening. Sets rather than toggles: send suppressed explicitly.
feature.suppressed kernel
The recipe's record of a feature that has been suppressed: it takes a place in the timeline, keeps its ft: id, and builds nothing.
Detail
The recipe's record of a feature that has been suppressed: it takes a place in the timeline, keeps its ft: id, and builds nothing. This is what feature.suppress leaves behind in the document's own operation log, and it is on the wire because reopening a document replays that log. To suppress or unsuppress a feature, send feature.suppress - not this: sent by a live client it is refused with INVALID_ARGUMENT.
feature.sweep kernel
Carry a closed sketch region along a path to make a solid — a pipe, a moulding, a rail.
Detail
Carry a closed sketch region along a path to make a solid — a pipe, a moulding, a rail. Take the profile ID from query.profiles, and name the path either as sketch curves it runs along (query.sketch) or as edges of one body (query.edges), which is how a path that leaves a plane is named. The order you name them in does not matter: they are joined end to end by where they actually meet, and a path that branches or has a gap in it is refused. The path may close on itself, which makes a ring and gives it no end caps. The profile is swept from where it was drawn and is never moved onto the path, so one end of the path has to start on the plane the profile is drawn on — that end is the start, so there is no flip flag. orientation says whether the section stays square to the path or stays parallel to the profile as drawn, twist rolls it as it travels, and guide names a second run of curves for the section to turn and follow. operation says what becomes of the swept solid: a body of its own, or joined to / cut from / intersected with the bodies it meets, which keep their IDs and names. surface: true sweeps a SURFACE instead of a solid (ADR 0301): the profile boundary's swept skin with no caps, answering a SHEET body — sheet: true on the reply and the tree row, no volume to measure until feature.thicken gives it one, and one skin per boundary loop (a hole's loop sweeps as its own tube rather than being cut). The path, guide, twist and orientation read exactly as for a solid, and operation is refused beside it.
feature.symmetry_cage kernel
Give a SUBDIV (freeform) body's control cage a SYMMETRY that its point moves keep, so one side is shaped and the other follows: a MIRROR across a plane (a bottle, a car body, a face) or a CIRCULAR symmetry of count copies round an axis (a knob, a rosette).
Detail
Give a SUBDIV (freeform) body's control cage a SYMMETRY that its point moves keep, so one side is shaped and the other follows: a MIRROR across a plane (a bottle, a car body, a face) or a CIRCULAR symmetry of count copies round an axis (a knob, a rosette). From then on feature.move_cage moves every named point's partners too - the mirror image of the move, or the move turned round the axis - and keeps a point on the plane or the axis on it. The partners are found on every move, not stored: a point lands on a partner when the symmetry sends it within a millionth of the cage's size of one, so a later extrusion on one side simply has no partners until the other side has its twin (query.cage's symmetry lists the points that have none). Every other cage edit keeps the symmetry. type none removes it. One step, one undo, a timeline feature; asking for the symmetry the cage already has records nothing. Refused, by name: a body that is not a subdiv body, a plane or axis with no direction, an argument that belongs to the other type, and a symmetry under which no point of the cage has a partner (the cage is not symmetric there).
feature.texture_mesh kernel
Press a surface texture into a MESH body, where it stands - a knurl, ribs, scales, leather grain or a picture - by moving every corner of its surface along its own normal by the pattern's height there.
Detail
Press a surface texture into a MESH body, where it stands - a knurl, ribs, scales, leather grain or a picture - by moving every corner of its surface along its own normal by the pattern's height there. size is one repeat of the pattern and depth its full height; mode raise stands the texture on the surface (material added) and mode cut sinks it in so the surface is the texture's top (material taken away, the part keeps its size). mapping box (the default) lays the pattern on any shape from the side each part of it faces; cylinder wraps it round an axis with a whole number of repeats so it closes with no seam; plane projects it along an axis. region limits it to a box. A texture needs triangles finer than itself - on average at most a quarter of size - so give edgeLength to even the surface out first in the same step (an eighth of size is a good choice); without it a coarse surface is refused, naming the length that works. Corners in one place move together, so a closed body stays closed unless the texture folds it through itself, which is not refused - the reply says whether it still closes and its volume. The body keeps its ID, name, material and appearance; one undo takes the texture back. Refused: an exact body (turn it into a mesh with body.to_mesh first), an axis missing for cylinder or plane or given for box, a canvas missing for the image pattern or given for another, a region holding none of the body, and a surface too coarse. preview: true works it all out and changes nothing. If nothing moved the reply says changed false and NOTHING is recorded.
feature.thicken kernel
Give a SHEET body - a surface with no enclosed material (ADR 0301) - a wall's worth of thickness, and it becomes a SOLID: same ID, same name, same place in the tree, the sheet flag simply gone, and volume, mass properties and the combine all reachable again.
Detail
Give a SHEET body - a surface with no enclosed material (ADR 0301) - a wall's worth of thickness, and it becomes a SOLID: same ID, same name, same place in the tree, the sheet flag simply gone, and volume, mass properties and the combine all reachable again. The sheet's own faces keep their IDs. This is the inverse door to feature.shell and feature.hollow, which start from solids; thicken starts from a sheet - a surface extrude's ribbon or tube, or an imported open shell - and a solid body is refused.
feature.thread kernel
Thread the named cylindrical faces of one body — the screw thread a bolt boss or a tapped hole carries.
Detail
Thread the named cylindrical faces of one body — the screw thread a bolt boss or a tapped hole carries. The form is ISO 68-1's 60-degree V, derived entirely from pitch, and it is cut AT the named face's own radius: THE FACE IS THE CREST, so there is no diameter argument anywhere — an external thread's major diameter is the boss's own diameter, an internal thread's minor diameter is the hole's own drilled size, and which side the thread is on is derived from the face itself (a boss threads external, a hole wall internal; there is no flip). A hole drilled at a standard's tapDrill (query.hole_standards) and threaded at the same row's pitch is that standard's internal thread with no number retyped. By default the thread is COSMETIC: the document records the feature — it appears in the timeline and will appear in drawings — and the 3D view, exports and mass properties keep the plain cylinder, which is what machined-part CAD wants and what keeps eight threaded holes from costing a mesher's bill. Send modeled true to cut the real helical grooves so STL/3MF/OBJ exports carry them — what a printed part needs — and expect a modeled thread to be the most expensive geometry in the document per feature. feature.edit flips modeled either way later.
feature.trim kernel
Cut away pieces of a SHEET body (ADR 0301 - a surface with no enclosed material).
Detail
Cut away pieces of a SHEET body (ADR 0301 - a surface with no enclosed material). Name the sheet in body, a cutting tool as exactly ONE of plane/face/constructionPlane (an unbounded plane), tool (a sheet body - bounded), or profile (a sketch region extended perpendicular to its sketch into a fence), and at least one remove point - the piece nearest each point is removed, exactly as sketch.trim's at works one dimension down. What remains stays one body where connected; a remainder in separate pieces keeps the ID and name on the largest piece by area and the rest become new bodies. The tool is never consumed. A tool that does not divide the sheet clean through is refused - a partial score removes nothing.
feature.unbend kernel
Straighten one bend of a sheet-metal part, so a slot or a hole can be cut across it and the fold put back with feature.rebend.
Detail
Straighten one bend of a sheet-metal part, so a slot or a hole can be cut across it and the fold put back with feature.rebend. Name the bend with bend - either of its cylindrical faces, innerFace or outerFace from query.bends, and it does not matter which - and the wall that STAYS PUT with face, one of that bend's own walls, also from query.bends. face is required and has no default: unbending turns one side of the fold rigidly, so which side holds still decides where the part ends up, and the two walls give two different parts. There is no angle, no direction and no radius to state: the metal already has them and this reads them off it, so the flat this puts back is exactly as long as the arc it takes away - angle in radians times (radius + kFactor x thickness). kFactor overrides the body's sheet-metal rule for this one unbend, and it is the only number here that can be overridden because it is the only one nobody can measure. Afterwards query.bends reports one fewer bend, because the metal has one fewer bend in it. A bend whose two walls are also joined somewhere else - a closed box, a corner a later feature bridged - is refused and says so, because opening it would tear metal you cannot see. Leaving a part unfolded is a perfectly good part; nothing insists you fold it back.
feature.unstitch kernel
Take a body apart into one SHEET body per face - the inverse of feature.stitch.
Detail
Take a body apart into one SHEET body per face - the inverse of feature.stitch. Works on sheet bodies and solids alike; a solid becomes its boundary faces, each a sheet body of its own. The face with the largest area keeps the body's ID and name, and the rest are new bodies named for it. Stitching the pieces back together restores the body - a closed set promotes back to a solid. A body that is already a single face is refused.
feature.untrim kernel
Remove the interior boundaries (holes) of a SHEET body's faces.
Detail
Remove the interior boundaries (holes) of a SHEET body's faces. Name the body and, optionally, which of its faces in faces - left out, every face that has an interior loop is untrimmed. Each untrimmed face keeps its ID; the holes' edges retire. A loop another face of the body fills (an imprinted seam) is not a hole and is kept. The OUTER boundary is never touched - only loops inside a face are removable, because an outer boundary's natural extension is unbounded for a flat face and this build refuses to invent a bound. A face with no interior loop, named, is refused by name; a body with none anywhere is refused whole. Solids are refused - a solid's holes belong to the features that cut them.
Solid primitives
Bodies created directly, without a sketch.
body.box kernel
Create a rectangular box body.
Detail
Create a rectangular box body. Dimensions in millimetres along X, Y and Z.
body.chain kernel
Make a print-in-place chain of ball-and-socket links along a path - a flexi chain, snake or tail that prints as one part and moves when it comes off the bed.
Detail
Make a print-in-place chain of ball-and-socket links along a path - a flexi chain, snake or tail that prints as one part and moves when it comes off the bed. The links are spaced pitch apart in a straight line along the path (each link is rigid, so it spans a chord) and each one is a hollow socket with a neck running to a ball that sits inside the next link's socket, clearance all round. Every size of a link follows from ballDiameter and clearance, and the reply states them. A joint can bend only so far before the neck meets the socket's rim (swing, in degrees, in the reply): a path that bends more than that between two links is REFUSED and says where - use a gentler curve, a shorter pitch, or a smaller clearance. Two links that are not neighbours but come close enough to print fused (a tight spiral, a path that crosses itself) are refused too, naming both. The answer is ONE body holding every link as a separate solid, so it exports as one file; the links touch nothing. The path does not have to be used up: the chain stops at the last whole link and leftover says how much path was not reached. A CLOSED path makes a ring (closed: true in the reply): the pitch is adjusted to the nearest one that divides the ring into whole links - never below minPitch - so the last ball sits in the first socket, and the reply's pitch is the adjusted one beside requestedPitch. With joint hinge each link is instead a centre knuckle with a pin through it at one end and a bored fork at the other, so the chain bends in one plane (a band or a tread): a path that leaves its plane is refused naming the first link that does. A ball chain's neck can be your own section - profile, a closed region of a sketch - in place of the round one. Set preview true to see the plan without building anything.
body.composite_curve kernel
Join sketch curves and body edges into one WIRE body: a single chain of curves with no faces and no material, which is what a sweep, a loft's centerline or a pattern follows.
Detail
Join sketch curves and body edges into one WIRE body: a single chain of curves with no faces and no material, which is what a sweep, a loft's centerline or a pattern follows. This is the only place the two kinds may be MIXED - a sweep's own path is all sketch curves of one sketch or all edges of one body, and this command's answer is one run in one identity world, so a path that starts on a drawing and carries on along a part is named here first. The curves may come from any number of sketches and any number of bodies, in any mixture, and a helix counts. THE ORDER YOU NAME THEM IN DOES NOT MATTER: they are chained by where their ends actually meet, and a run that branches, has a gap in it, or names the same curve twice is refused and says which. A single circle, ellipse, closed spline or closed edge is a whole chain on its own and makes a ring. The answer is a COPY - it does not move when the curves it was made from move, and deleting them does not delete it. A wire body has no volume, no mass and no mesh: query.edges draws it, query.measure answers its length, and the commands that need material or faces refuse it by name. The reply's edgeIds are what to name as a path.
body.cylinder kernel
Create a cylinder body, axis along +Z from its origin.
Detail
Create a cylinder body, axis along +Z from its origin.
body.derive kernel
Derive bodies from another CoCAD document - the file's own recipe is replayed and the bodies it builds arrive HERE as plain bodies in the Bodies folder, under one timeline feature, so you can cut, fillet, shell, combine or pattern them like any body: a mould from a part, a cover from a board, a fixture from an assembly.
Detail
Derive bodies from another CoCAD document - the file's own recipe is replayed and the bodies it builds arrive HERE as plain bodies in the Bodies folder, under one timeline feature, so you can cut, fillet, shell, combine or pattern them like any body: a mould from a part, a cover from a board, a fixture from an assembly. Nothing becomes a component or a placement - if the file is an assembly, its parts arrive flat, at the coordinates they stand at there, and the reply's flattened says how many placements that was. bodies names which of the source's bodies to take, by the names its tree shows; leave it out for every body, and read the reply's sourceBodies to see what it holds. at takes the source as its timeline stood just after one of its features, ft:N - the part before the later features were added - instead of as it ends. By default the geometry is EMBEDDED - this document keeps its own copy of the source and opens anywhere. Send link if you want this document to follow the source: it is then re-read from its path every time this document opens or rebuilds, query.links reports it, assembly.relink repoints it when the file moves, and doc.pack carries it; to read a linked file again NOW, without reopening, send assembly.relink with from and to both its path. Use assembly.insert_component instead when the file should stay a PART with an identity of its own - a parts-list row, joints, further placements.
body.field kernel
Create a FIELD body - a smooth, organic body defined by a list of shapes and the operations that combine them, like a short program: each node is a shape (sphere, box, capsule, cylinder, torus, halfSpace, skeleton) or an operation on EARLIER nodes named by their position in the list, counted from 0 (union, intersect, subtract - each with an optional blend that rounds the seam where the inputs meet into a smooth fillet of that radius - offset, which grows or shrinks a node's surface by a distance, and shell, which hollows a node INWARD leaving a wall of that thickness).
Detail
Create a FIELD body - a smooth, organic body defined by a list of shapes and the operations that combine them, like a short program: each node is a shape (sphere, box, capsule, cylinder, torus, halfSpace, skeleton) or an operation on EARLIER nodes named by their position in the list, counted from 0 (union, intersect, subtract - each with an optional blend that rounds the seam where the inputs meet into a smooth fillet of that radius - offset, which grows or shrinks a node's surface by a distance, and shell, which hollows a node INWARD leaving a wall of that thickness). The LAST node is the body, and every other node must be used by a later one. Example - two balls joined by a smooth neck: [{"type":"sphere","center":{"x":0,"y":0,"z":10},"radius":10}, {"type":"sphere","center":{"x":16,"y":0,"z":10},"radius":8}, {"type":"union","of":[0,1],"blend":6}]. A capsule from start to end with a different endRadius is a tapered limb; a halfSpace (point, normal facing OUT of the material) cut off by an intersect makes a flat face. A gyroid (cellSize, thickness) is an INFILL - a smooth wall of that thickness, at most a quarter of the cell, winding through all of space - so intersect it with a shape to fill that shape; an endThickness with start and end grades the wall in a straight line between them, denser where it is thicker. Example - a box with a 2 mm skin and a gyroid inside: [{"type":"box","center":{"x":0,"y":0,"z":10},"size":{"x":40,"y":40,"z":20}}, {"type":"shell","of":[0],"thickness":2}, {"type":"gyroid","cellSize":10,"thickness":1}, {"type":"intersect","of":[0,2]}, {"type":"union","of":[1,3]}]. A cubicLattice, bccLattice or octetLattice (cellSize, radius) is a STRUT lattice, an infill the same way - round struts along every cell edge, from every corner to the cell's centre, or along every face diagonal (the octet truss, the stiffest of the three for its weight) - and an endRadius with start and end grades the struts exactly as a gyroid's wall. A skeleton (points, each {x, y, z, radius}) is a smooth SKIN over a curve through its points, as thick as each point's radius and tapering smoothly between them - a limb, a horn, a handle, a branch; union several with a blend for an organic part. Example - a horn curling up from a thick base: [{"type":"skeleton","points":[{"x":0,"y":0,"z":6,"radius":6},{"x":20,"y":0,"z":12,"radius":4},{"x":34,"y":0,"z":28,"radius":2.5},{"x":38,"y":0,"z":46,"radius":1.2}]}]. The list is what is stored and query.tessellate draws the surface; feature.edit with a new list changes the body and everything made from it follows. A field body has no exact faces, so exact modelling commands refuse it: body.from_field makes a mesh body from it, for the mesh exports, the mesh booleans and printing. The reply's fieldBoundingBox is a box the surface lies inside, and smallestSize the finest size the list names. Refused, naming the node: a key that is not its type's, a missing one, an input that is not earlier, an unused node; and a list that holds no material or has no outer limit.
body.from_field kernel
Convert a FIELD body into a MESH body - triangles sampled from its surface, closed by construction, every corner on the surface.
Detail
Convert a FIELD body into a MESH body - triangles sampled from its surface, closed by construction, every corner on the surface. The field body is kept and the mesh is a new body beside it, born with its material, one undo taking it away. A mesh body is what the mesh exports (export.stl, export.3mf) write, feature.combine joins and cuts, and feature.remesh_mesh evens out; a field body has no direct exact conversion - body.from_mesh on this mesh is the way to exact faces. edgeLength sets how far apart the surface is sampled; omitted, it is an eighth of the smallest size the field names, coarsened only as far as one conversion's grid holds. The reply says the edgeLength used, how many triangles, the mesh's area and volume, and whether it closes. Refused: a body that is not a field body, an edgeLength coarser than the smallest size the field names (it could lose that feature) or finer than one conversion holds (the refusal names the finest that fits). Set preview true to see the numbers without adding anything.
body.from_mesh kernel
CoCAD Pro only.
Detail
CoCAD Pro only. Convert a MESH body with FLAT, CYLINDRICAL, CONICAL and SPHERICAL faces into an exact solid - scan-to-CAD. Triangles are merged into flat faces (a corner may sit up to tolerance off its face); a run of narrow facets whose corners all lie within tolerance of one cylinder or cone becomes ONE exact round face - a hole, a pin, a boss, a rounded corner, a slot end, a D-flat shaft, a tapered boss, a countersink, a chamfered hole or pin - provided each end is a flat face square to its axis or another round face on the same axis met at a crease, and a cone may instead run to its point (a pointed pin, a drill point); and one sphere's facets become ONE exact spherical face - a ball, a domed end on a pin (meeting it tangentially), a ball on a straight or tapered stick, the scoop on an ice-cream cone (touching it), a spherical cap on a flat, a dimple, a ball ground flat on several sides (its edge arcs meeting at corners, a domed pin ground flat on its dome, a knob on a shaft, plain or ground) - cut by any number of flat faces, or by one or two cylinders or cones on its axis and any number of flat faces that cut only the ball. Corners are placed where neighbouring faces meet, and the faces are sewn into one closed B-rep solid you can fillet, cut, dimension and export as STEP. Faces are never one per triangle. The scan is kept and the solid is a new body beside it, one undo taking it away. Refused, with the scan left a mesh, when the triangles do not close (run feature.repair_mesh first); when a part is CURVED and no cylinder, cone or sphere fits it (a blend, a torus or a freeform surface - the refusal says how many triangles); or when a round face cannot be built yet - it meets a round face on another axis other than as a tee or two crossed holes, is a cone that runs to its point beside a flat side touching it, or has an end on flat faces meeting in both a ridge and a valley (the refusal says which; a round face cut by ONE slanted flat at an end converts, and so do a moulded part's drafted rounded corner, its walls touching the cone, a tapered boss shaved flat along its length (on one side or two, its ends square, or one end a pin it chamfers - a D-flat chamfered pin, its chamfer sawn off on a slant too - or one end sawn off on a slant, wide or narrow, the wide one under a pin too, or sawn into a keel or a valley at either end, a pin on the square end too - or a flat running out up the taper - on one side, on each, beside a flat reaching both ends (a narrow end sawn on a slant or into a keel or a valley above them, or a wide end sawn on a slant or into a keel or a valley below them, too), or up to a slanted end, wide or narrow, a pin standing on the square end too, or up to an end sawn into a keel or a valley, wide or narrow, a pin on the square end too), a pointed tip ground flat on one side or sawn off on a slant or into a keel or a valley or on a bevel beside a square face (ground flat beside any of them too) or into a chisel, a square face between two slopes (a bevel or a chisel ground flat inside its square face, or a chisel ground flat across one ridge or both, too), a pin under a gable or a hip (stood on a chamfer, or with a flat ground down its side - pitched at both ends, notched across its foot, or on a slanted floor - too), a pin under a chisel - a square face between two slopes - at one end or both, a D-flat pin under a bevel or a chisel (its flat across the square face too), a pin with a V notched across its end, and a pin or a hole whose end runs down a step - or two, or across a groove or a tongue, or at both ends, or on a pin stood on a chamfer). With partial: true a curve nothing fits, and a round face that cannot be built yet, is left as a mesh instead: the exact faces become an open sheet and the rest a separate mesh body, both new, in one undoable step. An exact body is refused. Set preview true to see the result - its triangles to draw, its bounds and its counts - without adding anything; CoCAD Free previews, and adding the result to the model is part of CoCAD Pro.
body.from_reference_mesh kernel
Make a MESH BODY from a reference mesh - the step that turns an imported scan or print (an rm:) into geometry of your own, in the timeline, that can be named, hidden, painted, given a material and drawn.
Detail
Make a MESH BODY from a reference mesh - the step that turns an imported scan or print (an rm:) into geometry of your own, in the timeline, that can be named, hidden, painted, given a material and drawn. The reference mesh is COPIED, not consumed: it stays where it was, and so does the file's winding - nothing is repaired or smoothed on the way. A mesh body is triangles, not surfaces, so it is not exact geometry: fillet, combine, shell, STEP export and every other command that acts on faces and edges refuse it by name. query.tree marks it representation "mesh" with its triangle count, and query.tessellate draws it. Undo removes the body and leaves the reference mesh.
body.from_subdiv kernel
Convert a SUBDIV body into an EXACT solid - the step that lets a freeform body be filleted, combined, shelled, drawn and exported to STEP.
Detail
Convert a SUBDIV body into an EXACT solid - the step that lets a freeform body be filleted, combined, shelled, drawn and exported to STEP. An OPEN cage (a plane's, or any cage with an edge only one face meets) has no inside, so it becomes an exact SHEET instead - a surface with an edge - and the reply says sheet true, its volume and limitVolume null; feature.thicken makes a sheet a solid. The cage's smooth limit surface is fitted with one exact B-spline face per four-sided cage region (a non-quad cage face makes several), every face lying within tolerance of the surface (default 0.01 mm) and neighbouring faces meeting within angularTolerance where the surface is smooth (default 0.5 degrees); the faces are sewn into one closed solid (or one sheet). The subdiv body is kept and the solid is a new body beside it, born with its material, one undo taking it away. The reply says how close the fit came (deviation, seamAngle), how many spans each face needed, and the solid's volume beside the smooth surface's own (limitVolume). Refused, with the measured numbers: a cage the tolerances cannot be met on (loosen them), and a body that is not a subdiv body. Set preview true to see the numbers without adding anything.
body.helix kernel
Create a helix - a spring's path - as a WIRE body: one curve, no faces and no material.
Detail
Create a helix - a spring's path - as a WIRE body: one curve, no faces and no material. This is what a coil is swept along: draw a closed profile on a plane through the helix's start point, then feature.sweep with this body's edge as the path. There is no separate coil command because the sweep already is one. The height is turns times pitch and is not an argument; the answer carries it as height, and startPoint says exactly where the curve begins so a profile can be put there. Give endRadius as well as radius for a tapered helix (a conical spring, an auger, a scroll). A flat spiral is not this shape and is not built. A wire body has no volume, no mass and no mesh - query.edges is how it is drawn, query.measure answers its length, and the commands that need material or faces refuse it by name.
body.lithophane kernel
Make a canvas's picture into a lithophane BODY in the model - a thin plate that shows the picture when light shines through it, there to look at, measure, move and export before it is printed.
Detail
Make a canvas's picture into a lithophane BODY in the model - a thin plate that shows the picture when light shines through it, there to look at, measure, move and export before it is printed. It is exactly the solid export.lithophane writes with the same arguments: dark is thick and bright is thin between minThickness and maxThickness, a flat plate lies with its back on the XY plane centred on the origin, and a cylinder or a dome stands on it. The picture is read as the canvas's file holds it, before any rotation or flip the canvas has in the model. It is a MESH body (query.tree marks it representation "mesh"): move, mirror, pattern, measure and export.stl work on it, and commands that act on faces and edges refuse it by name. One undoable step in the timeline; undo removes the body and leaves the canvas. To write a file without adding anything, use export.lithophane.
body.relief kernel
Raise a canvas's picture as a RELIEF body - an opaque plaque or emboss whose surface height follows the picture, for printing in one colour.
Detail
Raise a canvas's picture as a RELIEF body - an opaque plaque or emboss whose surface height follows the picture, for printing in one colour. The picture stands on a solid back base millimetres thick and rises up to depth more; with raise light (the default) white is tallest, with raise dark black is. It sits on exactly one plane, face or construction plane - named as sketch.new names one - with its back on that plane and the relief rising along its normal (out of a face), the picture's top along the plane's y axis, centred on a face's centroid or on the plane's origin. It is a MESH body (query.tree marks it representation "mesh"), a separate body beside the part it sits on: move, mirror, pattern, measure and export.stl work on it, and exported with the part a slicer prints the two together. The picture is read as the canvas's file holds it, before any rotation or flip the canvas has in the model, and transparent areas count as white. One undoable step in the timeline; undo removes the body and leaves the canvas. For a picture that shows when light shines THROUGH it, use body.lithophane.
body.sphere kernel
Create a sphere body, centred on its origin.
Detail
Create a sphere body, centred on its origin.
body.subdiv_box kernel
Create a SUBDIV body (a freeform, smooth body) from a box-shaped control cage: a Catmull-Clark cage of width x depth x height, centred on origin, cut into widthFaces, depthFaces and heightFaces faces along X, Y and Z (2 each by default).
Detail
Create a SUBDIV body (a freeform, smooth body) from a box-shaped control cage: a Catmull-Clark cage of width x depth x height, centred on origin, cut into widthFaces, depthFaces and heightFaces faces along X, Y and Z (2 each by default). The body is the cage's smooth LIMIT surface, which lies inside the cage and rounds off every corner and edge - more faces along a side keep the surface closer to that side. The cage is what is stored; query.tessellate draws the surface. A subdiv body has no exact faces, so exact modelling commands refuse it: convert it with body.from_subdiv for an exact solid. The reply's cageBoundingBox is the cage's box, which the surface lies inside.
body.subdiv_cylinder kernel
Create a SUBDIV body (a freeform, smooth body) from a CYLINDER cage about Z: radius and height, centred on origin.
Detail
Create a SUBDIV body (a freeform, smooth body) from a CYLINDER cage about Z: radius and height, centred on origin. Each cap is cut into diameterFaces x diameterFaces faces laid onto a disc, so 4 x diameterFaces faces run round the wall, and the wall is cut into heightFaces faces along Z (2 each by default). Every face is a four-sided quad, so it shapes cleanly. The body is the cage's smooth LIMIT surface, a rounded column lying inside the cage - not an exact cylinder (use body.cylinder for that). The cage is what is stored; query.tessellate draws the surface. A subdiv body has no exact faces, so exact modelling commands refuse it: convert it with body.from_subdiv for an exact solid. The reply's cageBoundingBox is the cage's box, which the surface lies inside.
body.subdiv_from_mesh kernel
Fit a closed MESH body (a scan) with a SUBDIV body - a freeform, smooth body whose surface lies on the scan - for the organic shapes body.from_mesh cannot rebuild from flat and round faces (a figurine, a handle, a shell, a sculpted grip).
Detail
Fit a closed MESH body (a scan) with a SUBDIV body - a freeform, smooth body whose surface lies on the scan - for the organic shapes body.from_mesh cannot rebuild from flat and round faces (a figurine, a handle, a shell, a sculpted grip). The scan is laid out in even triangles paired into quads, each split into four-sided cage faces (about faces of them, 384 by default), and the cage's points are solved so its smooth limit surface sits on the scan. The reply says how close it came: deviation.max (the farthest the surface and the scan stand apart, either way) and deviation.mean, in mm - a scan is noisy and the surface is smooth, so it never follows the noise; ask for more faces for more detail. Sharp edges are rounded: a part made of flat and round faces converts exactly with body.from_mesh. The scan is kept and the freeform body is new beside it, born with the scan's material, one undo taking it away; shape its cage with the feature.*_cage tools and make it exact with body.from_subdiv, whose default 0.5-degree seams a fitted scan's cage meets (where a saddle-shaped scan's does not, its refusal names the angularTolerance that would). The reply's cageBoundingBox is the cage's box, which the surface lies inside. Refused: an exact body (turn it into a mesh with body.to_mesh first), a scan whose triangles do not close (mend it with feature.repair_mesh), and too few faces for the shape, which would fold the surface through itself (fit again with more). Set preview true to see the fit's numbers without adding anything.
body.subdiv_plane kernel
Create a SUBDIV body (a freeform, smooth body) from a flat PLANE cage: width along X by depth along Y, cut into widthFaces x depthFaces faces (2 each by default), centred on origin and facing +Z.
Detail
Create a SUBDIV body (a freeform, smooth body) from a flat PLANE cage: width along X by depth along Y, cut into widthFaces x depthFaces faces (2 each by default), centred on origin and facing +Z. The cage is OPEN - a sheet with an edge and no inside - so until its points are moved its LIMIT surface is the flat rectangle itself, edge and corners kept. The cage is what is stored; query.tessellate draws the surface. A subdiv body has no exact faces, so exact modelling commands refuse it; body.from_subdiv converts it to an exact SHEET - a surface with an edge, not a solid, since an open cage has no inside. The reply's cageBoundingBox is the cage's box.
body.subdiv_quadball kernel
Create a SUBDIV body (a freeform, smooth body) from a QUADBALL cage: a cube cut into faces x faces faces a side (2 by default) with every cage point pushed out onto a sphere of radius about origin.
Detail
Create a SUBDIV body (a freeform, smooth body) from a QUADBALL cage: a cube cut into faces x faces faces a side (2 by default) with every cage point pushed out onto a sphere of radius about origin. Every face is a four-sided quad, so it shapes cleanly, and the eight cube corners are the only points where three faces meet. The body is the cage's smooth LIMIT surface, a near-sphere lying inside the cage - not an exact sphere (use body.sphere for that). The cage is what is stored; query.tessellate draws the surface. A subdiv body has no exact faces, so exact modelling commands refuse it: convert it with body.from_subdiv for an exact solid. The reply's cageBoundingBox is the cage's box, which the surface lies inside.
body.subdiv_sphere kernel
Create a SUBDIV body (a freeform, smooth body) from a UV SPHERE cage about Z: longitudeFaces faces round Z (8 by default) and latitudeFaces from pole to pole (4 by default), every cage point on a sphere of radius about origin.
Detail
Create a SUBDIV body (a freeform, smooth body) from a UV SPHERE cage about Z: longitudeFaces faces round Z (8 by default) and latitudeFaces from pole to pole (4 by default), every cage point on a sphere of radius about origin. The bands between the rings are four-sided quads and each pole is a fan of three-sided faces - a globe's lines, for a shape pulled out along its axis; for a ball of quads only, use body.subdiv_quadball. The body is the cage's smooth LIMIT surface, a near-sphere lying inside the cage - not an exact sphere (use body.sphere for that). The cage is what is stored; query.tessellate draws the surface. A subdiv body has no exact faces, so exact modelling commands refuse it: convert it with body.from_subdiv for an exact solid. The reply's cageBoundingBox is the cage's box, which the surface lies inside.
body.subdiv_torus kernel
Create a SUBDIV body (a freeform, smooth body) from a TORUS cage about Z: ringFaces faces round the ring (8 by default) and tubeFaces round the tube (4 by default), every cage point on the torus of majorRadius (the centre to the middle of the tube) and minorRadius (the tube's own), centred on origin.
Detail
Create a SUBDIV body (a freeform, smooth body) from a TORUS cage about Z: ringFaces faces round the ring (8 by default) and tubeFaces round the tube (4 by default), every cage point on the torus of majorRadius (the centre to the middle of the tube) and minorRadius (the tube's own), centred on origin. Every face is a four-sided quad and four meet at every point, so the surface is smooth everywhere. The body is the cage's smooth LIMIT surface, a ring lying inside the cage - thinner than minorRadius, more so with fewer tubeFaces - and not an exact torus (use body.torus for that). majorRadius must be greater than minorRadius. The cage is what is stored; query.tessellate draws the surface. A subdiv body has no exact faces, so exact modelling commands refuse it: convert it with body.from_subdiv for an exact solid. The reply's cageBoundingBox is the cage's box, which the surface lies inside.
body.to_mesh kernel
Convert an EXACT body into a MESH body - triangles, at an accuracy you choose.
Detail
Convert an EXACT body into a MESH body - triangles, at an accuracy you choose. tolerance is the greatest distance a triangle may stand off the exact surface (default 0.05 mm) and angularTolerance the greatest turn a curved face makes across one triangle (default 15 degrees); at the defaults the mesh is exactly the triangles export.3mf writes for the body. The triangles are welded into one surface: a solid's mesh is closed, a sheet's is open, and the reply says which (closed). The exact body is kept and the mesh is a new body beside it, born in the same component with the same material, one undo taking it away. The reply measures the accuracy on both sides - the mesh's area and volume beside the exact body's - and says how many triangles and corners it holds. A mesh body is what feature.combine joins to a scan, feature.remesh_mesh evens out, and feature.decimate_mesh simplifies; body.from_mesh goes the other way. Set preview true to see the numbers without adding anything. Refused: a mesh body (already triangles), a curve with no face, a body whose faces the mesher could not triangulate, and more than 5000000 triangles (the refusal names a coarser tolerance).
body.torus kernel
Create a torus body, centred on its origin with its axis along +Z.
Detail
Create a torus body, centred on its origin with its axis along +Z.
Queries
Read-only questions about the document, the session and the registry itself — how an AI (or any client) sees what it is doing.
query.activity
Whether anyone else is changing the document right now, what they are running, who they are, and which document (documentId) it is in.
Detail
Whether anyone else is changing the document right now, what they are running, who they are, and which document (documentId) it is in. The same fields the ai.activity_changed event carries, so a client that connected in the middle of a long command can ask once and then listen.
query.axis kernel
One construction axis: where it is, which way it runs, and what it was built from.
Detail
One construction axis: where it is, which way it runs, and what it was built from. The line is infinite - a point on it plus a unit direction - so a caller that wants to draw it picks its own length. cylinderIssue is null while the face the axis was built from still resolves, and carries a code plus any candidates when an edit split or consumed it; the axis keeps its stored line either way.
query.backups
List the kept previous versions of a document, newest first.
Detail
List the kept previous versions of a document, newest first. Every doc.save that replaces an existing file keeps the bytes it was about to destroy as a stamped sibling, the newest files.backupCount of them. Each one is a complete .cocad, so restoring a version is doc.open on the path reported here - there is no separate restore command. Answers an empty list when there are none, including when the document itself is gone.
query.bends kernel
Every bend in one body, measured off the part itself - the bend table a shop reads and the first thing a flat pattern is built from.
Detail
Every bend in one body, measured off the part itself - the bend table a shop reads and the first thing a flat pattern is built from. A bend is found as a pair of cylindrical faces sharing an axis and a swept angle: innerFace and outerFace are their fc: ids, radius is the INSIDE bend radius in millimetres and angle is how far the metal turns, in DEGREES. thickness is the stock at that bend, measured as the outer radius less the inner one rather than read from the body's sheet-metal rule - so comparing it with the rule's own thickness is how you find a part that is no longer the stock it says it is. length is how far the bend runs along its axis, and axis is a point on that axis (at the middle of the run) with a unit direction, both in document millimetres. walls lists the flat faces the bend joins, normally two; fewer means a wall has been cut away. bendAllowance is the flat metal the bend consumes - angle in radians times (radius + kFactor x thickness), the number you add between two walls when laying the part out flat - and kFactor is the body's own, from its sheet-metal rule. BOTH ARE NULL when the body carries no sheet-metal rule: where the neutral axis sits inside the metal is a property of the alloy and the tooling and cannot be measured off the finished shape, so set a rule with feature.base_flange or doc.set_sheet_metal_rule and ask again. A body with no bends answers an empty list, which is an answer and not an error - a box, an unfolded blank and a turned shaft all come back that way. Nothing is changed, nothing is recorded: this is a read.
query.board_layout kernel
Read a circuit board as GEOMETRY, for building a case around it: the board's two faces (top and bottom, by face id) and thickness, its FRAME (origin, x, y, z: z points out of the top face, and the board fills 0..width by 0..depth by 0..thickness in it, so every number below is a size), its outline's width and depth (the plan box - a notched or round board is read as its box; the top face's edges are the true outline), its through HOLES largest first (diameter, at - the centre on the top face in world coordinates, plan - the same in the frame; mounting holes are usually the largest), every PART on it (body, side top or bottom - where most of its height is, so a through-hole part with pins below is top - height above that face, its box in the frame, and its gaps to the four outline sides minX, maxX, minY, maxY, negative when it overhangs), the PORTS - one row per part and side it comes within portGap of, with the opening's centre and outward normal in world coordinates, its width along the side and height, and the same span in the frame - and the ENVELOPE, the box the board and its parts fill in the frame (a case's inside must hold it).
Detail
Read a circuit board as GEOMETRY, for building a case around it: the board's two faces (top and bottom, by face id) and thickness, its FRAME (origin, x, y, z: z points out of the top face, and the board fills 0..width by 0..depth by 0..thickness in it, so every number below is a size), its outline's width and depth (the plan box - a notched or round board is read as its box; the top face's edges are the true outline), its through HOLES largest first (diameter, at - the centre on the top face in world coordinates, plan - the same in the frame; mounting holes are usually the largest), every PART on it (body, side top or bottom - where most of its height is, so a through-hole part with pins below is top - height above that face, its box in the frame, and its gaps to the four outline sides minX, maxX, minY, maxY, negative when it overhangs), the PORTS - one row per part and side it comes within portGap of, with the opening's centre and outward normal in world coordinates, its width along the side and height, and the same span in the frame - and the ENVELOPE, the box the board and its parts fill in the frame (a case's inside must hold it). parts defaults to every other solid the same feature made: one import.step of a KiCad board brings the board and its components in together, and partsFrom says which rule chose them (given, sameFeature, none). Nothing here knows what a part IS - a port is a part near an edge. Refused: a body that is not a solid, one with no two opposite flat faces, and one thicker than it is narrow. Lengths are millimetres, Z-up. Nothing is changed, nothing is recorded: this is a read.
query.bom
The parts list - one row per component definition, with its item number, the quantity placed across the whole nested tree and the part-metadata record as the row's columns.
Detail
The parts list - one row per component definition, with its item number, the quantity placed across the whole nested tree and the part-metadata record as the row's columns. item is the row's position in the partsOnly order - 1 for the first listed definition - and it is the number a drawing's balloon prints, so a balloon and the table can never disagree; a definition that appears at two levels of the structured tree carries one item at both, because an item names the part. partsOnly, the default, is the flattened rollup a person prints: every definition once, however deep its placements sit. structured is the indented tree: rows carry children, and a child row's quantity counts inside all instances of its parent row together - a sentence that stays true even when one instance has been edited apart from its siblings. A part is a definition: a mirrored component is its own row, and so is each member definition a nested placement materializes, because a placement's content is a self-contained replay. A definition whose record carries excludeFromBom loses its row in both modes and is disclosed in excluded - the omission is never silent, and the entry names the component so one query.metadata call shows the flag. Loose bodies are not rows: the BOM of a loose-body part file is empty, and empty is an answer - the document's own record is a title block's, not a row. Never journaled - asking for a parts list is not a modelling step.
query.branches
List this document's branches, sorted by name: each one's name, the branch it was forked from (null for the original line), how many operations its recipe holds, and whether it is the one that is open.
Detail
List this document's branches, sorted by name: each one's name, the branch it was forked from (null for the original line), how many operations its recipe holds, and whether it is the one that is open. current names the open branch. A document that has never branched answers one row, main.
query.build_fit kernel
Does a body fit a 3D printer's build volume - and if not, where would it have to be cut so that every piece does?
Detail
Does a body fit a 3D printer's build volume - and if not, where would it have to be cut so that every piece does? The body stands AS MODELLED: Z is up on the printer as it is in CoCAD, so extent is the part's size along x, y and z and fits says whether that box is no larger than volume. fitsTurned says whether it would fit after a quarter turn on the bed (x and y swapped), which prints exactly the same layers - do that with feature.move and a 90 degree rotation about Z. Laying the part on its side is not tried, because that changes how it prints, and neither is setting it diagonally across the bed. When it does not fit, pieces says how many pieces along each axis (and in total) make every piece fit, and cuts lists the planes that make them: equal spacing along each axis, so no piece is a sliver. Each cut names its axis and the coordinate it sits at, and is spelled for the commands that make it: construct.plane with type offset, plane, and distance (XZ's normal points along -Y, so a y cut's distance is minus its coordinate), then feature.split with that constructionPlane - one split per cut, each piece split again by the cuts that pass through it. A cut whose distance is 0 lies ON the base plane: pass plane to feature.split directly. A mesh body (a scan) is measured off its own triangles and an exact body off its surfaces. The pieces are plain cuts - no pins, dovetails or joints yet. A plan of more than 1000 pieces is refused: that is a millimetres-versus-metres mistake, not a print. Nothing is changed, nothing is recorded: this is a read.
query.build_orientation kernel
Which way up a body should print on a filament (FDM) 3D printer.
Detail
Which way up a body should print on a filament (FDM) 3D printer. Every candidate pose - the six axis directions, plus standing on each of the body's largest flat faces - is measured and the list is answered BEST FIRST: supportVolume (mm3 of support, measured as columns straight down to the plate under every surface steeper than overhangAngle, so it over-counts where the part itself would catch them), overhangArea, contactArea (mm2 standing on the plate), height, and with loadDirection loadAcross (1 when the load pulls the layers apart, 0 when it lies along them). The ranking: least load across the layers first when a load is named, then least support, then most contact, then lowest - each measure rounded to a step (a tenth, 1% of the part's volume, 1% of its surface) so near-equal poses fall through to the next. Each pose's move is feature.move's own arguments (type rotate, axis, angle - a turn in place about the body's centre) that makes it: send it with bodies: [bodyId] to apply it; the pose as modelled (+Z up) has move null. Turning about the vertical changes none of these, so where the part sits on the bed is query.build_fit's question, and its time and filament in a pose are query.print_estimate's with that pose's up as buildDirection. A mesh body (a scan) must be closed - feature.repair_mesh mends one that is not; a sheet or a wire is refused. Nothing is changed, nothing is recorded: this is a read.
query.cage kernel
Read a SUBDIV (freeform) body's control cage - the points and faces a person shapes, which its smooth surface lies inside.
Detail
Read a SUBDIV (freeform) body's control cage - the points and faces a person shapes, which its smooth surface lies inside. points is every cage point as flat x,y,z triples in millimetres, Z-up, in the cage's own order, and pointIds names each one in the same order (cx:<body>.<n> - n is the point's place in that list and never changes; null for a point no face uses any more). faces is every cage face, each with its id (cf:<body>.<n> - n is the face's number, counted from 0, which it keeps through every cage edit; a deleted face's number is never reused, so after feature.delete_cage the numbers skip it), its corner points (indices into points, counter-clockwise seen from outside), its center and its outward unit normal. edges is every cage edge, each with its id (ce:<body>.<n> - an edge keeps its number while its two points still share a face, and an edit numbers the edges it makes after every edge that already was), its two points, the one or two faces that run it (one: the cage's open rim) and its sharpness - 0 smooth, 10 a crease at every level (an open edge is always 10), a value between sharp for that many subdivision levels before it softens. closed is false for an open cage (a plane's), which has an edge. symmetry is null, or the symmetry feature.symmetry_cage gave the cage - its type, its plane (mirror) or axis and count (circular) - with the pairs it finds NOW: pairedPoints, fixedPoints (on the plane or the axis) and unpaired, the cx: ids of points with no partner yet. The same cf: ids name the groups of query.tessellate's drawing, so a click on the surface and this list agree. An exact or mesh body is refused: it has no cage.
query.camera
Where the shared camera is for the document this connection is on: what it looks at, how far off, its bearing and height, and its projection.
Detail
Where the shared camera is for the document this connection is on: what it looks at, how far off, its bearing and height, and its projection. Session state, not document state — it is never saved and never undone.
query.canvas
One canvas, whole: its pixel dimensions, its calibration, the support and frame it lies in, and the image's own bytes as base64 - what a client draws the underlay from.
Detail
One canvas, whole: its pixel dimensions, its calibration, the support and frame it lies in, and the image's own bytes as base64 - what a client draws the underlay from. The bytes are the imported file's, undecoded; hand them to the image decoder you already have. They never change for a given canvas, so fetch them once per document and keep them. Use query.tree to list the canvases - they are the Reference folder's cv: rows.
query.canvas_circles pixels
Find the circles in a canvas's picture - holes, bosses, pins - and say where they sit on the canvas's plane and how big they are.
Detail
Find the circles in a canvas's picture - holes, bosses, pins - and say where they sit on the canvas's plane and how big they are. A first draft for a person to review, and it adds nothing to the model: draw the circles you agree with with sketch.draw on a sketch on the canvas's own support (query.canvas reports it), where each center is that sketch's own coordinate. Dark and light circles are both found, because a hole is dark lit from the front and light lit from behind. Every region that is not a circle is listed under untraced rather than guessed at, circles that share a center or a diameter are listed under concentric and equal, and every size is only as true as the canvas's calibration - which the reply repeats. Photograph the part square-on: a circle seen at an angle is an ellipse and is left untraced.
query.canvas_outline pixels
Trace the outline of the part in a canvas's picture - the largest shape the picture's edge does not cut - as a short closed chain of lines and arcs placed on the canvas's plane.
Detail
Trace the outline of the part in a canvas's picture - the largest shape the picture's edge does not cut - as a short closed chain of lines and arcs placed on the canvas's plane. A first draft for a person to review, and it adds nothing to the model: draw the elements you agree with with sketch.draw on a sketch on the canvas's own support (query.canvas reports it), where every point is that sketch's own coordinate - a line from start to end, an arc in threePoint mode through start, third and end, a circle from center and radius. The elements run in order around the outline and each begins exactly where the one before it ends. Joins that are tangent, and lines along the sketch's horizontal or vertical axis, are listed under tangent, horizontal and vertical so you can add those constraints if you agree. An outline that cannot be drawn as a short chain - a jagged, textured or very detailed edge - is left untraced, with how many pieces it would have taken, rather than handing you hundreds of segments to delete. The part's holes are traced the same way and listed under holes, largest first, each in the outline's own shape - a round hole is one circle, a slot two lines and two arcs - and draw them in the same sketch so the profile has its holes; a hole that cannot be drawn as a short chain is listed under untracedHoles instead. Every size is only as true as the canvas's calibration, which the reply repeats.
query.commands
The command registry with JSON Schemas — the self-describing API surface.
Detail
The command registry with JSON Schemas — the self-describing API surface. Pages at 50 commands — pass nextCursor back for the rest. Every row says its edition: free runs in every copy of CoCAD, and pro needs a CoCAD Pro license - CoCAD Free answers it with REQUIRES_PRO (one call of drawing.export or body.from_mesh can still be Free; the command index says which).
query.configurations
Every configuration saved with feature.configuration, compared with the parameters NOW.
Detail
Every configuration saved with feature.configuration, compared with the parameters NOW. One row per configuration in timeline order: featureId, name, suppressed, and inputs - for each parameter it names, the expression it sets, the value that expression has in the configuration, and current, the parameter's expression in the document now (null when the parameter is gone). active is true when every expression the configuration sets is exactly the parameter's current expression - the part is in that configuration; two configurations that agree on what they set can both be active. usable is false, with reason saying why, when a parameter it names is gone or its values no longer evaluate. To switch to a configuration, send param.set_many with its inputs (name and expression of each).
query.connections
Who has a socket open on this bus right now, and what each of them says it is.
Detail
Who has a socket open on this bus right now, and what each of them says it is. This is live: a client appears here when it connects and is gone when its socket closes, which is what makes it the honest answer to whether an AI actually reached CoCAD. kind is human or ai as that client declared with core.identify, or null if it never declared - there is no third value and nothing is guessed - and name is the label it chose, or null. self is the clientId of the connection asking, which is in clients like any other, so a caller can tell itself from everybody else. The order is the order they connected. This is NOT query.activity, which reports who is running a command and leaves the caller out, and it is not the identity table behind query.history, which keeps a departed client's badge for ever so that its work stays attributed. It says nothing about the open document and never fails.
query.coordinate_system
One user coordinate system: its frame - origin, xAxis, yAxis and normal (+Z) - exactly as stored, plus its name and whether it is shown.
Detail
One user coordinate system: its frame - origin, xAxis, yAxis and normal (+Z) - exactly as stored, plus its name and whether it is shown. The frame object is spelled exactly as a sketch's, so a client that draws one draws this.
query.copy kernel
Copy bodies out of this document as bytes, so they can be pasted into another one with feature.paste.
Detail
Copy bodies out of this document as bytes, so they can be pasted into another one with feature.paste. The reply IS the clipboard: CoCAD stores nothing between the two calls, so hold the content yourself and paste it whenever you like, into any document, in this core or another. The geometry is exact - it is CoCAD's own B-Rep rather than a STEP or mesh conversion - so nothing is rounded on the way through. Omit bodies to copy the whole document. bodies and names come back index-aligned with the blob, so pass names straight to feature.paste to keep what each body was called. Use export.step to write a file for another application instead.
query.curvature
Curvature sampled along every curve in a sketch, ready to draw as a curvature comb — the analysis companion to query.polyline.
Detail
Curvature sampled along every curve in a sketch, ready to draw as a curvature comb — the analysis companion to query.polyline. Each station carries the curve's own parameter u, the point x,y in sketch millimetres, the unit tangent tx,ty and the SIGNED curvature in 1/mm: positive where the curve turns left of its tangent, so a counter-clockwise circle answers +1/r and a line answers 0 everywhere. Stations are evenly spaced in the curve's parameter, not in arc length; a closed curve gets samples stations around its period with no repeat at the seam, an open one gets its two ends exactly. A station where the curve has no direction — a spline corner made of repeated poles — is omitted rather than guessed at, and the gap is visible because every station names its own u. A point curve answers no stations. Nothing here changes the sketch.
query.design_check kernel
Review one body or one sketch against the design rules this build knows, and report what each rule found.
Detail
Review one body or one sketch against the design rules this build knows, and report what each rule found. subjectId takes a body ("bd:1") for the thickness, overhang and fit rules or a sketch ("sk:1") for the sketch rules; a rule whose category cannot be about your subject is simply not applied. Every finding carries BOTH numbers - measured, what this part actually is, and threshold, what the rule asks for - because a finding you can check is worth more than a verdict you cannot. The category says how to read them: thickness in millimetres, overhang in degrees, sketch a count of degrees of freedom, fit in millimetres of diameter. A thickness finding fires where a face's thinnest wall is BELOW the rule's minimum; an overhang finding where a face leans further TOWARD the build direction than the rule allows, in query.draft's sign, so a flat top is never one and a flat underside always is - including the one resting on the build plate, because nothing here knows where you will place the part. A sketch finding fires where the sketch's dof is above what the rule accepts. A fit finding fires where a round hole or pin - a cylindrical face that closes on itself, so never a fillet or the end of a slot - is predicted to print further from its drawn diameter than the rule's maxFitError, by the line the named fit calibration fitted to its caliper readings: measured is that distance in millimetres, and a fit row alone also carries nominal, the diameter drawn, and predicted, the diameter the printer is expected to make, so you can see which way it is off. A hole is judged by the calibration's hole line and a pin by its pin line, never one line for both. A round that a feature.fit declares - what it is sized FOR - is judged against that fit's band instead of its drawn size: measured is the predicted diameter's distance from the middle of the band, threshold is half the band's width, and the row adds fitFeature (the feature.fit), target (the middle of the band) and suggested, the diameter to DRAW so this printer prints the target - which nothing applies for you. findings are ordered by severity, critical first, which is the only thing severity does: no command in CoCAD ever fails because a design rule fired, since a part that is unprintable today is the ordinary condition of a part that is not finished. buildDirection has no default - omit it and every overhang rule is listed in skipped instead of judged, because an answer computed against an axis you did not choose is wrong in a way that looks right. calibration has no default either, for the same reason: omit it and every fit rule is listed in skipped, and a calibration that recorded no holes (or no pins) skips that half and says so, while one nobody recorded is refused. skipped also names a sketch rule on a sketch nothing has solved yet. A skipped row is ruleId, reason - the sentence, in English - and reasonId, that sentence's id in CoCAD's message catalogue, so a client can show it in the person's language. unmeasured names the faces a read could not answer for - a ray that left the body, a normal the sampler could not read - so a face nobody could measure is never mistaken for a face that passed. profile and category narrow which rules are applied and both are optional; a profile or category that does not exist is refused rather than answered empty, because an empty answer reads as: your part is fine. Nothing is changed, nothing is recorded: this is a read.
query.design_rules
Every design rule this build knows - the thresholds a part is reviewed against for manufacturability, and the table you edit to make that review yours.
Detail
Every design rule this build knows - the thresholds a part is reviewed against for manufacturability, and the table you edit to make that review yours. Each rule names a category and carries exactly one threshold, which is the one its category needs: a thickness rule carries minThickness in millimetres, an overhang rule carries maxOverhang in degrees, a sketch rule carries maxDof, a count, and a fit rule carries maxFitError, millimetres of diameter. The other three are absent rather than zero, because absent means this rule is not about that and 0 is a real threshold - a fully constrained sketch. severity reads info, warning or critical, and it orders findings and nothing else: no command in CoCAD ever refuses because a design rule fired, since a part that is unprintable today is the ordinary condition of a part that is not finished. profile is the process profile a rule belongs to, and it is a row-set id rather than a record - an FDM printer with a 0.4 mm nozzle IS the rows whose profile reads fdm-0.4mm, so nothing looks it up and there is no profile file; general means a rule that is not about a process at all. This table measures nothing: the reads it is written for already exist, and are query.wall_thickness, query.draft (a printing overhang is a lean taken against the build direction, in that command's own sign), dof on query.sketch, and for fit the round holes and pins query.design_check finds, compared with the diameter a fit calibration from query.fit_calibrations predicts each one prints at. maxOverhang is read against that same sign, where 0 is a wall along the build direction and 90 a face square to it. ref names where each threshold came from, and they are rules of thumb rather than published standards: confirm them against your own machine and material. source on each row reads built-in, user, or built-in, overridden - saying whether that row is this build's own or came from your design-rules.json, which adds rules and replaces shipped ones by id, a rule at a time and whole. version names the shipped table's shape rather than your file's. It says nothing about the open document and never fails.
query.design_variants kernel
Build several versions of the part at different parameter values and weigh each one, without changing the document - "give me eight versions of this bracket".
Detail
Build several versions of the part at different parameter values and weigh each one, without changing the document - "give me eight versions of this bracket". Each variant names parameters (query.parameters lists them) with new expressions, exactly as param.set would be sent; CoCAD installs all of a variant's values at once, rebuilds the whole part from its timeline in a scratch copy, measures it and throws the copy away. Each row, in the order given: label, inputs (each with the value it evaluated to), built, and when built bodies, volume, area and mass (query.mass_properties' combined rollup - mass only when every solid has a material), size (x, y, z of every body's box together), requirements (query.requirements' counts and the ft: of each one that fails) and, when print is sent, print (seconds, grams and cost summed over every body query.print_estimate can estimate, notPrinted naming the ones it refused). A version that cannot be built is not a refusal: built is false and reason says why in the rebuild's own words, with failedFeature the ft: that refused - every other version is still built. current carries the same numbers for the document as it is now, to compare against. Rank the rows yourself by whatever matters - lightest, quickest, cheapest, still passing every requirement. To make a version the document, send its inputs as param.set, one per parameter, under one group. Nothing is changed and nothing is recorded; each version is a whole rebuild, so ask for the ones worth comparing.
query.diagnostics
The tail of this core's own log file (ADR 0028), so a client can see what the core did without being on the machine.
Detail
The tail of this core's own log file (ADR 0028), so a client can see what the core did without being on the machine. lines is the newest records OLDEST FIRST, so printing them straight down the page is the right order; matched says how many records the whole file held, so a caller can tell a complete answer from a window onto a longer one. Pass commandId to keep only the records belonging to one command - the same id the bus envelope carries and every line records, which is what lets one modelling step be followed here and in the mcp and host logs by one string; it keeps only this core process's records, because ids restart at every launch and the file is shared by every core that has run on this machine. An empty commandId filters nothing, exactly as an absent one does. level is the lowest level this process actually writes: a record quieter than it was never written, so an answer that looks empty is explained by this field and not by a missing event, and the fix is to restart the core with COCAD_LOG=debug. path and process name the file these lines came from, and path is null on a core started with COCAD_LOG=off or one whose logger could not open a file - both are a core running normally with nothing to show, so this answers rather than fails. Only the current file is read, never the rolled core.1.log and its siblings. It says nothing about the open document and never fails.
query.diff
Compare two versions of a model as features and parameters rather than as lines: which features were added, removed, moved in the timeline or changed - and which of their arguments, before and after - and which parameters changed.
Detail
Compare two versions of a model as features and parameters rather than as lines: which features were added, removed, moved in the timeline or changed - and which of their arguments, before and after - and which parameters changed. before is a .cocad file, or beforeBranch one of the open document's branches; after is another file, afterBranch another branch, or the open document when both are omitted, so leaving them out answers what has changed since that version. Each file or branch is rebuilt from its recorded steps first, so an undone step is not reported as a change, and one that does not rebuild whole is refused rather than half-compared. Steps neither list itemises - sketch drawing, undo, notes - are counted in otherSteps, and geometry compares the two fingerprints, so a difference the rows do not name is still reported. Changes nothing.
query.documents
Every document open in this core process, and which one this connection is acting on.
Detail
Every document open in this core process, and which one this connection is acting on. Each connection has its own current document, so two clients can work in different parts at the same time and neither moves the other. Answers an empty list before anything is open. Open a second document with doc.new keepCurrent, move between them with core.switch_document, and close one with doc.close. Each row says whether that document is read-only, which it is when another CoCAD holds the file it was opened from; a document that has never been saved is not read-only. Each row also gives that document's revision: a counter that moves whenever anything in the document changes, and never for a selection or a camera. Compare two readings of the same documentId to tell whether the model has moved under a plan made against an earlier one. Revisions restart at 0 in every document, so a number read from one document says nothing about another.
query.draft kernel
How each face of a body leans against a pull direction — the draft analysis that says whether a moulded or cast part can leave its tool, and which faces stop it.
Detail
How each face of a body leans against a pull direction — the draft analysis that says whether a moulded or cast part can leave its tool, and which faces stop it. One row per face, in the same order query.tree lists them, each carrying the least and greatest lean over that face in DEGREES: 0 for a wall parallel to the pull (an undrafted box side), ±90 for a face square to it (a mould floor). Positive means the face GROWS along the pull, which is the same convention feature.draft's angle and feature.extrude's taper use — so a 10 mm cube drafted +5 degrees reports +5 on its walls, the number the draft was given. (That is deliberately the opposite of the mould shop's sign, where a positive draft angle eases extraction, so read the sign against feature.draft and not against another CAD package's legend.) minAngle and maxAngle are EQUAL exactly when the face is planar. There is no threshold argument, because this read must be answerable before anybody has decided what draft the shop wants: a face has at least T degrees of draft ALONG the pull when maxAngle <= -T, and against it when minAngle >= +T. undercut is true when a face's lean spans zero — part of it belongs to each half of the tool, so no movement along that axis frees it, the inside of a sideways bore being the everyday case; a planar face is never undercut. sampled says how the two numbers were got: false means exact (a plane, in closed form), true means they are the extremes over a finite sample of a curved face and the true range may be WIDER. defined is false where the face has no normal the sampler could read — minAngle, maxAngle, undercut and sampled are then null, because nothing about that face was measured. Nothing is changed, nothing is recorded: this is a read.
query.drain_sites kernel
Suggest where a hollowed body's drain holes should go - the points to hand straight to feature.drain_hole.
Detail
Suggest where a hollowed body's drain holes should go - the points to hand straight to feature.drain_hole. Give the body and the build direction (the way its layers stack, away from the plate); the holes go where the body's sealed void is lowest along it, nearest the build plate, which is where resin pools and where it drains from. The first is at the void's lowest point; each next is as far from the others as the low part of the void allows, so one drains while another lets air in. Every point suggested is one feature.drain_hole would drill with the same diameter - through the wall, opening into the void whole. Nothing is changed. The reply's points are on the outside of the part; fit says how many were found, which can be fewer than count when the bottom of the void is small. Refused when the body has no sealed void - including one an earlier drain hole already opened, which is named - or when no hole of that diameter fits anywhere low on it. A hollowed mesh body (a scan) is read the same way.
query.drawings
Every drawing this document holds, in the order they were made, each giving its name, its drafting standard, its projection angle and its sheets in order.
Detail
Every drawing this document holds, in the order they were made, each giving its name, its drafting standard, its projection angle and its sheets in order. Each sheet gives its width and height in millimetres as drawn, its default drawing scale, the views placed on it and the BOM tables placed on it - each table a recipe saying where its header sits, which way its rows stack, which query.bom mode and which columns it prints, with the layout every column is drawn to, and never the rows, which query.bom answers; and the revision tables placed on it - each a REV block whose rows ARE stored, a person's words about the print, with the layout its five columns are drawn to; and its titleBlock, or null - the record's five stored words beside every derived cell (title, drawing number, material, latest rev, sheet n of m, scale, size, projection) with its label, value and place, worked out afresh on every read; there is no orientation field, because comparing the two lengths says which way round it is and a square sheet is neither. Each view gives the RECIPE that draws it - which bodies (an empty list meaning every solid body in the document), which direction it looks from, where on the page it sits in millimetres from the lower-left corner, its own scale or null for the sheet's, the effective scale either way, and whether hidden lines are drawn - the annotations drawn on it, each with the words it says, which corners of the model it points at (none, for a general note) and where its text sits - the GD&T symbols drawn on it, each a datum feature symbol with its letter or a feature control frame with its characteristic, tolerance, modifiers and datum references, all stored - and the dimensions drawn on it, each saying which corners of the model it measures between, which distance it states, where its text sits, the tolerance and the decimal precision it is written with (stored - a shop's allowance is nobody's measurement) and whether it prints dual units, but never the number. Neither the curves nor the measurements are here: query.view_geometry works both out afresh on every call, so a view never goes stale and a drawing can never state a length the part does not have. A build with no geometry kernel cannot place a view, and answers an empty list on every sheet. A drawing has no geometry of its own and no row in query.tree, so this is how you find out what prints a document carries.
query.edges kernel
Every edge of a body as a run of straight segments, ready to draw or to hit-test — the 3D companion to query.polyline.
Detail
Every edge of a body as a run of straight segments, ready to draw or to hit-test — the 3D companion to query.polyline. Points are flat x,y,z triples in millimetres, Z-up. The points come from the same triangulation query.tessellate returns, so an edge lies exactly on the facets it borders. A closed edge does NOT repeat its first point, so draw a loop rather than a strip when closed is true. Each edge also carries its bisector: the point halfway along it and the unit direction pointing OUT of the material there, midway between the two faces that meet at the edge — which way is "away from the part" at that corner, and the direction a fillet or chamfer handle runs along. Null where there is no such direction: an edge with one face on both sides (a cylinder's seam) or a knife edge whose two faces point exactly opposite ways.
query.explode_states
Every explode state this document holds, in the order they were made, each naming the bodies it offsets and by how much.
Detail
Every explode state this document holds, in the order they were made, each naming the bodies it offsets and by how much. A body with no row here is drawn where it lives. Each row also names the component placement its body is filed in, or null when the body is loose, so a client can group an explosion by part without a second call. The offsets are millimetres in the document's own axes, and each one is also the trail line from a part's home position to where the state draws it.
query.features
Every timeline feature this document holds, oldest first - what made each part of it, in the order it was made, with the arguments the command was given.
Detail
Every timeline feature this document holds, oldest first - what made each part of it, in the order it was made, with the arguments the command was given. A body says which feature made it through featureId on query.tree; this says what that feature was. Primitives (body.box, body.cylinder) are features too and are listed, and so are the assembly commands - a feature that made a component owns no body of its own and is listed all the same. Timeline groups come back beside them: groups lists each group with its name, and a grouped feature's row carries group naming its tg: - doc.create_timeline_group makes one. Each row also says who made it - mine, authorKind and authorName, exactly as query.history reports them for the step that minted it - so a timeline can badge the features an AI made. Each row's at is when that same step was recorded, exactly as query.history reports it (an opened document's steps carry the time it was opened), so a timeline can say when each feature was made. A feature somebody wrote a reason for also carries intent: the note, when it was written, who wrote it in the same three keys, the ids the sentence is about with each one's alive saying whether it is still in the document, and stale - true when any of them has gone, which is a note that may now mislead. feature.set_intent writes one. A document rolled back with feature.set_rollback also lists the features after its marker, each with rolledBack: true and the at its command was recorded with, and says where the marker is in rollback - after (the last feature built, null for before the first) and held (how many are not built); neither key is there when nothing is rolled back.
query.find_entities kernel
Find faces, edges or bodies by geometric predicate - the search that turns "all vertical edges of this body" or "every 3 mm fillet" into entity IDs you can hand straight to select.set, feature.fillet or feature.draft, with no pixel-picking and no ID guessing.
Detail
Find faces, edges or bodies by geometric predicate - the search that turns "all vertical edges of this body" or "every 3 mm fillet" into entity IDs you can hand straight to select.set, feature.fillet or feature.draft, with no pixel-picking and no ID guessing. Say what to look for with kind (one kind per call), where to look with bodies (absent means the whole document), and what must be true with any mix of the predicates - every predicate sent must hold at once, and a predicate about a fact an entity does not have excludes it (a plane has no radius, so a radius predicate excludes every plane; a sheet encloses no volume, so a volume predicate excludes every sheet). To OR two searches, send two calls and combine the answers. Each match comes back with the facts the search read - a face's surface, surfaceKind, area and radius; an edge's curve, length, radius and direction; a body's kind, volume, area and length - so a list can be shown with no second call, and searched says how many entities were examined, so an empty answer over a big model reads differently from an empty answer over an empty scope. Directions compare within within degrees, defaulting to exactly parallel at the kernel's own precision; radius matches within tolerance, defaulting to the kernel's linear precision. For "similar to this one": read the exemplar's facts with query.measure, then send them here as predicates. A round face's SEAM - the line where a cylinder, cone or sphere meets itself - is not one of the body's edges here: it bounds no second face, so nothing can round, chamfer or draft it, and it is neither matched nor counted in searched (query.edges still lists it). Nothing is changed, nothing is recorded, and nothing is selected - hand the IDs to select.set to select them.
query.fit_calibrations
What your printers actually make - every fit calibration this installation has recorded.
Detail
What your printers actually make - every fit calibration this installation has recorded. Each is one printer, material and nozzle, the coupon's holes and pins as designed (nominal) and as measured, and the line through each list: measured = offset + scale x nominal, in millimetres. holeFit and pinFit are separate because a machine that prints holes small prints pins large. scaleMeasured is false when every reading was one size, so the scale is 1 by assumption rather than measured; worstResidual is the furthest any reading sits from its line, so a mistyped reading shows. A fit is null for a list with no readings. Answers an empty list on a fresh installation.
query.fit_clearance
The clearance to DRAW for a joint so it prints with the gap you want, by the fit calibration of the printer it is made on.
Detail
The clearance to DRAW for a joint so it prints with the gap you want, by the fit calibration of the printer it is made on. A joint's socket is a hole and its tongue a pin, so the tongue's printed width comes from the calibration's pin line and the socket is drawn so its hole line prints it gap wider on each side: clearance is (drawnSocket - size) / 2, millimetres a side - the number to send as the clearance of feature.dovetail, feature.finger_joint, feature.snap_fit or feature.dowel. predictedTongue and predictedSocket are the widths this printer is expected to make. calibration has no default: one nobody recorded is refused, and so is one that never measured the holes or the pins this needs. clearance can come out below zero on a printer that prints holes large enough, and is answered anyway - the joint commands refuse a negative clearance and say why. Nothing is changed: this is a read.
query.fits
The ISO 286 limits-and-fits table: send a tolerance class and a nominal size and get the two deviations it means there, in millimetres, signed - H7 at 25 answers upper 0.021 and lower 0, g6 at 25 answers -0.007 and -0.020.
Detail
The ISO 286 limits-and-fits table: send a tolerance class and a nominal size and get the two deviations it means there, in millimetres, signed - H7 at 25 answers upper 0.021 and lower 0, g6 at 25 answers -0.007 and -0.020. Upper-case letters name a hole (H7, JS9, P7), lower-case a shaft (g6, k6, js7); grades run 01, 0, 1 to 18; sizes run over 0 up to 500 mm. The holes are derived from the shafts by the standard's own rule (ISO 286-1:2010 Table 2), so K, M, N are stated from grade 3 and K up to grade 8 exactly as the standard states them; j, za, zb and zc are not in the table, nor are a and b up to 1 mm, t up to 24, v up to 14 or y up to 18. it is the tolerance width IT(n) at that size, so upper minus lower. The table is a vocabulary rather than a dependency: a dimension stores the designation it was given (drawing.set_dimension's tolerance type fit) and derives its deviations from the size it measures, so nothing here is copied into a document. version names the table's shape rather than how many classes it has. It says nothing about the open document.
query.flat_pattern kernel
One body laid out flat - the blank it is cut from, and where the brake goes.
Detail
One body laid out flat - the blank it is cut from, and where the brake goes. outline is the boundary and the holes in it, as exact curves in the same vocabulary query.sketch and query.view_geometry use, in flat millimetres with the layout's minimum corner at (0, 0); width and height are how big a piece of stock it needs. bendLines is one line per bend, running down the MIDDLE of the band of flat that bend eats: allowance is how wide that band is, so the two tangent lines a shop marks are half of it either side. direction is up when the metal folds towards the side the flat is seen from and down when it folds away, and viewingFace names that side - flip both to look at the other. Nothing is unfolded and nothing is stored: this is derived from the part every time you ask, so a part and its flat pattern can never disagree and folding round-trips exactly. The part must carry a sheet-metal rule, because how much flat a bend eats depends on where the neutral axis sits inside the metal and that cannot be measured off the finished shape - set one with feature.base_flange or doc.set_sheet_metal_rule. A part with no bends is already flat and lays out as itself. unreachedWalls, unplacedBends and pieces are all normally zero, zero and one; anything else means the part does not all hang together and says which way - a wall is every piece of metal the part has, two faces the stock apart, so a tray with sharp corners and no bends counts its four sides as unreached rather than laying out as its floor alone. joinedEdges is normally empty: it names the edges along which two walls meet with NO bend between them - a corner an import modelled shut, a wall extruded square onto another - and such a part cannot be unfolded, so the layout claims the corner twice. Open them with feature.rip on exactly those edges, then ask again. Use query.bends for the bend table that goes beside this. cutLength is how far a cutter travels in millimetres: the boundary and every hole. Send any of perBend, perCutMetre and setupPerPart (and currency) and the reply also carries cost: each placed bend at the bend rate, cutLength at the per-metre rate, the setup charge once, and their total - the flat priced, with no material, margin or tax. Nothing is changed, nothing is recorded: this is a read.
query.fonts fonts
The font files on this machine, ready to name in sketch.draw's font.
Detail
The font files on this machine, ready to name in sketch.draw's font. Each entry is a path plus the family and style read out of the file itself — font takes a PATH, never a family name (ADR 0066), so this is how a client finds one. Ordered by family, then style, then path, and paged. A file that cannot be parsed is skipped rather than reported, and only the first face of a .ttc collection is listed, because that is the only face a path alone can reach. Nothing here is installed, cached on disk or modified; it is a directory scan. Set COCAD_FONT_DIRS to search somewhere else instead — directories in the reply always says where this answer came from.
query.history
The undo timeline, oldest first.
Detail
The undo timeline, oldest first. Steps flagged undone are the redo tail. Returns the most recent 50 by default. Each step says what one undo of it takes: commands (how many commands joined it under a group token), entities (everything it created or changed) and featureIds. Step numbers are minted once and never reused, so after a new command discards an undone tail the numbering skips; totalSteps counts steps, not numbers. at is when this core recorded the step, ISO 8601 UTC with milliseconds; on a document opened from a file every step is stamped as the log replays, so it is the open time rather than the authoring time.
query.hole_standards
Every fastener size this build knows, so a hole can be sized from a standard instead of from a chart.
Detail
Every fastener size this build knows, so a hole can be sized from a standard instead of from a chart. Each size carries a clearance triple - close, normal and loose, which are ISO 273's fine, medium and coarse - plus a counterbore and a countersink where the standard publishes one, and one entry per thread cut in that size carrying the drill a tap needs. Every number is a feature.hole argument value in its own unit, millimetres and degrees, so a caller picks a row and sends the number: nothing here is converted, scaled or rounded, and no command resolves a designation for you. counterbore, countersink and threads may be absent, and absent means the standard publishes no value rather than zero. standardRef beside each group names where its numbers came from, and source on each standard, size and thread reads built-in, user, or built-in, overridden - saying whether that row is this build's own or came from your hole-standards.json. kind on each standard reads fastener, insert, pilot or bearing: an insert standard's rows each carry one installDiameter, an insertLength and a minHoleDepth for a heat-set insert, and outerDiameter where the vendor publishes the knurl's; a pilot standard's rows carry the pilotDiameter a thread-forming screw wants; a bearing standard's rows carry a bought bearing's bore, outerDiameter and width - none of those three kinds carries clearance fits, heads or threads. A fastener size may also carry hardware, the parts that fit it: a socketHeadCapScrew (headDiameter, headHeight - the counterbore's own depth - socketAcrossFlats, socketDepth and the lengths that are sold), a hexNut (acrossFlats, thickness) and a washer (innerDiameter, outerDiameter, thickness), each absent where the table publishes none. It says nothing about the open document and never fails.
query.interference kernel
Which solids in this document are sharing the same space, and how much of it.
Detail
Which solids in this document are sharing the same space, and how much of it. Every pair that overlaps comes back with the volume they have in common and the box that volume sits in, so you can tell a 0.02 mm rub from a part that is half-buried in another. Bodies that merely TOUCH - two faces flush against each other, a shaft exactly the size of its bore - are not reported unless you send touching, because they share a surface and no substance; with it they come back beside the overlaps with a volume of 0 and no box. Nothing is changed, nothing is created and nothing enters the timeline: this is a question, and asking it a hundred times costs a hundred nothings. Pairs are screened on their bounding boxes before any solid arithmetic runs, so a large assembly of parts that are nowhere near each other is cheap; a document where everything overlaps everything is not. Pairs you have told this document to ignore with assembly.set_interference_ignored are left out of pairs and listed in ignored instead, so a designed press fit stops being noise without the answer ever hiding it from you. Both bodies of any pair reported here can be handed straight back to assembly.create_interference_body, which makes the material they share into a body you can measure, section or cut with - which is how you answer "how much do I have to shave off?" rather than only "they overlap".
query.joints kernel
Every joint in this document, in the order they were made - what is jointed to what, how, and on which faces.
Detail
Every joint in this document, in the order they were made - what is jointed to what, how, and on which faces. Each row names the two placements, the two faces the joint origins were inferred from, the offset, angle and flip it was created with, and values and limits - a list each, one entry per degree of freedom in the order the joint's type lists them, so a rigid joint reports two empty lists and a ball reports three numbers. The faces are reported rather than the positions they work out to, because the faces are what the document actually stores: ask query.measure about one if you want where it is now. A placement appears as child at most once, which is what makes the set a tree.
query.license_state
This copy's license state and edition (ADR 0653).
Detail
This copy's license state and edition (ADR 0653). state is unlocked (a build that checks no license - every developer build - so everything runs), licensed (a paid License File covers this release) or free (CoCAD Free: no License File, one that does not read or was refunded, or a release dated after its Download Year). unlocked and licensed are CoCAD Pro; free is CoCAD Free. reason is one word a client can switch on: no-key, licensed, no-license, unreadable, release-after-year or withdrawn. edition is personal or business when a License File decided the state, otherwise null. until is the UTC date (YYYY-MM-DD) that decides it - a Download Year covers releases dated before it - otherwise null. It never names the licensee: the core keeps no name and no email. The state is worked out again whenever a License File is added, kept or withdrawn or the UTC date rolls, with no restart, and license.changed tells every connection when it does. CoCAD Free runs everything but the CoCAD Pro features, and refuses those with REQUIRES_PRO, whose details carry {feature, command, edition, upgradeUrl, reason}. It says nothing about the open document and never fails.
query.links
Every linked component this document holds, in the order its recipe names them, and whether the file each one points at is still there.
Detail
Every linked component this document holds, in the order its recipe names them, and whether the file each one points at is still there. A linked component is one inserted with link true: the part is not embedded, so the file is re-read every time this document opens, and moving or renaming that file is what breaks it. Each row gives the path exactly as the recipe stores it, where that path points from this document today, the name the part goes by, the command that made the link, the ft: id of the timeline feature that made it (null when the recipe records no number, which a hand-written file will not), and issue - null when the file is there, or an object naming what is wrong with it. A stored path may be relative, which means beside this document's own file: resolvedPath is where it lands, and it is the same string as path for an absolute one. resolvedPath is null only when the path is relative and this document has never been saved, so there is no folder to measure it from - the issue code for that is UNRESOLVED_PATH, and the remedy is to save the document rather than to go looking for the part. The other code is INVALID_PATH, the same code the open itself refuses with, meaning there is no file where the path points. The check is about the FILE and not about the document: a link can be broken while the part is still on screen, because the file was moved after this document opened, and a broken link blocks nothing - the rest of the document goes on working exactly as it did. Embedded components are not listed and do not need to be: their bytes are in this document, so there is nothing outside it to lose. A suppressed insert is not listed either, because a suppressed record does not re-read its file. Nothing here is stored: the answer is computed where it is asked, so a file put back where it belongs reads healthy on the next call with no repair step at all.
query.mass_properties kernel
The full engineering mass-properties report: per body, the volume (mm³), surface area (mm²), centre of gravity (mm, world, the VOLUME centroid), the moments and products of inertia, the principal axes and moments, and the radii of gyration — plus a combined rollup over everything named, which is how an assembly is weighed.
Detail
The full engineering mass-properties report: per body, the volume (mm³), surface area (mm²), centre of gravity (mm, world, the VOLUME centroid), the moments and products of inertia, the principal axes and moments, and the radii of gyration — plus a combined rollup over everything named, which is how an assembly is weighed. entities is optional: absent means every body in the document; a bd: names one body and an oc: names a component placement, contributing every body it owns, nested placements included. Each body is weighed at the density it HAS: the call's density argument if one is sent (it overrides everything, which is how "weigh it all in aluminium" is asked), else the material assigned to that body with doc.set_material, else nothing — and every row says which number fed it in its own density key (g/cm³, or null). With a density, mass is answered in GRAMS and the inertia moments in g·mm²; without one those keys are NULL: assign a material or send a density, because a made-up number would be worse than a missing one. Rows may legitimately differ — a steel pin in an ABS housing — and combined then carries the true mass-weighted rollup with a null density of its own, because there is no single number to name. combined's mass is null unless EVERY solid row had a density: a sum missing one body reads as the whole assembly's mass and is not. The density-free half is answered either way: the principal AXES and the radii of gyration do not depend on a uniform density at all (a radius of gyration is sqrt(I/m), and the density cancels). frame chooses where the inertia tensor is taken: "com" (the default) is about each body's own centre of mass in world axes — the rollup's about the combined one; "world" is about the document origin in world axes; a cs: ID is about that coordinate system's origin in ITS axes. A construction plane is refused by name: its in-plane axes derive from its normal by convention, so a tensor in them would be nine numbers about axes nobody chose — construct.coordinate_system is how a chosen frame becomes something this argument takes. Principal properties are always about the centre of mass whatever frame says, because they are the frame-free half of the report. Convention: ixx is the MOMENT ∫(y²+z²)dm and ixy is the PRODUCT ∫xy·dm — positive integrals, the numbers a handbook tabulates; the inertia TENSOR's off-diagonals are their negatives. A sheet or wire body answers solid: false with every measurement null — it has no enclosed material, so it has no mass properties; measure a sheet's area or a wire's length with query.measure. A mesh body (a scan made a body with body.from_reference_mesh) is weighed off its own triangles, exactly for what they are, when they close into one consistently wound surface, and joins combined like any solid; an open or inconsistently wound one answers solid: false, as a sheet does. combined sums the solid rows only and says so: count is every row, measured is how many fed the sums. Nothing is changed, nothing is recorded: this is a read.
query.materials
Every material this build knows - a small engineering set, each row a name, a density in grams per cubic centimetre, its provenance in ref, and a default appearance as r, g and b fractions between 0 and 1.
Detail
Every material this build knows - a small engineering set, each row a name, a density in grams per cubic centimetre, its provenance in ref, and a default appearance as r, g and b fractions between 0 and 1. The library is a vocabulary rather than a dependency (ADR 0324): a document never references these rows - a caller reads one and sends the numbers themselves, so a saved model can never depend on which machine opened it or on later edits to this table. density is in the unit query.mass_properties takes; nothing here is converted, scaled or rounded. source on each row reads built-in, user, or built-in, overridden - saying whether that row is this build's own or came from your materials.json, which adds materials and changes shipped ones by name. appearance is absent on a row that names no default look, and absent never means black. version names the shipped table's shape rather than your file's. It says nothing about the open document and never fails.
query.mcp_setup
How an AI client connects to THIS install of CoCAD, worked out from what is on this machine rather than described in general.
Detail
How an AI client connects to THIS install of CoCAD, worked out from what is on this machine rather than described in general. snippet is the text to paste into an MCP client's configuration file - the whole mcpServers object, so it lands at the right nesting level - and serverKey is the name CoCAD is filed under inside it, which is what a person means when they tell an AI to use cocad. server says whether this build could find its MCP server at all: command and args are absolute paths that exist, layout is installed (beside the core) or repo (a development checkout), and env carries COCAD_CORE_PATH so a client that starts before CoCAD does can launch a core instead of refusing. When found is false, problem is one sentence saying what is missing and searched lists every path that was looked at, in order, so the answer can be checked rather than believed. clients is the clients this build knows how to set up here, each with its configPath, whether that file exists yet, and its transport: a stdio row launches CoCAD with the snippet above and its own snippet is null, while an http row connects to a running cocad-mcp --http and its snippet is that client's own spelling with <url> and <token> left where the server's address and bearer token go. The list is open and being absent from it means only that nobody has verified that client - every MCP-capable client works with the same snippet. Nothing here is guessed: a path in this reply is a path this build looked at. It says nothing about the open document and never fails.
query.measure kernel
Measure bodies, faces, edges and corners: volume, surface area, centre of gravity, arc length and radius per entity, a corner's position (its row's centroid, kind vertex, every other quantity null, nothing added to the totals), running totals over the whole list, and — when exactly two things are named — the shortest distance between them, the two points that realise it, the dX/dY/dZ between those points, and the centre-to-centre distance where both ends are round — a circular edge, a cylindrical face or a spherical face, so the spacing of two holes is measured by naming either their rims or their bores, and of two balls by naming their surfaces.
Detail
Measure bodies, faces, edges and corners: volume, surface area, centre of gravity, arc length and radius per entity, a corner's position (its row's centroid, kind vertex, every other quantity null, nothing added to the totals), running totals over the whole list, and — when exactly two things are named — the shortest distance between them, the two points that realise it, the dX/dY/dZ between those points, and the centre-to-centre distance where both ends are round — a circular edge, a cylindrical face or a spherical face, so the spacing of two holes is measured by naming either their rims or their bores, and of two balls by naming their surfaces. A spherical face's row carries its centre and radius, with axis null. The two ends may be parts of the SAME body, which is how one wall's thickness is measured: name that wall's outside face and the face directly behind it. On a hollowed (shelled) part a face inside the hollow is named for the way it POINTS - into the hollow - so the inside of the Front wall is named Back and the inside of the Back wall is named Front; pair a wall's faces by where they are, never by matching names, or the answer is the distance across the hollow. query.wall_thickness answers every face's wall at once. Lengths are millimetres, areas mm², volumes mm³, Z-up; round for display with the units.precision preference. Mass is absent here - query.mass_properties weighs a body at the material doc.set_material assigned it, or at a density you send. A SHEET body — a surface with no enclosed material (ADR 0301) — answers volume null and centroid as its surface's own: null is 'not a measurement', never zero, because a sheet has no volume to measure until feature.thicken gives it thickness and makes it a solid (ADR 0302). Every row also says where the thing CAME FROM: feature is the ft: of the timeline feature that made it, and seeds is what a face or edge was derived from in that feature's own words - a hole's wall answers ["hole:shank", ...], a box's side ["face:000000"] - so a tool can find the feature behind a face and edit it (ADR 0310). seeds is null on a body. A MESH body - one made from a scan - is measured off its own triangles, exactly for what they are: its area always, and its volume and volume centroid only when the triangles close up into one consistently wound surface; an open scan answers volume null and its surface's centroid, as a sheet does. between is null when either of two named things is a mesh body, because the distance is taken between exact surfaces. A face row names what lies under the face twice: surface is plane, cylinder or other, and surfaceKind says what an other is - plane, cylinder, cone, sphere, torus, bspline, revolution, extrusion, offset, or other for a surface with no name (ADR 0643); both are null on a body and on an edge.
The part-metadata record as stored - part number, description, material, revision, the exclude-from-BOM flag and any custom fields.
Detail
The part-metadata record as stored - part number, description, material, revision, the exclude-from-BOM flag and any custom fields. Name a component definition ("cp:1") to read its record, or leave entity out to read the document's own - a part file's part IS the document. Sparse: only what has been set is present, so an unset record is an empty object, and empty is an answer rather than an error. Occurrences and bodies carry no record of their own - a placement reads its definition's, and a body's part is the definition or document that owns it.
query.mirror_planes kernel
Which planes is a body a mirror image across - and, for a broken or partly missing part, how much of it still is?
Detail
Which planes is a body a mirror image across - and, for a broken or partly missing part, how much of it still is? The surface is sampled evenly by area; a plane counts a sample as matched when the sample's mirror image lands on the surface within tolerance, facing the same way. Each plane is reported with coverage, the share of the surface area matched (1 is a perfect mirror image; a part with a piece broken off one side matches less, and the planes are found from the part that survived, so the missing piece does not pull them off), deviation, the root mean square gap of the matched points, and matchedArea/unmatchedArea in square millimetres. Planes covering less than 60% are not reported, and only the best plane in any one direction is: a whole part cannot be a mirror image across two parallel planes. Best first, at most 12 (truncated says there were more - a ball or a round bar is a mirror image across every plane through its centre or axis). A plane is normal (a unit vector, its largest component positive) and offset, so that normal . point = offset on the plane; origin is a point of the plane near the middle of the matched surface. A plane square to an axis is reported exactly square to it and spelled for the commands that use it: basePlane names the base plane it is parallel to and distance is what construct.plane with type offset takes from that base plane (XZ's normal points along -Y, so a plane at y = 5 is distance -5); at distance 0 it IS the base plane, which feature.mirror takes directly. basePlane is null for any other plane. To complete a broken part from its surviving half, mirror the body across the plane and join the image to it. A mesh body (a scan) is measured off its own triangles, whichever way they are wound; an exact body off a tessellation finer than the tolerance. Nothing is changed, nothing is recorded: this is a read.
query.motion_study kernel
Drive a joint through a range of motion WITHOUT moving anything, and find out where its parts collide.
Detail
Drive a joint through a range of motion WITHOUT moving anything, and find out where its parts collide. The joint is swept from from to to in steps equal poses (both ends counted), and every pose comes back with where each moving body would stand - a rigid motion from where it is now, and its bounding box - and every pair of a moving body against a still one that would share material there, with the volume and the box, in exactly query.interference's shape. clearSteps and firstCollision are the range of motion in two numbers; the per-step list is the evidence. Nothing is changed, nothing is journaled and no event is raised: this is a question, not a drive, so the live assembly stays where it is and nobody's window moves. Leave from and to out to sweep the joint's own limits, which must both be set for that. Every pose is checked against the limits exactly as assembly.set_joint_value would check it - a study never reports a pose a drive would refuse. Bodies that move together (the joint's whole subtree) are not checked against each other, because their overlap is the same at every pose - ask query.interference about those. Pairs ignored with assembly.set_interference_ignored are skipped and listed in ignored; mesh, freeform and field bodies are passed over and listed in skipped. Send touching to count contact as a collision. Send links to move other joints WITH this one - two meshing gears, a pinion and its rack, a lead screw and its nut: each linked joint moves ratio times as far as this one, from where it stands now, its bodies join movingBodyIds, and bodies two different joints move are checked against each other at every pose.
query.mounting_features kernel
What can this part be mounted by?
Detail
What can this part be mounted by? Lists a body's HOLES, BOSSES, FLATS and the PATTERNS its holes make, so mounting a motor, a board or a bearing to something is one read: "four 3.2 mm holes on a 31 mm square round a 22 mm boss, on the front face". A hole or a boss is a cylindrical face that goes all the way round - a hole with the material outside it, a boss (a pin, a shaft, a pilot) with the material inside; a fillet or a slot's rounded end is neither, and coaxial rounds (a counterbore, a stepped shaft) are separate rows. Each has its face, diameter, direction (a unit vector, its largest component positive), start and end (the ends of its axis, in that direction) and depth or height. A hole's openings are the flat faces it opens onto, each with at - where its axis meets that face, the centre to put a matching hole or a sketch circle at - and through is true when it opens at both ends; a boss's standsOn is the flat it rises from, the same way. flats is every planar face, largest first, with its outward normal, origin (its centroid), area and the holes and bosses on it. patterns groups holes of equal diameter on parallel axes, two or more, and reports every arrangement that is true of them - line (direction, length, and spacing when equal), grid (direction, columns, rows, spacing, rowSpacing) and circle (centre, the pitch-circle diameter, and angle when equally spaced) - so four holes on a square come back as both a grid and a circle; an arrangement that does not fit is null. Not recognised: countersinks (cones), slots, threads (query.features has a hole feature's thread) and a bore split into separate faces. For the gap between two parts use query.interference (do they share material?) and query.measure on the two bodies (how far apart?). Lengths are millimetres, Z-up. Nothing is changed, nothing is recorded: this is a read.
query.named_views
Every named view this document holds, in the order they were made - each giving its camera (the five channels view.set_camera takes), its display style, the section and explode states it shows (null meaning uncut/assembled), and the entities it hides.
Detail
Every named view this document holds, in the order they were made - each giving its camera (the five channels view.set_camera takes), its display style, the section and explode states it shows (null meaning uncut/assembled), and the entities it hides. Applying one is a composition: view.set_camera with the camera, doc.set_visible for the hidden set. Nothing here says which view is showing: that belongs to whoever is looking, exactly as a camera does.
query.open_with desktop
List the programs this computer offers to open a kind of file - its own Open with list for an extension, so for 3mf or stl usually the slicers installed here (Bambu Studio, PrusaSlicer, OrcaSlicer...) and for step the CAD packages.
Detail
List the programs this computer offers to open a kind of file - its own Open with list for an extension, so for 3mf or stl usually the slicers installed here (Bambu Studio, PrusaSlicer, OrcaSlicer...) and for step the CAD packages. Each handler has an id, the name the desktop shows, and default: true on the one a double-click uses. Hand an id back as openWith on export.3mf, export.stl, export.obj, export.gltf, export.step or export.iges to write the file and open it in that program rather than the default. CoCAD keeps no list of programs of its own: this is the desktop's list, so it is empty on a machine with nothing registered for the type and on platforms where the desktop does not list handlers (canChoose: false) - open: true still opens the default there. Reading the list starts nothing.
query.parameters
Every user parameter this document holds, with its computed value, the names it refers to, the names that refer to it, and the recorded operations that stand on it - the where-used view, both halves - and the intent note, when somebody wrote down why the value is what it is (param.set_intent).
Detail
Every user parameter this document holds, with its computed value, the names it refers to, the names that refer to it, and the recorded operations that stand on it - the where-used view, both halves - and the intent note, when somebody wrote down why the value is what it is (param.set_intent). Also lists every function the expression language has.
query.pause_state
Whether the human has paused AI control, who paused it, and how much is held.
Detail
Whether the human has paused AI control, who paused it, and how much is held.
query.plane
One plane - a construction plane or one of the three base planes: where it is, and what it was built from.
Detail
One plane - a construction plane or one of the three base planes: where it is, and what it was built from. The frame is the same twelve numbers a sketch reports, so anything that can place a sketch in the model can place a plane. query.tree lists them all. baseIssue (or baseIssues, in step with base and bases) and edgeIssue are null while the references the plane was built from still resolve, and carry a code plus any candidates when an edit split or consumed one - the plane keeps its stored frame either way.
query.point kernel
One construction point: where it is, and what it was built from.
Detail
One construction point: where it is, and what it was built from. entityIssue is null while the edge or face the point was built from still resolves, and carries a code plus any candidates when an edit split or consumed it; the point keeps its stored position either way.
query.polyline
Every curve in a sketch as a run of straight segments, ready to draw — the 2D companion to query.tessellate.
Detail
Every curve in a sketch as a run of straight segments, ready to draw — the 2D companion to query.tessellate. Points are flat x,y pairs in sketch coordinates and millimetres; place them in the model with the frame query.sketch reports. A closed curve does NOT repeat its first point, so draw points as a loop rather than a strip when closed is true. Construction geometry and centrelines are included and flagged, never filtered. fullyConstrained says whether the solver pinned that curve, and dof how many degrees of freedom the sketch has left; both are null when nothing has solved it since it changed.
query.preferences
Application preferences: what they are set to now, what they ship as, and what each one accepts.
Detail
Application preferences: what they are set to now, what they ship as, and what each one accepts. Session state, not document state — a new document does not reset them.
query.print_estimate kernel
Roughly how long a body takes to print on a filament (FDM) 3D printer, and how much filament it uses.
Detail
Roughly how long a body takes to print on a filament (FDM) 3D printer, and how much filament it uses. An ESTIMATE from the body's surface and the print settings, not a slicer: the part is split into walls (walls lines of lineWidth round every layer), skins (topLayers and bottomLayers of solid layers under and over every surface facing up or down) and infill (infill percent of what is left inside), and each is timed as its volume over lineWidth x layerHeight x its average speed. Travel, retraction, layer changes and supports are NOT counted - a slicer's figure is usually somewhat longer, and its plan is the one to trust before a long print. Every setting has a default (a 0.4 mm nozzle printing PLA at 0.2 mm layers) and the reply echoes the profile it used. The part prints as modelled, +Z up, unless buildDirection says otherwise. The reply: seconds and grams (the totals), filamentLength (mm off the spool), the enclosed volume, height and layers, and walls/skins/infill each with its volume (mm3 of plastic) and seconds. A mesh body (a scan) must be closed - feature.repair_mesh mends one that is not; a sheet or a wire has no material and is refused. Give any of materialPerKg, machinePerHour and setupPerPart (and currency) and the reply also carries cost: the grams at the kilogram rate, the seconds at the hourly rate, the setup charge once, and their total - the estimate priced, with no margin or tax. Nothing is changed, nothing is recorded: this is a read.
query.printer_reachable desktop
Check that a printer answers at its address.
Detail
Check that a printer answers at its address. For OctoPrint and PrusaLink this is a GET of /api/version and for Moonraker of /server/info, each with the stored key in the X-Api-Key header; for a Bambu printer it is a secure (TLS) connection to its LAN port, 8883 unless the host names another, and nothing is sent over it. reachable says something answered; status is the HTTP status (null for Bambu); keyAccepted is true when the printer accepted the request, false when it refused it for want of a key (401 or 403) and null when that was not asked - a Bambu access code is checked when a print is sent. For a Bambu printer, certificate is the certificate it showed (sha256, serial, issuer) and certificateCheck compares it with the one trusted for it: matches, notPinned (none trusted yet - save it again), changed (a different certificate - refused until trusted with core.set_printer's certificate), inspected (issued by a program inspecting the connection, such as an antivirus) or noSerial; both are null for the other kinds and when nothing answered. address is what was dialled, and detail says the outcome in one sentence. Nothing is sent to print and nothing is changed. Waits at most timeoutSeconds for an answer (3 when omitted).
query.printer_status desktop
What a printer is doing now, asked over its own local API: OctoPrint /api/job, PrusaLink /api/v1/status (and /api/v1/job for the file's name), Moonraker's print_stats and virtual_sdcard.
Detail
What a printer is doing now, asked over its own local API: OctoPrint /api/job, PrusaLink /api/v1/status (and /api/v1/job for the file's name), Moonraker's print_stats and virtual_sdcard. state is one of idle, printing, paused, finished, attention (waiting for someone at it), error, busy, offline (OctoPrint not connected to the printer) or unknown; printerState is the printer's own word for it. job is null when nothing is loaded, else the file, progress as a percentage, secondsPrinting and secondsLeft - each null where the printer does not report it, never estimated. reachable, status, keyAccepted and address mean what they mean in query.printer_reachable, and detail says it in one sentence. A Bambu printer is asked over its encrypted LAN mode (MQTT, a full report) once a certificate is trusted for it and its access code is kept - nothing is sent to one showing a different certificate; without them this is a connection check, state is unknown and detail says what is missing. Changes nothing.
query.printers desktop
The printers this installation sends to: each with the name you gave it, its kind (the local API it speaks - octoprint, prusalink, moonraker or bambu), its host on your network, hasKey - whether an API key or access code is kept for it - and certificate: for a Bambu printer the certificate trusted for it (sha256, serial, issuer), else null.
Detail
The printers this installation sends to: each with the name you gave it, its kind (the local API it speaks - octoprint, prusalink, moonraker or bambu), its host on your network, hasKey - whether an API key or access code is kept for it - and certificate: for a Bambu printer the certificate trusted for it (sha256, serial, issuer), else null. The key itself is never shown: it is kept in Windows Credential Manager, never in a CoCAD file. canStoreKeys is false where this computer has no credential store. path is the file the list is kept in. Answers an empty list on a fresh installation.
query.profiles
The closed regions in a sketch — what feature.extrude takes.
Detail
The closed regions in a sketch — what feature.extrude takes. Every closed loop is one profile, including a loop nested inside another, and openChains names the gaps when nothing closes. A profile ID names a region, not a position in this list: it survives edits elsewhere in the sketch, and the list order is not the ID order. Curves that cross without sharing an endpoint are NOT split at the crossing.
query.provenance kernel
What made one face, edge or vertex, and what stands on it - the document's own record of where a piece of geometry came from and what would break if it went away.
Detail
What made one face, edge or vertex, and what stands on it - the document's own record of where a piece of geometry came from and what would break if it went away. madeBy is the ft: of the timeline feature that CREATED this element's durable name, and seeds are what that feature built it from (a sketch curve cu:, a hole role like "hole:shank", a primitive's canonical face) - an element a later feature merely carried through keeps its name, so madeBy is its origin and not the last thing that touched it. dependents lists every committed operation whose arguments name this element: its command, the ft: it minted if it minted one, that feature's label, and via - the id the arguments spelled. They are matched by DERIVATION, not by the id string, so a reference is still found after a rebuild renumbered it. alive says whether this element is still in the body; when it is not, successors names what replaced it, so a stale reference can be followed by hand. Every answer comes from the operation log and the naming tables - nothing is guessed from geometry, and a question the records cannot answer comes back null rather than invented. A body is not an element and is refused: query.tree's featureId says which feature made one. Nothing is changed, nothing is recorded: this is a read.
query.recent
List the documents most recently saved or opened, newest first.
Detail
List the documents most recently saved or opened, newest first. A document joins the list whenever doc.save or doc.open names it, and the newest files.recentCount of them are kept (10 by default, 0 to remember none). Each entry says whether the file is still there, so one that has been moved or deleted is reported rather than quietly dropped - open it with doc.open on the path reported here. Answers an empty list on a fresh installation, and when remembering is switched off.
query.recipe
Read a recipe file back - its name and the ordered list of commands inside it - so you can run them yourself, one at a time or all at once.
Detail
Read a recipe file back - its name and the ordered list of commands inside it - so you can run them yourself, one at a time or all at once. Every step is checked against THIS build's registry first, so a recipe you can read is a recipe you could run: a command this build does not have, arguments its schema refuses, a step that only reads or one that acts on the running core is refused whole, naming the step by index. Nothing is run and nothing is changed - the steps come back to you to send. inputs lists the parameters a recipe filed from a whole document builds; pass inputs to build it at other values, and one param.set per input you give is appended to the steps. Needs no open document.
query.recognize_features kernel
What features was this body made with?
Detail
What features was this body made with? Reads a body - typically one import.step brought in with no recipe - back as the HOLES, COUNTERBORES, COUNTERSINKS, SLOTS, FILLETS and CHAMFERS a person would have modelled, and lists every face no rule explains, so an empty finding never means "all recognised". holes: each plain round bore (query.mounting_features' own hole rows, the same arithmetic) with its face, diameter, direction, start, end, depth, through (open at both ends), openings (the flat faces it opens onto, with at - its centre on that face) and bottom - for a blind hole, the face closing it and its kind, flat or cone (a drill point), or null when nothing closes it squarely. counterbores: a bore whose mouth is a wider coaxial bore closed by a flat step, as ONE row spelled the way feature.hole takes it - head "counterbore", diameter (the shank's), headDiameter, headDepth (the step, from the entry plane), depth (where the shank's bore ends, from the same plane) - with face (the head's bore), shank, step, direction (into the material), entry (the mouth's centre on the entry plane), through, openings and bottom. countersinks: a bore whose mouth is a whole-turn cone on its axis - head "countersink", diameter, headDiameter (the rim), headAngle (the cone's included angle, degrees), sinkDepth (the cone's own depth, the number feature.hole derives), depth, face (the cone), shank, direction, entry, through, openings and bottom. slots: two concave half-cylinders of one radius on parallel axes, each running smoothly into the same two parallel flat walls - ends and walls (their faces), width (the diameter), length (tip to tip), depth, centres (the two end arcs' centres on the entry plane, the points sketch.draw type "slot" takes), direction (into the material), through and bottom (the flat floor, or null). fillets: each partial cylinder or torus running smoothly into two or more other faces, with its face, surface (cylinder or torus), radius (a torus's tube radius), turn (its arc in degrees - 90 for a quarter round), concave (true for a fillet in an inside corner, false for a round over an outside edge, null on a sheet) and blends (the faces it runs into). chamfers: each flat strip creased to two flat faces along parallel straight edges of equal length, with its face, between (the two faces, each with the distance from the virtual edge where their planes would have met - the numbers feature.chamfer takes), angle (between those two faces' normals), length and width. unexplained: every other face with its surface word (plane, cylinder, cone, sphere, torus, bspline, ...), the body's own outer flats included - the stock those features were cut from is not a feature this read names. faces is the body's face count. Known limits, said rather than guessed: a counterbore whose head does not open onto a flat face (a chamfered or filleted mouth) is two hole rows and a chamfer or fillet row; a countersink on a counterbore is a countersink and a hole; a slot with a rounded floor, an arc slot or a slot whose end arcs are split into several faces is not a slot and its ends read as 180-degree fillets; a bore split into separate faces by a slot is not a hole; a variable-radius blend, a corner patch where fillets meet and a sphere are unexplained. Lengths are millimetres, angles degrees, Z-up. Nothing is changed, nothing is recorded: this is a read.
query.recovery
List the unsaved sessions this installation can still recover, newest first.
Detail
List the unsaved sessions this installation can still recover, newest first. CoCAD records every command that changes a document as it commits, and deletes that recording when it shuts down cleanly - so anything reported here is work from a session that crashed. Recover one with doc.recover on the path reported here. Answers an empty list when there is nothing to recover, which is the ordinary case.
query.reference_mesh kernel
The triangles of one reference mesh, in millimetres, Z-up - what a viewport draws an imported scan or print as.
Detail
The triangles of one reference mesh, in millimetres, Z-up - what a viewport draws an imported scan or print as. positions is flat x,y,z triples and indices is three entries per triangle, pointing into them. There are NO normals, and that is a fact about the file rather than an omission: an imported mesh keeps the winding the file gave it, because a real STL often disagrees with itself about which way a facet faces, so draw a reference double-sided and shade it flat from each triangle. The answer never changes for a given mesh - nothing in CoCAD edits one - so read it once per document and keep it. Use query.tree to list the reference meshes and query.tessellate for a body.
query.render_providers
Who can currently draw a screenshot.
Detail
Who can currently draw a screenshot. Empty means view.screenshot will fail with NO_RENDER_PROVIDER.
query.requirement_blame kernel
Which feature broke a requirement - the change after which it stopped being met.
Detail
Which feature broke a requirement - the change after which it stopped being met. Give featureId, a requirement's ft: from query.requirements. CoCAD rebuilds the model as it stood before each recorded change, newest first, and measures the requirement there with the same read query.requirements uses, until it finds the latest point where the requirement WAS met (or where what it measures did not exist yet). brokenBy names the feature (ft:) the change right after that point made, brokenByCommand the command, and before and after say what the requirement measured on either side of it - so "the fillet at ft:7 took the wall from 1.8 mm to 1.2 mm" is read straight off the reply. A change that made no feature of its own (a doc.delete, a doc.set_material) has brokenByCommand and a null brokenBy. Nothing is found when the requirement is met now, is suppressed, was never met at any earlier point, or the search stopped - reason says which, in English, with reasonId (and reasonArgs when it takes any) naming that sentence in CoCAD's message catalogue so a client can show it in the person's language; at most 40 earlier models are rebuilt, and searched counts them. Like git blame, it answers about the timeline as it is now: an edit to an early feature is blamed on that feature's place in the timeline. Nothing is changed. Each model searched is one rebuild, so ask it about a requirement that is failing, not on every change.
query.requirements kernel
Every requirement stated with feature.require, checked NOW against the current model - the test results for the part.
Detail
Every requirement stated with feature.require, checked NOW against the current model - the test results for the part. One row per requirement in timeline order: its statement, the check (quantity, entities, axis, atLeast, atMost, unit), status (pass, fail, unmeasured or suppressed), measured (the number, or null), reason (why it could not be measured, in English, with reasonId and reasonArgs naming that sentence in CoCAD's message catalogue when it has one), face (for wallThickness, the fc: where the wall is thinnest) and read - the exact command and arguments that produced the number, so you can ask it again and see the whole answer. unmeasured is never a pass: a requirement whose body was deleted or whose read now refuses is reported with the read's own sentence. counts sums the rows. Read this after every change you make, before saying the part is done: a fail means the change broke something the person asked for. Nothing is stored and nothing is changed: every read is a fresh check, so it is never stale.
query.rigid_groups kernel
Every rigid group in this document, in the order they were made, each naming the placements it welds.
Detail
Every rigid group in this document, in the order they were made, each naming the placements it welds. A group has no geometry of its own, so this is the only way to find out what is welded to what - and the members are read off the placements rather than stored on the group, so a row here can never disagree with the tree.
query.rotation_axes kernel
Which axes does a body repeat itself about, and how many times - and, for a broken or partly missing part, how much of it still does?
Detail
Which axes does a body repeat itself about, and how many times - and, for a broken or partly missing part, how much of it still does? A flange with six lugs repeats six times about its centre; a sprocket with a tooth gone still repeats twenty times, minus the tooth. The surface is sampled evenly by area; for a count n, each of the turns k * 360 / n is tried, and coverage is the share of the surface area whose turned image lands on the surface within tolerance, facing the same way, averaged over every turn of the pattern (1 is a perfect repeat; a part with a piece broken off matches less, and the axis is found from the part that survived, so the missing piece does not pull it off). count is the LARGEST count that matches as well as the best (a part that repeats six times also repeats three times and twice), at most 100. An axis about which the part matches under ANY turn - a revolved part, a cylinder, a ball - is round: true, with count and angle null. deviation is the root mean square gap of the matched points, and matchedArea / unmatchedArea are in square millimetres. Axes covering less than 60% are not reported, and only the best axis in any one direction is; best first. Each axis is spelled for feature.pattern's circular type: direction (a unit vector, its largest component positive) and origin (the point of the axis nearest the middle of the surface) are its axis, count its count and angle its angle. To complete a broken part from what survives, pattern the body about the axis with that count and angle, operation join and targets the body itself - every copy fills in what another lost. An exact body's axis is placed exactly on a whole round face of it (a bore, a hub, a pin) when it lies along one, so the copies meet the original exactly. A mesh body (a scan) is measured off its own triangles, whichever way they are wound; an exact body off a tessellation finer than the tolerance. Nothing is changed, nothing is recorded: this is a read.
query.section_states
Every section state this document holds, in the order they were made, each giving its cutting plane as a point on the plane and a unit normal - millimetres in the document's own axes, the normal pointing at the material the cut removes.
Detail
Every section state this document holds, in the order they were made, each giving its cutting plane as a point on the plane and a unit normal - millimetres in the document's own axes, the normal pointing at the material the cut removes. Nothing here says which state is showing: that belongs to whoever is looking, exactly as a camera does.
query.selection
The shared selection: which entities the human and any connected AI are pointing at, in order, in the document this connection is on.
Detail
The shared selection: which entities the human and any connected AI are pointing at, in order, in the document this connection is on. Session state, not document state — it is never saved and never undone.
query.shape_search kernel
Find parts shaped like one body: every other body in the open document and in the .cocad files paths names (a folder is searched whole, every .cocad under it) is ranked by how close its SHAPE is to body's, closest first.
Detail
Find parts shaped like one body: every other body in the open document and in the .cocad files paths names (a folder is searched whole, every .cocad under it) is ranked by how close its SHAPE is to body's, closest first. Shape is compared by the D2 shape distribution - the distances between a thousand points scattered evenly over each surface - so where a part sits and how it is turned change nothing, and SIZE is divided out: a 10 mm cube and a 30 mm cube are the same shape. It tells proportions apart well and fine detail weakly - two blocks of one size with different holes read as close. Each match carries distance (0 is the same shape, a cube and a ball are about 0.016 apart, a cube and a 10:1 bar about 0.27; never more than 3), size (the body's mean point-to-point distance, mm) and sizeRatio (its size over body's, so 3 is three times as big), with path null for a body in the open document. Each file is rebuilt from its recorded steps, as doc.open would, without opening it - once: what a rebuild found is kept in a per-user shape index, so a later search answers a file whose size and write time have not changed without rebuilding it again (filesFromIndex counts those; the answer is the same either way). A file that does not read or rebuild is listed in skipped with why (message, in English, with messageId and messageArgs naming that sentence in CoCAD's message catalogue when it has one), and the search goes on. A body with no surface to compare - a curve, or a subdiv or field body not yet converted - is listed in notCompared. compared counts the bodies ranked. More than 1000 files under paths is refused: name a narrower folder. No document is changed and nothing is recorded: this is a read.
Every sheet-metal rule this build knows - a thickness, the inside bend radius to fold it at, the K-factor that says where the neutral axis sits across that thickness, and the bend relief to cut where a bend meets an edge.
Detail
Every sheet-metal rule this build knows - a thickness, the inside bend radius to fold it at, the K-factor that says where the neutral axis sits across that thickness, and the bend relief to cut where a bend meets an edge. Lengths are millimetres; kFactor is a fraction strictly between 0 and 1, where 0 is the inside face and 1 the outside. relief.type reads rectangular, round or tear, and a tear carries no width and no depth because it is a rip rather than a cut-out - absent there never means zero. material names the stuff the rule was written for, spelled as query.materials spells it, but it is a word on the row rather than a reference: nothing looks it up, and a rule carries every number a bend needs without one. The table is a vocabulary rather than a dependency (ADR 0427): a feature stores the numbers, never a reference to a row here, so a saved model's flat pattern can never change because a machine's rule table did - and a thickness this table does not list is folded by sending the numbers yourself. ref names where each rule's numbers came from, and they are typical air-bend values rather than a published standard: confirm them against your own press brake. source on each row reads built-in, user, or built-in, overridden - saying whether that row is this build's own or came from your sheet-metal-rules.json, which adds rules and changes shipped ones by id. version names the shipped table's shape rather than your file's. It says nothing about the open document and never fails.
query.sheet_sizes
Every drawing-sheet size this build knows - the ISO A series and the ANSI sizes - so a sheet can be set from a standard instead of from a chart.
Detail
Every drawing-sheet size this build knows - the ISO A series and the ANSI sizes - so a sheet can be set from a standard instead of from a chart. Each row gives its two EDGES in millimetres rather than a width and a height: shortEdge and longEdge, because which way round a sheet is drawn is the sheet's own field and not the size's. series reads iso-a or ansi, and ref names where the numbers came from - the ANSI rows are exact conversions of their inch definitions, so nothing here is rounded. The table is a vocabulary rather than a dependency (ADR 0333): a sheet stores the two lengths, never a reference to a row here, so a saved drawing's page size can never change because a machine's table did - and a size this table does not list is set by sending the two lengths yourself. version names the table's shape rather than how many rows it has. It says nothing about the open document and never fails.
query.shortcuts
Every keyboard shortcut CoCAD answers, so a shortcut editor - or a person asking what a key does - needs no second list.
Detail
Every keyboard shortcut CoCAD answers, so a shortcut editor - or a person asking what a key does - needs no second list. Each row gives an id, the label a person reads, the scope it is answered in, and the binding it ships with. scope reads global (answered wherever the focus is), model (the viewport with no sketch open) or sketch (the viewport with a sketch open): that is why F fits the view outside a sketch and arms the Fillet tool inside one, and it is what decides whether two bindings collide - global overlaps both of the others and model and sketch never meet. A binding is written unspaced with the modifiers Ctrl, Alt and Shift first, in that order, then the key. Esc is not in this list and cannot be bound to anything: it is the way back out of whatever is happening. The mouse is not here either - which product's mouse the viewport follows is the navigation.scheme preference. version names the shape of a row rather than how many rows there are. It says nothing about the open document and never fails.
query.sketch
Everything in one sketch: what it is drawn on, where that is in the model, its curves and its constraints.
Detail
Everything in one sketch: what it is drawn on, where that is in the model, its curves and its constraints. Curves and constraints page independently. dof is the degrees of freedom left at the last solve, and fullyConstrained on each curve says whether the solver pinned it; both are null when nothing has solved this sketch since it last changed. conflicting names the constraints that last solve could not satisfy together, whoever asked for it - [] when it settled, and null when nothing has solved this sketch since it last changed. On a face sketch, supportIssue is null while the stored face reference still resolves, or names what became of the face when it does not. A driving dimension that was given its number as an argument expression carries that text as expression - the parameter arithmetic the value is re-computed from on every rebuild - and a dimension whose number was typed carries none.
query.strength kernel
Will this part hold?
Detail
Will this part hold? A first-order strength check of one solid under one load case: the faces named in fixed are held still, each load pushes its face with a total force in newtons, and the reply answers how far the part bends and how close it comes to giving way. displacement: max (mm, the largest movement anywhere), at and direction. stress: max (MPa, the largest von Mises stress), at and face (the face nearest it). safetyFactor: yieldStrength over that stress - under 1 means it yields, 2 or more is the usual margin - or null when nothing is stressed; with buildDirection it is the smaller of that and acrossLayers.safetyFactor. acrossLayers (only with buildDirection): max (MPa, the largest stress pulling two printed layers apart), at and safetyFactor (layerStrength over it). hotFaces: up to ten faces with the highest stress next to them, highest first - where to add material. material and buildDirection echo what was used. cellSize, cells and modelledVolume say how finely the part was sampled (equal cubes; detail smaller than one cube is not seen), and converged and iterations say whether the solve finished. notModelled names what this check leaves out, so a reply is never read as more than it is: contact between parts, large deflections, buckling, fatigue and creep, stress concentrations finer than one cube, and a hold that reaches about one cube deep. Refused: a sheet or wire body, a face of another body, a face that touches no cube (send a smaller cellSize), material not joined to a held face, a load whose every cube is held, and more than 400,000 cubes. Lengths millimetres, forces newtons, stresses megapascals, Z-up. Nothing is changed, nothing is recorded: this is a read.
query.tangent_chain kernel
The smooth run of edges one edge belongs to: every edge reachable from it by stepping across a vertex where the curve carries straight on.
Detail
The smooth run of edges one edge belongs to: every edge reachable from it by stepping across a vertex where the curve carries straight on. This is how you round a whole rounded boundary in one feature.fillet instead of naming its arcs and straights one at a time — a rounded pocket is four lines and four arcs, and they are one chain. The answer always includes the edge you named, so a chain of one means nothing continues it. Reads the exact geometry, so it never moves with display density.
query.templates
List the templates a new document can be started from, in name order, and say where CoCAD keeps them.
Detail
List the templates a new document can be started from, in name order, and say where CoCAD keeps them. A template is an ordinary .cocad file in that folder: start from one with doc.open on its path followed by doc.save to wherever the new part belongs, and make one with doc.save into the directory reported here - there is no template format and no template-only command. The folder is reported even when it does not exist yet, because saving into it is what creates it. A template's name is its file name, so renaming the file renames the template. Answers an empty list on a fresh installation.
query.tessellate kernel
Triangle mesh for a body, in millimetres, Z-up.
Detail
Triangle mesh for a body, in millimetres, Z-up. Deterministic for equal inputs.
query.thumbnails
Read the preview pictures CoCAD has cached for these documents, in the order asked for.
Detail
Read the preview pictures CoCAD has cached for these documents, in the order asked for. Each entry answers the PNG as base64 or null when nothing is cached for that path - a document CoCAD has never had a picture of, and one whose picture has fallen off the end of the list, are the same answer. A preview is kept even when the file itself has gone, because a picture of what used to be there is the clearest way to say where it was.
query.tolerance_stack
A 1D tolerance stack-up: add a chain of sizes, each with its tolerance and a direction, and get the result's worst case and its statistical (RSS) spread.
Detail
A 1D tolerance stack-up: add a chain of sizes, each with its tolerance and a direction, and get the result's worst case and its statistical (RSS) spread. Each contributor is a drawing dimension (dimensionId - its measured size and its own tolerance, a fit's deviations derived at that size) or a size in hand (nominal, with a tolerance in query.drawings' spelling, a fit looked up in ISO 286 at the nominal); sign 1 adds it and -1 takes it away, so a gap is the housing's length minus each part inside it. worstCase puts every size at the end of its band that pushes the result furthest; rss reads each band as a symmetric 3-sigma spread about its middle and combines them in quadrature, carrying the shift of an asymmetric band. Both give max and min, and upper and lower as deviations from the stack's nominal. Each contributor's worstShare and rssShare say how much of the variation it is - the one to tighten first has the largest rssShare. With a requirement ({min, max}) the reply says whether each method stays inside it. Nothing is changed: this is a read, and it needs no open document unless a dimensionId does.
query.tree
The scene tree.
Detail
The scene tree. Summary by default (depth 2) so large models stay cheap to read; ask for more depth explicitly. Pages at 200 nodes — pass nextCursor back for the rest.
query.version
Which build of this core is running.
Detail
Which build of this core is running. id is the build's ONE name - <version>+<commits>.g<sha8>, plus .dirty.<hash> when it was built from uncommitted changes - and it is the string the installer's VERSION.txt carries, the window shows, and every saved file's generator records, so quote id in a bug report and nothing else needs quoting. commits counts the commits behind it and only ever grows, so a build 'at or after' another is a number compare. Beside it: version, commit, dirty, builtAt (the date), build (the preset that produced it), and one capabilities entry per optional library saying whether that library is linked. The command surface depends on the build - a core with no geometry kernel never registers body.box at all. The capability list is open: read the entries that come back rather than naming keys, because a build gate added later appears here without a client change. It says nothing about the open document and never fails.
query.vertices kernel
Every corner point of a body — the exact points, not mesh nodes, so they never move when the display density changes.
Detail
Every corner point of a body — the exact points, not mesh nodes, so they never move when the display density changes. Each carries how many edges meet there: three at a box's corner, two where a cylinder's seam ends. This is what to snap a dimension to, measure between, or hand a construction that wants a point in space — construct.plane type three_point takes three of these. There is no segments argument because a vertex has no length to discretise. A vertex ID is a durable identity, like fc: and eg:: it keeps naming the same corner through later features, and a corner an edit consumes leaves the list rather than renumbering the ones after it.
query.view_geometry kernel
The curves a drawing view draws, worked out NOW from the bodies it names - visible edges in one list, the ones the solid hides in another, and on a SECTION view the boundary of the cut in a third, because a print draws all three with different pens and hatches inside the last.
Detail
The curves a drawing view draws, worked out NOW from the bodies it names - visible edges in one list, the ones the solid hides in another, and on a SECTION view the boundary of the cut in a third, because a print draws all three with different pens and hatches inside the last. Nothing is stored and nothing goes stale: edit the model and ask again, and the answer has moved with it. Every curve is a line, circle, arc, ellipse or spline in the view plane's own millimetres, spelled exactly as query.sketch spells a 2D curve so anything that can draw a sketch can draw a print - but with no IDs, because a view's curves are a picture rather than entities anything can reference. THE SCALE IS REPORTED AND NOT APPLIED, and neither is the view's place on the page: these are the part's own millimetres, so a length measured off them is a length of the part rather than of the paper. Sharp edges and the outline are drawn; the smooth line where a fillet meets the face it blends into is not, because both ISO and ASME suppress it. The view's dimensions come back MEASURED here too - each with the number it states, worked out now, the two points its extension lines run from, and the LABEL the print draws: text, the number to its stored precision with its prefix and any ±tolerance, and stack, null or the pair written after it (the two deviations, reduced; or the two limits, full height); a dimension carrying an ISO 286 class also answers fit - the class's two deviations at the size just measured, in millimetres, or two nulls and a reason when the table does not state the class at that size; a dimension whose corners have left the model is answered with a null value and dangling true, kept on the sheet to be reattached rather than silently dropped. The view's annotations come back beside them, each with the words it says and where each of its leaders lands in this picture; a note's text is STORED rather than worked out, so a note whose corners have left the model is answered dangling and STILL CARRYING ITS OWN WORDS - which is the difference from a dimension, and is what lets a person read what a broken note was for before reattaching it. A general note points at nothing, so it has no leaders and can never dangle. A BROKEN view answers the shortened picture: the run between the break's from and to is gone, everything beyond it has slid back, breakLines says where each cut falls and how far across the part it reaches, broken and brokenBy say the band and the view that owns it - and every dimension's value was measured BEFORE the break, so a length across it is the part's. A BROKEN-OUT view answers the picture with its pocket cut in: the floor's boundary in cut, to hatch, the window's edge where it crossed material in breakoutBoundary, to draw thin, and breakout the pocket itself - a detail of such a view answers its parent's. And the corners come back too - every vertex of every body this view draws, with the vx: that names it in the MODEL, where it lands in this picture in the same millimetres as the curves, and how far into the picture it sits so that two corners one behind the other can be told apart. That list is how a click on a drawn corner becomes something drawing.add_dimension can measure between: the curves carry no IDs and never will, so this is the only way from the picture back to the part. A callout is the one annotation whose words are DERIVED rather than stored - off the hole or thread feature it names - so its text comes back HERE and not on query.drawings, with one leader landing per hole the feature drilled; and holes lists every drilled point and threaded face of the bodies this view draws, with the ft: a callout names it by and the words it would print, which is how a click on a drawn hole becomes a callout. circles lists every circular edge of those bodies - a hole's rim, a cylinder's end, a fillet's arc - with the eg: a radial or diameter dimension names it by, where its centre lands in this picture, its radius, and the shape of its projection (the unit direction it is widest in and the minor-over-major ratio: 1 seen true-shape, 0 seen edge-on), so a click on a drawn rim becomes a diameter. edges lists every STRAIGHT edge of those bodies with the eg: a linear dimension names it by and where its two ends land in this picture, so a click on a drawn line becomes its length: drawing.add_dimension takes that one eg: alone as a shorthand for the edge's two corners. A radial or diameter dimension's value is the MODEL's radius or diameter in every view, and its two points run from the centre to the rim (radial) or across the widest diameter (diameter). An angular dimension's value is the angle in DEGREES at its first corner between the rays to the other two, as this view draws them, and its three points are those corners in that order - the apex first; a side lying along the line of sight has no direction here, so the value is null with dangling false and the points still answered.
query.wall_thickness kernel
How thick the wall is behind each face of a body — the check that says whether a shelled, cast or moulded part is thin anywhere, and which face is thin.
Detail
How thick the wall is behind each face of a body — the check that says whether a shelled, cast or moulded part is thin anywhere, and which face is thin. One row per face, in the same order query.tree lists them, each carrying the least and greatest thickness measured over that face in MILLIMETRES. minThickness is the number to compare against what the process needs: there is no threshold argument, because this read must be answerable before anybody has decided what that is. Each measurement fires a ray from a point on the face along its inward normal — into the material — and takes the distance to the first face it meets, so on a tube's bore it reports the WALL and not the hole. Two things follow from that and both are facts about the answer, not caveats: it is a RAY thickness rather than a rolling-ball one, so where two walls are not parallel it reads LONG (a corner's true minimum runs across the diagonal, which the inward normal misses); and the face is SAMPLED on a grid rather than solved, so a thin spot smaller than the sampling can be missed and the true minimum may be SMALLER than what is reported. defined is false where nothing on that face could be measured — minThickness and maxThickness are then null. That happens when the body has no solid in it (a surface or wire body has no material side, so it has no wall thickness at all — measure across it with query.measure by naming its two faces instead), when every ray leaves the body without meeting a far wall, or when the face has no normal the sampler could read. Nothing is changed, nothing is recorded: this is a read.
Drawings
Sheets, views, dimensions, annotations, balloons and GD&T symbols.
drawing.add_annotation kernel
Put an annotation on a drawing view - the marks a shop reads beside the numbers.
Detail
Put an annotation on a drawing view - the marks a shop reads beside the numbers. Eight kinds, chosen with kind: a NOTE (the default) is words, a CENTRE MARK is the cross at a round feature's centre, a CENTRELINE is the chain line between two corners, a SURFACE FINISH is the check-mark symbol with its value beside it, a WELD is the reference line and arrow with the weld's designation on the arrow side - the two symbols drawn the way the drawing's standard draws them, with the words stored exactly as sent - and a CALLOUT is the hole or thread callout, the one kind whose words are DERIVED: it names a feature.hole or feature.thread ("ft:<n>") and prints what that record says ("4X ⌀6.6 ↧12", "M6×1") on every read, so it can never state a hole the part does not have; a BALLOON is the circled item number of an assembly drawing, the second derived kind - it names one corner of a part and prints that part's row number from query.bom, so it can never disagree with the parts list; and a BEND CALLOUT is the third, the UP or DOWN, the angle and the inside radius written beside a fold line on a flat-pattern view - it names the bend's inner face ("fc:<body>.<n>") and reads the words off the blank's own bend line, so it says exactly what the bend chart says. A note's TEXT IS STORED EXACTLY AS SENT, which is the deliberate opposite of a dimension: a dimension's number is a measurement of the part and is worked out afresh on every read, where a note is a statement you made and there is nothing in the model to derive it from. A note points at as many corners of the part as you like, with a leader line running to each - or at NONE at all, which is a general note, the kind that sits in a drawing's corner saying how the whole print is to be read; a centre mark takes exactly one corner and a centreline exactly two, and neither takes any text, because both draw themselves from the corners they name. The corners are named in the MODEL - "vx:<body>.<n>" - and not in the picture, which is what makes the mark survive a recompute; a corner removed later leaves it in place, marked dangling and still carrying its own words, to be reattached rather than vanishing off the sheet. x and y are where the text sits, in the view's own millimetres. Undoable, and it is not a modelling step: it adds nothing to the timeline and changes no geometry, no mass and no export.
drawing.add_balloons kernel
Balloon a whole view at once - the auto-balloon of an assembly drawing, and P5B-6's add_balloons.
Detail
Balloon a whole view at once - the auto-balloon of an assembly drawing, and P5B-6's add_balloons. One balloon per PLACEMENT the view draws that is on the parts list and has no balloon yet, each pointing at that placement's topmost corner in the picture and standing off it up and to the right by standoff millimetres ON THE SHEET (10 by default, converted by the view's scale, because a standoff is a drafting distance and not a model one). Two placements of one part get two balloons with one number, which is how an assembly print reads. A placement already ballooned on this view is left alone, so sending this twice fills in what a person did by hand and moves nothing; a part excluded from the BOM gets none, because a balloon with nothing to say is not worth minting; loose bodies are not placements and get none. Each balloon is an ordinary annotation afterwards - drag it with drawing.set_annotation, remove it with drawing.remove_annotation - and the whole set is ONE undo step. A view with nothing to balloon answers an empty list and is not an error.
drawing.add_dimension kernel
Measure the part on a drawing view - the number a shop cuts to: between two corners (aligned, horizontal or vertical), a corner's signed coordinate from an origin corner (ordinate_x, ordinate_y - a baseline set is several of the linear kinds sharing their first corner), a circular edge's radius or diameter, or the angle at a corner between two others (angular, in degrees).
Detail
Measure the part on a drawing view - the number a shop cuts to: between two corners (aligned, horizontal or vertical), a corner's signed coordinate from an origin corner (ordinate_x, ordinate_y - a baseline set is several of the linear kinds sharing their first corner), a circular edge's radius or diameter, or the angle at a corner between two others (angular, in degrees). THE VALUE IS NEVER STORED: the dimension records what it measures, and query.view_geometry works the number out afresh every time it is asked, so editing the model moves the print with nothing to regenerate and a drawing can never state a length the part does not have. The operands are named in the MODEL - "vx:<body>.<n>" corners, or an "eg:<body>.<n>" edge: a circular one for a radius or diameter, a STRAIGHT one named alone on a linear kind as a shorthand for its two ends, or two straight edges meeting at a corner on an angular kind as a shorthand for the three corners - and not in the picture, which is what makes the dimension survive a recompute; one removed later leaves the dimension in place and marked dangling, to be reattached, rather than vanishing off the sheet. x and y are where the text sits, in the view's own millimetres. A tolerance (±0.1, +0.1/-0.05, the two limits, or an ISO 286 class such as H7 whose deviations the table gives at the measured size) and a decimal precision may be stated with it - both are STORED, because nothing in the model knows how much a shop may miss by - and query.view_geometry answers the label they produce, in the document's own unit (query.documents' units), with the other system's number bracketed beside it when dualUnits is true. Undoable, and it is not a modelling step: it adds nothing to the timeline and changes no geometry, no mass and no export.
drawing.add_gdt kernel
Put a GD&T symbol on a drawing view - a DATUM feature symbol (the boxed letter on a leader ending in a triangle at the feature it names) or a FEATURE CONTROL FRAME (the row of boxes a shop reads as a geometric tolerance: the characteristic's symbol, the tolerance zone with ⌀ for a cylindrical one and Ⓜ or Ⓛ after it, then up to three datum references).
Detail
Put a GD&T symbol on a drawing view - a DATUM feature symbol (the boxed letter on a leader ending in a triangle at the feature it names) or a FEATURE CONTROL FRAME (the row of boxes a shop reads as a geometric tolerance: the characteristic's symbol, the tolerance zone with ⌀ for a cylindrical one and Ⓜ or Ⓛ after it, then up to three datum references). Everything it says is STORED - the letter, the characteristic, the tolerance in millimetres, the modifiers, the references - because every one is a person's claim about the part and nothing in the model could derive it; what query.view_geometry adds is where each leader lands, whether it still resolves, the printed cells and which referenced datum letters the drawing carries no symbol for. The fourteen characteristics decide the grammar: form tolerances take no datum, orientation and runout require one, a ⌀ zone and a material-condition modifier are legal only where the standards allow them - a frame that can never be right is refused saying why. A datum references by LETTER: a frame may name datum B before a datum B exists, and prints that cell amber until it does. A datum names exactly one corner ("vx:<body>.<n>") and a frame any number or none - a frame beside a dimension is the commonest placement on a print. x and y are where the box's lower-left corner sits, in the view's own millimetres. Undoable, and it is not a modelling step: it adds nothing to the timeline and changes no geometry, no mass and no export.
drawing.add_sheet
Add a sheet to a drawing - one page of the print, the thing views get placed on.
Detail
Add a sheet to a drawing - one page of the print, the thing views get placed on. Say which size, either by name from query.sheet_sizes ("iso-a3", "ansi-b") or as width and height in millimetres for a size that is not listed; left out, it is A4 landscape. orientation says which of the two lengths is the width, so a size and an orientation together describe any page. A sheet stores the two lengths rather than a size name, so its page can never change because a machine's size table did. scale is the sheet's default drawing scale as one number - the drawn length over the model length, 1 for full size, 0.5 for 1:2, 2 for 2:1 - and it is what views placed here will use unless they say otherwise. The sheet is added at the end; drawing.set_sheet moves it. Undoable, and it is not a modelling step: it adds nothing to the timeline and changes no geometry.
drawing.auxiliary_view kernel
Fold an AUXILIARY view off a view already on the sheet, about a planar FACE that view sees on edge - the way a print shows the true shape of a chamfer, a drafted wall or an angled cut that no front, side or top view sees square on.
Detail
Fold an AUXILIARY view off a view already on the sheet, about a planar FACE that view sees on edge - the way a print shows the true shape of a chamfer, a drafted wall or an angled cut that no front, side or top view sees square on. The new view looks straight at the face, so the face is drawn true-shape, and it is aligned to the view it is folded off along the face's own direction on that view's paper: on a third-angle drawing it sits on the side the face looks toward, on a first-angle drawing on the opposite side, offset millimetres away along that line. Turning or moving the parent turns and moves it; the hinge itself is worked out from the face ONCE and stored (query.drawings answers it as auxiliary.angle, degrees counter-clockwise from the parent's paper-right), and query.view_geometry says dangling when the face has since gone or leaned - send drawing.set_view auxiliary {face} to fold about it afresh. The face must be planar, on a body the parent draws, and seen as a LINE in the parent: a face the parent already sees square on needs no auxiliary, and one seen obliquely wants a secondary auxiliary view, which is not built yet. Nothing projects off an auxiliary, and an auxiliary of a section or a detail is refused. Undoable, and it is not a modelling step - no geometry, no mass and no export changes.
drawing.create
Start a drawing of this model - the 2D print a shop works from, and the thing a supplier package is made of.
Detail
Start a drawing of this model - the 2D print a shop works from, and the thing a supplier package is made of. A drawing lives inside this document and is saved with it, so opening the part opens its drawings and there is no second file to keep in step. Say which drafting standard it is drawn to - ISO or ASME - and, if the shop's convention differs from the standard's, which projection angle arranges its views; left out, the projection follows the standard, ISO being first-angle and ASME third-angle. A drawing carries no units of its own: dimensions read in the document's units, so a print always measures the same as the part. A document may hold as many drawings as you like - a machining print beside a weldment - each to its own standard. Undoable, and it is not a modelling step: it adds nothing to the timeline and changes no geometry, no mass and no export. A new drawing has no sheets yet.
drawing.delete
Remove a drawing from this document, with everything on it.
Detail
Remove a drawing from this document, with everything on it. Nothing about the model changes - a drawing is a picture OF the part, so deleting one moves no geometry, no mass and no export. Undoable: one Ctrl+Z brings the drawing and its contents back exactly as they were, which is what makes this safe to offer at all.
drawing.detail_view kernel
Place a DETAIL view - an enlarged picture of one circular region of a view already on the sheet, the way a print shows a small groove or a thread relief that the main view draws too small to dimension.
Detail
Place a DETAIL view - an enlarged picture of one circular region of a view already on the sheet, the way a print shows a small groove or a thread relief that the main view draws too small to dimension. It looks exactly where the view it enlarges looks and follows that view when it is turned, but it is PLACED rather than aligned: x and y put it anywhere on the sheet, as a base view is put, because both drafting standards let a detail sit wherever there is room and the detail's name is the link. detail is the window - the centre and radius of the circle drawn on the view it enlarges, in THAT view's own millimetres, the same coordinates query.view_geometry answers its curves in; left out, a circle in the middle of what that view draws. The picture is what lies inside the circle, worked out with a real boolean along the line of sight, so a body behind a neighbour is still hidden by it and a detail of a SECTION view shows the cut and answers the cut's outline clipped to the circle. scale left out is TWICE the scale of the view it enlarges, live - rescale that view and the detail follows. Nothing projects off a detail, and a detail of a detail is refused: enlarge the first one's window instead. Undoable, and it is not a modelling step - a detail is a picture of the part, so no geometry, no mass and no export changes.
drawing.export kernel
CoCAD Pro only.
Detail
CoCAD Pro only. Write one drawing sheet to a file - the PDF a shop prints or the DXF another CAD or a plotter reads. The sheet is drawn exactly as the sheet canvas shows it: every view's visible edges (and its hidden edges, where the view draws them), a section's cut face outlined heavy and hatched, the section line and arrows on the view it was cut from, every dimension with its extension lines, arrowheads and number, every note, symbol, callout and balloon with its leader, every parts list with its rules and cells, and each view's caption. The PDF page is the sheet's own size in millimetres, so a 1:2 view prints at 1:2 with a rule laid on the paper - print to scale needs no dialog. The DXF puts the ink on named layers (VISIBLE, HIDDEN, CUT, HATCH, CENTER, SECTION, DIMENSIONS, ANNOTATIONS, TABLE, the sheet's edge on 0), in paper millimetres with the sheet's lower-left at the origin; dimensions are lines and text rather than DIMENSION entities, so a receiving CAD cannot re-measure the paper and print the wrong number. A dangling dimension prints ? and a dangling annotation prints its words, both in amber, so a print with a lost reference says so. Exporting changes nothing and cannot be undone; the file is written atomically and the reply says where the bytes landed and what was drawn. Set preview true to be told how big the file would be and what it would hold without writing anything. A CoCAD Free copy prints "CoCAD Free - non-commercial use" along the bottom of every sheet it exports.
drawing.flat_pattern_view kernel
Put the FLAT PATTERN of one sheet-metal part on a drawing sheet - the blank it is cut from, before anybody folds it, with a line down the middle of every bend.
Detail
Put the FLAT PATTERN of one sheet-metal part on a drawing sheet - the blank it is cut from, before anybody folds it, with a line down the middle of every bend. This is the drawing a laser or a punch works from, where drawing.place_view gives the drawing a person reads the folded part from. Say which sheet and which body; x and y put it on the page in millimetres from the sheet's lower-left corner, and left out it goes in the middle. scale is the drawn length over the model length and defaults to the SHEET's. There is no direction to choose: a blank is not a picture of the part from anywhere, so query.view_geometry answers direction null and says under flatPattern which FACE of the metal it is seen from. There is no hiddenLines or tangentEdges either - a blank is flat, and a developed sheet has no fillet to run out into anything. The part must carry a sheet-metal rule, because how much flat a bend eats depends on where the neutral axis sits inside the metal: build it with feature.base_flange or set one with doc.set_sheet_metal_rule. THE PICTURE IS NOT STORED: the blank is worked out from the part every time it is asked for, exactly as query.flat_pattern does and from the same code, so the sheet, the DXF and the read can never describe three different parts. Undoable, and it is not a modelling step: it adds nothing to the timeline and changes no geometry, no mass and no export.
drawing.insert_bend_table kernel
Put a bend chart on a flat-pattern view - the table a press brake operator works from: one row per bend in the blank, numbered in the flat pattern's own order, each with whether the metal folds UP or DOWN away from the face you are looking at, the angle in degrees, the inside bend radius and the bend allowance.
Detail
Put a bend chart on a flat-pattern view - the table a press brake operator works from: one row per bend in the blank, numbered in the flat pattern's own order, each with whether the metal folds UP or DOWN away from the face you are looking at, the angle in degrees, the inside bend radius and the bend allowance. THE ROWS ARE NEVER STORED: the table records only where it sits on the page and which way it reads, and query.view_geometry works every row out afresh from the view's own bend lines, so changing a flange angle changes the print with nothing to regenerate. Every bend in the picture is also numbered beside its fold line. It must go on a FLAT-PATTERN view - place one with drawing.flat_pattern_view - because nothing else has bends to list, and because a flat-pattern view already names exactly one part. x and y are where the table's header row sits in the SHEET's millimetres - left out, the upper-left corner 10 mm in, rows reading down. Undoable, and it is not a modelling step: it adds nothing to the timeline and changes no geometry.
drawing.insert_bom
Place a parts list - a BOM table - on a sheet.
Detail
Place a parts list - a BOM table - on a sheet. The table is a recipe, never a copy: it says where its header sits, which way its rows stack, which of query.bom's two modes it prints and which columns, and the rows are query.bom's on every read, so the table on the print can never disagree with the parts list the document answers and a balloon always names the row it points at. Left out, it prints partsOnly with item, quantity, partNumber, description and material, rows stacking upward from the header, in the sheet's lower-right corner 10 mm in from the right edge and clear of the title block's room - where a parts list sits over the title block, whether or not the sheet carries one yet. The reply's layout gives every column's printed label and paper width and the row height, which is what a client draws from. Undoable, and it is not a modelling step: it adds nothing to the timeline and changes no geometry.
drawing.insert_hole_table kernel
Put a hole chart on a drawing view - the table a fixture plate or a bolt pattern is made from: one row per hole the view shows, each with a tag (A1, A2, B1 - lettered by size, numbered within the letter), its X and Y from one corner of the part, and its size.
Detail
Put a hole chart on a drawing view - the table a fixture plate or a bolt pattern is made from: one row per hole the view shows, each with a tag (A1, A2, B1 - lettered by size, numbered within the letter), its X and Y from one corner of the part, and its size. THE ROWS ARE NEVER STORED: the table records which corner is the origin and where it sits on the page, and query.view_geometry works every row out afresh from the holes the view draws, so drilling another hole or moving one changes the print with nothing to regenerate and a chart can never list a hole the part does not have. Every hole in the picture is also tagged beside its circle. x and y are where the table's header row sits in the SHEET's millimetres - left out, the upper-left corner 10 mm in, rows reading down. Undoable, and it is not a modelling step: it adds nothing to the timeline and changes no geometry.
drawing.insert_revision_table
Place a revision table - a REV block - on a sheet.
Detail
Place a revision table - a REV block - on a sheet. Unlike a parts list or a hole chart, its rows are STORED: a revision is a person's words about the print - who changed what, when, and who signed it - and nothing in the model can derive them. Each row is rev and description with optional zone, date (YYYY-MM-DD) and approved, printed in the order sent; the five columns are ASME Y14.35's and cannot be chosen. Left out, the block is empty - the ruled block a first issue prints - with rows reading down from a header in the sheet's upper-right corner 10 mm in from both edges. The reply's layout gives every column's printed label and paper width and the row height, which is what a client draws from. Undoable, and it is not a modelling step: it adds nothing to the timeline and changes no geometry.
drawing.insert_title_block
Place a title block on a sheet - the block in the lower-right corner that names the print.
Detail
Place a title block on a sheet - the block in the lower-right corner that names the print. Only five of its cells are stored, because only a person can say them: the company, who drew, checked and approved it, and the date of issue. Every other cell is DERIVED on every read and can never disagree with the document - the title (the document's description, or its name), the drawing number, material and revision from doc.set_metadata's record, the latest rev from the sheet's revision table when one has rows, SHEET n OF m from the sheet's place in its drawing, the scale, the size by name and the projection angle. A sheet carries exactly one; left out, it sits in the lower-right corner 10 mm in from both edges with every word empty. The reply's cells give each cell's label (ISO 7200's wording on an ISO drawing, ASME Y14.100's on an ASME one), value, place and size, which is what a client draws from. Undoable, and it is not a modelling step: it adds nothing to the timeline and changes no geometry.
drawing.place_view kernel
Put a view of the model on a drawing sheet - the picture a shop reads the part from.
Detail
Put a view of the model on a drawing sheet - the picture a shop reads the part from. Say which sheet, which direction to look from (front, back, left, right, top, bottom or isometric; left out, front), and which bodies to draw - leave bodies out for every solid body in the document, which is what a view of the whole part wants and which keeps including bodies you add later. x and y put it on the page in millimetres from the sheet's lower-left corner; left out, the middle of the sheet. scale is the drawn length over the model length and defaults to the SHEET's, so changing the sheet's scale still moves every view that did not choose its own. hiddenLines says whether the edges the solid hides are drawn dashed; left out, they are not. tangentEdges says whether the smooth join where a fillet runs out into the face it blends into is drawn thin; left out, it is not, which is what ISO 128 and ASME Y14.2 ask for. THE PICTURE IS NOT STORED: the view records what to draw and query.view_geometry works out the curves each time it is asked, so editing the model updates the drawing with nothing to regenerate. Undoable, and it is not a modelling step: it adds nothing to the timeline and changes no geometry, no mass and no export.
drawing.project_view kernel
Fold a second view off one already on the sheet - the side, top or bottom view a print is arranged from.
Detail
Fold a second view off one already on the sheet - the side, top or bottom view a print is arranged from. Say which view to project FROM and which side of it the new one sits on; which way it LOOKS follows from the drawing's projection angle, which is the whole difference between first-angle and third-angle drafting, so the side is the only thing there is to choose. THE CHILD IS LOCKED TO ITS PARENT: it draws the same bodies, at the same scale, aligned on the same line, and it follows when the parent is moved, turned or rescaled - so aiming a base view re-aims the whole arrangement with nothing to regenerate. offset is how far apart the two sit on the page; left out, they are spaced so the two pictures do not overlap. An isometric view projects nothing. Undoable, and it is not a modelling step: it adds nothing to the timeline and changes no geometry, no mass and no export.
drawing.remove_annotation kernel
Take a note off its view.
Detail
Take a note off its view. Nothing about the model changes - an annotation is a statement about the part rather than part of it, so removing one moves no geometry, no mass and no export. Undoable: one Ctrl+Z puts it back exactly where it was, saying exactly what it said.
drawing.remove_bend_table kernel
Take a bend chart off its view.
Detail
Take a bend chart off its view. Nothing about the model changes - the table stores no rows, so removing one loses nothing about the bends. Undoable: one Ctrl+Z puts it back exactly where it was.
drawing.remove_bom
Take a parts list off its sheet.
Detail
Take a parts list off its sheet. The sheet, its views and the model are otherwise untouched - a BOM table stores no rows, so removing one loses nothing about the parts. Undoable: one Ctrl+Z puts the table back exactly where it was.
drawing.remove_dimension kernel
Take a dimension off its view.
Detail
Take a dimension off its view. Nothing about the model changes - a dimension is a statement about the part rather than part of it, so removing one moves no geometry, no mass and no export. Undoable: one Ctrl+Z puts it back exactly where it was, measuring exactly what it measured.
drawing.remove_gdt kernel
Take a datum symbol or a feature control frame off its view.
Detail
Take a datum symbol or a feature control frame off its view. Nothing about the model changes. A datum other frames reference is removed all the same, and those frames report its letter missing on query.view_geometry and print that cell amber until a datum with the letter exists again. Undoable: one Ctrl+Z puts it back exactly as it was.
drawing.remove_hole_table kernel
Take a hole chart off its view.
Detail
Take a hole chart off its view. Nothing about the model changes - the table stores no rows, so removing one loses nothing about the holes. Undoable: one Ctrl+Z puts it back exactly where it was, measured from the same corner.
drawing.remove_revision_table
Take a revision table off its sheet.
Detail
Take a revision table off its sheet. The rows go with it - they are stored on the table and nowhere else - so this is the one table on a sheet whose removal loses words; undoable, and one Ctrl+Z puts the table back with every row exactly as it was.
drawing.remove_sheet
Take a sheet off a drawing, with everything placed on it.
Detail
Take a sheet off a drawing, with everything placed on it. The drawing and the model are otherwise untouched. Removing a drawing's last sheet is allowed: a drawing with no sheets is empty rather than broken. Undoable - one Ctrl+Z brings the sheet and its contents back exactly as they were, in the place they were in.
drawing.remove_title_block
Take a title block off its sheet.
Detail
Take a title block off its sheet. The five stored words go with it; the derived cells were never stored, so nothing about the document changes. Undoable, and one Ctrl+Z puts the block back with every word exactly as it was.
drawing.remove_view kernel
Take a view off its sheet.
Detail
Take a view off its sheet. THE VIEWS PROJECTED FROM IT GO WITH IT, and theirs: a projected view stores no aim and no place of its own, so an orphan would be a record with nothing to draw and nowhere to sit - the reply names every one that went. Their dimensions go with them, because a dimension is drawn on a view. Nothing about the model changes: a view is a picture OF the part, so removing one moves no geometry, no mass and no export. Undoable: one Ctrl+Z brings the whole family back exactly where it was.
drawing.section_view kernel
Fold a CUT view off one already on the sheet - the section a shop reads a part's inside from.
Detail
Fold a CUT view off one already on the sheet - the section a shop reads a part's inside from. It is drawing.project_view with a cutting plane: the same side, the same alignment, the same locked aim and scale, plus a line across the view it is cut from. Everything between the eye and that line is removed before the picture is drawn, and query.view_geometry answers a THIRD list of curves - where the plane met solid material, which is the outline a print draws heaviest and hatches inside. position is where the cut crosses the view it is projected from, in THAT view's own millimetres - the same coordinates query.view_geometry answers, so a number read off the picture is the number to send; left out, the cut passes through the middle of the part. A full section only: half, offset and aligned section lines need more than one number and are not built. An isometric view sections nothing. Undoable, and it is not a modelling step - the cut is a picture of the part, so no geometry, no mass and no export changes.
drawing.set_annotation kernel
Change what a note says, what it points at, or where its text sits - absolute values only, and any subset.
Detail
Change what a note says, what it points at, or where its text sits - absolute values only, and any subset. Absent fields are left exactly as they are, so a retry is always safe and nothing here is ever a nudge; send at least one. Sending entities is how a dangling note is reattached: name corners that exist and its leaders land again - and sending an EMPTY list is a real change, taking the leaders off and leaving a general note. Undoable, and it changes no geometry - an annotation is a statement about the part, not a shape.
drawing.set_bend_table kernel
Change where a bend chart sits on the sheet or which way its rows read - absolute values only, and any subset.
Detail
Change where a bend chart sits on the sheet or which way its rows read - absolute values only, and any subset. Absent fields are left exactly as they are, so a retry is always safe and nothing here is ever a nudge; send at least one. There is no origin to set: a bend's angle, radius and allowance are measured from nothing, so a bend chart has no datum corner and nothing about it can come adrift. Undoable, and it changes no geometry - a chart is a reading of the part, not a shape.
drawing.set_bom
Change where a parts list sits, which way its rows stack, which mode it prints or which columns - absolute values only, and any subset.
Detail
Change where a parts list sits, which way its rows stack, which mode it prints or which columns - absolute values only, and any subset. Absent fields are left exactly as they are, so a retry is always safe and nothing here is ever a nudge; send at least one. columns replaces the whole list when sent. Undoable, and it changes no geometry - a table is a recipe on a page, not a shape.
drawing.set_dimension kernel
Change what a dimension measures, which number it states, where its text sits, its tolerance, its precision or whether it prints dual units - absolute values only, and any subset.
Detail
Change what a dimension measures, which number it states, where its text sits, its tolerance, its precision or whether it prints dual units - absolute values only, and any subset. Absent fields are left exactly as they are, so a retry is always safe and nothing here is ever a nudge; send at least one. Sending entities is how a dangling dimension is reattached: name two corners (or one straight edge, meaning its two ends), one circular edge, or three corners on an angle (or two straight edges meeting at one), that exist and it measures again. A kind from another family (linear, circular, angular) must bring its entities with it. Undoable, and it changes no geometry - a dimension is a statement about the part, not a shape.
drawing.set_gdt kernel
Change what a datum symbol or a feature control frame says, what it points at, or where it sits - absolute values only, and any subset; absent fields are left exactly as they are, so a retry is always safe.
Detail
Change what a datum symbol or a feature control frame says, what it points at, or where it sits - absolute values only, and any subset; absent fields are left exactly as they are, so a retry is always safe. The call is judged as the record it PRODUCES: a characteristic that forbids the datums the frame already stores is refused naming them, and the fix is to send both in one call. Sending entities is how a dangling symbol is reattached; sending an empty list on a frame takes its leaders off. Turning a datum into a frame needs a characteristic and a tolerance in the same call. Re-lettering a datum other frames reference is allowed - those frames report the old letter missing. Undoable, and a call that changes nothing records no step.
drawing.set_hole_table kernel
Change which corner a hole chart measures from, where it sits on the sheet or which way its rows read - absolute values only, and any subset.
Detail
Change which corner a hole chart measures from, where it sits on the sheet or which way its rows read - absolute values only, and any subset. Absent fields are left exactly as they are, so a retry is always safe and nothing here is ever a nudge; send at least one. Sending origin is how a dangling chart is reattached: name a corner that exists and every X and Y reads again. Undoable, and it changes no geometry - a chart is a reading of the part, not a shape.
drawing.set_revision_table
Change where a revision table sits, which way its rows stack, or its rows - absolute values only, and any subset.
Detail
Change where a revision table sits, which way its rows stack, or its rows - absolute values only, and any subset. Absent fields are left exactly as they are, so a retry is always safe and nothing here is ever a nudge; send at least one. rows replaces the whole list when sent - to add a revision, send every row plus the new one - and an empty list clears the block. Undoable, and it changes no geometry.
drawing.set_sheet
Change a sheet's size, orientation, scale or place in its drawing - absolute values only, and any subset.
Detail
Change a sheet's size, orientation, scale or place in its drawing - absolute values only, and any subset. Absent fields are left exactly as they are, so a retry is always safe and nothing here is ever a nudge; send at least one. size names a query.sheet_sizes row and width with height give a size it does not list - one or the other, never both. orientation on its own turns the sheet, swapping the two lengths without restating them. position is 1-based within this sheet's own drawing and is how sheets are reordered. A new size moves the title block and every table with the corner it sits nearest, so one placed 10 mm in from a corner is still 10 mm in from it; views stay where they are. The reply's offSheet names every block and view that no longer fits the page - empty when everything does. Undoable, and it changes no geometry - a sheet is a page, not a shape.
drawing.set_title_block
Change where a title block sits or its stored words - absolute values only, and any subset.
Detail
Change where a title block sits or its stored words - absolute values only, and any subset. Absent fields are left exactly as they are, so a retry is always safe and nothing here is ever a nudge; send at least one. A word sent as the empty string is cleared. The derived cells cannot be set here: change the document's record with doc.set_metadata, the sheet with drawing.set_sheet, the latest rev with the sheet's revision table, and the block follows. Undoable, and it changes no geometry.
drawing.set_view kernel
Change which bodies a view draws, which way it looks, where it sits on the page, its scale or whether hidden lines are drawn - absolute values only, and any subset.
Detail
Change which bodies a view draws, which way it looks, where it sits on the page, its scale or whether hidden lines are drawn - absolute values only, and any subset. A view made by drawing.project_view takes offset instead of x, y and direction, because it has one degree of freedom rather than three: it is aimed and aligned by the view it was projected from, and sending the wrong pair is refused rather than quietly stored. Absent fields are left exactly as they are, so a retry is always safe and nothing here is ever a nudge; send at least one. Sending scale as null puts the view back on its sheet's scale, which is how an inherited scale is restored once it has been overridden. broken shortens a long part: {axis, from, to, gap} takes the run between from and to out of the picture along that axis and draws the two ends gap apart with break lines between them, every dimension still stating the part's true length; null draws the view whole again. A break belongs to the view that owns the axis - a top view of a shaft broken along its length is broken by the front view's own band, because the two share the axis - so it is sent to the base view, or to a projected child only along the axis it does not share. breakout shows the inside of the part at one place without a second view - a local section: {x, y, radius, depth} cuts a round pocket into the picture, centred there in this view's own millimetres and depth deep behind the surface inside it, the floor hatched and its edge drawn thin; null fills it in again. radius and depth may be left out on a new break-out for a default read off the picture. A view is drawn with a break or a break-out, never both, and a detail of a broken-out view shows the pocket. Undoable, and it changes no geometry - a view is a picture, not a shape.