# DXF Desk > Drop the DXF of a flat part you are about to send to a laser cutter, a waterjet, a CNC router or a > plasma table. A real ASCII DXF reader runs free in your browser, measures the part, and checks every > measurement against the published minimum for your process and material thickness. Then one of four > AI lanes turns those numbers into judgement: read the file, check it will cut, correct the part, or > build the order packet. Live at . Built on the SkillSafe apps platform. The browser side is free and needs no account; the four AI lanes are metered and need a signed-in SkillSafe account. ## The one-sentence job Take the DXF flat part you are about to upload to a fabrication service and get it order-ready in one sitting: read what the file actually contains, measure every feature against the process minimums, correct it, and build the order packet. ## What runs in the browser, free, with no account A DXF is a flat stream of group code and value pairs, two lines each. Everything else - sections, tables, blocks, entities - is a convention layered on top. So the reader tokenises pairs first and interprets second. - **HEADER variables** are read, so `$INSUNITS` and `$MEASUREMENT` decide millimetres versus inches rather than a guess. When the file states neither, that is the loudest flag on the page: a part read in the wrong units is wrong by a factor of 25.4. - **The LAYER table** is read, so a layer that exists but carries no geometry is still known about. - **BLOCKS are read and every INSERT is expanded** into model space with its own translation, rotation and scale, recursively, to a bounded depth, including rectangular arrays. - **A CIRCLE stays a circle** - with an exact diameter - whenever the transform that placed it was a similarity (uniform scale, any rotation, any mirror). Under a *non-uniform* scale it is an ellipse, so it is discretised in the block's own frame and the points are transformed, which is geometrically right; scaling the radius would not be. The app says when it did this. - **Polyline bulges become real arcs.** A DXF bulge is `tan(theta/4)` for the arc's included angle. A bulge measured as a straight chord understates a rounded rectangle's perimeter by several per cent. - **SPLINE and ELLIPSE** are measured through fit points where they exist, and along the control polygon where they do not. A control polygon is an *outer* bound on a B-spline, so a spline contour can only be reported as longer and wider than it is - an error that never turns a violation into a pass. Every such case is listed as a bound, not a value. - **Binary DXF, DWG, ZIP and PDF are refused by name** with what to do instead, rather than parsed into nonsense. Then the geometry: - **Contour stitching.** Cut entities are chained into closed loops by matching endpoints within a stated tolerance. Everything that does not close is reported as an **open contour** with the size of the gap and both endpoint coordinates. An open contour has no inside, so the machine cannot tell material from scrap - it is the most common reason a flat-part file is rejected by a shop. - **Nesting by containment**, so a part outline, a hole in it and an island inside that hole are told apart by parity rather than by drawing order. - **Measurements**, all in millimetres: part size, net area, cut length, etch length, pierce count, every opening's diameter, the narrowest neck on any contour, the closest approach between two contours (labelled *web* for two separate cuts and *edge* for an opening inside its own outline), the tightest concave turn a cutter would have to reach into, the shortest segment the drawing actually contains, and duplicate entities lying on top of each other. - **Bend lines**: length, angle, the flange either side measured by projecting the outline onto the bend's perpendicular across the bend's own span, how far the bend line stops short of the outline, and the nearest opening to it. - **Annotations** - `TEXT`, `MTEXT`, `DIMENSION`, `HATCH`, `POINT` - are found and reported with the layer they sit on. A dimension left on the cut layer gets cut into the part. - **Layer role inference** from the layer's name, with its confidence stated. A layer whose name says nothing is treated as cut geometry, because that is what a shop's importer will assume too. ## The rule table, and what it is not Every limit is a **ratio applied to your material thickness**, and the app shows the ratio, the thickness and the resulting limit next to the measured value, every time. Examples for laser-cut sheet metal: minimum hole diameter one thickness; minimum slot width one thickness; web between two cuts two thicknesses; hole to part edge one and a half; minimum flange four; hole to bend line two and a half. A CNC router's floor is its tool diameter instead, because no end mill cuts a slot narrower than itself and no internal corner can be sharper than the tool's radius. **These are published sheet-metal guidance, not any vendor's catalogue.** This app has no network access and cannot fetch a price list, so it never pretends to have one. **No price and no lead time is quoted anywhere in the app, in any lane.** The cost drivers it names - cut length, pierce count, part area, secondary operations, quantity - are the quantities a quote is computed *from*. Confirm every minimum against your shop's own published specification before you order. ## Free exports, no account - the read-out as Markdown - contours as CSV (one row per contour and per open contour, with every measurement and its basis) - the rule table as CSV (ratio, floor, thickness, limit, measured, verdict) - the flags as CSV - the whole measurement as JSON, including every contour's point list in millimetres - a rewritten **R12 DXF containing only cut geometry and bend lines** - annotations, reference geometry and duplicates dropped, contours that did not close moved to a layer named `OPEN-REVIEW` so they are visible in CAD rather than silently discarded. R12 with `POLYLINE`/`VERTEX`/`SEQEND` on purpose: every importer ever written understands it, while `LWPOLYLINE` dates from R13. Circles stay `CIRCLE` entities so exact diameters survive the round trip. It is a new file; your original is never rewritten. ## The four lanes Each is one `task` value in the run input. They share one system prompt, one output envelope and one work object - the same DXF - and each result offers the next lane as a button. | task | Stage | What it answers | | --- | --- | --- | | `read` | Understand | What this file actually contains: what the part is, what the units are, what each layer means, what each contour is for, and which of the browser's readings are guesses that still need settling. | | `dfm` | Decide | Whether the part can be made by the process, material and thickness you picked: every measured value against its limit, the consequence of each violation, the remedy, and the secondary operations the geometry implies. | | `fix` | Produce | The specific edits that clear the findings, plus a parametric `build123d` script that regenerates the corrected part and exports DXF and STEP - so the fix is repeatable and the next revision is a parameter change. | | `order` | Order | The order as a shop needs it: material, thickness, quantity and finish, the services in the sequence they physically happen, the hardware, the quantities a quote is computed from, the questions to ask, and the pre-upload checklist. | ## The input contract ```json { "task": "read | dfm | fix | order", "dxf_excerpt": "the DXF text, cut on whole ENTITY boundaries if it was too large", "process": "laser_metal | laser_acrylic | waterjet | router_alu | plasma", "material": "free text", "thickness_mm": 2, "quantity": 5, "finish": "none | deburr | anodise | powder_coat | plate | brush | paint", "context_note": "what the user says this part is", "facts": { "units": {}, "part": {}, "layers": [], "contours": [], "open_contours": [], "bends": [], "annotations": [], "measures": {}, "rules": [], "flags": [] }, "prior_read": { "carried from the read lane when the user came from it" } } ``` `facts` is the important field: it is everything the browser measured, and it is what the model is held to afterwards. ## The output contract One JSON object. Common envelope for every lane: `task`, `task_inferred`, `title`, `verdict` (`ready` | `fix-first` | `blocked` | `unreadable`), `summary`, `assumptions[]`, `open_questions[]`, `findings[]` (`id`, `severity`, `location`, `title`, `why`, `fix`), `reconciliation[]` (`flag_id`, `status`, `note`), `next_lane`, and a per-lane `body`. Every lane's body carries a runnable Python `script` - `ezdxf` for reading and rewriting DXF, `build123d` for authoring geometry. ## How the AI pass is kept honest 1. **The browser measures first** and its numbers go into the run. The model may not contradict them. 2. **One reconciliation entry per critical and high flag, by id.** A defect the model ignored is displayed as unaccounted for rather than quietly dropped. 3. **Every citation is checked.** A contour, layer, bend or rule id that is not in the file is kept and shown *marked*, never silently removed. 4. **Every layer name the returned script reads is checked** against the file - including the `ezdxf` query idioms, not just `layer="X"` - while a layer the script creates itself is not flagged. 5. **Per-lane coverage.** On `read`, any layer carrying geometry that the reading does not mention is listed, because anything not read is cut by default. On `dfm`, any rule the browser measured as failing that the review passed over in silence is listed too. 6. **Bounds are labelled as bounds** - the chord tolerance, the spline outer bound, the stitch tolerance, the work limit on the contour-to-contour search. ## What it deliberately does not do - It does not nest parts on a sheet and it does not price anything. - It does not evaluate spline basis functions; it says so and reports the bound. - It cannot measure an inside bend radius from a flat pattern, because that is a tooling choice rather than a property of the drawing. The radius is listed as a rule the flat pattern must have been developed against, never as a measurement. - It never rewrites your original file. - It is not a manufacturability guarantee and not engineering sign-off for a part that carries load. ## Source skills and credit DXF Desk is a derived work inspired by three published agent skills, all from : - **@earthtojake/dxf** - DXF handling. - **@earthtojake/sendcutsend** - preflighting a DXF or STEP upload for a fabrication service, covering upload readiness, material and thickness availability, and service-specific checks for laser cutting, CNC routing, bending, tapping, countersinking, hardware insertion and finishing. - **@earthtojake/cad** - STEP-first `build123d` part authoring, inspection and validation. The in-browser ASCII DXF reader, the contour stitching, the geometry mathematics, the rule engine, the flags and all six exports are an independent implementation written for this app. DXF Desk is not affiliated with, endorsed by, or maintained by those authors, by SendCutSend, by any other fabrication service, or by Autodesk. DXF and AutoCAD are trademarks of Autodesk, Inc. ## Pages - - the app - - the API tutorial, eight languages - - token management (noindex)