본문으로 건너뛰기
cccskills
무료GitHub에 공개

dxf

Create and update 2D DXF drawings from written requirements or CAD geometry using Python and build123d. Prepare cutting profiles and marking layers, check for open contours and duplicate geometry, and review drawings in CAD Viewer.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

원문원문 설명 보기

Generate, regenerate, and validate 2D DXF drawings from Python build123d sources. Use for DXF files, `.py` drawing scripts, @dxf models, 2D profiles, outlines, templates, gaskets, panels, flat patterns, laser/plasma/waterjet cut layouts, and 2D drawing exports of CAD geometry. Open and visually review existing DXF files in CAD Viewer.

설치 방법 보기

이럴 때 유용합니다

  • Create dimensioned gasket or panel drawings
  • Generate flat profiles from STEP geometry
  • Separate cutting and engraving geometry into layers
  • Check and visually review existing DXF drawings

포함된 파일(4)

  • SKILL.md17.7 KB
  • agents/openai.yaml300 B
  • LICENSE1.0 KB
  • references/generator-templates.md6.1 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

DXF generation and validation

Provenance: maintained in earthtojake/text-to-cad. Use the installed local skill files as the runtime source of truth; the repository link is only for provenance and release review.

Setup

Run cadgen through uv, so this skill's commands share one installation, and its warm build daemon, with the CAD app's server:

  • cadgen below means uvx --no-config --managed-python --python 3.13 --from cadgen==0.7.26 cadgen
  • python below means uvx --no-config --managed-python --python 3.13 --from cadgen==0.7.26 python

The first run downloads that installation and the first snapshot its headless browser; later runs reuse both.

cadgen doctor <skill-dir> reports the installation in use and checks that it is the one this skill pins, and that the CAD kernel loads; use it for installation or kernel load errors.

Drawings are build123d geometry, so a drawing build loads the CAD kernel like a STEP build does (~2.5s cold; the warm daemon absorbs it on re-runs). cadgen dxf snapshot needs no Node at all: it flattens the drawing with ezdxf (which arrives with cadgen) and paints it in the bundled headless browser.

Purpose

Create or modify 2D DXF drawings from natural-language requirements or from CAD geometry, generate validated drawing artifacts, and return checked outputs. A DXF drawing's source of truth is a Python file named <name>.py defining one parameterless @dxf model function.

A drawing is a model. It has the same wrapper, record, freshness gate and build job a @step part has; its one output is the .dxf file; it has no geometry tree (nothing links to a drawing). Every run writes the sibling <name>.dxf (or the out= the decorator names); an unchanged source is a no-op; a drawing that calls a part model — bracket() inside its body — is stale whenever that part's GEOMETRY changes and current when it does not; cadgen store why <drawing>.py explains the verdict; --force rebuilds it anyway. The CAD Viewer and dxf snapshot read the .dxf file itself, so the file you hand a cutting service, the file the viewer draws and the file a snapshot renders are one and the same.

The contract

A @dxf function takes no parameters and returns build123d 2D geometry. The engine writes the DXF. You never construct a document, name a file, or place an entity — the same division of labor @step has.

from cadgen import build123d as bd
from cadgen import dxf


HOLE_D = 4.5


@dxf
def gasket():
    with bd.BuildSketch() as cut:
        bd.Rectangle(60, 40)
        bd.Circle(HOLE_D / 2, mode=bd.Mode.SUBTRACT)
    return cut.sketch          # bare shape -> the CUT layer


if __name__ == "__main__":
    gasket()
  • Bare shape → one CUT layer. That is the whole contract for most drawings.
  • {layer: shape} → named layers, when the drawing genuinely has more than one CAM operation (CUT / ENGRAVE / SCORE). A Compound whose children are all labelled means the same thing.
  • No parameters. Dimensions are module constants (HOLE_D = 4.5) or constants imported from the part the drawing derives from; a different drawing is a different file.
  • Text is bd.Text(...) engraved OUTLINES on a marking layer, never a DXF TEXT entity: cut and marking toolchains consume geometry, and font rendering inside CAM is unreliable.
  • Geometry must lie in the XY plane. A face taken from a solid sits at that solid's height; relocate it (flatten.flatten_face(face), or bd.Location((0, 0, -z)) * face). The engine REFUSES off-plane geometry rather than silently writing its XY shadow.
  • Output bytes are a function of the geometry. Layers are sorted by name and entities by geometric content, so an unchanged drawing rebuilds to an identical file, cold or warm, on any machine.

The three DXF workflows

