Zum Inhalt springen

← Blog

DWG-Zeichnungen mit Python automatisieren (und mit AutoLISP oder MCP)

· Anleitungen

Die Programmoberfläche und die Hilfe sind auf Englisch und Spanisch verfügbar. Befehle und Optionen stehen hier so, wie sie in der englischen Version des Programms heißen.

In jedem Projekt dasselbe Achsraster zeichnen, Blöcke in hundert Plänen zählen oder auf den richtigen Layer verschieben, was jemand auf Layer 0 gelassen hat: Das sind Aufgaben, die sich wiederholen. LinceCAD lässt sich über eine lokale API von außen steuern: Ein Python-Skript öffnet Zeichnungen, erzeugt Objekte, ändert Layer, führt Befehle aus und speichert als DWG. Alles läuft über Kanäle auf dem eigenen Rechner; nichts geht ins Internet.

Vier Wege, je nach Bedarf

WegWas es istWann man ihn nutzt
Lokale API (JSON-RPC)Eine JSON-Nachricht pro Zeile über eine Named Pipe (Windows) oder einen Socket (Linux). Funktioniert aus jeder Sprache.LinceCAD aus eigenen Programmen steuern, mit oder ohne geöffnetes Fenster.
Python-Client linceEine Bibliothek ohne Abhängigkeiten auf dieser API: dib.linea(…), dib.guardar_como(…)…Kürzere, besser lesbare Python-Skripte.
Wheel lince_nucleoEin kompiliertes Python-Modul, das DWG/DXF liest, ändert und speichert, ohne LinceCAD zu öffnen.Dateistapel, Server oder Jupyter.
AutoLISPDer eingebaute Interpreter mit rund 200 Funktionen.Eigene Befehle im Programm oder vorhandene LISP-Routinen.

Außerdem bringt LinceCAD einen MCP-Server zum Anbinden von KI-Assistenten mit, um den es am Ende geht.

Schritt 1: Automatisierung aktivieren

Die API ist standardmäßig deaktiviert. Es gibt zwei Arten, sie zu nutzen:

Programme weisen sich mit einem Token aus (einem Passwort mit 64 Zeichen), das in api.toml steht, unter %APPDATA%\lince in Windows oder ~/.config/lince in Linux. Nur Ihr Benutzer kann es lesen.

Schritt 2: ein Skript mit der Standardbibliothek

Dieses Beispiel braucht außer Python nichts weiter. Starten Sie vorher lince --servidor --canal blogpy (oder nutzen Sie den Kanal des geöffneten Fensters). Das Skript meldet sich mit dem Token an, erzeugt eine Zeichnung, einen Layer und ein Flurstück von 30 × 20 und speichert es als DWG:

import json, os

# Das Token (Passwort der API) steht in %APPDATA%\lince\api.toml
toml = os.path.join(os.environ["APPDATA"], "lince", "api.toml")
ficha = next(l.split("=", 1)[1].strip().strip('"')
             for l in open(toml, encoding="utf-8") if l.startswith("ficha"))

canal = open(r"\\.\pipe\blogpy", "r+b", buffering=0)  # lince --servidor --canal blogpy
n = 0

def llamar(metodo, **params):
    global n
    n += 1
    msg = {"jsonrpc": "2.0", "id": n, "method": metodo, "params": params}
    canal.write((json.dumps(msg) + "\n").encode("utf-8"))
    r = json.loads(canal.readline())
    if "error" in r:
        raise RuntimeError(r["error"]["message"])
    return r["result"]

llamar("session.hello", token=ficha)
llamar("document.new")
llamar("layer.create", name="PARCELA", color=1)
llamar("entity.create", entity={"type": "LWPOLYLINE", "layer": "PARCELA", "closed": True,
                                "vertices": [[0, 0], [30, 0], [30, 20], [0, 20]]})
print(llamar("document.summary")["byType"])         # {'LWPOLYLINE': 1}
print(llamar("document.saveAs", path=r"C:\planos\parcela.dwg"))

Die erste Anfrage jeder Verbindung muss session.hello sein; sonst wird die Verbindung geschlossen. Unter Linux verbinden Sie statt open() einen socket.AF_UNIX mit dem Socket-Pfad und verwenden s.makefile("rwb", buffering=0); der Rest bleibt gleich.

Die API hat Methoden für Zeichnungen (document.open, save, saveAs, summary…), Objekte (entity.query, get, create, set, delete, als Objekte oder als DXF-Listen von entget), Layer, Blöcke, Stile, Variablen, Auswahl, Rückgängig, Befehle (command.run), AutoLISP (lisp.eval), Plotten als PDF, PNG und SVG, Ansichtserfassung und Ereignisse. document.saveAs speichert je nach Endung als DWG oder DXF, standardmäßig in Version 2018 oder in 2013, 2010, 2007, 2004, 2000 und R14.

Schritt 3: dasselbe mit dem Python-Client

Der Client lince verpackt diese API in Objekte. Dieses Skript startet mit lince.iniciar() LinceCAD ohne Fenster, zeichnet ein Achsraster mit Beschriftungen und zwölf Stützen von 30 × 30 cm und speichert das DWG, ein PDF und ein Bild:

import lince

ejes_x = [0, 5.0, 10.5, 16.0]      # Lage der Achsen, in Metern
ejes_y = [0, 4.5, 9.0]
h = 0.15                            # halbe Seitenlänge einer Stütze von 30 x 30 cm

