Zum Inhalt springen

Ein Format-Plugin schreiben

Dieses Tutorial zeigt, wie Sie LinkCAD mit Python um Unterstützung für benutzerdefinierte Dateiformate erweitern.

Format-Reader (Import)

Ein Format-Reader konvertiert ein externes Dateiformat in die Zeichnungsdatenbank von LinkCAD.

Beispiel: Einfacher Reader für Koordinatendateien

from pathlib import Path
from linkcad.plugin import format_reader, FormatReader, Option, DrawingContext
@format_reader(
name="Coordinate File",
extensions=["*.xyz", "*.coord"],
description="Simple X Y coordinate files",
)
class CoordReader(FormatReader):
scale = Option.integer("Scale factor", default=1000, min=1, max=1000000)
layer_name = Option.string("Layer name", default="imported")
def read(self, path: Path, drawing: DrawingContext) -> None:
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()
x = float(parts[0]) * self.scale
y = float(parts[1]) * self.scale
vertices.append((x, y))
# Don't forget the last polygon
if vertices:
layer.polygon(vertices)

Schlüsselkonzepte

  • @format_reader() registriert die Klasse als Importformat
  • extensions legt fest, welche Dateien der Reader verarbeitet
  • DrawingContext stellt eine Builder-API zum Erstellen von Zellen, Ebenen und Formen bereit
  • drawing.iter_lines() liest Zeilen mit automatischer Fortschrittsverfolgung
  • drawing.iter_binary() liest Binärdaten mit Fortschrittsverfolgung

DrawingContext-API

MethodeBeschreibung
cell(name, main=False)Kontextmanager — erstellt/öffnet eine Zelle
iter_lines(path)Textdateizeilen mit Fortschritt durchlaufen
iter_binary(path, chunk_size)Binäre Blöcke mit Fortschritt durchlaufen
progressFortschritt abrufen/festlegen (0,0 bis 1,0)

CellContext-API

MethodeBeschreibung
layer(name)Kontextmanager — wählt eine Ebene aus

LayerContext-API

MethodeBeschreibung
polygon(vertices)Erstellt ein Polygon aus (x, y)-Tupeln
polyline(width, vertices, closed)Erstellt eine Polylinie
circle(center, diameter)Erstellt einen Kreis

Format-Writer (Export)

Ein Format-Writer exportiert LinkCAD-Geometrie in eine Datei.

Beispiel: Einfacher Text-Writer

from pathlib import Path
from linkcad.plugin import format_writer, FormatWriter, Option, WriterContext
@format_writer(
name="Simple Text",
extensions=["*.stxt"],
)
class SimpleWriter(FormatWriter):
separator = Option.choice(
"Separator",
choices=["Space", "Comma", "Tab"],
default="Space",
)
precision = Option.integer("Decimal places", default=3, min=0, max=10)
def write(self, path: Path, drawing: WriterContext) -> None:
sep = {"Space": " ", "Comma": ", ", "Tab": "\t"}[self.separator]
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")

WriterContext-API

MethodeBeschreibung
shapes(cell, layer)Alle Formen durchlaufen (optionaler Zellen-/Ebenenfilter)
shapes_by_layer(cell)Formen gruppiert nach Ebene durchlaufen
shapes_by_cell(layer)Formen gruppiert nach Zelle durchlaufen
cells()Zellennamen durchlaufen
layers()Ebenennamen durchlaufen
cell_count()Anzahl der Zellen
shape_count()Gesamtanzahl der Formen
main_cell_name()Name der Top-Zelle
layer_names()Liste aller Ebenennamen
flattenHierarchie-Reduzierung abrufen/festlegen
progressFortschritt abrufen/festlegen (0,0 bis 1,0)

ShapeInfo-Eigenschaften

EigenschaftTypBeschreibung
layer_namestrEbenenname
cell_namestrZellenname
verticeslist[tuple]Liste von (x, y)-Koordinaten
is_polygonboolTrue für Polygone, False für Polylinien
widthintPolylinienbreite (0 für Polygone)
is_closedboolGibt an, ob die Form geschlossen ist

Fehlerbehandlung

Verwenden Sie die integrierten Exception-Klassen für klare Fehlermeldungen:

from linkcad.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