Copy the full template for the applicable workflow from references/generator-templates.md when creating a new drawing.

  1. Drafted from scratch (gaskets, panels, templates, cut layouts with no 3D model behind them): a <name>.py that builds sketches and returns them.

  2. Flat pattern of a generated STEP part: a drawing script beside the model it derives from, with its OWN stem (one model per file — bracket_drawing.py beside bracket.py). Import the model and call it, exactly as an assembly composes a child: importing never builds, and inside the drawing's build the call returns the part's geometry (building the part first if it is stale).

    from cadgen import dxf, flatten
    from bracket import bracket        # a child: tracked by its RESULT
    
    KERF = 0.15
    
    
    @dxf
    def bracket_drawing():
        return flatten.flat_pattern(bracket(), coordinate=3.0, kerf=KERF)
    
    
    if __name__ == "__main__":
        bracket_drawing()
    

    The drawing's record pins the part's tree, so a part edit that changes its geometry makes the drawing stale, and one that does not (a comment, a refactor, a colour) leaves it current. Constants imported from the part (from bracket import THICKNESS) are tracked by value the same way.

  3. Flat pattern of an imported STEP (a .step/.stp with no Python source): read it with cadgen.read_step (warm from the store, the same geometry as build123d.import_step). Like every file a build reads, it is an input: replacing the vendor STEP makes the drawing stale on its own, with no --force.

    from pathlib import Path
    
    from cadgen import dxf, flatten, read_step
    
    _HERE = Path(__file__).resolve().parent
    
    KERF = 0.15
    
    
    @dxf
    def panel_flat():
        panel = read_step(_HERE / "imported" / "vendor_panel.step")   # recorded input
        return flatten.flat_pattern(panel, coordinate=3.0, kerf=KERF)
    
    
    if __name__ == "__main__":
        panel_flat()
    

    Never read a STEP this project generates. Reading the .step a @step model writes is not a loop, it is a drawing whose input changes on every run of the model: the freshness gate can never say "current", every build is a full rebuild, and the flat pattern depends on what the last run left on disk. Keep source STEPs in an imported/ directory beside the drawing, committed like any other input — input path and output path being different files is the whole rule. For a STEP this project DOES generate, use workflow 2 instead: import the model script and call it, which is tracked by result and never touches an artifact.

One model per file is the recommendation, and a drawing gets its own script: a file MAY declare several models — two @dxf drawings, or a @dxf beside a @step — and each is its own record, output and job (a sole model writes <file>.dxf; models sharing a file write <function>.dxf), but they share the file's closure, so editing one rebuilds them all. A drawing composes models, never the reverse: calling a @dxf function from a @step body is just its 2D geometry and links nothing. The viewer catalog is artifacts-only: scripts never list; the .dxf the run writes is the entry the viewer renders.

Use this skill when

Use this skill when the user asks for DXF files, 2D drawings, profiles, outlines, templates, gaskets, panels, flat patterns, or cut layouts for laser, plasma, waterjet, or CNC routing.

Use $cad for the 3D part or assembly a DXF derives from. Use $sendcutsend for SendCutSend-specific upload preflight.

Defaults

Use these defaults unless the user specifies otherwise:

  • Units: millimeters. The engine sets them; a drawing never declares units.
  • Geometry lives at 1:1 scale in the XY plane.
  • Cut profiles close. Open contours belong on bend/engrave/reference layers — generation validation enforces this (see Validation).
  • For CAD-backed parts, derive contours from the real topology with cadgen.flatten rather than redrawing them: planar_faces selects, flatten_face lays a face into XY exactly, union_faces fuses, and flat_pattern does all of it in one call. Hand-drawn parametric outlines only when there is no reliable 3D topology.
  • Kerf / tool-radius compensation is flatten.offset_profile(shape, amount) or flat_pattern(..., kerf=...); never hand-offset coordinates.
  • Curves stay curves. The union and the offset are exact OCC operations, so a filleted corner exports as an ARC and a hole as a CIRCLE, kerf included. A profile that comes out as hundreds of short LINEs means something fell back to the sampled path — investigate rather than accept it.
  • Layers carry intent: keep cut geometry and bend/fold lines on separate layers, and include "bend" in bend-layer names so downstream tools classify them as bends rather than cuts.
  • DXF layers are drawing structure, not STEP part/assembly structure.

Tool

python <drawing>.py [flags]                    # its __main__ calls the @dxf model, which writes the .dxf
cadgen dxf snapshot <drawing.dxf> <file.png>   # render it
cadgen store why <drawing>.py                  # why the drawing is stale or current

