DWG-Zeichnungen mit Python automatisieren (und mit AutoLISP oder MCP)
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
| Weg | Was es ist | Wann 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 lince | Eine Bibliothek ohne Abhängigkeiten auf dieser API: dib.linea(…), dib.guardar_como(…)… | Kürzere, besser lesbare Python-Skripte. |
Wheel lince_nucleo | Ein kompiliertes Python-Modul, das DWG/DXF liest, ändert und speichert, ohne LinceCAD zu öffnen. | Dateistapel, Server oder Jupyter. |
| AutoLISP | Der 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:
- Mit geöffnetem Fenster: Aktivieren Sie in
OPTIONS, Registerkarte Automation (Automatisierung), den lokalen Kanal. Dort können Sie sie auch auf Nur-Lesen stellen und die Ordner einschränken, in denen geöffnet, gespeichert und geplottet werden darf. Der Kanal ist\\.\pipe\lince-<Benutzer>unter Windows und$XDG_RUNTIME_DIR/lince.sockunter Linux. - Ohne Fenster:
lince --servidorbedient die API ohne sichtbare Oberfläche, für Stapelprozesse. Mit--canal NAMEwählen Sie den Namen der Pipe. Unter Linux braucht es eine grafische Sitzung (oderxvfb-run).
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)

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
- Nur lokal. Die API bedient Programme auf demselben Rechner; die Pipe weist entfernte Clients ab,
und HTTP lauscht nicht außerhalb von
127.0.0.1. - Eine Anfrage nach der anderen pro Verbindung und keine JSON-RPC-Batches. Für paralleles Arbeiten öffnen Sie mehrere Verbindungen.
- Objekte im Modellbereich. Bemaßungen sind über
entity.createnur lesbar: Sie werden mitcommand.runoder dem MCP-Werkzeugadd_dimensionerzeugt. True Color wird gelesen, aber nicht geschrieben. - Keine Rückfragen an den Benutzer.
lisp.evalschlägt fehl, wenn die Routine Eingaben verlangt (getpoint,entsel…), und der fensterlose Modus öffnet keine Dialogfelder. - Das Wheel führt keine Befehle aus, auch kein AutoLISP, keine Plots und keine Erfassungen: Das übernehmen der Client oder das Fenster.
- Python-Pakete in der Beta. API und MCP-Server sind in
lince.exeenthalten. Die Paketelinceundlince_nucleowerden noch nicht auf PyPI veröffentlicht und auch nicht mit dem Installationsprogramm ausgeliefert (das Paket, das auf PyPI derzeitlinceheißt, gehört zu einem anderen Projekt); das Beispiel aus Schritt 2 funktioniert ohne sie.
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.