with lince.iniciar() as s:          # startet LinceCAD ohne Fenster
    dib = s.nuevo()
    dib.crear_capa("EJES", color=1)
    dib.crear_capa("PILARES", color=7)
    dib.crear_capa("ROTULOS", color=3)
    with dib.transaccion():         # alles in einem einzigen Rückgängig-Schritt
        for i, x in enumerate(ejes_x):
            dib.linea([x, -1.5], [x, ejes_y[-1] + 1.5], layer="EJES")
            dib.texto([x - 0.15, ejes_y[-1] + 2], str(i + 1), altura=0.4, layer="ROTULOS")
        for j, y in enumerate(ejes_y):
            dib.linea([-1.5, y], [ejes_x[-1] + 1.5, y], layer="EJES")
            dib.texto([-2.3, y - 0.2], "ABC"[j], altura=0.4, layer="ROTULOS")
        for x in ejes_x:
            for y in ejes_y:
                dib.polilinea([[x - h, y - h], [x + h, y - h], [x + h, y + h], [x - h, y + h]],
                              cerrada=True, layer="PILARES")
    print(dib.resumen()["byType"])  # {'LINE': 7, 'LWPOLYLINE': 12, 'TEXT': 7}
    dib.trazar_pdf(r"C:\planos\ejes.pdf")
    dib.guardar_como(r"C:\planos\ejes.dwg")
    dib.captura(r"C:\planos\ejes.png", ancho=1280)
Raster aus vier senkrechten Achsen (1 bis 4) und drei waagerechten (A bis C) in Rot, mit zwölf quadratischen Stützen an den Kreuzungen und den Achsbeschriftungen in Grün, auf weißem Grund.
Das Bild, das das Skript mit dib.captura speichert.

Um mit dem bereits geöffneten Fenster zu arbeiten, verwendet man lince.conectar() und s.dibujo (die aktive Zeichnung). Außerdem gibt es .circulo, .arco, .mtexto, .insertar (Blöcke), .consultar (nach Typ, Layer, Box oder Filter), .comando, .lisp und .trazar_png/.trazar_svg.

Ohne LinceCAD zu öffnen: das Wheel lince_nucleo

Für viele Dateien arbeitet das Wheel lince_nucleo direkt im Python-Prozess. Dieses Fragment aus der Dokumentation listet die Kreise eines Plans auf und speichert ihn als DWG 2018:

import lince_nucleo as ln
dib = ln.abrir("plano.dwg")
for e in dib.consultar(tipo="CIRCLE"):
    print(e["handle"], e["radius"])
dib.guardar("salida.dwg", "2018")

Die Alternative ohne Python: AutoLISP

Wenn Sie bereits mit LISP arbeiten, können Sie dabei bleiben. Der Interpreter von LinceCAD unterstützt unter anderem defun C:, ssget mit Filtern, entget, entmod, entmake und command; Routinen werden mit APPLOAD oder automatisch aus acaddoc.lsp geladen. Dieser Befehl zählt die Stützen im vorigen Plan:

(defun C:CONTARPILARES (/ ss)
  (setq ss (ssget "X" '((0 . "LWPOLYLINE") (8 . "PILARES"))))
  (princ (strcat "\nPilares: " (itoa (if ss (sslength ss) 0))))
  (princ)
)

Auf ejes.dwg antwortet er „Pilares: 12“ (Stützen: 12). Für feste Befehlsfolgen gibt es außerdem Skripte (SCRIPT).

KI-Assistenten mit MCP

lince --mcp ist ein MCP-Server (Model Context Protocol) über Standardein- und -ausgabe, für Assistenten, die ihn selbst starten. Bei geöffnetem Fenster lässt sich zusätzlich ein MCP-Server über HTTP aktivieren, nur auf 127.0.0.1. Der Assistent sieht Werkzeuge zum Öffnen, Abfragen, Erstellen, Bemaßen, Einfügen von Blöcken, Plotten als PDF, Erfassen der Ansicht und Rückgängigmachen, dazu die Hilfe von LinceCAD als Dokumentation. So melden Sie ihn zum Beispiel in Claude Code an:

claude mcp add --scope project lince -- "C:\Program Files\lince\lince.exe" --mcp

Mit aktivierter Bestätigung wartet jede Änderung, die der Assistent anfordert, in der Palette AIACTIONS, bis Sie sie annehmen oder ablehnen, und alles, was ein Aufruf tut, lässt sich mit einem einzigen UNDO zurücknehmen.

Einschränkungen

Häufige Fragen

Und wenn der Ausgangsplan ein Scan ist? Dann muss er zuerst in Vektoren umgewandelt werden: Das erklären wir in einen gescannten Plan vektorisieren und in DWG umwandeln.

Und unter Linux? Die API funktioniert genauso, mit einem Unix-Socket. Lesen Sie DWG unter Linux öffnen und bearbeiten.

Und für die Vermessung? Der Ablauf mit der Registerkarte Topography steht in Höhenlinien aus einer LAS/LAZ-Punktwolke.

Die lokale API, AutoLISP und der MCP-Server sind in LinceCAD enthalten, mit unbefristeter Lizenz. Download · Preise ansehen · AutoLISP, Automatisierung und alle weiteren Funktionen.