Vai al contenuto

← Blog

Automatizzare disegni DWG con Python (e con AutoLISP o MCP)

· Guide

L’interfaccia del programma e la guida sono disponibili in inglese e in spagnolo. I comandi e le opzioni sono riportati qui come nella versione inglese del programma.

Disegnare la stessa griglia di assi in ogni progetto, contare i blocchi in cento disegni o mettere sul layer giusto ciò che qualcuno ha lasciato sul layer 0 sono compiti che si ripetono. LinceCAD si può comandare dall’esterno con un’API locale: uno script Python apre disegni, crea entità, cambia layer, esegue comandi e salva in DWG. Tutto passa per canali del computer stesso; nulla esce verso Internet.

Quattro strade, a seconda di ciò che ti serve

ViaChe cos’èQuando usarla
API locale (JSON-RPC)Un messaggio JSON per riga tramite una named pipe (Windows) o un socket (Linux). Funziona da qualsiasi linguaggio.Comandare LinceCAD, con la finestra aperta o senza, dai tuoi programmi.
Client lince per PythonUna libreria senza dipendenze sopra quell’API: dib.linea(…), dib.guardar_como(…)…Script Python più brevi e leggibili.
Wheel lince_nucleoUn modulo Python compilato che legge, modifica e salva DWG/DXF senza aprire LinceCAD.Lotti di file, server o Jupyter.
AutoLISPL’interprete integrato, con circa 200 funzioni.Comandi propri dentro il programma, o routine LISP che hai già.

Inoltre LinceCAD include un server MCP per collegare assistenti IA, di cui parliamo alla fine.

Passo 1: attivare l’automazione

L’API è disattivata per impostazione predefinita. Ci sono due modi per usarla:

I programmi si identificano con un token (una password di 64 caratteri) che si trova in api.toml, in %APPDATA%\lince su Windows o ~/.config/lince su Linux. Solo il tuo utente può leggerlo.

Passo 2: uno script con la libreria standard

Questo esempio non richiede di installare nulla oltre a Python. Avvia prima lince --servidor --canal blogpy (o usa il canale della finestra aperta). Lo script si presenta con il token, crea un disegno, un layer e una particella di 30 × 20 e la salva in DWG:

import json, os

# Il token (la password dell'API) si trova 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"))

La prima richiesta di ogni connessione deve essere session.hello; altrimenti la connessione viene chiusa. Su Linux, invece di open(), collega un socket.AF_UNIX al percorso del socket e usa s.makefile("rwb", buffering=0); il resto è uguale.

L’API ha metodi per i disegni (document.open, save, saveAs, summary…), le entità (entity.query, get, create, set, delete, come oggetti o come liste DXF di entget), layer, blocchi, stili, variabili, selezione, annulla, comandi (command.run), AutoLISP (lisp.eval), stampa in PDF, PNG e SVG, cattura della vista ed eventi. document.saveAs salva in DWG o DXF in base all’estensione, nella versione 2018 per impostazione predefinita oppure in 2013, 2010, 2007, 2004, 2000 e R14.

Passo 3: lo stesso con il client Python

Il client lince avvolge quell’API in oggetti. Questo script, con lince.iniciar(), avvia LinceCAD senza finestra, disegna una griglia di assi con le loro etichette e dodici pilastri di 30 × 30 cm, e salva il DWG, un PDF e un’immagine:

import lince

ejes_x = [0, 5.0, 10.5, 16.0]      # posizione degli assi, in metri
ejes_y = [0, 4.5, 9.0]
h = 0.15                            # metà lato di un pilastro di 30 x 30 cm

with lince.iniciar() as s:          # avvia LinceCAD senza finestra
    dib = s.nuevo()
    dib.crear_capa("EJES", color=1)
    dib.crear_capa("PILARES", color=7)
    dib.crear_capa("ROTULOS", color=3)
    with dib.transaccion():         # tutto in un solo passo di annullamento
        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)
Griglia di quattro assi verticali (da 1 a 4) e tre orizzontali (da A a C) in rosso, con dodici pilastri quadrati negli incroci e le etichette degli assi in verde, su fondo bianco.
L’immagine che lo script salva con dib.captura.

Per lavorare con la finestra già aperta si usano lince.conectar() e s.dibujo (il disegno attivo). Ci sono anche .circulo, .arco, .mtexto, .insertar (blocchi), .consultar (per tipo, layer, riquadro o filtro), .comando, .lisp e .trazar_png/.trazar_svg.

Senza aprire LinceCAD: la wheel lince_nucleo

Per elaborare molti file, la wheel lince_nucleo lavora dentro lo stesso processo Python. Questo frammento, tratto dalla documentazione, elenca i cerchi di un disegno e lo salva in 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")

L’alternativa senza Python: AutoLISP

Se lavori già con il LISP, puoi continuare a farlo. L’interprete di LinceCAD supporta defun C:, ssget con filtri, entget, entmod, entmake e command, tra le altre; le routine si caricano con APPLOAD o automaticamente da acaddoc.lsp. Questo comando conta i pilastri del disegno precedente:

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

Su ejes.dwg risponde «Pilares: 12» (pilastri: 12). Per sequenze fisse di comandi ci sono anche gli script (SCRIPT).

Assistenti IA con MCP

lince --mcp è un server MCP (Model Context Protocol) su standard input e output, per gli assistenti che lo avviano da sé. Con la finestra aperta si può attivare anche un server MCP via HTTP, solo su 127.0.0.1. L’assistente vede strumenti per aprire, interrogare, creare, quotare, inserire blocchi, stampare in PDF, catturare la vista e annullare, e la guida di LinceCAD come documentazione. Per esempio, per registrarlo in Claude Code:

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

Con la conferma attivata, ogni modifica chiesta dall’assistente attende nella palette AIACTIONS finché non la accetti o la rifiuti, e tutto ciò che fa una chiamata si annulla con un solo UNDO.

Limiti

Domande frequenti

E se il disegno di partenza è una scansione? Prima va trasformato in vettori: lo spieghiamo in come vettorializzare un disegno scansionato e convertirlo in DWG.

E su Linux? L’API funziona allo stesso modo, con un socket Unix. Leggi aprire e modificare file DWG su Linux.

E per la topografia? Il procedimento con la scheda Topography è in curve di livello da una nuvola di punti LAS/LAZ.

L’API locale, AutoLISP e il server MCP sono inclusi in LinceCAD, con licenza perpetua. Download · Vedi i prezzi · AutoLISP, automazione e tutte le altre funzionalità.