The command line
dxcad is the widest door into DX-CAD: every operation the kernel has is
reachable from it, no window is opened unless one is asked for, and every
command reads and writes plain files. This page has one section per
subcommand, in the order dxcad --help lists them, and each says what the
command is for, what it takes, what it writes, every option it has and what
it exits with. Each section closes with the command's usage line and its
arguments, generated from the command itself by
python -m dxcad.docsgen cli, so that part can never say other than what
--help does.
Three statuses are used throughout, and they are the same in every command:
0, the command did what it was asked.1,cli.UNSOUND: nothing was wrong with the command line, and the answer is no. Onlyvalidate,printabilityanddoctorgive it.2,cli.USAGE_ERROR: the command line, or a file it named, was wrong. Nothing is written and a line saying what went wrong goes to stderr.
A model that fails is a usage error too: the model's own traceback is turned into one line naming the model and the line in it that raised, never a traceback of DX-CAD's own.
The worked commands
Every section gives a command that can be pasted as it stands. They run in the order they are written, in one empty directory, and the test suite runs them there at every commit, so a command on this page is a command that works. These two come first and make the part the rest of them read:
Worked, exits 0:
dxcad examples bracket
dxcad run bracket.py --output bracket.dxcprt
info
What a project holds, in three columns: one line per entry with its name, its volume and whether it is a valid solid, then a last line naming the model the project carries and how long it is.
Takes a .dxcprt or .dxcasm project (an older .dxcad too), a .py model to run first, or - for a model on
standard input. Writes nothing but its own output.
--timeout SECONDSstops a model that runs longer than this. No limit by default, and it is the same option, with the same meaning, wherever a command can be given a model.
Exits 0, or 2 when the file is not a project and not a model.
Worked, exits 0:
dxcad info bracket.dxcprt
usage: dxcad info [-h] [--timeout SECONDS] project
project: a .dxcprt or .dxcasm file, or a .py model to run, or - for a model on standard input--timeout SECONDS: stop a model that runs longer than this; no limit by default
bounds
The bounding box of everything in a project, as two lines, min and max, in millimetres. What a print bed or a billet has to hold.
Takes what info takes. Writes nothing but its own output.
--timeout SECONDS, as everywhere.
Exits 0, or 2 when the file cannot be read.
Worked, exits 0:
dxcad bounds bracket.dxcprt
usage: dxcad bounds [-h] [--timeout SECONDS] project
project: a .dxcprt or .dxcasm file, or a .py model to run, or - for a model on standard input--timeout SECONDS: stop a model that runs longer than this; no limit by default
validate
Whether every entry is a sound solid, and with --script whether the shapes
in the file still agree with the model that is supposed to build them. It
prints nothing when all is well, which is what a build step wants.
Takes what info takes. Writes nothing.
--scriptre-runs the model the project carries and compares what it builds with what is stored.--tolerance TOLERANCEis how far a volume may differ from the model's, relative; 1e-06 by default.--timeout SECONDS, as everywhere.
Exits 0 when sound, 1 when a solid is invalid or a volume disagrees, and
2 when the file cannot be read or the tolerance is not a number.
Worked, exits 0:
dxcad validate bracket.dxcprt --script
usage: dxcad validate [-h] [--script] [--tolerance TOLERANCE] [--timeout SECONDS] project
project: a .dxcprt or .dxcasm file, or a .py model to run, or - for a model on standard input--script: also check the entries against the model.py the project carries--tolerance TOLERANCE: how far a volume may differ from the model's, relative; 1e-06 by default--timeout SECONDS: stop a model that runs longer than this; no limit by default
describe
Everything an agent needs to reason about a part without seeing it: per entry the volume and area, the bounds and size, the centre of mass, the faces by the kind of surface under them, the edges and vertices, and every round hole with its diameter, depth, axis and centre.
Takes what info takes. Writes nothing but its own output.
--name NAMEdescribes that one entry; every entry by default, and a name the project does not have is a usage error.--jsonprints the same facts as one JSON document, numbers unrounded, which is the form to pipe into something else.--timeout SECONDS, as everywhere.
Exits 0, or 2 when the file cannot be read or the name is not there. An
entry that is an unsound solid is said to be invalid and still exits 0.
Worked, exits 0:
dxcad describe bracket.dxcprt
usage: dxcad describe [-h] [--name NAME] [--json] [--timeout SECONDS] project
project: a .dxcprt or .dxcasm file, or a .py model to run, or - for a model on standard input--name NAME: the one entry to describe; every entry by default--json: print the same facts as one JSON document, numbers unrounded--timeout SECONDS: stop a model that runs longer than this; no limit by default
serve
The agent door: an MCP server on standard input and output, one JSON-RPC message a line, holding one document of named parts. It is what agents.md is about, and every tool it offers is listed there.
Takes no file: the client speaks to it down a pipe. Writes only what a tool is asked to write, and only inside its directory.
--directory DIRis the directory the tools' paths are taken from and the only place the server may read or write. The directory it was started in by default, which is not somewhere a client chooses carefully.--allow-runoffers the two tools that exec a model.py with the user's own permissions. Without it the server has neither of them.--configstarts no server and prints the JSON an MCP client is configured with, naming this Python and this directory. On stderr it names the file--installwould write.--installstarts no server either: it writes what--configprints into Claude Desktop's configuration file. On Windows that is the Microsoft Store edition's, under%LOCALAPPDATA%\Packages\Claude_*\LocalCache\Roaming\Claude, when that edition is installed, and otherwise the one under%APPDATA%\Claude. On macOS it is under~/Library/Application Support/Claude, and elsewhere under~/.config/Claude. It keeps every other key the file holds, its other servers and its preferences alike, and copies the old file beside it with.bakadded. It prints the path it wrote, and on stderr the backup's name.--directoryand--allow-rungo into the entry. A dxcad entry already there is replaced only with--force, and a file that is not JSON is left alone; either exits1.--config-file FILEis the file--installwrites instead of Claude Desktop's own.--forcelets--installreplace a dxcad entry.--httpserves the same tools over HTTP instead, on 127.0.0.1 only, athttp://127.0.0.1:PORT/mcp: a JSON-RPC message is POSTed and answered as JSON. Every request carriesAuthorization: Bearer TOKEN, TOKEN being whatDXCAD_TOKENholds or one printed on stderr at start; without it, or with another, the answer is 401. The two tools that run Python need--allow-run-httpas well as--allow-run.--port PORTis the port--httplistens on; 8765 by default.--allow-run-http, with--allow-run, offers the run tools over HTTP.--window [CHANNEL]drives the open DX-CAD window instead of a document of the server's own: every tool call is carried out on the window's document, one undo step each, and the window's model.py in its pane gains the statement for it, as a window action writes one: for the tools that make, move, drill, round or chamfer a part, the booleans, the patterns, the two sketch tools, and renaming, copying or removing a part. The first call takes the template's place, and undoing it puts the template back. For any other tool (hollow, the sheet metal tools, an import) the status bar says the model has no line for it and the part stays. A relative path a tool writes to is taken from the window's document folder when the document has been saved, else from--directory, else from the user's Documents folder; the answer gives the whole path aswritten, and the window's status bar says where the file went. A window that closes lets the server go on: while no window is open each tool call is refused saying so, and the next window that listens on the channel is found by the next call, with no restart. The window listens on a named pipe on Windows and a Unix socket elsewhere, never a network port, this user's channel unless CHANNEL names another.--allow-runstill gates the two tools that run Python.
Exits 0 at the end of input, 1 when --window finds no window
listening, or 2 when the directory is not there.
Not run by the test: a server waits on standard input, so it would never return; examples/bracket.md drives one from a file instead.
dxcad serve --directory .
usage: dxcad serve [-h] [--directory DIR] [--allow-run] [--window [CHANNEL]] [--config] [--install]
[--config-file FILE] [--http] [--port PORT] [--allow-run-http] [--force]
--directory DIR: work in DIR: the tools' relative paths are taken from it, since the client that starts the server chooses where and cannot be told--allow-run: offer run_model and model_set, which exec a model.py with your own permissions; without this the server has neither tool--window [CHANNEL]: drive the open DX-CAD window instead of a document of the server's own, over its local channel (this user's by default); fails at once with no window open--config: start no server: print the JSON an MCP client is configured with, naming this Python and --directory's DIR, to paste into Claude Desktop's claude_desktop_config.json or Claude Code's .mcp.json--install: start no server: write what --config prints into Claude Desktop's configuration, keeping its other servers and backing the old file up beside it--config-file FILE: the configuration --install writes; Claude Desktop's own on this platform by default--http: serve over HTTP on 127.0.0.1 only instead of standard input and output, every request carrying the bearer token DXCAD_TOKEN holds, or one printed at start--port PORT: the port --http listens on; 8765 by default--allow-run-http: with --allow-run, offer the two tools that run Python over HTTP too--force: let --install replace a dxcad entry the configuration already has
printability
Whether each entry will print on a desktop printer: per entry the volume and the mass in the material given, the centre of mass, how many faces overhang further than the printer can manage and their area, the thinnest wall and where it is, and a warning for each check that fails.
Takes what info takes. Writes nothing but its own output.
--material MATERIALis the filament, one of PLA (1.24 g/cm3), PETG (1.27), ABS (1.04), ASA (1.07) and TPU (1.21), in any case; PLA by default. The mass line names the material and density it assumed.--density DENSITYis the density in g/cm3 of a filament not in that list, instead of--material.--min-wall MIN_WALLis the thinnest wall in millimetres that prints; 0.8 by default.--angle ANGLEis the steepest overhang, in degrees below the horizontal, that prints without support; 45 by default, and it must lie strictly between 0 and 90.--jsonprints the same reports as one JSON document, numbers unrounded.--timeout SECONDS, as everywhere.
Exits 0 when no entry has a warning, 1 when any has, and 2 when the file
cannot be read, holds no entries, or an option is not a number it takes.
Worked, exits 0:
dxcad printability bracket.dxcprt
usage: dxcad printability [-h] [--material MATERIAL | --density DENSITY] [--min-wall MIN_WALL]
[--angle ANGLE] [--json] [--timeout SECONDS]
project
project: a .dxcprt or .dxcasm file, or a .py model to run, or - for a model on standard input--material MATERIAL: the filament, one of PLA, PETG, ABS, ASA, TPU, mild steel, stainless 304, aluminium 5052, galvanised steel; PLA by default--density DENSITY: the material's density in g/cm3, for a filament not in that list--min-wall MIN_WALL: the thinnest wall in mm that prints; 0.8 by default--angle ANGLE: the steepest overhang in degrees below the horizontal that prints; 45.0 by default--json: print the same reports as one JSON document, numbers unrounded--timeout SECONDS: stop a model that runs longer than this; no limit by default
bom
A bill of materials: parts a model put in with place() from one source, as
one shape, are one line with a count, and every other part is a line of its
own. Each line gives its name (the start its parts' names share, so bolt_1
to bolt_4 are bolt), how many, one part's volume, its mass when a material
or a density is given, one part's size before it was placed, and the file
it came from when it was placed from one or taken from another project with
use() (item 576), as from bracket.dxcprt:bracket.
Takes what info takes. Writes nothing but its own output.
--material MATERIALgives each line's mass in that filament, one of thoseprintabilitytakes.--density DENSITYgives each line's mass at that density in g/cm3, instead of--material.--csvprints the bill as CSV with a header row: name, count, volume, mass, size_x, size_y, size_z, the parts, joined by;, and the source file.--flattotals each part over the whole assembly. Without it an assembly holding sub-assemblies (use(path, as_group=True), item 577) is printed as a tree, each sub-assembly a line naming its file with its own bill set in under it, the counts multiplied down it.--timeout SECONDS, as everywhere.
Exits 0, and 2 when the file cannot be read or holds no entries.
Worked, exits 0:
dxcad bom bracket.dxcprt --csv
usage: dxcad bom [-h]
[--material MATERIAL | --density DENSITY | --default-material DEFAULT_MATERIAL]
[--csv] [--columns KEYS] [--each] [--flat] [--timeout SECONDS]
project
project: a .dxcprt or .dxcasm file, or a .py model to run, or - for a model on standard input--material MATERIAL: give each line's mass in this filament, one of PLA, PETG, ABS, ASA, TPU, mild steel, stainless 304, aluminium 5052, galvanised steel--density DENSITY: give each line's mass at this density in g/cm3--default-material DEFAULT_MATERIAL: take each part with no material of its own to be made of this, marked (default), as the window's Default material does--csv: print the bill as CSV, with a header row--columns KEYS: print the bill as CSV in a drawing's parts list columns, comma-separated, of item, part_number, description, material, qty, rev, size and mass--each: list every part on a line of its own, rather than identical parts as one--flat: total each part over the whole assembly rather than listing sub-assemblies as a tree--timeout SECONDS: stop a model that runs longer than this; no limit by default
where-used
Lists the assemblies and drawings in a folder, and in every folder below it,
that use a part file, each with how many copies it holds: the projects whose
model uses the file through use() or puts it in with place(), read from
each model without running it, and the drawings whose model is the file. A
part keeps a stable id through renames, so an assembly using it by an old
name still finds it.
Writes nothing but its own output.
Exits 0, or 2 for a part file or a folder that is not there.
Worked, exits 0:
dxcad where-used bracket.dxcprt .
usage: dxcad where-used [-h] path folder
path: the part file, a .dxcprtfolder: the folder to search, and every folder below it
interference
Whether any two parts clash: for every pair, in document order, overlap
with the volume they share and its bounding box, touching when they meet
but share no volume (a face against a face), or clear.
Takes what info takes. Writes nothing but its own output.
--name NAMEchecks only the pairs among the parts named, one--nameeach; every part by default.--jsonprints the pairs as one JSON document, with how many overlap.--timeout SECONDS, as everywhere.
Exits 0 when no pair overlaps, 1 when any does, and 2 when the file
cannot be read or names no such part.
Worked, exits 0:
dxcad interference bracket.dxcprt
usage: dxcad interference [-h] [--name NAME] [--json] [--timeout SECONDS] project
project: a .dxcprt or .dxcasm file, or a .py model to run, or - for a model on standard input--name NAME: check only the pairs among the parts named, one --name each; every part by default--json: print the same pairs as one JSON document--timeout SECONDS: stop a model that runs longer than this; no limit by default
render
A picture of the parts as a PNG, drawn by OCCT with no window on screen: the
picture the agent door's render_view tool answers for the same request,
byte for byte.
Takes what info takes and the .png file to write.
--name NAMEdraws only the parts named, one--nameeach; every part by default.--view {front,back,left,right,top,bottom,isometric}; isometric by default.--mode {shaded_edges,shaded,wireframe,translucent}, the window's display modes; shaded_edges by default.--width WIDTHand--height HEIGHTin pixels, each 1 to 2048; 800 by 600 by default.--explode FACTORdraws the parts moved apart, asexport --explodewrites them.--timeout SECONDS, as everywhere.
Exits 0, 1 when this machine cannot draw, and 2 when the file cannot be
read, names no such part or a size is out of range.
Not run by the test: drawing with no window is built for Windows only so far, and the page's commands are run on every platform the suite is.
usage: dxcad render [-h] [--name NAME] [--view {front,back,left,right,top,bottom,isometric}]
[--mode {shaded_edges,shaded,wireframe,translucent}] [--width WIDTH]
[--height HEIGHT] [--explode FACTOR] [--theme {light,dark}] [--timeout SECONDS]
project output
project: a .dxcprt or .dxcasm file, or a .py model to run, or - for a model on standard inputoutput: the .png file to write--name NAME: draw only the parts named, one --name each; every part by default--view {front,back,left,right,top,bottom,isometric}: where the parts are seen from; isometric by default--mode {shaded_edges,shaded,wireframe,translucent}: how the parts are drawn, as the window's display modes; shaded_edges by default--width WIDTH: pixels across; 800 by default--height HEIGHT: pixels down; 600 by default--explode FACTOR: draw the parts moved apart by FACTOR, as an exploded view; 0 by default--theme {light,dark}: the view's background and part colours, as View > Theme; light by default--timeout SECONDS: stop a model that runs longer than this; no limit by default
export
One entry, or all of them, written out for a slicer, a mesher or another CAD.
Takes a project and the file to write, which ends in .step, .stl,
.3mf or .brep; with --all, a directory instead. Writes that file, or one file per
entry in that directory.
A file ending .dxf or .svg is a drawing instead: the Sketches the model
(or the project's model) names at its top level, one layer or group each,
named as the model names them, in millimetres, with lines, arcs, circles,
ellipses and splines each written as themselves. A model that makes only
sketches, and registers no part, draws as well as any.
--name NAMEis the entry to write; the first entry by default. For a drawing it is the one sketch to draw, every sketch by default.--allwrites every entry into the output directory, one file each, or with a drawing format every sketch, one file each.--format {3mf,brep,dxf,step,stl,svg}is the format--allwrites; step by default.--explode FACTORwrites each part moved apart as an exploded view of the whole project shows it: away from the assembly's centre of mass along the line to the part's own, FACTOR times that distance; 0 is assembled. Not for a drawing.--timeout SECONDS, as everywhere.
Exits 0, or 2 when the project cannot be read, the name is not there or
the suffix names no format DX-CAD writes.
Worked, exits 0:
dxcad export bracket.dxcprt bracket.step
usage: dxcad export [-h] [--name NAME] [--all] [--format {3mf,brep,dxf,step,stl,svg}]
[--explode FACTOR] [--timeout SECONDS]
project output
project: a .dxcprt or .dxcasm file, or a .py model to run, or - for a model on standard inputoutput: the file to write, ending in .step, .stl or .3mf, or .dxf or .svg for a drawing of the model's sketches; a directory with --all--name NAME: the entry to write, the first by default; for a drawing, the one sketch to draw, every sketch by default--all: write every entry into the output directory, one file each--format {3mf,brep,dxf,step,stl,svg}: the format --all writes; step by default--explode FACTOR: write each part moved apart as an exploded view of the whole project shows it, FACTOR times its distance from the centre; 0 is assembled--timeout SECONDS: stop a model that runs longer than this; no limit by default
drawing
Given a .dxcdrg, a drawing saved from the window (items 572 and 682; an older .dxcaddrg too), it draws that
drawing from its project as the project is now, with its own sheet, views,
scale and fields, and writes what the window's Export Drawing writes; the
file to write may follow it, dxcad drawing part.dxcdrg part.pdf. A
project that is gone is named by its path, and exits 2.
Otherwise, a drawing sheet of a project's parts: the front, top, right and isometric views, visible edges solid and hidden ones dashed, at one standard scale that fits every view in its quarter of the drawing area, inside the title block, with the bill of materials as a parts list. The views are fitted first: a list longer than one column of the sheet takes a second column beside them only where they keep their scale, and runs on to further sheets, the same title block numbered on, where they would not. Written as a DXF (AutoCAD 2000, one layer per view's visible and hidden edges) and as a one-page PDF the size of the sheet. The title block states the scale and the sheet size and names the project, its file and the date. The front, top and right views carry their overall width and height, and every drilled hole a diameter callout where it is seen round, with its depth when it is blind, each a DIMENSION in the DXF; none is put over a view, and one that would be is stacked further out. This is a draft a person finishes, not a toleranced drawing.
Takes a project or a model.py. Writes PROJECT-drawing.dxf and PROJECT-drawing.pdf beside it, or the files named.
--output PATHis a file to write, ending.dxfor.pdf; give it twice for both.--sheet NAMEis the sheet: A4, A3, A2 or A1, landscape on the default title block, or one of ten ready sheets (item 571): ISO 5457ISO-A4-portrait,ISO-A4,ISO-A3,ISO-A2,ISO-A1andISO-A0with an ISO 7200 title block, and ASME Y14.1ANSI-A,ANSI-B,ANSI-CandANSI-Dwith an ANSI one, each with the Designmatix logo; on those the scale is the largest of 5:1, 2:1, 1:1, 1:2, 1:5, 1:10 and 1:20 that fits. A3 by default; any other name is refused, listing them. Their fields a person fills arecompany_name,drawn_by,checked_by,material,finish,tolerance,drawing_noandrev_number.--font NAMEletters the sheet in a TrueType font of the system's, by its file's name (arial) or a.ttfpath: named in the DXF's STYLE table and embedded in the PDF. The bundled DejaVuSans by default; a named font this machine lacks is replaced by it, with a warning naming both.--text-height MMis the height of the dimensions, the view labels and the title block's fields: 2.5, 3.5, 5 or 7.--field NAME=VALUEfills a field the title block names, such ascustomer_nameorproject_name; it may be given again for another. Fields nobody fills are left empty.--forcewrites over a file that is already there.--timeout SECONDS, as everywhere.
Exits 0, 1 when the sheet cannot be made, or 2 when the project cannot
be read, a file is in the way or a suffix is neither .dxf nor .pdf.
Worked, exits 0:
dxcad drawing bracket.dxcprt --sheet A4 --field customer_name=ACME
usage: dxcad drawing [-h] [--output PATH]
[--sheet {A4,A3,A2,A1,ISO-A4-portrait,ISO-A4,ISO-A3,ISO-A2,ISO-A1,ISO-A0,ANSI-A,ANSI-B,ANSI-C,ANSI-D}]
[--font NAME] [--text-height MM] [--field NAME=VALUE] [--force]
[--timeout SECONDS]
project [OUTPUT]
project: a .dxcprt or .dxcasm file, or a .py model to run, or - for a model on standard input, or a .dxcdrg drawing saved from the windowOUTPUT: a file to write, ending .dxf or .pdf, as --output names one--output PATH: a file to write, ending .dxf or .pdf; may be given twice; by default PROJECT-drawing.dxf and PROJECT-drawing.pdf beside the project--sheet {A4,A3,A2,A1,ISO-A4-portrait,ISO-A4,ISO-A3,ISO-A2,ISO-A1,ISO-A0,ANSI-A,ANSI-B,ANSI-C,ANSI-D}: the sheet: A4 to A1 landscape, or one of the ISO and ANSI sheets; A3 by default--font NAME: a TrueType font of the system's, by its file's name such as arial, or a .ttf path, named in the DXF and embedded in the PDF; the bundled DejaVuSans by default--text-height MM: the height of the dimensions, labels and title block fields: 2.5, 3.5, 5 or 7--field NAME=VALUE: fill a field the title block names, such as customer_name=ACME; may be repeated--force: write over an output file that is already there--timeout SECONDS: stop a model that runs longer than this; no limit by default
flat
The flat pattern of a sheet part, as a DXF for a laser or a plasma table:
the outline to cut on layer CUT, each round hole a circle on CUT, each
rectangular cutout a closed polyline on CUT, each bend's two lines on layer BEND and a note beside each bend on layer NOTES,
such as UP 90 R2. The project's
model.py is re-run, as rebuild runs it, and the pattern is worked out from
what the model built the part from: its base profile, its flanges, and the
thickness, bend radius and K-factor of its SheetSpec. Prints the file
written, then the flat's size and bend count, such as
124.524 x 50.000 mm, 1 bend, with its hole count after them when it has
holes: 124.524 x 50.000 mm, 1 bend, 1 hole, and its cutout count last
when it has cutouts, the base's and its flanges' together:
124.524 x 50.000 mm, 1 bend, 1 cutout.
Takes a project carrying a model.py. Writes NAME-flat.dxf beside it, or the file named.
--part NAMEis the sheet part to unfold, one the model registers withpartfrombase_flangeandflange.--output PATHis the .dxf file to write, or a .svg: an SVG in millimetres, +y up, with the outline and each cutout as a closed path, holes as circles, bend lines dashed and each bend's note as text; or a .step or .stp: the flat as one solid, the outline extruded by the sheet's thickness from z = 0 with every hole and cutout cut through it, for a CAM program that wants a solid. Any other name is written as DXF.--allunfolds every sheet part the model registers instead, each to NAME-flat.dxf beside the project, in the model's order, printing one line for each: its path, then its size and bend count after a colon. It takes no--partand no--output.--titlewrites the part's name and the sheet's thickness, such astray, 2 mm, once below the flat on the DXF (a TEXT on layer NOTES) or the SVG (a text), so the cut part can be told apart on the shop floor. With--all, each part's own name. A .step or .stp output ignores it.--bend-zonesalso draws the two edges of each bend zone, continuous, on layer BEND-ZONE (a class of its own in the SVG), beside the one dashed centre line on BEND that every flat has, for a shop that wants them. Without it every byte is as before.--edgesprints, straight after the size line, one line per edge of the part's outline, numbered from 0 asflange()takes them: its two ends, its length and the flange on it with its leg, orfree, such asedge 1: (100, 0) to (100, 50), 50.000 mm, flange UP 90 R2 20.000 mm. With--all, each part's edge lines follow its own line. Without it the output is as above.--bendsprints a bend table for the press brake after the size line and any edge lines, one line per bend in the flat's order: its direction, angle and inside radius, its bend allowance worked with that radius, and the length of its bend lines, such asbend 1: UP 90 R2, allowance 4.524 mm, length 50.000 mm. With--all, each part's bend lines follow its own line. Without it the output is as above.--cutprints, after the size line and any bend lines, the flat's cut length, the outline's perimeter plus every hole's circumference and every cutout's perimeter, and its area, the outline's less every hole and cutout, for quoting a laser or a plasma table, such ascut length 349.048 mm, area 6226.195 mm², then a line with the flat's mass, its area times the thickness at its sheet's metal, and the metal, such asmass 97.751 g, mild steel. With--all, each part's lines follow its own lines. Without it the output is as above.
A shop's CAM software may want a different DXF. --profile NAME writes it
as a shop export profile has it: the DXF version (R12, R2000, R2013 or
R2018), the units (mm or inch), the names of the cut, bend and notes layers,
each bend as its dashed centre line or its two zone edges, holes as circles
or as polylines within a chord tolerance, notes on or off, and a colour for
each layer. Profiles are kept in DX-CAD's settings; Default is the plain
output above, byte for byte, and is what is written without --profile.
--profiles lists them, one line each. A profile applies to a DXF; an SVG or
STEP is written as ever. An unknown profile is refused, listing the names.
Exits 0, or 2 when the project cannot be read or carries no model.py,
the model fails, it builds no part of that name, the part is not a sheet
part, neither --part nor --all is given, --all comes with --part or
--output, or --all finds no sheet part. With --all, a sheet part that
cannot be unfolded is said on stderr, the others are still written, and the
exit is 1. The bracket is not a sheet part:
Worked, exits 2:
dxcad flat bracket.dxcprt --part bracket
usage: dxcad flat [-h] [--part PART] [--all] [--output OUTPUT] [--bends] [--cut] [--edges] [--title]
[--bend-zones] [--profile PROFILE] [--profiles]
[project]
project: a .dxcprt or .dxcasm file carrying a model.py (needed but for --profiles)--part PART: the sheet part to unfold--all: unfold every sheet part the model registers, each to NAME-flat.dxf (item 514)--output OUTPUT: the .dxf file to write, or a .svg, or a .step or .stp for the flat as a solid; NAME-flat.dxf beside the project by default--bends: after the size line, print one line per bend for the press brake (item 543)--cut: after the size and any bend lines, print the cut length and area (item 549)--edges: after the size line, print one line per outline edge and its flange (item 552)--title: write the part's name and the thickness below the flat on the DXF or SVG (item 555)--bend-zones: also draw each bend zone's two edges, continuous, on layer BEND-ZONE (item 565)--profile PROFILE: write the DXF as the shop export profile of this name has it (item 607); Default is the plain output--profiles: list the shop export profiles and exit (item 607)
merge
Two projects into one, the first project's entries followed by the second's. The model is not merged: the result carries no script, since no one script builds both halves.
Takes two projects and the file to write. Writes that project.
Exits 0, or 2 when either project cannot be read, when the two hold an
entry of the same name, or when the output is a .py model.
Worked, exits 0:
dxcad examples flange
dxcad run flange.py --output flange.dxcprt
dxcad merge bracket.dxcprt flange.dxcprt both.dxcasm
usage: dxcad merge [-h] first second output
first: the project whose entries come firstsecond: the project whose entries are appendedoutput: the .dxcprt or .dxcasm file to write
import
A project made out of STEP or BREP files, one entry per file, each named after the file it came from.
Takes the project to write and the parts to read. Writes that project.
Exits 0, or 2 when a part cannot be read or the output is a .py
model. A part that comes in as several solids is one entry still.
An output ending .dxcasm brings one STEP assembly in whole instead: the
assembly as a .dxcasm, a .dxcprt for each distinct part with its shape
beside it as a .brep of the same name, and a .dxcasm for each
sub-assembly, used as a group, so the file's levels are kept. Each part keeps
its name, colour, part number, revision and properties, and each component
its place, in millimetres whatever unit the file was written in.
Worked, exits 0:
dxcad import imported.dxcprt bracket.step
usage: dxcad import [-h] output [parts ...]
output: the .dxcprt or .dxcasm file to write; a .dxcasm brings one STEP assembly in wholeparts: the .step or .brep files to read
convert
One file into another format without a project in between: STEP or BREP in, STEP, STL, 3MF or BREP out.
Takes the file to read and the file to write. Writes that file.
Exits 0, or 2 when the input cannot be read or either suffix names no
format DX-CAD knows.
Worked, exits 0:
dxcad convert bracket.step bracket.stl
usage: dxcad convert [-h] input output
input: the .step or .brep file to readoutput: the .step, .stl, .3mf or .brep file to write
run
A model.py into a project: the script is run, every part it registers becomes an entry, and the model travels inside the project it built. This is the command the parametric model is made of.
Takes the model to run, or - to read one from standard input. Writes the
project and prints its name, then one line per part with its volume.
--output OUTPUTis the project to write; with none, the model's own name, a.dxcprtwhen it builds one part and a.dxcasmwhen it builds more or uses another file. Required with-.--forcewrites over an output file that is already there.--timeout SECONDS, as everywhere.
Exits 0, or 2 when the model raises, when the output is there already
without --force, or when the output would be written over the model itself.
Worked, exits 0:
dxcad run bracket.py --output bracket.dxcprt --force
usage: dxcad run [-h] [--output OUTPUT] [--force] [--timeout SECONDS] model
model: the model.py to run, or - to read one from standard input--output OUTPUT: the .dxcprt or .dxcasm file to write; with none, the model's own name, a .dxcprt for one part and a .dxcasm for more; required with ---force: write over an output file that is already there--timeout SECONDS: stop a model that runs longer than this; no limit by default
rebuild
The other half of run: re-run the model a project already carries and bring
its shapes level with it. It says what changed, or nothing changed when the
file already agrees with its model.
Takes a project that carries a model. Writes that project, or another.
--output OUTPUTis the file to write the result to; the project itself by default.--dry-runsays what would change and writes nothing.--forcewrites over an output file that is already there.--timeout SECONDS, as everywhere.
Exits 0, or 2 when the project carries no model, when the model raises or
when the output is there already without --force.
Worked, exits 0:
dxcad rebuild bracket.dxcprt
usage: dxcad rebuild [-h] [--output OUTPUT] [--dry-run] [--force] [--timeout SECONDS] project
project: a .dxcprt or .dxcasm file carrying a model.py--output OUTPUT: the file to write the result to; the project itself by default--dry-run: say what would change and write nothing--force: write over an output file that is already there--timeout SECONDS: stop a model that runs longer than this; no limit by default
script
The model.py a project carries: printed, written out, replaced, or taught to read the parts it does not build.
Takes a project, or nothing with --template. Writes what the option asks
for, and prints the script when none does.
--templategives the model.py a new project starts from rather than a project's own.--output OUTPUTwrites the script to this file instead of printing it.--set SOURCEreplaces the project's script with this file's text, or with standard input's for-.--adopt [DIRECTORY]writes every part the model does not build to a file in that directory and adds the line that reads it back.--forcewrites over an output file that is already there.--timeout SECONDS, as everywhere.
Exits 0, or 2 when the project carries no model, when the output is there
already without --force, or when the output would be written over a
project.
Worked, exits 0:
dxcad script bracket.dxcprt --output bracket-model.py
usage: dxcad script [-h] [--template] [--output OUTPUT | --set SOURCE | --adopt [DIRECTORY]]
[--force] [--timeout SECONDS]
[project]
project: a .dxcprt or .dxcasm file; not needed with --template--template: give the model.py a new project starts from, rather than a project's own--output OUTPUT: write the script to this file instead of printing it--set SOURCE: replace the project's script with this file's text, or with standard input's for ---adopt [DIRECTORY]: write every part the model.py does not build to a file in this directory, the project's own name ending .parts by default, and add the line that reads it--force: write over an output file that is already there--timeout SECONDS: stop a model that runs longer than this; no limit by default
gui
The viewer: an OpenCASCADE scene in a Qt window, with the model in a pane beside it. Qt is imported here and nowhere else, so every other command runs on a machine with no display.
Takes a project or a model to open, or nothing for an empty document. Writes what the window is asked to save.
Exits 0 when the window closes, or 2 when the file given cannot be read.
Not run by the test: it opens a window and waits for a person. What the window holds is in gui.md, and whether it draws correctly is a manual check.
dxcad gui bracket.dxcprt
usage: dxcad gui [-h] [project]
project: the .dxcprt or .dxcasm file or the .py model to open
doctor
What is installed and whether it works: one line each for DX-CAD, Python,
cadquery-ocp, PySide6, the platform and the plugins loaded (none, or each
with its version, or why it was skipped; see plugins.md) and
whether DX-CAD's files are associated (see associate below), and the folder
DX-CAD's log is kept in (log, DX-CAD\logs under the local app data on
Windows, where every dxcad command, each refusal and any error in full are
written; nothing is sent anywhere), then the smoke test, which builds a part,
checks it and exports it. The first thing to run when an install looks
wrong, and the first thing to paste into a report.
Takes nothing. Writes nothing but its own output and a part in a temporary directory.
--guibuilds the window after the smoke test, shows it, closes it and prints one line startingGUI OK, orGUI FAILEDwith the error. A windowed build has no console to fail on, so this is how to tell that its window starts. Whether the view draws the part correctly is still a check by eye.--reportprints the support report instead, everything a bug report needs (item 647): DX-CAD's version and commit, Python, OCCT and Qt, the OS, the OpenGL renderer, vendor and version, where the settings and the log are kept, the plugins and their state, the view's theme and the log's last 50 lines. Nothing personal goes in: your own folder is written as~, and your login and the machine's name, where they would show, as<user>and<host>. Help > Copy Support Report in the window gives the same text.--copy, with--report, puts the report on the clipboard as well, to paste into the bug report form.
Exits 0, or 1 when the smoke test fails or, with --gui, the window does
not come up, or 2 for --copy without --report. A distribution that is missing is said to be not installed and
is not on its own a failure.
Worked, exits 0:
dxcad doctor
usage: dxcad doctor [-h] [--gui] [--report] [--copy]
--gui: after the smoke test, build the window, show it and close it--report: print the support report a bug report needs instead: versions, OpenGL, paths, plugins, theme and the log's last lines, with nothing personal in it--copy: with --report, put the report on the clipboard too
examples
The example models that travel in the package, listed or copied out. Every one of them is in examples/README.md as well.
Takes the name of one example, or nothing to list them all. Writes the copy where it is told to.
--output FILEis the file to write the copy to; NAME.py in the working directory by default.--all DIRcopies every example into DIR, which is made if it is not there.--forcewrites over an output file that is already there.
Exits 0, or 2 for an unknown name, for a file that is there already
without --force, or for --all given a name as well.
Worked, exits 0:
dxcad examples
usage: dxcad examples [-h] [--output FILE] [--all DIR] [--force] [name]
name: the example to copy out; with none, every example is listed--output FILE: the file to write the copy to; NAME.py in the working directory by default--all DIR: copy every example into DIR, which is made if it is not there--force: write over an output file that is already there
gallery
A model.py for the gallery, checked the way the test suite
checks the shipped examples, one line each: its first line is the SPDX
licence line, its docstring gives a title and known tags, it imports
nothing, it builds at least one part within 60 seconds, every part is valid,
and it builds again, valid, with its first number changed. Each line starts
ok or FAIL. new starts a part for a contributor: a model.py of three
numbers and a box, with a docstring to fill in, and its row in the examples'
index in name order. The starter passes check as it is written.
Takes check and the path of the model.py, or new and the new part's
name, which must be a Python identifier no example has yet.
--examples DIRis the foldernewwrites into; docs/examples, from the root of a checkout, by default.
Exits 0 when every line passes, 1 when one fails, or 2 for a file that
is not there; new exits 0, or 2 for a name it refuses.
Worked, exits 0:
dxcad gallery check bracket.py
usage: dxcad gallery [-h] [--examples DIR] {check,new} TARGET
{check,new}: check: run the gallery's checks on TARGET, one line each; new: write a starter part called TARGET and its row in the examples' indexTARGET: the model.py to check, or the new part's name--examples DIR: with new, the examples folder to write into; docs/examples by default
plugins
Which plugins are installed and what each one brings. The first line is
plugin API N, the version a plugin's require() is checked against. Then
each plugin gives its name, its version and the distribution it came from,
and four indented lines list the model names, commands, tools and window
actions it registered, none where it registered nothing. A plugin that was
skipped gives its reason instead, such as needs plugin API 2, this DX-CAD
has 1. With no plugin installed it prints no plugins. See
plugins.md for how to write one.
Takes nothing. Writes nothing but its own output.
Exits 0.
Worked, exits 0:
dxcad plugins
usage: dxcad plugins [-h]
Takes no arguments.
addons
Installs, lists, disables, enables and removes add-ons, as Help > Add-ons
does in the window. list prints one line per installed plugin: its name and
version, its publisher, its licence state (open, unlocked, or locked
and what it needs), whether it is enabled and the folder it lives in; no
add-ons when there are none. install WHEEL checks a plugin wheel first: one that declares no
dxcad.plugins entry point, is built for another platform or for another
plugin API is refused with the reason. A plugin wheel says its API with the
classifier Framework :: DX-CAD :: Plugin API :: N; one without it is taken
as built for API 1. The wheel is installed into DX-CAD's own add-ons folder
(DX-CAD\addons under the local app data on Windows,
~/Library/Application Support/DX-CAD/addons on macOS and
~/.local/share/DX-CAD/addons on Linux, or where DXCAD_ADDONS_DIR says),
never into a Python of the user's and never inside the installed program,
which a signed app, Program Files and an AppImage do not allow, and loads at
the next start. disable NAME keeps a plugin installed but not loaded, enable
NAME loads it again, and remove NAME uninstalls an add-on DX-CAD installed.
Writes only into the add-ons folder.
Exits 0, or 2 when a wheel is refused or there is no such add-on.
Worked, exits 0:
dxcad addons list
usage: dxcad addons [-h] {list,install,remove,enable,disable} [target]
{list,install,remove,enable,disable}: what to dotarget: the wheel (.whl) to install, or the add-on's name
associate
Makes DX-CAD's files open in DX-CAD: older .dxcad projects with the DX icon,
and on Windows the three document types too, each with an icon of its own: .dxcprt parts as
DXCAD.Part, .dxcasm assemblies as DXCAD.Assembly, and .dxcdrg
drawings, with older .dxcaddrg ones, as DXCAD.Drawing; for the current user
alone and with no administrator rights: what an installer does, for a pip
install, which has none. On Windows it writes the DXCAD.Project type the
installer registers under HKEY_CURRENT_USER\Software\Classes, the icon
from the package and dxcad-gui to open the file with, and asks Explorer to
show it. On Linux it writes the desktop entry, the shared-mime-info file and
the icon under $XDG_DATA_HOME (~/.local/share when unset) and rebuilds
the user's MIME and desktop databases where the tools are there. On any
other desktop, macOS among them, it says what it would do and does nothing.
dxcad doctor says whether the association is in place.
--removetakes the association out again, every extension, leaving an extension's key alone when another program has since claimed it.
Exits 0, or 1 when the registry or the files cannot be written.
dxcad associate
Not run by the test: it writes into the user's own registry or desktop database, which a test run must leave as it found it; the suite registers under a key of its own instead.
usage: dxcad associate [-h] [--remove]
--remove: take the association out again
freeze
The PyInstaller spec a desktop build is made from, written for this machine's desktop or another's. Nothing is built and PyInstaller is never imported, so the spec can be written on a machine that does not have it.
Takes nothing. Writes dxcad.spec and prints it, then the PyInstaller
command line to run over it.
--platform {windows,macos,linux}is the desktop to write the spec for; this machine's by default.--output OUTPUTis the directory to write the spec into; the working directory by default.--pack DIRzips DIR, the directory a freeze collected, into the output directory instead, and prints the zip's path. Everything goes in under oneDX-CAD/folder; the zip is named after the version and the platform, asDX-CAD-<version>-windows-x64.zip, and two packs of one build are the same bytes. WithDXCAD_SIGN_THUMBPRINTset, a DIR whose executables are not signed yet is refused, naming the first, so a signed release's zip cannot ship them unsigned.--appdir DIRlays DIR, the directory a Linux freeze collected, out asDX-CAD.AppDirin the output directory instead, and prints its path: DIR whole asusr/bin, anAppRunthat startsDX-CAD, the desktop entry and the DX icon.appimagetoolpacks it intoDX-CAD-x86_64.AppImage, as CI's build job does (item 643). An AppDir already there, or a DIR with noDX-CADexecutable, is refused. The macOS spec's bundle carriesInfo.plist(bundle iduk.co.designmatix.dxcad, the version) and the.icnsicon, and CI packsDX-CAD.appintoDX-CAD-<version>-macos.dmg.--installer DIRbuilds the Windows installer of DIR, the directory a freeze collected, into the output directory instead, with Inno Setup 6's ISCC found on PATH or in its default install folder, and prints its path,DX-CAD-<version>-windows-x64-setup.exe. Without Inno Setup it says so, naming it, and builds nothing. Windows only. The installer script is the one the package carries asdxcad/installer/dxcad.iss, so this works from a pip install, else a checkout'sinstaller/dxcad.iss; it says which.--sign, with--installer, signs the build withinstaller/sign.ps1through PowerShell. The executables in DIR (DX-CAD.exe,dxcad.exe, anddxcad-gui.exewhere there is one) are signed before Inno Setup packs them. Then Inno Setup signs the uninstaller and the installer with the same script as it builds them. The certificate is the oneDXCAD_SIGN_THUMBPRINTnames, and the timestamp server isDXCAD_SIGN_TIMESTAMP(http://ts.ssl.comby default). Without the script, the variable or PowerShell, it says why and builds the installer unsigned.--release DIRmakes the signed Windows release of DIR into the output directory, every step in order: signs the executables, builds the installer and has Inno Setup sign it, packs the zip, reads back every signature withinstaller/verify.ps1, and prints the installer's and the zip's paths and a table of files, statuses and signers. Without Inno Setup, the signing script orDXCAD_SIGN_THUMBPRINTit is refused, saying why. Not with--packor--installer.
Exits 0, 1 when ISCC, the signing or a signature fails, when a release
cannot be signed or built, or when --pack finds an unsigned executable, or
2 when a directory it is given is not there or --appdir refuses it, the installer or the release is
asked for another platform, --sign is given without --installer, or
--release with --pack or --installer.
The Windows zip is what a GitHub release carries for someone without Python:
they download DX-CAD-<version>-windows-x64.zip, unzip it anywhere, run
DX-CAD.exe from the DX-CAD folder, and run dxcad.exe doctor there to
tell that it works.
Not run by the test: the Windows spec is frozen by the suite through the release checklist's freeze step instead, and the macOS and Linux builds are made on machines this suite never sees.
dxcad freeze --platform linux
usage: dxcad freeze [-h] [--platform {windows,macos,linux}] [--output OUTPUT] [--pack DIR]
[--appdir DIR] [--installer DIR] [--sign] [--release DIR]
--platform {windows,macos,linux}: the desktop to write the spec for; this machine's by default--output OUTPUT: the directory to write the spec into; the working directory by default--pack DIR: zip DIR, a frozen build's collected directory, into the output directory for a release, instead of writing the spec--appdir DIR: lay DIR, a frozen Linux build's collected directory, out as DX-CAD.AppDir in the output directory for appimagetool, instead of writing the spec--installer DIR: build the Windows installer of DIR, a frozen build's collected directory, into the output directory with Inno Setup, instead of writing the spec--sign: with --installer, sign the executables, the uninstaller and the installer with installer/sign.ps1; skipped, saying why, without it or DXCAD_SIGN_THUMBPRINT--release DIR: make the signed Windows release of DIR into the output directory: sign the executables, build and sign the installer, pack the zip, verify every signature and print a table of files and signers