Ein Format-Plugin schreiben
Dieses Tutorial zeigt, wie Sie LinkCAD mit Python um Unterstützung für eigene Dateiformate erweitern.
Format-Reader (Import)
Ein Format-Reader überführt ein externes Dateiformat in die Zeichnungsdatenbank von LinkCAD.
Beispiel: einfacher Koordinatendatei-Reader
from pathlib import Pathfrom linkcad.v1.plugin import format_reader, FormatReader, Option, DrawingContext
@format_reader( name="Coordinate File", extensions=["*.xyz", "*.coord"], description="Simple X Y coordinate files",)class CoordReader(FormatReader): units = Option.choice( "Units", choices=["nm", "um", "mil", "mm", "cm", "inch", "m"], default="um", tooltip="Physical units of the coordinate values in the file", ) layer_name = Option.string("Layer name", default="imported")
def read(self, path: Path, drawing: DrawingContext) -> None: # Name the unit once and LinkCAD converts every coordinate you hand it. drawing.units = self.units
with drawing.cell(path.stem, main=True) as cell: with cell.layer(self.layer_name) as layer: vertices = [] for line in drawing.iter_lines(path): line = line.strip() if not line or line.startswith("#"): # Blank line = end of polygon if vertices: layer.polygon(vertices) vertices = [] continue parts = line.split() vertices.append((float(parts[0]), float(parts[1])))
# Don't forget the last polygon if vertices: layer.polygon(vertices)Kernkonzepte
@format_reader()registriert die Klasse als Importformatextensionsbestimmt, welche Dateien der Reader verarbeitetDrawingContextstellt eine Builder-API zum Erzeugen von Zellen, Ebenen und Formen bereitdrawing.unitsbenennt die Einheit Ihrer Koordinaten, sodass Sie nie von Hand skalieren müssendrawing.iter_lines()liest Zeilen mit automatischer Fortschrittsanzeigedrawing.iter_binary()liest Binärdaten mit Fortschrittsanzeige
Arbeitseinheiten
Wird drawing.units einmal gesetzt, sind alle Koordinaten und Breiten, die Sie übergeben, in dieser Einheit zu verstehen. Zulässig sind nm, um, mil, mm, cm, inch und m sowie die naheliegenden Aliasse (micron, millimetre, in, …).
Bleibt der Wert ungesetzt, gelten reine Datenbankeinheiten — genau wie vor Einführung der Eigenschaft. Ein unbekannter Name oder eine Zeichnung ohne deklarierte Datenbankeinheiten löst ValidationError aus.
Ein Reader, der Koordinaten mit einer eigenen Skalierungstabelle multipliziert, ist veraltet — löschen Sie die Tabelle und benennen Sie stattdessen die Einheit.
DrawingContext-API
| Eigenschaft / Methode | Beschreibung |
|---|---|
units | Einheit Ihrer Koordinaten; None für reine Datenbankeinheiten |
cell(name, main=False) | Kontextmanager — erzeugt bzw. öffnet eine Zelle |
iter_lines(path, encoding="utf-8") | Textzeilen mit Fortschrittsanzeige durchlaufen |
iter_binary(path, chunk_size=8192) | Binärblöcke mit Fortschrittsanzeige durchlaufen |
progress | Fortschritt lesen/setzen (0.0 bis 1.0) |
CellContext-API
| Methode | Beschreibung |
|---|---|
layer(name) | Kontextmanager — wählt eine Ebene aus |
LayerContext-API
Koordinaten sind in der Arbeitseinheit der Zeichnung angegeben.
| Methode | Beschreibung |
|---|---|
polygon(vertices) | Geschlossenes Polygon aus (x, y)-Tupeln erzeugen |
polyline(width, vertices, closed=False) | Polylinie erzeugen |
circle(center, diameter) | Kreis erzeugen |
Nachbearbeitungs-Hook
Ein Reader kann optional post_process() definieren, um an den Phasen teilzunehmen, die LinkCAD nach dem Parsen durchläuft — derselbe Hook, den auch die eingebauten nativen Reader verwenden. Er läuft auf derselben Instanz wie read(), sodass dort Notiertes weiterhin verfügbar ist. Ein False bricht den Import ab.
from linkcad.v1.plugin import Phase
class CoordReader(FormatReader): def post_process(self, phase, drawing, resolution) -> bool: if phase == Phase.ResolvedRefs: ... # every reference now points at a real cell return TrueDie Phasen kommen in dieser Reihenfolge: ParsedFile, ParsedAll, ClosedOpenCells, ResolvedRefs, SelectedMainCell, ResolvedLayersByBlock, AutoNumberedZ.
Format-Writer (Export)
Ein Format-Writer schreibt LinkCAD-Geometrie in eine Datei.
Beispiel: einfacher Text-Writer
from pathlib import Pathfrom linkcad.v1.plugin import format_writer, FormatWriter, Option, WriterContext
@format_writer( name="Simple Text", extensions=["*.stxt"],)class SimpleWriter(FormatWriter): units = Option.choice( "Output units", choices=["nm", "um", "mil", "mm", "cm", "inch", "m"], default="um", ) separator = Option.choice( "Separator", choices=["Space", "Comma", "Tab"], default="Space", ) precision = Option.integer("Decimal places", default=3, min=0, max=10) flatten = Option.boolean("Flatten hierarchy", default=False)
def write(self, path: Path, drawing: WriterContext) -> None: sep = {"Space": " ", "Comma": ", ", "Tab": "\t"}[self.separator]
# Name the unit once and every coordinate arrives already converted. drawing.units = self.units drawing.flatten = self.flatten
with open(path, "w") as f: for layer_name, shapes in drawing.shapes_by_layer(): f.write(f"# Layer: {layer_name}\n") for shape in shapes: for x, y in shape.vertices: f.write(f"{x:.{self.precision}f}{sep}" f"{y:.{self.precision}f}\n") f.write("\n")Arbeitseinheiten und Reduzieren
drawing.units funktioniert für Writer genauso wie für Reader, nur in die andere Richtung: einmal gesetzt, kommt jede Koordinate und Breite aus shapes() bereits in dieser Einheit an. Ein Writer, der durch eine eigene Skalierungstabelle dividiert, ist veraltet.
drawing.flatten wählt die Traversierung. Setzen Sie den Wert vor dem Iterieren:
flatten = Falsedurchläuft die Formen jeder Zelle und überlässt Ihnen die Zellenreferenzen. Kurven kommen ohne Stützpunkte zurück, weil ihre Tesselierung den Host erfordert.flatten = Truelässt den Host die Hierarchie rendern; dieser wendet dabei den Transformationsstapel an und tesseliert Kurven unterwegs. Kreisbögen, Kreise, Ringe und NURBS erreichen einen Writer daher nur bei aktiviertem Reduzieren als Polygone und Polylinien.
In beiden Fällen ist shapes() die einzige Traversierung — einen separaten Iterator für reduzierte Geometrie gibt es nicht.
WriterContext-API
| Eigenschaft / Methode | Beschreibung |
|---|---|
units | Einheit, in der Sie die Geometrie erhalten; None für reine Datenbankeinheiten |
flatten | Reduzieren der Hierarchie lesen/setzen. Vor dem Iterieren setzen |
shapes(cell=None, layer=None) | Formen durchlaufen (optionaler Zellen-/Ebenenfilter) |
shapes_by_layer(cell=None) | Formen nach Ebene gruppiert durchlaufen |
shapes_by_cell(layer=None) | Formen nach Zelle gruppiert durchlaufen |
cell_names / layer_names | Listen aller Zellen- bzw. Ebenennamen |
cell_count | Anzahl der Zellen |
shape_count | Gesamtzahl der Formen |
main_cell_name | Name der Top-Zelle |
progress | Fortschritt lesen/setzen (0.0 bis 1.0) |
ShapeInfo-Eigenschaften
| Eigenschaft | Typ | Beschreibung |
|---|---|---|
layer_name | str | Ebenenname |
cell_name | str | Zellenname |
vertices | list[tuple] | (x, y)-Koordinaten in der Arbeitseinheit |
is_polygon | bool | True für Polygone, False für Polylinien |
width | int | Polylinienbreite in der Arbeitseinheit (0 für Polygone) |
is_closed | bool | Ob die Form geschlossen ist |
Fehlerbehandlung
Verwenden Sie die eingebauten Ausnahmeklassen für klare Fehlermeldungen:
from linkcad.v1.plugin import ParseError, WriteError, ValidationError
# In a reader:raise ParseError("Invalid coordinate", line=42, path=path)
# In a writer:raise WriteError("Cannot write to locked file")
# In option validation:raise ValidationError("Scale must be positive")Nächste Schritte
- Tutorial zur Panel-Zusammenstellung — fortgeschrittenes Tool mit Tabellenoptionen
- Referenz der Format-Dekoratoren — vollständige Dekorator-API