Running the script (its __main__ call) is the only door. There is no cadgen dxf build: a .dxf has no derived state a command must materialize — the file IS the product, and both the CAD Viewer and dxf snapshot draw it straight from its own bytes. The drawing's gate makes a rebuild cheap: an unchanged source whose .dxf still verifies and whose part children are unchanged is a no-op, and --force rebuilds anyway. The bytes are a function of the drawing's GEOMETRY, so a cold run and a warm daemon worker write the same file. Builds never wait on or cancel one another; a drawing that calls parts builds them in parallel like any parent.

An imported .dxf needs nothing at all — hand it straight to snapshot or the Viewer.

Use the active project Python interpreter; treat python as an interpreter placeholder, and use --help for the full interface. Target paths resolve from the command's current working directory; run from the workspace that owns the artifacts with cwd-relative target paths. Keep a drawing script in the same directory as the geometry it derives from, named <name>.py.

Flags (a model script runs itself; there is no generation CLI):

  • --force — regenerate even when the recorded output is current.
  • --verbose, --json.

A run answers on stdout exactly as a STEP model's does — built DXF/plate_drawing.dxf or current DXF/plate_drawing.dxf — with progress on stderr; --json makes the result one JSON line (outcome, document, and tree, which is null for a drawing) and the progress one JSON line per transition.

One script, one drawing: run each script you want built. Do not put output paths in the @dxf function's return value; out= on the decorator is the only place a drawing names its destination (relative to the script).

cadgen dxf snapshot draws a drawing flat, to a PNG still — the same picture the CAD Viewer shows, from the same flattening, through the same drawing code:

cadgen dxf snapshot path/to/imported.dxf review.png
cadgen dxf snapshot path/to/drawing.dxf review.png --appearance dark

It takes the .dxf document only — a model script is refused by name (run python <drawing>.py, then snapshot the drawing it wrote). The whole drawing is fitted to the image and painted head on, in the pens the file declares; an entity with no pen of its own (ACI 7) takes the appearance's foreground on its background. The command flattens the drawing with ezdxf and renders it through the shared snapshot CLI (cadgen.snapshot_cli) and the same headless browser runtime every rendering skill uses.

OUT — the second positional — is written exactly as given, with a relative path resolved against the current working directory. The target is deleted before the render starts and the finished image is written atomically, so: reuse one name while iterating (every read is provably the render you just ran), name the iterations when you genuinely need to compare two. Invalid request combinations fail before touching OUT; after a request is accepted, OUT is cleared first so a later failure leaves a missing file instead of a stale image. A directory (tmp/ as OUT) is the don't-care case and gets a generated timestamped name inside it, printed on the saved snapshot: line.

Grammar: cadgen dxf snapshot TARGET [OUT] [flags]. Flags: --appearance light|dark, --size-profile, --width/--height, --job, --debug, --json. A drawing has no 3D scene settings: --camera, --display, --mode and --view-labels are not CLI flags. A job can frame a window of the drawing with a plan-view camera ({"target": [x, y, 0], "position": [x, y, d], "up": [0, 1, 0], "orthographicHalfHeight": h}) and draw an annotation over it, in drawing coordinates: a Quick Edit prompt's views file is such a job, and cadgen dxf snapshot --job <it> renders the views the person saw again. Other camera poses, per-output cameras, scene display settings, scale, list mode, output label/viewLabel, and output.padding/viewLabels/tightFrame are refused. A job's output.renderScale and output.transparent still apply. Quick Edit supplies this packet inline as JSON or by a .snapshot.json path; save inline JSON to a temporary file before using --job. Inspect supplied annotations before editing. Without annotations, the captured view is optional context.

No CLI inspects an existing .dxf. For entity/layer checks read it with ezdxf directly (it arrives with build123d), and validate_dxf_file for the drawing checks; review geometry visually (see Show the model).

Workflow

  1. Convert the request into a short brief: outline dimensions, holes and slots, layers, units, output path, and validation targets.
  2. Pick the workflow: drafted from scratch, flat pattern of a generated model (create and validate the 3D geometry with $cad first), or flat pattern of an imported STEP.
  3. Write or edit the <name>.py source with meaningful dimensions as named constants, reusing the model's geometry helpers instead of duplicating formulas.
  4. Run each drawing script directly (python <drawing>.py); do not sweep directories.
python path/to/source.py
python path/to/source.py --force
  1. Validate the generated DXF deterministically, then hand off and report.

Show the model

Show the user each file you create or change, and any they ask to see. Snapshots and validation don't replace this.

  • If your tools include cad_show (your host may prefix it), use it with the file's absolute path, and follow its description for when to call it again. cad_view reads what the user selected; cad_screenshot shows you what they see. Neither is a review of your own work.

  • Otherwise run the CAD Viewer, from any folder:

    cadgen viewer --host 127.0.0.1 --json --detach
    

    --detach returns once the viewer answers requests and leaves it running in the background: always pass it, since a foreground viewer never exits (and piping its output through tail can hide the URL for good). It starts this machine's one viewer, or reuses it. Read url from its one JSON line (never guess the port), and for each file return url?file=<its URL-encoded absolute path>. If it fails to launch, say so.

