| drawing_infoA | Get comprehensive metadata for the current drawing. Returns: name, path, entity_count, layer_count, block_count,
extents (min/max), units, version, backend name, and the document's
document_id (a uuid4 hex minted when it was opened or created) and
revision (its content revision: moved by every content change, never by
a save, an export, a finalize or a delivery). On the live engine a call
made after the operator switched AutoCAD's active document is refused with
kind: "active_document_changed" (bound, active). |
| drawing_newA | Create a new drawing, optionally from a template. A bundled name resolves to templates/<name>.dxf headlessly and
templates/<name>.dwt on the live engine (falling back to the DXF with
source: "bundled_dxf" when no .dwt twin is committed); a path is used
as given. The result carries template: {name|path, path, source}. On the live engine only a genuine .dwt reaches Documents.Add —
measured on AutoCAD 2026, Add(<file.dxf>) silently returns the default
drawing — so a .dxf template (bundled or a path) is first converted
through AutoCAD into a cached .dwt and template.dwt names it
(template.dwt_cached says whether the conversion was reused). The
drawing then really carries the template's layers, tabs and page setup. Refused before anything is replaced: a bare name that is not in the
catalogue (the message lists the five), a template path that does not
exist, and a path outside the allowed directories. With bootstrap=True
(default) the standard engineering linetypes and layers are ensured
afterwards — idempotent on a template that already has them. |
| drawing_openA | Open an existing DXF drawing file (DWG too, on the live COM backend). T0.2: a .dwg path is refused up front when the active backend has no dwg
capability. ezdxf sniffs content rather than extensions, so it would parse a
mislabelled DXF-in-a-.dwg and this tool would answer with a document that
does not exist in that format. |
| drawing_saveB | Save the current drawing. Optionally specify a new path. |
| drawing_save_asA | Save current drawing to a new path/format (DWG, DXF, or DWT template). The on-disk format is derived from the file extension so the bytes always
match the name (N2) — e.g. 'part.dxf' writes DXF, not DWG. format overrides
only when the path has no recognised extension. |
| drawing_export_dxfA | Export the current drawing as a DXF copy. The open document is never re-pointed: it keeps its name, path and saved flag
(drawing_save_as is the call that re-points). Live: Document.Export, renamed to
the name given; headless: a copy written by ezdxf. The result names the method
and the DXF version written. Refused: a name that is not .dxf (a .dwg headlessly
with capability dwg). |
| drawing_export_pdfA | Export the current drawing (or a paper-space layout) to PDF. |
| drawing_purgeA | Purge all unused objects (layers, blocks, linetypes, styles) from the drawing. |
| drawing_auditA | Audit the drawing: repair every fixable structural problem, and report it. This mutates the drawing. fixes lists repairs that have ALREADY been
applied, so save afterwards to keep them; errors lists problems that could
not be repaired. On the live COM backend AutoCAD applies repairs but hands
back no counts, so they arrive as null with detail: "unavailable" rather
than as zero. |
| drawing_closeA | Close the active document. If save is True (default), the drawing is
saved to its current path before closing; an untitled document is closed
and warning says its changes were discarded (headless) or the call is
refused (live, where the alternative is a modal Save dialog). The
active-document case of document_close; after the last document is
closed, call drawing_new or drawing_open before any other tool. |
| drawing_undoA | Undo the last drawing operation. On the live COM backend this is AutoCAD's own undo. The headless backend has
no journal, so a step is a full DXF snapshot and history is off by
default — set EZDXF_UNDO_DEPTH to the number of steps you want. Measured
cost of switching it on: 37x on entity creation (0.18 -> 6.65 ms per call).
For a single checkpoint around a risky sequence, transaction_begin /
transaction_rollback is far cheaper. Drawing something after an undo discards the redo branch, as in AutoCAD. |
| drawing_redoA | Reapply the operation you just undid. Same history as drawing_undo, so the headless backend needs
EZDXF_UNDO_DEPTH set. Anything drawn after an undo discards the redo
branch — otherwise redo would restore a state that never existed, with
geometry you had removed reappearing beside geometry you drew afterwards. |
| entity_create_lineA | Create a line from (x1,y1) to (x2,y2). Returns entity info with handle. |
| entity_create_circleA | Create a circle at (cx, cy) with given radius. |
| entity_create_arcA | Create a circular arc. Angles are in degrees, measured counter-clockwise from the positive X axis. |
| entity_create_polylineA | Create a lightweight 2D polyline through the given points. Example: points=[[0,0],[100,0],[100,100],[0,100]], closed=true → rectangle |
| entity_create_rectangleA | Create a closed rectangular polyline between two corner points. Convenience wrapper around entity_create_polyline. |
| entity_create_textA | Create a single-line text entity (DTEXT/TEXT). |
| entity_create_mtextA | Create a multi-line text entity (MTEXT) with word-wrap at the specified width. |
| entity_create_tableB | Create a native COM table or an explicitly-labelled ezdxf composite table. |
| leader_create_mleaderC | Create a native COM MLeader or an explicitly-labelled ezdxf composite. |
| entity_create_hatchB | Create a hatch fill pattern inside a closed boundary polygon. |
| entity_create_splineA | Create a NURBS spline curve passing through the specified fit points. |
| entity_create_ellipseA | Create an ellipse. major_x/major_y define the major axis vector from the center. |
| entity_create_pointB | Create a point marker entity at (x, y). |
| entity_create_block_refA | Insert a block reference (instance of an existing block definition). Refused before any write, on both engines: a name that is not a block
definition in this drawing (block 'X' is not defined — check
block_list), a layout block (*Model_Space / *Paper_Space, a
reference cycle) and a non-string name. The same gate as block_insert;
this tool is the no-attributes form. |
| hatch_set_gradientA | Fill a hatch with a gradient instead of a pattern. |
| hatch_editA | Edit an existing hatch in place. Omitted parameters are left alone — a partial edit that resets the rest is
data loss. changed reports which attributes actually moved, so re-setting
a value to what it already was comes back as an empty list rather than a
false positive. |
| hatch_add_boundaryA | Add one boundary path built from typed edges - an island inside the hatch. Typed edges exist because a boundary that only accepts vertex lists
silently straightens every curve it is given. Every edge is validated
before any is written, so a malformed list refuses instead of leaving a
half-built path. Both engines: headlessly the edges become an edge path;
on a live seat each becomes a temporary LINE, true ARC or ELLIPSE appended
as an inner loop and then deleted (a chain of lines becomes one polyline).
A loop that does not close is refused by AutoCAD and nothing is added. |
| entity_create_wipeoutA | Create a WIPEOUT that hides drawing content behind its outline. Refuses fewer than three points: a zero-area mask hides nothing while
reporting success. |
| entity_create_revcloudA | Draw a revision cloud: a polyline whose every segment carries an arc. A segment_length longer than the shortest edge is refused — the result
would carry no arcs at all and would be a plain polyline reported as a
cloud. |
| dimension_linearB | Create a linear dimension, optionally toleranced (ISO 129 or ISO 286 fit). |
| dimension_alignedA | Create an aligned dimension that measures the true distance between two points. |
| dimension_angularA | Create an angular dimension measuring the angle between two lines from a vertex. |
| dimension_radiusA | Create a radius dimension for a circle or arc, optionally toleranced. |
| dimension_diameterA | Create a diameter dimension for a circle, optionally toleranced (e.g. ⌀20 H7). |
| entity_moveA | Move an entity by the specified displacement vector (dx, dy, dz). |
| entity_copyA | Copy an entity and move the copy by (dx, dy, dz). Returns info of the new copy. |
| entity_rotateA | Rotate an entity around a base point by the specified angle. |
| entity_scaleA | Scale an entity uniformly from a base point. |
| entity_mirrorA | Mirror an entity across a line defined by two points. Returns the mirrored copy. |
| entity_offsetB | Create a parallel copy of a line, circle, or polyline at the given distance. |
| entity_trimA | Trim target against cutter, keeping the segment containing (keep_x, keep_y). V1 supports LINE+LINE only. Cutter is treated as an infinite ray (AutoCAD's
default 'implied extend' trim mode). Raises if the lines are parallel. |
| entity_extendA | Extend target to meet boundary. If end_x/end_y is None, the target
endpoint nearest the boundary is auto-selected. V1 supports LINE+LINE only. Raises if the lines are parallel. |
| entity_filletA | Round a corner with a tangent arc. Returns info on the new ARC entity
(or the first source line for radius=0). V1 supports LINE+LINE only. |
| entity_chamferA | Bevel a corner with a chamfer line. Returns info on the new chamfer LINE.
V1 supports LINE+LINE only. |
| entity_deleteA | Permanently delete an entity by its handle. |
| entity_array_rectangularA | Create a rectangular array of copies. Returns info of all created copies. rows x cols is unbounded, so this is a result-heavy tool despite being a
create: a 40x40 grid hands back 1600 full records. fields=["handle"] is
usually all a caller needs from it. |
| entity_array_polarA | Create a polar (circular) array of copies around a center point. count is unbounded, so the same result-shaping applies as for the
rectangular array: fields=["handle"] when the geometry is already known.
|
| entity_set_propertiesA | Change one or more properties of an entity (layer, color, linetype, lineweight, visibility). |
| entity_edit_textA | Edit an existing text label in place — change its content, height, or rotation. Use this to rename/relabel without deleting and recreating (which would lose
the handle). Works on both TEXT and MTEXT. |
| text_set_backgroundA | Mask what is behind an MTEXT so it stays readable over hatch or geometry. MTEXT only: TEXT has no background-fill attribute, so setting one on it
would report success and change nothing. |
| text_find_replaceA | Replace text in TEXT, MTEXT and block attributes (ATTRIB and ATTDEF). Both engines search the same places (searched_scope): model space, every
paper layout, every named block definition - so the next insert does not
reintroduce the old text - and the attributes of every block reference in
any of them; an xref's block holds another file's text and is not searched.
searched_types is on the response because "no matches" and "that type was
never searched" are different answers. DIMENSION text is out of
scope: its text field holds the <> override placeholder rather than the
measurement, so editing it would break the association. Anonymous blocks
(*D - a dimension's rendered measurement - *T, *U, *X) are
renderings regenerated from their owner and are not searched either. A multi-line
attribute is matched and rewritten as the whole value (Line1\PLine2),
the same value block_get_attributes reports and block_explode bursts. dry_run=True adds preview: the document's content revision, the exact
fingerprint of every matched entity and the planned rows. Applied with that
revision (expected_revision) and/or its preconditions, the search runs
again first: an edited entity, a moved revision or a new match the preview
did not list refuses the call with kind stale_revision and nothing is
replaced. A guarded apply reports revision ({checked, after, interleaved}). |
| entity_edit_geometryA | Edit the defining geometry of an existing entity in place (no delete/recreate). CIRCLE: cx/cy/radius · LINE: x1/y1/x2/y2 · ARC: cx/cy/radius/start_angle/end_angle.
Any argument left out is unchanged; the handle is preserved. |
| selection_windowA | AutoCAD's ssget window/crossing selection. Corners may be given in any order. Selection is by drawn position, so an
entity in a mirrored frame is found where entity_get reports it. A
zero-area box is refused rather than answered with an empty list. |
| selection_polygonA | Window or crossing selection against a polygon rather than a rectangle. |
| selection_filterA | AutoCAD's QSELECT: filter the drawing by properties. Named parameters rather than a query string, deliberately — a mistyped
attribute name in a query language comes back as an empty result, which is
indistinguishable from "no matches". filtered_by reports which filters
actually ran. |
| entity_getA | Get all properties of a specific entity by its handle. Coordinates are WCS. A HATCH also reports every boundary loop: loops
(each with kind, flags, depth, points and the parallel bulges,
edges for an edge path, exact and its area), hatch_style and the
filled area - outer loops minus islands by the hatch's own island style,
the rule analysis_measure_entity applies; None when a loop has an ellipse
or spline edge. A DIMENSION also reports dimension: dimtype, the five
defpoints, its own measurement (before DIMLFAC), text_override,
dimstyle, dimlfac and angle. On the live engine those two are read
from the drawing's DXF export (one export per call; detail_source says
so), and a member of a block definition reports detail_unavailable. An
entity in a plane tilted out of WCS XY reports plane_normal (or
tilted) and omits what xy cannot express. Refused: a handle the drawing
does not hold. |
| entity_listA | List entities in the drawing with optional type and layer filters. Returns handle, type, layer, color, and type-specific properties.
Use handles with entity_get, entity_move, entity_delete, etc. This is the most expensive result on the server — the full record runs
~250 characters per entity, and properties.bounding_box alone is about a
third of it. When all you need is handles, say so:: entity_list(layer_filter="GEOMETRY", fields=["handle", "type"], compact=True)
Paging honesty: a plain list has nowhere to say that more entities followed
the page, so compact=True is the only mode that reports total,
truncated and next_offset — all measured against the same filters. |
| entity_delete_manyA | Delete multiple entities in one call. Returns count of deleted entities. |
| selection_getA | Read the entities the user pre-selected in the AutoCAD viewport (COM backend only). Returns the implied "pickfirst" selection — the entities highlighted with
grips before invoking the AI — so work can be scoped to exactly those
entities instead of the whole drawing. Typical use:: sel = selection_get()
dimension_auto(sel["handles"], style="chain")
Result keys:
ok — True on the COM backend (even for an empty selection)
count — number of selected entities
handles — list of entity handles (hex strings) to act on
entities — full per-entity info (type, layer, color, ...)
pickfirst — state of the PICKFIRST sysvar (None if unknown)
message — guidance when nothing is selected On the ezdxf headless backend there is no viewport, so this returns
ok=False with an empty handles list. fields / compact shape the "entities" collection — this tool already
returns an object, so the columnar envelope lands under that key rather
than replacing the result. handles is unaffected, so a caller that only
wants handles can pass fields=["handle"] and still read handles directly.
|
| entity_get_xdataC | Extended entity data as {app: [values]}. An app with no XDATA is simply absent. |
| entity_set_xdataA | Replace the named app's XDATA on one entity; an empty list removes it. Limits are AutoCAD's and are enforced before writing: 255 characters per
string and 16 KB per entity. |
| layer_listA | List all layers with their properties (color, linetype, frozen, locked, visibility). Never truncated — a drawing's whole layer table is returned — so a compact
envelope here always reports truncated=false. |
| layer_createB | Create a new layer with specified properties. |
| layer_deleteA | Delete a layer. The layer must have no entities. Layer '0' cannot be deleted. |
| layer_set_currentA | Set the active/current layer for new entities. |
| layer_modifyA | Modify an existing layer's color, linetype, and/or lineweight. |
| layer_freezeA | Freeze a layer (makes it invisible and unselectable, faster regeneration). |
| layer_thawA | Thaw a frozen layer, making it visible and selectable again. |
| layer_lockA | Lock a layer (entities visible but cannot be selected or modified). |
| layer_unlockA | Unlock a layer to allow entity selection and modification. |
| layer_hideA | Turn off a layer (entities invisible but still processed in regeneration). |
| layer_showA | Turn on a layer that was previously turned off. |
| layer_isolateA | Hide all layers except the specified one (layer isolation). |
| linetype_listA | Return the names of all linetypes currently loaded in the active drawing. |
| linetype_loadA | Load a single linetype safely. Use this instead of system_run_command('_-LINETYPE _LOAD ...') — that
raw form deadlocks on the FILEDIA file-picker dialog and on the
-LINETYPE option-menu prompt (measured on AutoCAD 2026: it loads nothing
either way). This tool loads through the ActiveX Linetypes.Load member,
picks the right .lin file from MEASUREMENT, and verifies the linetype
actually loaded. Refuses a name that is not a valid symbol name, a file
outside the allowed paths, and reports a name the file does not carry
or a file AutoCAD cannot find as an error naming both. |
| block_listA | List all block definitions in the drawing (name, origin, attribute count, entity count). Never truncated — the whole block table is returned — so a compact envelope
here always reports truncated=false. |
| block_insertA | Insert a block and optionally set attribute values. Refused before any write, on both engines: an undefined or layout block
name, and an attribute value that is not text — a string is written as
is (one line), an int or finite float as its plain digits (101 →
"101"), while null, booleans, lists and objects are refused naming
the tag (they used to be written as their Python repr). Values for tags
the block does not define are ignored. |
| block_explodeA | Explode a block reference into its component entities, keeping its
attribute text (the Express Tools BURST rule, on both engines). Every attached ATTRIB becomes a TEXT with the same value, placement,
height, rotation and layer (an invisible attribute becomes an invisible
TEXT; a multi-line attribute becomes an MTEXT carrying every line), and
a constant attribute (which has no ATTRIB) becomes a TEXT of its value
too; AutoCAD's plain EXPLODE would keep only the tag-name placeholders
and drop the values. Everything lands in the layout that owns the
reference (model space or its paper-space sheet), whichever tab is
current. Returns inserted_handles (the geometry), attribute_texts
(one TEXT or MTEXT handle per attribute), exploded_handle and
backend. Refused, with nothing written: a handle that is not a block
reference, a reference nested inside a block definition (explode the
outer reference instead), an external reference (bind it first), a
MINSERT grid, and -- headless only, capability explode_opaque_members
-- a block holding a member ezdxf cannot transform (an OLE2FRAME logo, a
VIEWPORT, a proxy entity without proxy graphics), named by member; the
live engine hands those to AutoCAD. Not undoable except through
drawing_undo / a transaction. |
| block_get_attributesA | Get all attribute values from a block reference as {TAG: value} dict. A multi-line attribute reports its whole content with \P between the
lines (AutoCAD's TextString), on both engines. |
| block_set_attributesA | Update attribute values in a block reference. Same value rule as block_insert: strings and numbers are written,
null / booleans / lists / objects are refused naming the tag before
anything changes. updated_tags lists the tags that exist on the
reference and were written; unknown tags are ignored. A multi-line attribute takes Line1\PLine2 and keeps every line; the
value written is the one block_get_attributes reads back and
block_explode bursts, on both engines. |
| block_create_from_entitiesA | Create a new block definition from existing entities in the drawing. Works on both engines. The originals stay in model space — this defines a
reusable block from them rather than consuming them the way AutoCAD's BLOCK
command does; use block_insert to place copies, and delete the originals
yourself if you want the command's behaviour. Handles that do not resolve are listed in skipped rather than silently
dropped, and a call where none resolve fails instead of leaving an empty
definition behind. |
| block_defineA | Create a block definition with attribute definitions from typed specs. The whole request is validated before anything is written: one malformed
entry refuses the call and leaves no definition behind. Refusals: a
malformed primitive or ATTDEF (names entities[i]/attdefs[i] and the
key), a non-finite base point (names base_x/base_y), a name clash
without overwrite, an anonymous * name, and a primitive layer that
is not in the drawing's layer table (names the missing layers) unless
create_layers=true, which creates them and lists them in
layers_created. overwrite=true replaces the contents of an existing
block so its INSERTs keep pointing at the name and show the new geometry;
replaced reports it. Geometry inside the block is ByBlock so the
INSERT's layer supplies colour and lineweight. Insert with
block_insert(attributes={TAG: value}). |
| block_find_referencesA | Find all insert references to a specific block definition. Bounded by the backend's own default entity_list page (200 INSERTs scanned),
which is a pre-existing limit, not a new one: the compact envelope's total
counts the references found within that scan. |
| boundary_traceA | AutoCAD's BOUNDARY/BPOLY: create a closed polyline around a seed point. Returns the nearest enclosing loop, so a seed inside an island gives the
island rather than the outer region. Straight edges are split where they
cross, so a line drawn across a shape divides it the way it looks like it
should. A seed with no enclosing loop is refused, and the error names the
gap when the edges nearly close. |
| boundary_from_entitiesA | Chain the given entities into one closed polyline. The handles may arrive in any order — putting them in chain order is the
tool's job. A chain that does not close is refused, and the error names the
coordinates of the gap. |
| analysis_list_propertiesA | AutoCAD's LIST: the full DXF attribute set for one handle. dxf_attributes is the raw attribute set entity_get deliberately does
not carry. Coordinates in it are WCS, like everywhere else in this server,
and extrusion is reported so the entity's own frame is still visible.
|
| analysis_entity_statsA | Analyze the drawing and return entity counts grouped by type and by layer. Returns: total_entities, by_type (sorted by count), by_layer (sorted by count).
This is unique to AutoCAD MCP Pro – no other MCP server provides this! |
| analysis_find_in_regionA | Find all entities within a rectangular region (crossing selection). Uncapped: a window over a busy drawing returns every hit. Project with
fields and/or compact before widening the window. |
| analysis_measure_distanceA | Measure the Euclidean distance between two points. |
| analysis_measure_areaA | Area and perimeter of a polygon you supply the vertices for. This measures the numbers in the call, NOT the drawing. To measure something
that exists, use analysis_measure_entity(handle) — it reads the real
geometry, including curvature this tool can only see if you pass it. Straight-edged polygons are exact. Pass a third bulge element per vertex
for arc edges; omitting it on curved geometry under-reports (28% on a
semicircular edge), which is why assumes says what was taken on faith. |
| analysis_measure_entityA | Measure something already in the drawing, by handle. Reads the real geometry, so polyline bulges (arc edges) are included —
reading vertices back and shoelacing them yourself loses 28% of the area on
a semicircular edge, silently. Measurable: LWPOLYLINE, 2D POLYLINE, CIRCLE, ELLIPSE, SPLINE, HATCH, SOLID,
TRACE, 3DFACE. REGION and 3DSOLID need the live COM backend (their area is
in ACIS data ezdxf cannot evaluate) and refuse with
capability: "measure_area_acis". LINE/TEXT/INSERT bound no area on any
engine and are a plain error, not a capability gap. The payload states its own accuracy: exact is false when the shape had to
be flattened (then flatten_tolerance says how finely), assumed_closed is
true when an open boundary was closed the way AutoCAD's AREA does, and
self_intersecting warns when the shoelace cancelled crossed lobes — a
bowtie measures 0.0 and that number is worse than useless unflagged. |
| analysis_bounding_boxA | Get the bounding box (extents) of all entities in the drawing. |
| analysis_select_by_layerA | Get all entities on a specific layer. Returns entity list with handles. Capped at MAX_LIST_LIMIT (default 5000). The plain list cannot say it was
capped — the warning goes to the log stream, which most clients never show
the model — so use compact=True when the count matters: its total is the
layer's real population and truncated states whether the cap fired. |
| analysis_select_by_typeA | Get all entities of a specific type. Returns entity list with handles. Capped at MAX_LIST_LIMIT (default 5000); as with analysis_select_by_layer,
compact=True is the only shape that reports total and truncated. |
| analysis_layer_statsA | Return detailed statistics for each layer: entity count, types present. |
| cad_batchA | Execute an ordered list of tool calls in ONE round trip. N calls collapse into one request/response pair, and bind lets a later
step reference an earlier step's result so handles never have to be echoed
back through the model. steps=[
{"tool": "entity_create_line", "args": {...}, "bind": "edge"},
{"tool": "point_from_snap", "args": {"handle": "$edge", "snap": "mid"},
"bind": "mid"},
{"tool": "entity_create_circle","args": {"cx": "$mid.x", "cy": "$mid.y",
"radius": 4}},
]
Successful steps report only their handle; pass verbose=True for the full
result. Anything without a handle is returned whole. VALIDATION runs first, always: an unknown tool, a schema-invalid argument or
a reference no earlier step binds refuses the whole batch before anything
executes. on_error governs run-time failures only. dry_run=True returns
that validation report and executes nothing. ERRORS are typed, never text: each failed step carries error.kind - one of
unsupported (with the backend capability), invalid_args, refused, failed,
unknown_tool, unresolved_ref, denied, malformed_step, quarantined, busy,
active_document_changed (live engine: the operator switched documents),
stale_revision, scan_incomplete, timed_out, unknown_commit (a write that
outran its deadline while its worker ran), cancelled, operation_conflict -
and its own operation_id. PREVIEW AND APPLY. dry_run=True also returns preview: the document id and
content revision, the exact fingerprint of every LITERAL handle in a handle
parameter (a '$reference' resolves late and an entity a step creates has
none) and the planned steps. Pass its revision as expected_revision and
its preconditions back, and the batch runs only if nothing moved -
otherwise it is refused with kind stale_revision and no step runs. A
guarded batch reports revision: {checked, after, interleaved}; each step
is its own locked call, so a change another call made between two steps is
listed under interleaved (a rollback restores the checkpoint, that change
included). OPERATIONS: the batch and each step are operations with their own ids
(system_status lists the recent ones). Pass operation_id (or the
request's _meta.operation_id) to make a retry safe: the same id with the
same steps replays the recorded result instead of drawing twice. The
journal is in memory: a server restart forgets it (durable in 1.8.0, B13). ATOMICITY is reported, not assumed. Read the atomicity block: on the
headless backend rollback restores a full document snapshot; on live AutoCAD
it sends an UNDO whose landing AutoCAD never confirms. The default
on_error="stop" claims nothing and is exact on both. A checkpoint a step
opens with transaction_begin is closed with the batch's (unwound). NOT CALLABLE from a batch: the raw command/LISP escape hatches, and
cad_batch itself. Call those directly. For a few hundred entities of the same kind, entity_batch_create is denser
still (no per-step tool name) - and it can be one step of a cad_batch. |
| entity_batch_createA | Create multiple entities in a single call for better performance. Each entity dict must have a 'type' key and the parameters for that type.
Example: [{"type": "line", "x1": 0, "y1": 0, "x2": 100, "y2": 0}, {"type": "circle", "cx": 50, "cy": 50, "radius": 25}] Denser than cad_batch for many entities of the same kind (no per-step tool
name), and usable as one step of a cad_batch. Use cad_batch when the calls
differ, must be ordered, or must feed each other. |
| entity_batch_modifyA | Apply multiple modifications in a single call. Example: [{"handle": "1A", "action": "move", "dx": 10, "dy": 20}, {"handle": "2B", "action": "delete"}] Covers move/rotate/scale/delete/set_properties only. For anything else, for
ordering, or to feed one step's result into the next, use cad_batch. |
| template_apply_layersA | Apply a standard layer set from a predefined template. Available templates: architectural, mechanical, electrical, piping.
Creates all layers defined in the template with standard colors and lineweights. |
| template_listA | List all available layer templates and their contents. |
| validation_checkA | Run quality checks on the current drawing. Available checks: empty_layers: Find layers with no entities zero_length: Find zero-length lines duplicate_entities: Find entities at the same position
|
| view_zoom_extentsA | Zoom to show all entities in the drawing (fit drawing in viewport). |
| view_zoom_windowA | Zoom to display the specified rectangular window region. |
| view_screenshotA | Capture a screenshot of the current drawing view. COM backend: captures live AutoCAD window at current view.
ezdxf backend: renders via matplotlib to PNG. With overlay_handles, each entity is labelled with its handle at its own
centre — every modify tool takes a handle, and without the labels there is
nothing connecting "the circle at the top-left" to a hex string you can act
on. Crowded drawings are capped and the image says how many of how many were
labelled. Live AutoCAD captures its own window, so there is no render to
label there; it refuses with capability: "handle_overlay". Returns an Image content block with the PNG data. |
| view_zoom_and_screenshotA | Zoom to extents (or window if coordinates given), then capture a screenshot. The most useful tool for visually inspecting drawing state. |
| transaction_beginA | Begin a transaction (undo mark). COM backend: Sets AutoCAD undo mark. All subsequent operations can be
rolled back to this point with transaction_rollback. ezdxf backend: Saves a DXF snapshot. Rollback restores the full document
state to this point. Always pair with transaction_commit or transaction_rollback. |
| transaction_commitA | Commit the current transaction. COM: Ends the undo mark (changes are permanent but still undoable via drawing_undo).
ezdxf: Discards the rollback snapshot (changes are kept). |
| transaction_rollbackA | Rollback the current transaction to the point of transaction_begin. COM: Undoes all operations back to the UNDO Mark transaction_begin set;
refused (ok: false) when no transaction is active.
ezdxf: Restores the document from the saved DXF snapshot. WARNING: This is destructive – all changes since transaction_begin are lost. |
| system_statusA | Get full status of the AutoCAD MCP Pro server and backend connection. Returns backend name, connection status, capabilities, document info, and
the document's document_id and content revision (headless: the active
registry entry; live: the bound document, plus bound_document and
active_document_changed). Live, the revision counts this server's own
writes; edits the operator makes in AutoCAD are not counted. operations lists the last 20 operation records, newest last: one per
tool call (and per cad_batch step), with operation_id, tool,
request_hash, state (committed / partial / failed / refused /
quarantined / cancelled / unknown_commit / running), the document id and
the revision before and after. Held in memory; a restart forgets them.
|
| system_capabilitiesA | Return machine-readable support modes for the active backend. |
| system_get_variableB | Get an AutoCAD system variable value. |
| system_set_variableA | Set an AutoCAD system variable (e.g. DIMSCALE, LTSCALE, MEASUREMENT). Refusals, before anything is written: a value outside the catalogued
range or enum of a known variable, or a write to a read-only variable
(DIMSTYLE, CANNOSCALEVALUE, DWGNAME, …), is refused with the catalogue's
message — system_variable_describe(name) shows the range. A variable the
catalogue does not know is passed through unchanged. The headless engine
additionally refuses registry-saved variables (capability: registry_sysvar) because a file has nowhere to keep them, and names that
ezdxf has no header slot for (a ValueError naming the variable). |
| drawing_settingsA | Read or change common AutoCAD drawing settings by friendly name. A convenience facade over the system variables (INSUNITS, LUPREC, LTSCALE,
DIMSCALE, DIMTXT, DIMASZ, DIMDEC, DIMDSEP, DIMZIN, TEXTSIZE, OSMODE, LIMMIN/
LIMMAX, GRIDMODE/GRIDUNIT, SNAPMODE/SNAPUNIT, ORTHOMODE, AUTOSNAP/POLARANG,
PSLTSCALE, CANNOSCALE, LUNITS, AUNITS, DIMSTYLE, TEXTSTYLE) so the user can
say "set units to mm, limits to A3 and the grid on" without memorising
sysvar names. Call with no argument for a full snapshot; a write returns
applied, changed ({key: [old, new]} — only what moved) and errors. dim_text_height / dim_arrow_size / dim_decimals / decimal_separator
/ zero_suppression shape the dimension — text_size is TEXTSIZE, the
height of a standalone TEXT entity, and does not touch dimensions.
Refusals, per key, nothing else rolled back: an unknown key; a value outside
its range (grid/snap spacing > 0, polar_angle 0–360, precision 0–8, …); a
malformed limits or annotation_scale; osmode / polar / polar_angle
on the headless engine (capability: registry_sysvar — AutoCAD keeps them in
the registry, a file cannot, and a headless snapshot reports them as None);
dimstyle / textstyle when the backend has no styles contract. On the
live engine annotation_scale must name a scale in the drawing's scale list
(SCALELISTEDIT) and AutoCAD refuses the write on a
paper-space layout with no active viewport; the headless engine adds the
scale, seeding AutoCAD's default list first when the drawing has none,
and refuses it on an R12 file (no OBJECTS section, so the value would
vanish at save — save as R2000 or newer first; limits/grid/ortho survive).
Headlessly, grid/snap are stored on the active VPORT and the annotation
scale in the variable dictionary — the places AutoCAD reads them from. |
| system_run_commandA | Execute an AutoCAD command string directly (COM backend only). Append \n for Enter. Example: '_LINE 0,0 100,0 \n'. IMPORTANT: commands that finish at an option menu (e.g. -LINETYPE, -LAYER,
-STYLE return to '[?/Create/Load/Set]:' after their action) need an EXTRA
blank line or 'X\n' to exit, otherwise AutoCAD stays at a prompt and the
next COM call will deadlock. Example: '-LINETYPE _LOAD CENTER acad.lin\n\n'. A verb denylist refuses obviously destructive commands, but it is a guardrail
against issuing ERASE ALL by accident, NOT a security boundary — AutoCAD
accepts hundreds of commands and any loaded ARX/LISP adds more. Prefer the
typed tools (entity_delete, drawing_save_as, block_insert, drawing_purge):
they validate their arguments, which a free-text command string cannot. |
| system_run_lispA | Execute an AutoLISP expression (COM backend only). Example: '(setvar "DIMSCALE" 1.0)' A symbol denylist refuses the known code-execution and file-I/O channels;
text inside double quotes is treated as data, so drawing notes are not
mistaken for code. It is a guardrail, NOT a security boundary — AutoLISP has
more write channels than any denylist enumerates. Prefer the typed tools. |
| system_aboutB | Get detailed information about AutoCAD MCP Pro capabilities and available tools. |
| gear_draw_helical_front_viewA | Deterministic helical gear front view: full involute outline (40 pts/flank),
pitch/base/outer/root circles, helix symbol, optional bore + keyway. Returns a handle bundle plus 'metadata' for downstream gear_draw_section_aa. |
| gear_draw_spur_front_viewB | Deterministic spur gear front view (no helix symbol). |
| gear_draw_section_aaA | Deterministic side cross-section of a gear created by gear_draw_*_front_view.
Includes top/bottom/left/right boundaries, bore lines, keyway notch, ANSI31 hatch. |
| keyway_draw_keyed_boreA | Bore + DIN 6885 keyway in front view. Auto-sizes keyway from bore if width/depth omitted. |
| keyway_draw_sectionC | Side cross-section view of a keyed bore. |
| titleblock_apply_iso_a3A | ISO 7200 / A3 (420x297 mm) title block. Title text is used verbatim. Pass layout to put the sheet on a paper-space layout, which is where a
title block belongs — the border frames the printed sheet, not the model.
Your current space is restored afterwards, so asking for a border does not
move you onto the sheet. |
| drawing_finalizeA | Premium completion gate: runs BOTH the 8-step validator AND the premium critique focuses
(iso128, layer_color, dim_overlap, untrimmed_corner, duplicate_entities, construction_left,
gdt, plus the P&ID focuses pid_dangling_line, pid_duplicate_tag,
pid_incompatible_connection, pid_untagged_instrument, pid_illegal_tag,
pid_unconnected_equipment — silent on a sheet with no P&ID symbols, plus the
mechanical focuses mech_missing_centreline, mech_unhatched_section,
mech_view_misaligned, mech_duplicate_dimension, mech_thread_unrepresented,
mech_bom_balloon_mismatch — silent on a sheet with no mechanical part, plus the
architectural focuses arch_room_unlabelled, arch_wall_gap, arch_opening_clash —
silent on a sheet with no ACADMCP_ARCH record, plus the topology focuses
topo_dangling_endpoint, topo_near_miss, topo_interior_crossing — on network
layers no P&ID or architectural focus reads, silent on every sheet this server draws),
then saves to disk, exports a screenshot, and returns the DWG path. The validator and the critique share one read of the drawing - every entity of
every space, model and paper, with no cap (one DXF export on the live engine). A
drawing over MAX_QA_ENTITIES (default 2,000,000; 0 disables) is not read in part:
the validator reports scan_incomplete and each entity check reports an issue with
detail.code scan_incomplete, so the gate fails. A check that raises is an error
issue with detail.code check_failed, never a clean result. Raises ToolError if any validator 'error' finding is present, or if critique reports an
'error' (or, with strict_critique=True, any critique issue). Critique warnings are surfaced
under payload['critique'] without failing the gate by default. A quarantined document
is refused. With requirements (the drawing_verify_requirements shape) every requirement is
measured on the CAD geometry after the save: the payload adds geometry_acceptance
(the full report), drafting_quality (the score, unchanged), artifact_integrity
(the saved file's sha256 and reverified: every requirement measured again on the
saved file, read fresh and re-bound by handle, feature tag, then geometry, with the
before / after comparison; a saved file that cannot be re-read - a .dwg AutoCAD
will not let us copy - fails the acceptance) and coverage, and a requirement
that does not pass,
stale evidence or a dimension that disagrees with its geometry raises
failed_acceptance - a high drafting score never offsets it. Requirements that do
not parse are refused before anything is saved (invalid_args). |
| drawing_deliverA | Create a hashed, validated delivery bundle and verify DXF save/reopen parity. The result status is success, failed_validation, failed_export or
failed_acceptance. Failure intentionally keeps all generated artifacts for
diagnosis. The open document is never re-pointed or saved: the DXF is a copy (live:
Document.Export), and the manifest records the document's id, revision, path
and saved flag, the DXF version, every sha256 and the build. Parity reads the
delivered DXF back and compares it with a fresh serialisation of the document over
every space: zero changed, added or removed entities, the same counts per space,
the same block definitions. Both sides are exports, so parity cannot see content
the export itself loses (parity.scope says so); with requirements,
parity.content_check is acceptance, the check that can. With requirements every requirement is measured on the delivered DXF, read
fresh and re-bound from the document; the bundle gains acceptance.json and
acceptance.md, the result geometry_acceptance, drafting_quality (the
unchanged score), artifact_integrity, coverage and blocking, and a
requirement that does not pass, stale evidence or a dimension that disagrees
with its geometry makes the status failed_acceptance whatever the score
(failed_export and failed_validation are reported first). Refused before
any work: requirements that do not parse (invalid_args). |
| drawing_preflightA | Validate and normalize requirements before committing a drawing plan. Typed requirements go under requirements.items: each is checked with its
path (items[2].target.nominal: must be greater than zero, got -1.0. comes
back as an INVALID_REQUIREMENT conflict) and its canonical form replaces
the input in normalized_spec, so spec_hash covers what will be
verified; requirement_set carries the canonical set and its digest. A
legacy dimensions object is still accepted, kept as given and listed
under legacy - it is never measured. Conflicting provenance is kept and
reported (CONFLICTING_PROVENANCE, CONFLICTING_REQUIREMENT), never
collapsed to one value. Typed items are validated once units is known
(a MISSING_UNITS question asks for it). Nothing is refused: every problem
is a question or a conflict, and ready stays False until none is left. |
| drawing_planA | Commit a PlanSpec before any geometry is created. The PlanSpec is stored on the backend and surfaced for reference during
the workflow (it is not replayed as a critique). Always call this FIRST
in a premium workflow. With typed requirements.items the plan carries
requirement_digest; persist_requirements=True also writes the set into
the drawing (requirements_persisted: true) - the server's own XRECORD,
shown nowhere in AutoCAD. Refused: a spec_hash that does not match the latest ready preflight; a
malformed typed item, by its path (items[2].target.nominal: must be greater than zero, got -1.0.); persist_requirements=True with neither
typed items nor a legacy dimensions object ("nothing to read"). A
refusal stores nothing and commits no plan. |
| drawing_critiqueA | Run premium-quality checks. Returns zero issues for a clean drawing. Standard production gate: must return [] before drawing_finalize. The entity checks (construction_left, untrimmed_corner, duplicate_entities,
dim_overlap) read every entity of every space - model and every paper layout -
and compare pairs only within one space. Refusals and failures are issues, never
silence: a check that raises returns an error issue of its focus with
detail.code check_failed; a read that could not cover the drawing (more than
MAX_QA_ENTITIES entities, default 2,000,000; or a live export whose per-layout
counts differ from AutoCAD's) returns detail.code scan_incomplete. Neither code
is a focus name. A quarantined document is refused. |
| drawing_refineA | Run a bounded, transaction-safe critique/repair/re-critique loop. dry_run=True returns the plan with preview - the content revision and the
exact fingerprint of every handle a planned repair touches - also when the
score already meets min_score: threshold_met then says an apply at that
min_score would stop before repairing. Applied with the preview's
revision (expected_revision) and/or preconditions, the call is refused
with kind stale_revision and nothing changed when the document moved since;
the result then carries revision ({checked, after, interleaved}). |
| point_from_snapA | Compute a deterministic snap point on an entity. Use this INSTEAD OF
guessing coordinates — eliminates the most common LLM drawing error. |
| point_intersectionA | Compute the intersection of two geometry entities (LINE-LINE, LINE-CIRCLE,
CIRCLE-CIRCLE). When two candidates exist, ref_x/ref_y selects the nearest. Returns {x, y, on_first, on_second, on_both, candidates}. A LINE is
intersected as the infinite line through it, so the point can lie beyond
a drawn end: on_first / on_second say whether it lies on each drawn
segment (a CIRCLE always holds its own intersection points) and on_both
whether on both - check it before using the point as a corner.
candidates is how many intersections existed. Refused, with the case
named: parallel or coincident lines, a line that misses the circle,
concentric circles, circles that do not meet, any other entity pair. |
| point_tangentA | Compute the tangent point on a circle from an external point.
Returns {x, y}. Raises if the from-point is inside the circle. |
| construction_xlineA | Create an infinite construction line on the CONSTRUCTION layer.
Use as scaffolding; call construction_clear() before finalize. |
| construction_clearA | Delete every entity on the CONSTRUCTION layer. Idempotent.
Must be called before drawing_finalize to satisfy construction_left critique. |
| drawing_apply_iso_layersA | Bootstrap a full ISO-conformant layer set with correct colors and lineweights.
Idempotent — existing layers are not modified. Refused by name: a standard that is not one of mech, pid, iso13567, arch. |
| dimension_autoA | Generate ISO 129 dimensions across the listed entities in the chosen style.
V1 supports LINE entities only. |
| entity_select_smartA | Select entities by semantic predicate instead of memorising handles. Uncapped. The usual next step is dimension_auto(handles), so
fields=["handle"] is normally all this needs to return. |
| gd_frameA | Draw an ISO 1101 feature control frame from LINE + TEXT primitives. Renders identically on COM and ezdxf. Referenced datums are recorded so the
gdt critique focus flags any datum with no matching datum feature. |
| datum_featureA | Place a datum feature symbol (filled triangle + boxed letter). Establishes the datum so a feature control frame referencing this letter
passes the gdt critique focus. |
| layout_listA | List all layout tabs (Model + paper-space layouts) and the current one. |
| layout_createA | Create a new paper-space layout tab. |
| layout_set_currentB | |
| viewport_createA | Place a scaled model-space viewport on a paper-space layout. The viewport window shows the model region centered at
(view_center_x, view_center_y); view height = height / scale. |
| layout_deleteA | Delete a paper-space layout and every entity on it. Refuses model space, a blank name, and the last remaining sheet. If the
deleted tab was the current one, the returned current is where geometry
goes next — and handles from the deleted sheet stop resolving. |
| layout_renameA | Rename a paper-space layout. Entity handles are unaffected. |
| layout_copyA | Copy a paper-space layout: page setup, plot settings and all geometry. skipped names any DXF types that could not be cloned — check it rather
than trusting ok alone. Associative hatch boundaries are re-pointed at the
cloned entities; associativity_dropped counts those that referenced
something outside the source layout and had to be cleared.
|
| viewport_listA | List paper-space viewports: handle, geometry, scale and lock state. The layout's own main viewport is included with is_main: true — it is the
tab's pan/zoom state rather than a drafting viewport, and it is what remains
after every drafting viewport is deleted. scale and locked are null on
documents that cannot store them (R12) rather than fabricated. |
| viewport_set_scaleA | Rescale a viewport by adjusting its view height. Geometric scale only: annotative text and dimensions do not resize with it.
Refuses the layout's main viewport, whose view height is the tab's own
pan/zoom state rather than a drafting scale. |
| viewport_lockA | Lock or unlock a viewport's display scale. |
| viewport_deleteA | Delete a viewport. The layout's main viewport needs force=true; deleting it removes the tab's
own view state, and the layout's current-viewport pointer is repaired so the
file does not carry a dangling reference that only CAD would notice. |
| entity_change_spaceA | AutoCAD's CHSPACE: move entities across spaces, rescaled by the viewport. Geometry is transformed by the viewport's own matrix so it stays the same
size on screen — a move without that transform would leave a 100 mm feature
as 100 mm of paper inside a 1:2 viewport. Refused per entity for dimensions (unless freeze_dimensions), ACIS solids,
tables and proxies, viewports, and entities already in the target space;
refused outright for a twisted or non-plan viewport. Entities that end up
outside the viewport or off the sheet are moved and flagged, not refused. |
| pid_symbol_listA | The symbols pid_symbol_insert can place, with their ports and variant options. Authored from ISO 10628-2 (equipment, valves) and ISA-5.1 (instrumentation);
each row's source names the figure. Symbol-local sizes are millimetres at
A3/A1 paper scale (bubble Ø10, valve 8×4); scale at insertion rescales. |
| pid_symbol_insertA | Insert a catalogue symbol as a real block with TAG attributes and named ports. Defines the block on first use (defined), creates a missing family layer
from the P&ID layer set (layers_created), writes an ACADMCP_PID payload
so readers without the catalogue still see the ports, and returns every
port in WCS — connect them with pid_line_draw. An invalid ISA-5.1 tag is
written and reported in tag_warnings; drawing_critique flags it. |
| pid_line_drawA | Connect two ports with one LWPOLYLINE on the class's layer. Ports come from pid_symbol_insert; a bubble's radial port is entered
without a name. auto picks the shortest orthogonal route that leaves each
port straight for stub mm; when none exists the call refuses and says so
— pass waypoints. crossings counts existing P&ID lines the new one cuts
(reported, never refused) and port_reuse names ports that already had a
line (branching is legal). Signal classes get ISA-5.1 markers (//, X,
L, o) as small blocks on segments >= 15 mm; electric is dashed by layer.
A signal line carries no pipe line number: it gets no auto-built number
and no label, and does not consume the process sequence — a verbatim
line_number is still written and labelled. With waypoints, a bubble's
exit leaves towards the first waypoint (and the entry arrives from the
last one); crossings follows existing arcs, not their chords. |
| pid_graphA | Connectivity of the drawing as it is, not as it was drawn. Nodes: symbol INSERTs classified by catalogue name (confidence 1.0),
ACADMCP_PID payload (0.95), tag attributes / block-name keywords (0.6) or
a line touching an unknown INSERT (0.3); every node reports its source.
Ports come from the INSERT's real rotation, scale and mirror, measured
(a stretched bubble drops the node to 0.6 with a note). Edges: lines and
polylines; each end resolves to a port, a junction on another line, or
dangling with the nearest port as a hint — always within its own
space, so scope="all" never joins two sheets. stats.confidence_min
is the number to read before trusting a foreign drawing. Returns nodes, edges, junctions, dangling, unclassified, offpage_links,
stats, tolerance, scope and backend: node: id, kind, block_name, family, symbol, tag, tag_parsed, tag_source,
x, y, rotation_deg, scale, y_scale, mirrored, layer, space, description
(its DESC attribute), source, confidence, notes, and ports
{name, x, y, direction_deg, kind, radius, inferred, edges}; edge: id, line_class, class_source, line_number, number_source, size,
service, spec, insulation, from, to, length (plus length_approximate
when the engine measured none), layer, space, source; vertices and
bulges with include_geometry; junction: id, x, y, edges, space; dangling: edge, end, x, y, nearest.
|
| pid_instrument_indexA | Every instrument bubble with its ISA-5.1 reading and what it connects to. Rows come from pid_graph, never from typed-in lists; the drawing is not
modified. csv_path is the only file this tool writes (so it is not
annotated read-only); it is validated before the drawing is read, and an
empty path, a directory or a missing parent folder is refused.
signal_lines counts ISA-5.1 signal lines only; connected_to names a
tag, a handle, or the lines a junction on the instrument's line joins. |
| pid_line_listA | Every P&ID line with its number, class, size/service/spec/insulation and endpoints. Rows come from pid_graph; untagged lines sort last with line_number: null.
An end names a node's tag (its handle when untagged) and port, or — at a
junction — the line numbers (or handles) of the lines it joins.
The drawing is not modified; csv_path is the only file this tool writes,
validated before the drawing is read. |
| pid_equipment_listA | Every equipment, valve and connector node with its ports and how many lines reach them. Rows come from pid_graph; the drawing is not modified and csv_path is
the only file this tool writes, validated before the drawing is read. |
| pid_from_specA | Equipment, valves, instruments and connectors placed, then every line
drawn port-to-port, inside one transaction: any bad item rolls the whole
sheet back and the error names it (lines[2].to); so does an interruption
(a client cancellation mid-run leaves no half-drawn sheet and no open
transaction on either engine — the live one goes back to the UNDO Mark
transaction_begin set, so it never waits at an AutoCAD prompt; should
that rollback itself fail, the failure is logged, the cancellation is what
the client sees, and the drawing must be checked before a retry).
A non-finite coordinate, rotation, scale or stub is refused
by path before anything is placed. The response carries the graph read
back from the drawing and the P&ID critique issues, so the caller sees
dangling ends or duplicate tags in the same round trip. dry_run returns
the planned vertices and crossings without touching the drawing; crossings
are counted, on both runs, against the spec's own lines and the P&ID lines
already on the current layout (crossings_scope). The dry run also returns
the routing region and a preview whose precondition is the fingerprint
of every entity in that region. Applied with the preview's revision
(expected_revision) and/or preconditions, the run is refused with kind
stale_revision and nothing drawn when anything in the region (or the
revision) changed; a region precondition taken from another spec is
refused by path. A guarded run reports revision ({checked, after,
interleaved}). |
| pid_tag_parseA | ISA-5.1-2009 Table 4.1 as a grammar: first letter, modifier, readout and
output functions, trailing high/low, loop number and suffix — with the
standard's description ("Flow Indicating Controller") or the first
offending letter. Equipment prefixes are not standardised, so the default
map (P pump, V vessel, E exchanger, ...) can be replaced per call. |
| dimstyle_listA | Every DIMSTYLE table entry with the seventeen preset variables
(DIMTXT, DIMASZ, DIMEXE, DIMEXO, DIMGAP, DIMTAD, DIMTIH, DIMTOH, DIMDEC,
DIMDSEP, DIMLUNIT, DIMZIN, DIMBLK, DIMTXSTY, DIMLWD, DIMLWE, DIMSCALE). Headless, values is what the DXF stores (the schema default where an
entry omits a code). On the live engine ActiveX has no per-style getters,
so values is read for the current style only and the other rows carry
values: null, values_available: false — dimstyle_set_current a
style to read it. Never refuses on an open drawing. |
| dimstyle_createA | Create a dimension style: preset values first, then overrides. Refuses, before anything is written: an unknown preset; an override key
outside the 33-variable whitelist (the 17 preset variables plus DIMTOL,
DIMTP, DIMTM, DIMTOLJ, DIMTFAC, DIMLFAC, DIMRND, DIMATFIT, DIMTMOVE,
DIMCLRD/E/T, DIMSAH, DIMBLK1/2, DIMCEN); a value outside its range
(DIMDEC 0-8, sizes > 0, DIMTAD 0-4, DIMDSEP one character, lineweights an
AutoCAD code); a name that already exists (use dimstyle_modify); a
user DIMBLK/DIMBLK1/DIMBLK2 naming a block the drawing does not define
(built-in arrowheads need none); a DIMTXSTY that is neither an existing
text style nor a bundled preset (ISOCP, ISOCPEUR, ARIAL, ROMANS — those
are created on both engines, textstyle_created; live, a preset whose
font file the seat lacks is refused the same way, nothing written). On
the live engine a write ActiveX still refuses after the style is added
is rolled back — previous style current, the half-made entry deleted.
With set_current the next dimension carries the style on both engines. |
| dimstyle_modifyA | Change variables on an existing dimension style. changed names only the variables that actually moved — re-setting a
value to itself is not a change. dimensions_using_style lists the
dimensions already drawn with it; headlessly rerender_required: true
says they still show the old style until redrawn (AutoCAD re-renders on
the next regen). Refuses a missing style, an empty overrides, a key
outside the whitelist, a value outside its range, a DIMTXSTY that does
not exist, a user arrowhead block the drawing does not define — all
before any write. On the live engine, editing a non-current style makes
it current for the duration of the call and the previous style is
restored — also when a write fails midway (its unsaved overrides are
discarded, which is AutoCAD's own DIMSTYLE rule).
|
| dimstyle_set_currentA | Set $DIMSTYLE and load the style's variables as the current DIM*
settings — what a live seat's DIMSTYLE Restore does — so dimension_*
and dimension_auto draw with it on both engines. Per-dimension
tolerances, fits and text overrides still apply on top. Refuses a style
the drawing does not hold. Returns previous and changed. |
| textstyle_listC | Every STYLE table entry and the one new TEXT/MTEXT will use. |
| textstyle_createA | Create a text style. Headlessly a font nobody can find is written and reported
font_resolved: false (AutoCAD substitutes at open; the headless
renderer falls back), because a DXF stores only the name. The live
engine cannot do that: ActiveX refuses a font AutoCAD cannot open, so a
file that is neither on its support path nor in the Windows Fonts folder
is refused there before any write (the message names the folders and the
presets); a TrueType font is written by its typeface (SetFont, what the
STYLE dialog does — the record carries arial.ttf, never a machine
path), an SHX by the file name. Refuses, before any write on both
engines: a name that exists, an empty font, width_factor <= 0,
height < 0, an oblique angle outside ±85°. |
| textstyle_set_currentA | Set $TEXTSTYLE; entity_create_text / entity_create_mtext then
carry the style on both engines. Refuses a style the drawing does not
hold. Returns previous and changed. |
| mleaderstyle_listA | Every MLEADERSTYLE with its four values on both engines
(values_available: true). Headless they are read from the MLEADERSTYLE
object; live from the AcadMLeaderStyle objects the ACAD_MLEADERSTYLE
dictionary holds (ActiveX exposes no collection property for them, but
the dictionary items are full objects). leader_create_mleader can still
override any of them per leader. |
| mleaderstyle_createA | Create a multileader style: preset values first, then overrides. Headless it lands on doc.mleader_styles; live it is added through the
ACAD_MLEADERSTYLE dictionary (AddObject(name, "AcDbMLeaderStyle"))
and the object's properties are written. Refuses, before any write: an
unknown preset; an override key outside the four; arrow_size /
text_height <= 0, landing_gap < 0; a name that exists; a text_style
that is neither present nor a bundled preset (ISOCP, ISOCPEUR, ARIAL,
ROMANS — those are created on both engines, textstyle_created; live, a
preset whose font file the seat lacks is refused, nothing written). |
| drawing_apply_standardA | One call for the common case: the standard's dimension style (created
if missing, then current), its text style (created if missing, then
current), the shared units, and with layers the mech layer set (ANSI
layer naming is company-specific, so both standards share it). Every item reports created or already present; settings.changed
names only the variables that moved, so a second call reports nothing.
An existing ISO-25 / ANSI style is reused as it is, not reset — use
dimstyle_modify to change one. Refuses an unknown standard, or a units
variable it cannot read back, before any write; the underlying style
refusals (dimstyle_create, textstyle_create) apply unchanged. In the
lean profile (Task 13). |
| page_setup_listA | The page setup stored on each paper-space layout. paper is the catalogue name (ISO_A3, ANSI_B, …) when the stored size
matches one within 0.5 mm, otherwise the media name as stored; size_mm,
orientation, plot_style (ctb), scale ("fit", "1:50", or a custom
ratio), plot_area, device, margins_mm [top, bottom, left, right] and
center are read back from the LAYOUT object (headless) or the AutoCAD
Layout (live). Refuses an unknown layout name and Model (model space has
no sheet; plot it with drawing_export_pdf(layout=None)).
|
| page_setup_applyA | AutoCAD's PAGESETUP as one call, on both engines. Paper sizes are ISO 216 / ANSI Y14.1; the media is written in AutoCAD's own
spelling (ISO_A3_(420.00_x_297.00_MM)). changed lists only the values
that moved — re-applying the same setup reports {}. An unknown ctb is
written and reported plot_style_known: false (a missing ctb only matters
at plot time). Viewports on the sheet are never touched. Refused before anything is written: an unknown paper, orientation, scale
or plot_area, an empty device or plot_style, margins that leave no
printable area, Model, an unknown layout. On the live engine margins_mm
is refused (the .pc3 owns them) and a media the device does not offer is
refused with the device's names for the same paper. The proof is the PDF: batch_plot reads each sheet's /MediaBox back. |
| plot_style_listA | The ctb files AutoCAD ships (monochrome.ctb, acad.ctb, Grayscale.ctb,
the Screening set, …) and, on the live engine, the files actually present
in Preferences.Files.PrinterStyleSheetPath (source: "installed",
installed: true/false per row). Headlessly installed is null: there
is no installation to scan, and the catalogue is not evidence of one.
Never refuses; an unreadable Preferences object degrades to the catalogue. |
| batch_plotA | AutoCAD's PUBLISH for a PDF set, through drawing_export_pdf(layout=…). One row per sheet: path, bytes, and mediabox_mm parsed from the
PDF that was written (/MediaBox, points → mm), with paper naming the
catalogue size it matches within 0.5 mm — so the sheet size is verified,
never assumed. Model space is included only when named. Refused before any file is written: a format other than pdf, an empty
layouts list, a layout that does not exist, a file_pattern containing a
path separator or lacking {layout} when more than one sheet is plotted,
and any output path outside the allowed directories. A sheet whose PDF has
no readable MediaBox is reported with mediabox_mm: null and an error. |
| drawing_template_listA | The templates drawing_new(template=<name>) can start from. Each row: standard (ISO/ANSI), sheet, paper, layout (the sheet tab's
name), layer_set (mech / pid / iso13567), dimstyle / textstyle
(ISO-25 / ISOCP or ANSI / ROMANS), scale, title_block (the ISO 5457 A3
frame, A3 sheets only), the settings applied, and files.dxf /
files.dwt with present flags — the .dwt twins exist only once built
on a live AutoCAD (scripts/smoke_settings_com.py --build-dwt). Never
refuses; it reads a catalogue. |
| drawing_template_saveA | AutoCAD's SAVEAS → Drawing Template, on both engines. Live AutoCAD writes a real .dwt (SaveAs(path, ac2018_Template)) and
puts description into the template's summary Comments; the active
document is rebound to the new file, as SAVEAS does. Headlessly a .dxf
template is written — drawing_new(template=<path>) opens it — and a
.dwt request is refused with capability dwt_write (the message names
the DXF route and the COM route); a description is reported
description_written: false because DXF has nowhere to keep it. Any other
suffix, and any path outside the allowed directories, is refused before
a byte is written. Pack: core · lean: no (drawing_save_as is not lean either). |
| document_listA | Every open document with name, path, active, saved and
entity_count. Each row also carries the document's document_id and
content revision (None, live, for a document this session never bound). Headless, the server keeps its own registry: drawing_new / drawing_open
add an entry (untitled-N or the file path) instead of replacing the only
one, and document_activate chooses which one every later tool targets.
Live, this is AutoCAD's Documents collection. No refusals: an empty
backend answers with an empty list. Pack: settings · lean: no. |
| document_activateA | Make one open document the active one; reports previous. Matches the full path first, then the file name; an ambiguous name is
refused with the candidates, an unknown one with the list of open
documents. Headless, a document quarantined after an abandoned call cannot
be switched away from — drawing_new, drawing_open or closing it are
the ways out. Pack: settings · lean: no. |
| document_closeA | Close a document and report saved, discarded_changes and the new active. Refusals, all before anything is closed: unsaved changes with neither
save nor discard; save on a document that has never been saved (no
path to write — live, Close(True) would open AutoCAD's Save dialog and
block the COM thread); save together with discard. Closing the last
document leaves the backend with none open, which every tool already
reports. drawing_close is the same operation for the active document
with its 1.4 contract kept. Pack: settings · lean: no. |
| layer_state_saveA | Snapshot every layer's on/frozen/locked/color/linetype/lineweight/plot
flags plus the current layer as a named state stored in the drawing. These are the server's own portable layer states: JSON chunks in an XRECORD
under the ACADMCP_LAYERSTATES dictionary. They live in the file and
travel with it, work on both engines, and do not appear in AutoCAD's
Layer States Manager (LAYERSTATE). Same name replaces (replaced: true).
Refusals: an empty or control-character name, a non-string description.
Pack: settings · lean: no. |
| layer_state_restoreA | Apply a saved state to the layers that still exist. missing_layers (in the state, not in the drawing) are skipped, never
created; new_layers (in the drawing, not in the state) are untouched;
applied says how many layers and which properties moved. Refusals: an
unknown state name (lists the saved ones), a property outside the eight
(names the index). Live, a layer AutoCAD refuses to change (freezing the
active layer, making a frozen layer current) lands in warnings instead
of failing the call; the state's current layer is thawed before it is
made current when frozen is being restored, so save → freeze → restore
round-trips. Portable server states, not Layer States Manager entries.
Pack: settings · lean: no.
|
| layer_state_listA | Every state under ACADMCP_LAYERSTATES with its description and layer
count. These are the server's portable states, not AutoCAD Layer States
Manager entries. No refusals. Pack: settings · lean: no. |
| layer_state_deleteA | Remove the named state's XRECORD. Layers themselves are untouched.
Refusal: an unknown name (lists the saved ones). Pack: settings · lean: no. |
| view_named_saveA | Store a VIEW table entry (AutoCAD's VIEW command). Same name replaces
(replaced: true). Refusals: height/width ≤ 0 or non-finite, a
malformed center, and headless an empty drawing with no center/height
(there are no extents to default to). Pack: settings · lean: no. |
| view_named_restoreA | Live: zooms the active viewport to the saved window the way -VIEW _R
does — VIEWCTR becomes the saved centre and VIEWSIZE the saved height
(or width / display aspect when the window is wider than the display);
applied: "zoom_window" plus the read-back viewctr / viewsize.
Headless there is no display: the saved window is fitted into the
*Active VPORT — the view AutoCAD opens the file on — whose aspect ratio
is left as the file carries it (AutoCAD reconciles a changed aspect by the
viewport's lower-left corner, which shifts the centre); the result says
applied: "header_only" with the written vport_height and the kept
aspect_ratio, the same reported-no-op rule as view_zoom_extents.
Refusal: an unknown name (lists the saved views). Pack: settings · lean:
no. |
| view_named_listB | Every VIEW table entry with centre, height and width. No refusals.
Pack: settings · lean: no. |
| ucs_listB | The world row first, then every UCS table entry with origin and unit
axes, current on the active one. world is current only when the frame
IS the WCS (WORLDUCS live, the $UCS* header headless) — an unnamed UCS
(UCS Origin / 3P without saving) has an empty name too and is
reported as a trailing row with name: null and its origin/axes, so
current is null then and never world. Tool coordinates stay WCS on
both engines whatever is current. No refusals. Pack: settings · lean: no. |
| ucs_setA | Store a UCS table entry and make it current (AutoCAD's UCS command). Axes are normalised to unit vectors. Every tool keeps taking and
returning WCS coordinates — the repository rule; a UCS is for the
operator's own drafting, and no tool starts interpreting inputs in it.
Refusals, before any write: a name of world (reserved), a zero-length
axis, and non-perpendicular axes — the message carries the measured angle
(tolerance 0.001°). Pack: settings · lean: no. |
| ucs_restoreB | Live: ActiveUCS for a named entry; world runs UCS World, which is
refused while AutoCAD has an active command (CMDACTIVE — press ESC).
Headless: the $UCSNAME/$UCSORG/$UCSXDIR/$UCSYDIR header variables.
Refusal: an unknown name (lists the saved ones). Tool coordinates stay
WCS. Pack: settings · lean: no. |
| system_launchA | Connect to the application named by CAD_PROGID (attach if running,
launch otherwise) and report launched, attached, version and the
active document. Refusals: headless, capability: "live_application"
(there is no application to launch); an open_path that fails path
validation. Pack: settings · lean: no. |
| system_preferences_getA | The whitelisted Preferences.* values, enum values as names
(SaveAsType: "ac2018_dwg"), with read_only naming the four Files.*
paths. Refusals: headless, capability: "preferences" (they live in the
running application, not in a file); a key outside the whitelist.
Pack: settings · lean: no. |
| system_preferences_setA | Write one preference and report old, new and changed. Refusals, all before any write: a read-only key (Files.*), an unknown
key, a value of the wrong type, an int outside the authored range
(AutoSaveInterval 0–600 min, CursorSize 1–100, PickBoxSize 0–50, …),
an unknown SaveAsType name; headless, capability: "preferences".
Pack: settings · lean: no. |
| user_pick_pointA | Utility.GetPoint: returns the WCS x, y (z) the operator clicks.
ESC is an answer, not an error: cancelled: true with AutoCAD's reason.
Waiting longer than COM_CALL_TIMEOUT returns timed_out: true (the
prompt is abandoned on AutoCAD's side; press ESC there). Refusals: an
empty prompt; headless, capability: "interactive_prompt" (no operator).
Pack: settings · lean: no. |
| user_selectA | Returns handles the operator picked — one with mode="single" (plus
the picked point [x, y] in WCS — AutoCAD reports it in the current
UCS and the tool translates, so a UCS made current by ucs_set never
shifts it), any number with mode="multiple" (Enter with nothing
selected is count: 0, not a cancel). ESC → cancelled: true; a wait
longer than COM_CALL_TIMEOUT → timed_out: true. Refusals: a mode
outside the two, an empty prompt; headless, capability: "interactive_prompt". Pack: settings · lean: no. |
| system_prompt_messageB | Utility.Prompt: tell the operator something where they are looking.
Nothing in the drawing changes. Refusals: an empty message; headless,
capability: "interactive_prompt". Pack: settings · lean: no.
|
| system_variable_describeA | What an AutoCAD system variable means, from an authored catalogue of 90. With name: {known, name, type, range|enum, default, meaning, saved_in (drawing|registry|not_saved), engines: {ezdxf, com}, friendly_key, read_only} plus current when the active backend can read it (omitted,
with current_unavailable, when it cannot — no document open, or a
registry variable headlessly). An unknown name is never an error: known: false and the nearest catalogue names come back. With search: every row
whose name or meaning contains all the words. With neither: the index of
names. friendly_key names the drawing_settings key that wraps the
variable, which is the preferred way to set it; engines.ezdxf: false
means the headless engine refuses a write (registry-saved, or no header
slot in ezdxf). |
| drawing_properties_getA | The DWGPROPS dialog as data: summary (title, subject, author, keywords,
comments), summary_available, and custom ({key: value}). On the live engine the summary comes from the document's SummaryInfo. The
headless engine cannot read that stream, so the five summary fields are
null with summary_available: false — not empty strings, which would
claim the drawing has no title. Custom properties ($CUSTOMPROPERTYTAG /
$CUSTOMPROPERTY header pairs) are read on both engines. |
| drawing_properties_setA | Write DWGPROPS fields. Only the arguments given are touched; returns
summary_written, custom_written and custom_deleted (a key that was
never there is not reported deleted). Refusals, before anything is written: a summary field on the headless
engine (capability: dwgprops — SummaryInfo lives in the DWG, a DXF has
no slot for it; custom properties still work headlessly), a non-string
value (TypeError naming the field or key — nothing is coerced with
str()), an empty custom key, a custom key to write that AutoCAD's
AddCustomInfo would reject mid-write (measured on AutoCAD 2026: leading or
trailing whitespace, or any of the thirteen characters
" * , / : ; < = > ? \ |anywhere in the key; internal spaces, tabs and unicode are fine —ValueErrornaming the key, on both engines; a delete is exempt because RemoveCustomByKey never validates syntax, so a key that reached the drawing another way stays removable), two keys in one request that AutoCAD would call the same key (its key compare is a simple per-character case compare:Project/PROJECTandGrün/GRÜNare one key,Straße/STRASSE are two), a line break in a custom key or value (it corrupts the DXF on save), and headlessly a document older than R2004 (ValueError` — ezdxf only writes the custom-property header pairs
for AC1018+, so they would vanish at save; save as R2004 or newer first).
A key is matched to the drawing by that same rule on both engines and
keeps its stored spelling when updated. On the live engine an exact
spelling is changed with SetCustomByKey; otherwise AutoCAD decides —
AddCustomInfo, and on its 'Duplicate key' SetCustomByKey; a delete is
RemoveCustomByKey, and its 'Key not found' is reported as not deleted. |
| mech_part_drawA | One part model - a turned profile or a plate outline plus typed features - drawn as views. The model is written onto the drawing as ACADMCP_MECH XDATA on an anchor
POINT, so mech_view_add can add a section months later without the caller
re-describing the part, and mech_part_inspect reads it back. Refused before anything is drawn, by path: a non-finite or non-positive
number (segments[2].d_outer), a bore that is not smaller than its outside,
an outline with fewer than three distinct vertices or one that crosses
itself, an unknown material, a feature whose placement is off the part, two
features that would remove the same material (both names given), a thread
outside the transcribed ISO 261 table, a keyway outside DIN 6885's bore
range, gear teeth whose tip diameter disagrees with their segment. A DIN 509
undercut, a DIN 471/472 groove, a DIN 332 centre hole and an ISO 3601-2
O-ring groove need explicit dimensions in this build: those tables are not
transcribed and the lookup refuses by name rather than interpolate. A
feature that cannot be projected into a requested view is listed in
omitted, never dropped. |
| mech_view_addA | Another view of a part already on the drawing, laid out on its projection axis. The part model comes back out of the drawing's ACADMCP_MECH XDATA, so the
caller never re-describes it, and the placement follows the projection angle
recorded when the part was drawn (first angle by default: the view from the
right goes to the left). Refused by name: a section without a plane, or with a plane of zero length,
a plane that misses the part, or one that grazes an outline vertex so its
crossings cannot be paired; a half or offset section on the wrong kind of
plane (the message names the style that does apply); a detail without a
radius or with a scale of zero; an unknown part_id, and part_id=None on a
drawing that holds more than one part. |
| mech_dimension_partA | Every dimension the part and its features ask for, laid out without overlaps. Axial lengths are chained, stacked from a baseline or measured from an
origin; diameters stack outside the silhouette; fillets get a radius. Each
measurement appears once (ISO 129-1): every view record carries a
dimensioned flag, so after a mech_part_draw that dimensioned the front
view and a mech_view_add, this call dimensions only the new view, and
views naming a view already dimensioned is refused by name. fits resolves an ISO 286 code
against the measured nominal through the repository's authored tables and
appends the code to the dimension text; an explicit tol on a feature's own
intent does the same through the ISO 129 path. Refused by name: a fit together with an explicit tolerance, a fit outside
the authored ISO 286 range (over 1 mm to 500 mm, IT4-IT11), a fit on an
intent with no measurable nominal, an unknown style, an unknown part_id, a
call when every view is already dimensioned (the message lists them), and
part_id=None on a drawing that holds more than one part. An angular intent
is reported in skipped rather than drawn, because a DimIntent carries no
vertex. |
| mech_hole_patternA | A hole pattern on any drawing - the part model is not required. The same expansion HolePattern performs inside a part, exposed for a
drawing that was not built from the model. Refused before anything is drawn: an unknown pattern, a count below 1 (below
2 for polar), a linear pattern with no spacing, a grid with more than one
column or row and no pitch for it, a polar pattern with no pitch-circle
diameter, and a non-finite or non-positive diameter. |
| mech_part_from_specA | Several parts, their views and their dimensions, drawn inside one transaction. Every part is validated before the transaction opens, so a refusal leaves
the drawing untouched and names the offending path (parts[1]: segments[0].d_outer: ...). If a draw fails or the request is cancelled
part-way, the transaction is rolled back under an anyio shield, so a
cancelled call cannot leave half a sheet inside an open transaction. Refused by name: an empty parts list, any part refusal from
mech_part_draw, and a transaction that cannot be opened. |
| mech_part_inspectA | The ACADMCP_MECH payload a drawn part carries, decoded. Never modifies the drawing. Returns the part model exactly as
mech_part_draw accepts it (part), the views drawn so far with their
placements, and the payload version. Refused by name: an unknown part_id, a handle that carries no
ACADMCP_MECH payload, a corrupt or foreign payload, and part_id=None on
a drawing that holds no part or more than one (the message lists the
handles). |
| std_part_listA | Catalogue rows with the dimensions a drawing needs, and their provenance. Every row is transcribed from the named standard's own table and carries
its source. Coverage is deliberately narrow: ISO 261 first-choice sizes
only (M5-M36, M3-M24 for ISO 4762) and ISO 15 bore numbers 00-10 in the
600x / 620x / 630x series. A size outside a table is refused by name by
std_part_insert with the nearest entries, never interpolated and never
substituted. An unknown standard is refused with the list of catalogue
standards. coverage is the standards coverage manifest (also the resource
autocad://standards/coverage): one record per registered table - the
fastener and bearing tables above, ISO 261 and the feature tables
std_feature_draw reads - with edition, table locator, implemented sizes,
range and source. DIN 509, DIN 471/472, DIN 332-1 and ISO 3601-2 report
"no rows transcribed"; transcriber and reviewer are null because the
repository records none.
|
| std_part_insertA | Define the part's block once, insert it, and write its std_part XDATA. The block carries DESIG / STD / SIZE / MAT attributes and an ACADMCP_MECH
payload, so a parts list is a read of the drawing rather than a naming
convention. Refusals, all before any write: a designation outside the
transcribed tables (named, with the nearest catalogue entries - nothing is
drawn approximately), a malformed designation, a missing or stray nominal
length, a view the family does not have, an attribute tag the block does
not carry, and a non-finite coordinate or rotation. |
| std_feature_drawA | Add a standard feature to geometry that already exists - a foreign drawing being finished. Local frame: (x, y) is on the axis, +X runs along the axis in the
direction the feature extends and +Y is radially outward. The thread is the
ISO 6410 representation (minor diameter at 0.8 x major, thread-length limit
to the major) and its pitch comes from ISO 261 via size or from an
explicit pitch - it is never guessed. Every other kind takes its
dimensions from the registered standards table and is refused by name when
that table is absent, when the size is outside its coverage, or when the row
lacks a dimension the feature needs: no value is interpolated and no profile
is reconstructed. DIN 332 form R is refused - only forms A and B are drawn. |
| surface_textureA | Draw the 60° surface-texture vee with its annotation in the standard positions. Refusals, all before the first entity reaches the drawing: a text height
outside the seven ISO 1302 rows (2.5/3.5/5/7/10/14/20 mm — never
interpolated), a lay that is not one of the seven ISO 1302 directions of
lay, a machining outside any/required/prohibited, and a standard other
than ISO 21920-1 or ISO 1302. |
| weld_symbolA | Draw an ISO 2553 weld annotation: reference line, identification line, symbol, dimensions. Refusals, all before the first entity reaches the drawing: a kind outside
the six elementary symbols transcribed here (square, v, bevel, u, j,
fillet — the rest of the ISO 2553 table is deliberately not shipped rather
than guessed), a side outside arrow/other/both, a non-positive height,
and a pitch given without a length. |
| centre_marksA | Centre marks on the CENTER layer, whose linetype carries ISO 128-23's dash pattern. Pass handles and the radii are read back with entity_get rather than
restated — a radius from memory is the classic silent wrong number.
Refusals, all before the first entity is written: neither handles nor
centers given (or both), a handle that is not a CIRCLE or ARC, a circle
in a plane tilted out of WCS XY (capability ocs_tilted_plane, so it has
no radius in this frame), a style outside mark/lines, a non-positive
extension, and style='lines' on a centre given without a radius. |
| section_lineA | Draw the cutting-plane line and hand back the plane a section view consumes. Wide segments at the ends on GEOMETRY, the thin long-dash-dot middle on
CENTER, an arrow at each end whose head sits on the line end and points the
way the section is viewed, and the same letter beyond both arrows.
payload["plane"] is exactly {p1, p2, label, direction, style} — feed it
to the section view so the label on the plan and the label on the view
cannot disagree. Refusals, before any entity is written: p1 == p2, a zero
or parallel viewing direction, an empty label, a style outside
full/half/offset/revolved, and a non-positive height. |
| hatch_materialA | Section-hatch a cut face with the pattern ISO 128-50 gives its material. Refusals: an unknown material (named, with the full list, before anything
is drawn), neither boundary nor handles (or both), a boundary with
fewer than three points, and a non-positive scale. With handles the
loop is chained by boundary_from_entities, which the COM engine refuses
(capability boundary_trace) - pass boundary on a live seat, or run
headlessly. The HATCH layer is created first when the drawing lacks it:
ActiveX refuses an entity on an absent layer and would otherwise leave the
hatch orphaned on layer 0. The payload states its own accuracy, as analysis_measure_entity does:
area is the polygon actually hatched, boundary_area the exact area of
the chained loop, and accuracy is "exact" or "flatten_tolerance" -
an arc edge reaches entity_create_hatch as chords, so a curved cut face
is hatched to within HATCH_FLATTEN_SAGITTA of itself rather than being
replaced by its chord polygon. With handles, the outline
boundary_from_entities draws is scaffolding and is deleted; traced
reports its handle and whether the delete succeeded. A loop enclosing no
area is refused instead of writing a HATCH of area 0.0. |
| sheet_frameA | ISO 5457 drawing frame for A4-A0: a 20 mm filing margin, 10 mm on the
other three edges, the grid reference system and the centring/trimming marks. Borders, rules and marks land on TITLEBLOCK; the zone lettering on TEXT.
Refusals, all before the first entity is drawn: a size outside A4-A0 is
refused by name and the five covered sizes are listed; an orientation that
is neither 'landscape' nor 'portrait'; a layout that does not exist. The
zone divisions drawn are equal -- ISO 5457's shorter corner fields are not
implemented -- while the division counts are the standard's. |
| titleblock_applyA | ISO 7200 title block, 180 mm wide, in the lower-right corner of any
A4-A0 sheet. The title text is used verbatim. Carries the ISO 128-30 projection-angle symbol: 'first' draws the cone on
the left and the concentric circles on the right, 'third' is its mirror.
Refusals, all before the first entity: an unknown size (the five covered
sizes are listed), an unknown orientation, a projection that is not
'first'/'third'/'', a layout that does not exist. titleblock_apply_iso_a3
is this tool with size='A3' and no symbol, kept so no caller breaks. |
| revision_addA | Append one row to the revision block, creating the block on first use. Idempotent per revision code: a code the drawing already carries returns
created=false and draws nothing, so re-running a revision pass cannot
stack duplicates. The block defaults to the upper-right corner of the
drawing frame, growing downwards, so it does not collide with the ISO 7573
parts list above the title block. Refusals, all before the first entity: a
malformed code, a cloud region that is not [x0, y0, x1, y1], and any
request for clouds on a backend whose revcloud capability is false (the
COM engine — REVCLOUD has no ActiveX member) — that one carries
capability: "revcloud". |
| bom_extractA | Walk the INSERTs and return the ISO 7573 item rows. Never modifies the
drawing. bom_table is what draws them. Each row's source is reported: xdata when the ACADMCP_MECH payload
supplied it (what std_part_insert writes), attributes when the block's
own ATTRIBs did. A block with neither a payload nor a DESIGNATION attribute
is skipped rather than guessed at, and skipped counts them. The whole drawing is read by default — entity_list's 200-entity page is
paged through, not taken as a cap, because an item list that stops at the
200th INSERT prints a wrong QTY rather than a shorter one. Pass limit to
cap it deliberately; truncated is then true if and only if the cap cut
the list. Refusals: an unknown column or group_by field, named with the
list of the ones there are. |
| bom_tableA | Draw the ISO 7573 item list as a real TABLE entity, 180 mm wide (the
title-block width), growing upwards from directly above the title block. With direction="up" the heading row sits against the title block and item
1 is the row above it, so the list extends upwards as parts are added —
which is what ISO 7573 asks for on a drawing. Pass rows to draw a list
you already have, or omit it and the tool runs bom_extract first.
representation reports what was drawn: native (a real ACAD_TABLE on the
live engine) or composite (rules and MTEXT headlessly, whose handle is
the first child). Refusals: no rows to draw, an unknown column, an unknown
direction, a layout that does not exist. |
| balloon_addA | One ISO 6433 item reference: a numbered balloon, a leader, and a dot on
the item. The balloon carries an ACADMCP_MECH payload naming its targets, so running
the balloon pass again after the bill of materials is regrouped renumbers
the existing balloon (renumbered: true) instead of drawing a second one.
Refusals, all before the first entity: an item number below 1, a leader
target inside the balloon, and an item number already used by another
balloon for different targets — named with that balloon's handle. |
| xref_attachA | Attach an external reference and insert it once. Both engines. The block takes the referenced file's stem as its name. Refusals, all
before anything is written: a kind that is not 'attach' or 'overlay', a
file that does not exist, a non-positive or non-finite scale, and a block
name the drawing already holds — detach it first with
xref_manage(action='detach'). |
| xref_manageA | One operation on one external reference. list, detach and path work on both engines. reload and bind need
a live AutoCAD seat's xref manager: headlessly they are refused with
capability: "xref_live" rather than pretended, and the refusal says which
engine does them. Other refusals: an action outside the five, an unknown
xref name, a 'path' action with no new_path. On the live engine a listed
row's inserts and kind are both null — ActiveX's block interface
carries neither a per-xref insert count nor an overlay indicator, and this
server does not invent them. Headlessly both are measured: inserts
counts every insert in the drawing, model space and paper space alike, and
detach removes exactly those.
|
| image_attachA | Attach a raster underlay at the file's own aspect ratio. Both engines. scale is drawing units per pixel, so the placed size is the image's pixel
size times scale and the payload reports both. Refusals, all before
anything is written: a file that does not exist, a file no image reader can
open (named), a non-positive or non-finite scale.
|
| data_extractA | The same rows bom_extract returns, written to a file. Refusals: a format that is not 'csv' or 'xlsx'; a drawing with nothing to
itemise (nothing is written); and fmt='xlsx' without openpyxl, which
carries capability: "xlsx_write" and names both the package to install
and the CSV route that always works. |
| drawing_export_dwgA | Write a real DWG — not a DXF under a .dwg name. On a live AutoCAD seat this is Document.SaveAs with the matching
AcSaveAsType, which (as AutoCAD's own SaveAs does) leaves the session bound
to the file it just wrote. Headlessly it needs the ODA File Converter; when
that is absent the call is refused with capability: "dwg_write" and the
refusal names the install route and drawing_export_dxf, which writes a
DXF AutoCAD opens unchanged. Check system_capabilities first: the ezdxf
flag is re-evaluated at call time, so installing the converter changes it
without a restart. An unknown version is refused by name with the six. |
| arch_wallA | Add walls to the plan network already on the drawing and resolve every junction. Two ends at one point mitre into a clean L; an end inside another wall is a
T (the stem stops on the crossing wall's near face, which is cut there); two
axes crossing are an X (all four faces cut). A drawn wall whose outline the
new walls change is taken back out and redrawn with its openings - the
result lists it under redrawn - and a wall they do not touch is left alone.
Every wall carries an ACADMCP_ARCH record, so later calls find it by id. Refused before anything is drawn or erased, by path: a wall id already on
the drawing or used twice, an axis of fewer than two points or with a
zero-length segment, a non-positive thickness, an unknown justification or
material (the list is named), two walls meeting at less than 5° (the mitre
would run away), a wall corner lying inside another wall off its axis, an
end inside a wall whose axis only meets it past that wall's end, and a new
wall that would leave a drawn opening uncuttable. A curved wall is not
supported: an axis is straight segments only. |
| arch_openingA | A door or a window in a wall already drawn, found by its id; the wall is redrawn cut. The opening removes its width from both wall faces and each edge is closed
by a jamb. A door is drawn open at 90° - its leaf as long as the opening is
wide, hinged on hand, with a quarter-arc swing on the swing side; a
window is a frame line on each face and two glazing lines between them. The
opening's ACADMCP_ARCH record sits on the leaf or the frame, so a schedule
reads it back. Refused before anything is drawn or erased: a wall id not on the drawing
(the drawn ids are named), an opening id already drawn, an opening that
runs past its wall segment or straddles an axis vertex, one overlapping
another opening on the same wall (both ids named), one that runs into a
junction (the solid stretch it must fit in is named), an unknown kind,
swing, hand or language. |
| arch_stairA | A stair in plan: every riser as a line, the outline, the walking line with its arrow. The label ("UP" / "ÇIKIŞ") sits on the first tread at 2.5 mm × scale. The
result reports blondel - 2R + G against 600-650 mm, the step-length rule
attributed to François Blondel (1675). It is a design rule reported for the
drafter, not a building code: no national stair regulation is checked and
a value outside the band is reported (ok: false), not refused. Refused before anything is drawn: a stair id already on the drawing, a
non-positive width, riser height or going, fewer than 2 risers (4 for an L
or a U - two per flight), a non-integer riser count, an unknown kind, turn
or language. |
| arch_dimension_chainsA | The three exterior chains an architectural plan carries, as real DIMENSIONs. Nearest first: the openings row (every jamb in that facade), the walls row
(both faces of every wall meeting it - wall thickness, clear width, wall
thickness, ...) and the overall row. The points come from the wall engine's
own faces, read back from the plan on the drawing. A row that would only
restate a farther one is not drawn (ISO 129-1: each measurement once).
The row spacing defaults (10 mm, then 8 mm on paper) are this server's
drafting choices, not standard values. Text, arrows and gaps follow the
plot scale: each chain is drawn at DIMSCALE = scale (reported as
dimscale), and the drawing's own DIMSCALE is put back afterwards. Refused by name: a drawing with no walls, an unknown or repeated side, a
non-positive scale, offset or step. |
| arch_roomA | Label the room around (x, y) with its name, number and MEASURED area. The area is never typed: the tool reads the wall faces on the wall layer
of the arch set (LINE and lightweight polyline, both engines; anything else
there is listed in skipped), finds the closed face
the point lies in and writes that face's area - net of the wall thickness
and of any column inside it - into the label and into an ACADMCP_ARCH
room record on the name text, which arch_schedule reads. A door or window
recorded on the drawing closes its gap along the wall faces, so two rooms
either side of a door stay two rooms. Refused before anything is drawn: an unknown lang (named with en, tr), a
number/name the room model refuses, a room_id already labelled on the
drawing, a point in no closed face of the walls (draw or close them first,
or read a plan drawn by other means with arch_rooms_detect), a point
inside a wall body, and a point in a room that already carries a label (one
face, one room record - a retried call does not add a second area to the
schedule). |
| arch_rooms_detectA | Read the rooms of a plan - ours or a foreign one made of plain lines. Every LINE and lightweight polyline on the layers is split where lines
cross or touch, and the closed faces they bound are measured (mm², net of
nested pieces).
Faces under min_area, and thin faces (mean width under 600 mm - wall
bodies and reveals, this reader's heuristic) are left out. Each room
reports confidence: 1.0 when every edge lies on the arch wall layer, 0.6
when any edge is a plain line from elsewhere - read confidence_min before
trusting a foreign plan. Room labels already on the drawing are reported
in labels with the face they sit in; a face with more than one is listed
in label_conflicts. Never modifies the drawing. Arcs and bulged polyline edges, old-style
POLYLINEs and block references are listed in skipped with their handle
and reason - never flattened into chords, never dropped silently. Read
skipped before trusting count. A foreign plan's open doorways are
not closed - two rooms joined by one read as one face. Refused: a named
layer the drawing does not have (with the list of the ones it has), and no
layer matching WALL or DUVAR when layers is omitted. |
| arch_scheduleA | Draw a door, window or room schedule as a real TABLE - a read of the drawing. The rows come from the ACADMCP_ARCH records on the drawing (what
arch_wall / arch_opening / arch_room write), never from the caller:
doors by tag with width, height, swing, hand and wall; windows by tag with
width, height, sill and wall; rooms by number with name and the measured
area, plus a total. An opening drawn without a tag gets the next free D1 /
W1 (K1 / P1 in Turkish) in wall order; an explicit tag is kept. A value the
model does not carry is an empty cell, never a default. representation
reports what was drawn: native (ACAD_TABLE, live) or composite (rules
and MTEXT, headless). Refused before anything is drawn: an unknown kind or lang (named with
the list), nothing of that kind on the drawing, and more rows than one
TABLE takes (198). |
| arch_catalogue_listA | Catalogue rows: name, family, both labels, nominal size [w, d] in mm, block name, layer. Sizes are nominal catalogue dimensions - what a furniture or appliance
catalogue lists as a common size - and every row says so in size_basis;
they are not standards values. Twenty items: thirteen furniture, seven
sanitary. Refusals: a family other than furniture/sanitary and a lang
other than en/tr, each with the list. |
| arch_catalogue_insertA | Define the item's block ARCH_ once, insert it on the furniture or sanitary layer. The block carries an invisible ITEM attribute with the catalogue name. Its
size is a nominal catalogue dimension (reported with size_basis), not a
standards value; the outline is a plan symbol drawn inside that footprint.
The furniture / sanitary layer is created from the arch layer set when
the drawing lacks it. Refusals, all before any write: an unknown name
(with the nearest catalogue names) and a non-finite coordinate or rotation. |
| arch_gridA | Axis lines on the arch grid layer (its CENTER linetype comes from the layer) and a
5 mm bubble with its label at both ends of each axis, on the symbol layer. Numbers run along x and letters along y (A..Z, then AA, AB - no letter is
skipped) unless labels names them. The bubble and label sizes are this
server's declared drafting sizes in paper millimetres, not a standards value.
Refusals, all before any write: an empty axis list in either direction, a
non-finite or duplicate position, a label list whose length does not match
its positions, a duplicate or empty label, an unknown labels key, and a
non-positive extension or scale. |
| arch_symbolA | Draw one architectural symbol on the arch symbol layer. Sizes are this server's declared drafting sizes in paper millimetres times
scale (a 16 mm north-arrow circle, 10 mm section and elevation bubbles),
not standards values. Refusals, all before any write: an unknown kind
(with the list), a parameter the kind does not take (with the ones it
does), a section mark without p1/p2, with an empty label, an unknown side
or a cut line too short for its two arrows, an elevation direction outside
up/right/down/left or named twice, a non-finite level value, and a lang
other than en/tr. |
| arch_plan_from_specA | A whole plan drawn inside one transaction: walls with their hosted doors and
windows, stairs, room labels whose areas are measured off the walls just drawn,
the exterior dimension chains and the door / window / room schedules. Every item is validated before the transaction opens, so a refusal leaves the
drawing untouched and names its path (walls[1].thickness: ...,
rooms[0].area: ...). What only the drawing can refuse - a room point in no
closed face - rolls the transaction back, and so does a cancelled request (the
rollback runs under an anyio shield). The result carries each step's own
result, the wall engine's omitted list and the three arch_* critique
focuses run over the committed plan. Refused by name: an unknown key, no walls, an unknown language or material, a
non-finite or non-positive number, an arc segment in a wall axis, an opening
that overlaps another or runs past its wall segment (both ids named), a typed
room area (areas are measured, never typed), an unknown chain side or
schedule kind, and a transaction that cannot be opened. Catalogue furniture,
the grid and symbols are separate tools (arch_catalogue_insert, arch_grid,
arch_symbol). |
| drawing_understandA | One report on a drawing somebody else made, every claim with its evidence
and a confidence. Never modifies the drawing: a file is read as it is, and
the current document through a snapshot (headless: the document in memory;
live: a Document.Export DXF copy in a temporary folder, deleted after).
An xref's own entities are not read - the host drawing is. units: $INSUNITS as declared against the unit the geometry implies
(text heights, wall thickness, door swings, labelled room areas, overall
size - each item with its median and its value under every candidate
unit). A disagreement is a warning with the numbers, never a silent
correction.
extents: declared, computed and robust boxes and the outliers that
stretch them, farthest first, by handle.
clusters: separate bodies of model-space content (plan copies, sheets,
details), each with its box, entity count, commonest layers and tallest
labels.
layers: entity count, drawn length (and metres in the inferred unit)
and the discipline / service each most likely carries - the vocabulary's
confidence (0.9) for a name keyword, 0.6 when most texts on the layer
agree, 0.4 when fewer do.
equipment_tags (a tag found more than once is ambiguous), rooms
(room labels in five languages, each with the wall-layer face it sits in
and its measured area), languages (Latin / Turkish / Cyrillic character
classes), blocks (named / anonymous, kinds by name), layouts,
title_block and warnings.
Refused before anything is read: a path that does not exist, a DXF over
MAX_DXF_BYTES (the refusal names the size and the variable), and a file
the engine cannot parse (a DWG headlessly: ezdxf reads DXF only). |
| drawing_scale_checkA | Is the drawing to scale against the reference - or a schematic whose lengths
are lengths of drawn line, not of pipe? Read-only on both drawings. Equipment tags are matched between the two (a Cyrillic look-alike such as
Т4100 is the Latin T4100). Only a tag found exactly once in each is used;
a tag found more than once (plan copies, a legend, a second sheet) is listed
in ambiguous and takes no part. When a drawing holds several bodies of
content (two copies of one plan), the pair of scopes - whole drawing or one
cluster on each side - that matches the most tags is used and named in
scope. For every two matched tags at least min_pair_mm apart on the
reference, the ratio of their distances is taken (both in millimetres by
each drawing's inferred unit, see drawing_understand). The result gives
the matched tags, the median ratio, the quartiles and their range, the
share of pairs within +/-10 % of the median, the same per room of the
reference (or per cluster for tags in no room) in groups, and a verdict:
to_scale (at least 80 % within the band; factor is the median, so a
uniform other scale is recognised), schematic (50 % or less), partly
in between, insufficient with fewer than three matched tags or no pair
above the floor. Tag labels are not equipment centres; the band and the
floor absorb that offset, and the result's notes say so. Refused before anything is read: a reference or path that does not
exist, a DXF over MAX_DXF_BYTES (the refusal names the size and the
variable), a file the engine cannot parse (a DWG headlessly), and a
min_pair_mm that is not a positive finite number. |
| drawing_diffA | Compare two revisions of one drawing by geometric signature (spec §10). Entities are matched exactly first (type, layer, geometry rounded to tol,
text, block, attributes - handles do not matter), then by handle while
handles look stable, then by type + layer + nearest position within
move_tol; what is left is added or removed. The report counts changes by
layer and type, lists each changed entity with what changed (moved by, text
from -> to, attribute from -> to, radius from -> to, ...), compares the
block definitions when both revisions are DXF files or the headless current
document, and groups the changes into clusters. Read-only unless markup=True: then revision clouds are drawn around the
model-space clusters on the current document, which must be the newer
revision, and filed as one revision row - the only write this tool makes. Refused before anything is read: markup=True with new_path (the clouds go
on the current document), markup=True without a valid rev, markup=True
on an engine without the revcloud capability (the live engine -
capability: "revcloud"), a path that does not exist, a DXF over
MAX_DXF_BYTES (the size and the variable named), a file that is not a
readable DXF, and a non-positive tol or move_tol. |
| drawing_topology_checkA | Topology of a line network (spec §11): dangling ends, near misses (end to end and
end to line within gap) and interior crossings (two lines of one layer crossing
away from their ends). Never modifies the drawing. An end that touches another network line, any curve on another layer (a tank
outline) or the box of any block reference (a valve, a pump) is connected. Arcs
and bulged polyline segments are measured as true arcs; arcs are not tested for
crossings. The default layers come with their classification as evidence. Refused before any work: a path that does not exist or cannot be read, a
layers entry that is not a layer of the drawing (the drawing's layers named),
no layer classified as a network layer when layers is omitted (name them),
a non-positive tol or gap, and a gap that does not exceed tol. |
| drawing_verify_requirementsA | Measure source requirements on the CAD geometry and say, per requirement,
pass / fail / unknown / unsupported / ambiguous - with the evidence. Each requirement is bound to the real feature (by handle, feature tag, arch
element, geometric predicate or DIMENSION; two equal candidates are
ambiguous, never a pick) and measured on the geometry read from the drawing never on a label, a stored model or the numbers that were typed in. A row
gives target, measured, delta, tolerance basis, status, handles and source;
counts gives the denominators (required = pass + fail + unknown +
unsupported + ambiguous). status is pass only when every requirement
passes; accepted also needs fresh evidence and no dimension_mismatch
finding (a DIMENSION whose text or DIMLFAC disagrees with the geometry).
Modes: requirements ({"units": ..., "items": [typed requirements]}, or a
legacy {"dimensions": {...}} that is carried read-only and verifies
nothing) or use_stored=True: measured on
the current document. evidence records its id and content revision; a
later revision makes the report stale.
artifact_path: measured on that saved file, read fresh (a .dwg on a live seat
through a private copy), each feature re-bound from the current document - by
handle while handles are stable, then by feature tag, then by geometry, two
candidates being unknown - with rebinding and the before / after
comparison in the report. A count or absence is counted afresh on the
file, never carried over; a DIMENSION not found again there is a blocking
dimension_unverified finding. provenance says whether the current
document can be the file's source (at least half of the entities match
unchanged); when not, a blocking artifact_source_mismatch finding, no
comparison, and a handle-naming requirement is unknown.
manifest_path: re-hashes a drawing_deliver bundle and lists every
artifact whose sha256 no longer matches (stale) or that is gone
(missing).
report_path writes the report as JSON (.json) or Markdown (.md); nothing
else is written, and the drawing never is.
Refused before any work: requirements together with use_stored
(invalid_args); neither of them without manifest_path
(missing_requirement); use_stored on a drawing that stores no
requirements (missing_requirement); requirements that do not parse
(invalid_args, the offending path named); a binding_policy other than
strict / lenient; manifest_path together with requirements, use_stored
or artifact_path; an artifact_path or manifest_path that does not
exist; a manifest that is not a delivery manifest; a report_path not
ending in .json or .md (only .json in manifest mode); a DWG artifact on the
headless engine (capability dwg). A quarantined document is refused. |
| pipe_takeoffA | A pipe takeoff: topology from the P&ID, lengths from the layout, rows by room x service x diameter. The P&ID gives the runs (junctions merged, tees split, a line drawn twice
counted once, valves and reducers bridged), each run's service (the layer,
overridden by a supply / return word near the line), its diameters exactly
as labelled (direct, carried by continuity - never across a reducer - or
unassigned) and the equipment tags at its ends. The length comes from the
layout unless the scale check calls the P&ID to scale: the rectilinear
minimum spanning tree of the run's tag positions on the layout, each
connection along x first then y, plus vertical_allowance per connection.
The P&ID's drawn length stays beside it as schematic_m, never as the
answer. Lengths are metres from the unit the geometry implies; an INSUNITS
that disagrees is a warning, never a factor. Status A / B / C per run: a C
run (an end on no equipment, a tag missing from or written twice on the
layout) is on the Kontrol sheet with its schematic length, counted in the
total and flagged. Read-only on both drawings. With output it writes one workbook - Metraj,
Özet, Kontrol, Metodoloji - as XLSX and, always, as CSV beside it. Refused before a drawing is read: lang outside tr / en / ru, an unknown
service or length source, an allowance outside 0-1, a negative vertical
allowance, a non-positive tolerance, and length_source='layout' without
a layout. A missing, unreadable or oversize drawing is refused by the
reader, which names MAX_DXF_BYTES. Refused after the scale check:
length_source='pid' on a P&ID it calls schematic, unless force=True
(the refusal quotes the statistics). Without openpyxl the XLSX is not
written and files.refused carries capability: "xlsx_write" naming the
office extra; the CSV files are written all the same. |
| cable_takeoffA | A cable takeoff: one row per electrical load, the shop's cable method made repeatable. Power, phases, voltage, neutral and VFD come from the P&ID's electrical
texts near each tag (Russian, Turkish and English spellings). Power is
never invented: a load with no stated kW keeps an empty cell and an open
item. The panel comes from the layout's wiring callouts ('Wiring to CP1'
and its variants, normalised to CP-1), else from the P&ID ('к CP1'); a load
neither places takes the nearest panel on the layout, flagged
panel_inferred (panel_rule='stated' leaves it open). The length is the
Manhattan distance on the layout from the load's tag to its panel's tag,
and the cable is ROUNDUP(length x (1 + allowance)) to the metre. Room and
panel totals count known power once: a load wired to a panel that states
its own power is part of that package, and the package's power is counted
instead of its children's - the rule is written on the method sheet.
Sections only from section_rules; no standard table is applied. Open
items: missing power, missing panel, a tag or panel not on the layout, no
layout at all, a load no section rule covers. Read-only on both drawings. With output it writes one workbook - Metraj,
Özet, Kontrol, Metodoloji - as XLSX and, always, as CSV beside it. Refused before a drawing is read: lang outside tr / en / ru, an allowance
outside 0-1 and a malformed section rule (named by its path,
section_rules[0].section: ...). A missing, unreadable or oversize drawing
is refused by the reader, which names MAX_DXF_BYTES. Without openpyxl the
XLSX is not written and files.refused carries capability: "xlsx_write"
naming the office extra; the CSV files are written all the same. |