The viewer renders saved DXF files as read-only 2D drawings; it never runs generation scripts. Drag to pan, wheel/pinch to zoom, double-click to fit. Its Select, Pencil, Shapes and Measure feed Quick Edit, whose prompt names what the person picked as references into the drawing by entity HANDLE: panel.dxf#h2F is the modelspace entity whose handle is 2F (doc.entitydb["2F"] in ezdxf); anything a block reference draws is named by its INSERT, and a dimension is one entity. The prompt's chip reads it as the entity's type and layer ("Circle on CUT"). Measurements are in the unit $INSUNITS declares ("units" when it declares none).

Validation

Validation happens IN generation, not after: every @dxf build runs the drawing checks on the document the engine just serialized, before anything is written, and a build with error findings fails. The checks: cut-layer profiles must close (polylines, circles, or chained line/arc loops), zero-length/degenerate entities are rejected, exact duplicate geometry (double-cut risk) is rejected, explicitly unitless documents are rejected, and an empty modelspace is rejected. Open geometry is allowed only on bend/engrave/reference-intent layers (matched by name).

The same checks run post-hoc on any existing .dxf file — including one that never came from a generator — through cadgen.drawing_checks:

from cadgen.drawing_checks import validate_dxf_file

for finding in validate_dxf_file("path/to/file.dxf"):
    print(finding.render())

Beyond the built-in checks, verify requested dimensions with targeted ezdxf reads (entity counts by layer, drawing extents, every dimension the user specified) against the generated sibling .dxf (or the out= path when one is declared), and review geometry visually in the CAD Viewer:

import ezdxf

doc = ezdxf.readfile("path/to/source.dxf")
msp = doc.modelspace()
cut = msp.query('*[layer=="CUT"]')
holes = msp.query('CIRCLE[layer=="CUT"]')

Report only checks that actually ran.

Handoff

Show every drawing you created or changed (Show the model). Report any failure explicitly.

Final responses should include generated files, returned viewer links, validation actually run, and assumptions.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Prepare files for printing on Bambu Lab printers by opening sliced files in Bambu Connect or unsliced models in Bambu Studio. The user selects the printer, checks the setup, and starts printing in the app.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Open a sliced file in Bambu Connect
  • Open an unsliced model in Bambu Studio
  • Prepare printing through Bambu Cloud or LAN
earthtojake/text-to-cad2.3만2026년 10월 22일 업데이트

cad

무료

Create and edit 3D parts and assemblies with adjustable dimensions using cadgen. Export STEP, STL, 3MF, or GLB files, inspect geometry, and open existing models in CAD Viewer for visual review.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Create a part from specified dimensions or a drawing
  • Revise part dimensions and assembly placements
  • Export models as STEP, STL, 3MF, or GLB
earthtojake/text-to-cad2.3만2026년 10월 22일 업데이트

Check mesh files for 3D printing by measuring geometry and comparing it with process-specific design limits. Get findings on wall thickness, overhangs, and supports, plus build orientation options and concrete redesign guidance.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Check whether a mesh meets printing design limits
  • Find thin walls and unsupported overhangs
  • Compare build orientations to reduce supports
earthtojake/text-to-cad2.3만2026년 10월 22일 업데이트

dfm

무료

Review part designs for sheet metal, CNC machining, or injection molding. Compare geometry measurements with applicable supplier or tooling limits, then document manufacturing concerns, suggested changes, and checks that still need evidence.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Review sheet metal bends and flat patterns
  • Check CNC tool access and internal corners
  • Review molding draft and undercuts
earthtojake/text-to-cad2.3만2026년 10월 22일 업데이트

Create a manufacturing drawing PDF from a part’s 3D geometry, with projected views, measured dimensions, hole callouts, and a title block. Rerun the drawing script after model changes to update the sheet.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Prepare a dimensioned drawing for manufacturing
  • Document hole sizes and machining requirements
  • Update drawings after changing a part model
earthtojake/text-to-cad2.3만2026년 10월 22일 업데이트

gcode

무료

Turn 3D models into printer instructions called G-code with OrcaSlicer. The skill selects existing printer and material presets, slices the model, and checks dimensions and output settings before handing over the files.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Prepare an STL model for a specific printer
  • Slice models using existing material presets
  • Check model size and print settings
earthtojake/text-to-cad2.3만2026년 10월 22일 업데이트

earthtojake의 스킬 모두 보기

이 스킬의 문제 신고