Script Example Analysis
Um weitere Einblicke in die allgemeinen Aspekte des Scripting-Systems sowie in die Verwendung von Delphi- und X2-Objektmodellen in Skripten zu geben, werden hier zwei Beispielprojekte unter dem Gesichtspunkt ihrer Funktionalität betrachtet – ein Board-Outline-Kopierer und ein Skript zur Netlistenerzeugung.
Die Skripte Board Outline Copier und Netlister wurden unter Verwendung der X2-Objektmodelle entwickelt, um die Möglichkeiten des Scripting-Systems in Altium Designer zu veranschaulichen. Es handelt sich dabei um vorhandene Skripte aus der Beispielskriptsammlung, und zwar wie folgt:
-
Das Skript Board Outline Copier verwendet das PCB-Objektmodell, um die vorhandene PCB-Board-Outline als Tracks und Arcs auf eine angegebene Lage zu kopieren.
Siehe\Scripts\VB Scripts\CopyBoardOutlinePRJ.PRJSCR. -
Das Skript Netlist generator verwendet das WorkSpace Manager Object Model, um eine Netlist im traditionellen Protel-Format (v1 und v2) zu erzeugen.
Siehe\Scripts\Delphiscript Scripts\WSM\Protel Netlister\ScripterProtelNetlist.PRJSCR.
Board Outline Copier Project
Ziel des Board Outline Copier ist es, eine vorhandene Board-Outline aus dem PCB-Dokument auf eine andere Lage im selben Dokument zu kopieren.
Das Projekt verwendet ein Script Form, damit der Benutzer über einen Dialog die Breite der Board-Outline festlegen und ihre Ziellage aus einem Dropdown-Menü auswählen kann. Mithilfe des PCB-Objektmodells und seiner PCB-Schnittstellen aus der PCB-API werden die Objekte einer Board-Outline extrahiert und auf die angegebene Lage kopiert.
VBScript-Projekte gelten inzwischen als Legacy. Um die Erstellung neuer VBScript-Projekte zu aktivieren, markieren Sie die Option Legacy.Scripts.SupportOldLanguages im Dialog Advanced Settings.
Die Dokumentation zur Scripting-API finden Sie hier: Scripting API Objects. Bitte beachten Sie, dass diese Dokumentation zuletzt für eine ältere Version von Altium Designer aktualisiert wurde. Viele der Prinzipien und Vorgehensweisen bleiben zwar gleich, jedoch haben sich Schnittstellen, Objekte, Methoden, Eigenschaften und Ähnliches seitdem geändert und bilden daher nicht den vollständigen Umfang der in neueren Softwareversionen vorhandenen Elemente ab.
Die Hauptbestandteile des Skripts sind:
-
Eine globale Variable
PCB_Boardvom TypIPCB_Board. -
Eine Unterroutine
CopyBoardOutline, die die ParameterAWidthundALayerakzeptiert. -
Der Event-Handler
bOkClick, der die Werte für Breite und Lage aus dem Script Form übernimmt und anschließend die UnterroutineCopyBoardOutlineausführt. -
Der Event-Handler
bCancelClick, der das Board-Outline-Skriptformular (Dialog) schließt.
Skriptfunktionalität
Das Skript verwendet ein Script Form, das Event-Handler benötigt, um die Mausklicks einzelner Steuerelemente wie der Schaltflächen OK und Cancel zu erfassen.
Der Event-Handler der OK-Schaltfläche sieht im Wesentlichen wie folgt aus:
Sub bOKClick(Sender) Dim Width Dim Layer Call StringToCoordUnit(eWidth.Text,Width,PCB_Board.DisplayUnit) Layer = String2Layer(cbLayers.Items(cbLayers.ItemIndex)) End Sub
Hier verwendet der Maus-OnClick-Event-Handler des Formulars (bOKClick) die Funktion StringToCoordUnit, um die eingegebene Breite der Outline (die Zeichenfolge eWidth aus dem TEdit-Feld) in interne Koordinatenwerte umzuwandeln. Diese Funktion wendet die aktuellen Board-Einheiten (Eigenschaft PCB_Board.DisplayUnit) auf die Variable Width an.
Ebenso wird die ausgewählte Lagenzeichenfolge (das Element cbLayers aus der TComboBox des Formulars) an die Funktion String2Layer übergeben, um einen Aufzählungswert für die Variable Layer zu erhalten. Beachten Sie, dass in diesem Projekt die TComboBox des Formulars bereits mit einer indizierten Liste von Lagenzeichenfolgen (cbLayers.Items) vorbelegt ist – siehe die Datei CopyBoardOutlineForm.dfm des Formulars für die Lagenliste.
Im letzten Schritt ruft der Event-Handler (bOKClick) die Unterroutine CopyBoardOutline mit den Variablen Width und Layer als übergebenen Parametern auf. Der Handler für die Schaltfläche Cancel des Formulars (bCancelClick) schließt das Formular einfach.
IPCB_Board-Schnittstelle
Innerhalb des OK-Schaltflächen-Handlers (bOKClick) wird das aktuelle Board über die Schnittstelle IPCB_Board anhand des von der speziellen Funktion PCBServer zurückgegebenen IPCB_ServerInterface ermittelt. Hier setzt die Funktion GetCurrentPCB die aktuelle Board-Referenz auf die Variable PCB_Board.
Die aktuelle Board-Outline (IPC_BoardOutline) wird dann im gesamten Skript über die Eigenschaft BoardOutline der Schnittstelle IPCB_Board unter Verwendung der oben genannten Board-Referenz PCB_Board abgerufen.
Die Board-Outline muss initialisiert werden, bevor mit dem Kopieren und Erstellen einer neuen Outline fortgefahren wird. Eine Outline – dargestellt durch die Schnittstelle IPCB_BoardOutline – kann mithilfe der Rebuild-/Validierungsmethoden der Schnittstelle initialisiert werden.
PCB_Board.BoardOutline.Invalidate PCB_Board.BoardOutline.Rebuild PCB_Board.BoardOutline.Validate
Outline-Arc- und Track-Segmente
Die Schnittstelle IPCB_BoardOutline, die die Board-Outline repräsentiert, wird von der Schnittstelle IPCB_Group abgeleitet. Eine Schnittstelle IPCB_Group repräsentiert ein Gruppenobjekt, das untergeordnete Objekte speichern kann. Ein Beispiel für eine Schnittstelle IPCB_Group ist ein Polygon oder eine Board-Outline, da diese Arcs und Tracks als untergeordnete Objekte speichern können.
Ein Board-Outline-Objekt speichert zwei verschiedene Segmenttypen – ePolySegmentLine und ePolySegmentArc, die jeweils ein Track- bzw. Arc-Objekt repräsentieren. Die Anzahl der Segmente wird durch die Eigenschaft PointCount der Schnittstelle IPCB_BoardOutline bestimmt, die jeden Outline-Vertex für die Schleife For-To-Next in die Variable I extrahiert.
Jedes Segment der ermittelten Board-Outline wird mit der Anweisung If PCB_Board.BoardOutline.Segments(I).Kind = ePolySegmentLine Then auf Tracks und Arcs geprüft. Wenn es sich nicht um ein Track-Segment (ePolySegmentLine) handelt, geht der Teil Else der Anweisung davon aus, dass das Segment ein Arc ist.
Für jedes gefundene Segment wird abhängig vom Segmenttyp mithilfe der Funktion PCBObjectFactory ein neues Track- oder Arc-Objekt erstellt.
Funktion PCBObjectFactory
Die Erstellung der neuen PCB-Objekte erfolgt direkt über die Funktion PCBObjectFactory aus der Schnittstelle IPCB_ServerInterface.
'Create new Track object PCBServer.PCBObjectFactory(eTrackObject, eNoDimension, eCreate_Default) 'Create new Arc object PCBServer.PCBObjectFactory(eArcObject, eNoDimension, eCreate_Default)
Die Parameter der Funktion PCBObjectFactory legen den Objekttyp (Track, Arc, Via usw.), die Dimensionsart (linear, radial usw.) und den Objekterstellungsmodus fest (lokaler Standard oder globale Voreinstellungen).
Nachdem jedes Track- oder Arc-Objekt durch die Prozedur PCBObjectFactory erstellt wurde, werden seine Eigenschaften durch die nachfolgenden Track-/Arc-Anweisungen instanziiert.
Die Eigenschaften von Track und Arc werden durch ihre jeweiligen Schnittstellen IPCB_Track und IPCB_Arc repräsentiert, wobei die relevanten Eigenschaften durch das Skript implementiert werden. So werden beispielsweise die Koordinaten des neuen Tracks aus den Vertexen des Quell-Outline-Segments übernommen, wobei Track.X1 und Track.Y1 die Anfangskoordinaten des Tracks darstellen und die Eigenschaften X2 und Y2 seine Endkoordinaten sind.
Track.X1 = PCB_Board.BoardOutline.Segments(I).vx Track.Y1 = PCB_Board.BoardOutline.Segments(I).vy Track.X2 = PCB_Board.BoardOutline.Segments(J).vx Track.Y2 = PCB_Board.BoardOutline.Segments(J).vy Track.Layer = ALayer Track.Width = AWidth
Wie auch im obigen Codeausschnitt zu sehen ist, werden die Eigenschaften Layer und Width des Tracks einfach durch die übergebenen Werte definiert, die aus dem Dialog der Benutzeroberfläche extrahiert wurden – den Variablen cbLayers und eWidth des Formulars.
Sobald sie vollständig definiert sind, werden die neuen Objekte mit der Anweisung PCB_Board.AddPCBObject(NewObject) zu einer angegebenen Lage des PCB-Dokuments hinzugefügt, wobei NewObject hier Track oder Arc ist.
PreProcess und PostProcess
Beim Erstellen eines PCB-Objekts muss zunächst die Methode PreProcess aus der Objektschnittstelle IPCB_ServerInterface aufgerufen werden, um den PCB-Server vorzubereiten. Nach der Objekterstellung wird die Methode PostPocess (ebenfalls aus der Schnittstelle IPCB_ServerInterface) angewendet, um den Server darüber zu informieren, dass das Hinzufügen der Objekte abgeschlossen ist.
Die Methoden PreProcess und PostProcess halten das Undo-System und andere Subsysteme des PCB-Editors aktuell und synchronisiert. Nachfolgend ist ein repräsentativer Codeausschnitt mit den Anweisungen PreProcess und PostProcess dargestellt.
PCBServer.PreProcess 'Create PCB objects PCBServer.PostProcess
Wenn Objekte zu einer ausgewählten Lage hinzugefügt werden, die im PCB-Dokument nicht angezeigt wurde, muss die Lage zwangsweise sichtbar gemacht werden. Dies wird durch die Anweisung PCB_Board.LayerIsDisplayed(ALayer) = True behandelt, wobei ALayer die vom Benutzer ausgewählte Lage ist.
Dokumentaktualisierung
Abschließend wird das PCB-Dokument mit seiner neuen Board-Outline durch den Befehl PCB:Zoom und die zugehörigen Parameter Action = Redraw aktualisiert. Die Parameter des Zoom-Befehls werden mithilfe der Prozedur AddStringParameter angewendet, nachdem der Parameterpuffer zuvor mit der Methode ResetParameters geleert wurde.
Netlister-Projekt
Ziel dieses Netlister-Skriptprojekts ist es, eine standardmäßige Protel-Netzliste (entweder im Format Version 1 oder Version 2) für ein Altium Designer-Projekt mit Schaltplänen zu erzeugen. Eine flache Netzliste eines Schaltplanprojekts ist in zwei Abschnitte unterteilt:
- Komponentenbezeichner und die mit jeder Komponente verknüpften Informationen,
- Netznamen und die mit jedem Netznamen verknüpften Informationen zusammen mit den Pin-Verbindungen (Pins einer Komponente).
► Beispiel für die Skriptausführung
Das WorkSpace Manager Object Model der API stellt Schnittstellen bereit, die das Projekt und seine Bestandteile repräsentieren – die Dokumente, die Komponenten und ihre Pins sowie die Netze. Der WorkSpace Manager ist ein Systemserver, der eng mit dem Client-Modul gekoppelt ist, das Projekte und die zugehörigen Dokumente verarbeitet. Er bietet Kompilierung, Unterstützung für Multi-Sheet-Designs, Werkzeuge zur Konnektivitätsnavigation, Multi-Channel-Unterstützung, mehrere Implementierungsdokumente und mehr. Um die WorkSpace-Manager-Schnittstelle abzurufen, rufen Sie die Funktion GetWorkspace auf, die die Schnittstelle IWorkspace liefert.
Für das Netlister-Skript sind die Schnittstellen IWorkSpace, IProject, IDocument, IComponent und INet von Interesse.
Beachten Sie, dass einige der Schnittstellen, insbesondere die Designobjekt-Schnittstellen, entsprechenden Schematic-Object-Schnittstellen entsprechen. Das liegt daran, dass die logischen Dokumente in einem Projekt Schaltplandokumente mit Konnektivitätsinformationen sind. Tatsächlich kann das Schematic Object Model anstelle des WorkSpace Managers verwendet werden, letzterer bietet jedoch die Funktionalität, ein Projekt zu kompilieren und Dokumente aus einem Projekt zu extrahieren sowie Daten aus Schaltplanobjekten abzurufen.
Die Hauptbestandteile des Netlister-Skripts sind:
-
Eine globale String-Variable
TargetFileName. Sie ist der Dateiname der Netzliste. -
Ein globales Netlist-Collection-Objekt
TStringList, das mit den Netzlistendaten gefüllt wird. -
Die Prozeduren
WriteComponent_Version1undWriteComponent_Version2. -
Die Prozeduren
WriteNet_Version1undWriteNet_Version2. -
Eine Funktion
ConvertElectricToString, die die elektrische Eigenschaft eines Pins in eine Zeichenfolge umwandelt -
Die Prozedur
GenerateNetlist, die die Datenerzeugung sowie die Verwaltungsaufgaben für Dateiname, Pfad und Verzeichnis übernimmt.
Skriptfunktionalität
Die beiden parameterlosen Prozeduren GenerateProtelV1FormatNetlist und GenerateProtelV2FormatNetlist erscheinen im Dialog Select Item to Run dialog und bieten die Auswahl, eine Netzliste im Protel-V1-Format oder im Protel-V2-Format zu erzeugen. Diese Prozeduren rufen die Prozedur GenerateNetlist mit der Auswahl des Netzlistenformats (0 oder 1) als übergebenem Parameter auf.
Procedure GenerateProtelV1FormatNetlist; Var Version : Integer; Begin // Protel 1 Netlist format, pass 0 GenerateNetlist(0); End; Procedure GenerateProtelV2FormatNetlist; Var Version : Integer; Begin // Protel 2 Netlist format, pass 1 GenerateNetlist(1); End;
GenerateNetList
Die Prozedur GenerateNetList ruft die Workspace-Schnittstelle ab, sodass anschließend die Projektschnittstelle für das aktuelle Projekt extrahiert werden kann (IWorkspace.DM_FocusedProject).
Das Projekt muss kompiliert werden, bevor Netze extrahiert werden können, da der Kompilierungsvorgang die Konnektivitätsinformationen des Projekts aufbaut. Die Methode DM_Compile der Projektschnittstelle wird angewendet (IProject.DM_Compile), wie im folgenden Codeausschnitt gezeigt. Beachten Sie, dass aktuelle Versionen von Altium Designer Projekte automatisch kompilieren, sodass dieser Schritt optional ist.
WS := GetWorkspace; If WS = Nil Then Exit; Prj := WS.DM_FocusedProject; If Prj = Nil Then Exit; // Compile the project to fetch the connectivity info for design. Prj.DM_Compile;
Die Komponenten- und Netzinformationen werden im Netlist-Objekt vom Typ TStringList gespeichert, das später verwendet wird, um eine formatierte Netzlisten-Textdatei zu erzeugen. Das Objekt TStringList ist eine Delphi-Klasse, die in Skripten verwendet werden kann.
Danach wird die Prozedur Generate mit übergebenen Parametern aufgerufen, die den aktuellen Projektpfad und Dateinamen sowie die Versionsnummer des Netzlistenformats definieren.
Generate
Die Prozedur Generate ermittelt den Projektpfad als Ziel-Ausgabepfad für die erzeugte Netzlistendatei (aus dem übergebenen Parameter DocumentPath), bestimmt den Dateinamen der Netzliste (TargetFileName) und prüft den Flattened-Status des Projekts (IProject.DM_DocumentFlattened).
Für alle Schaltplandokumente in einem Projekt wird dann jedes Dokument mit den Prozeduren WriteNets und WriteComponents auf Netze und Komponenten geprüft und schließlich in das Objekt Netlist extrahiert.
Netze und Komponenten schreiben
Eine Netzliste besteht aus Komponenten- und Netzabschnitten, daher sind zwei Prozeduren erforderlich, um Komponentendaten und Netzdaten getrennt zu schreiben.
Nur Netze mit mehr als zwei Knoten werden in eine Netzliste geschrieben; Netze mit weniger Knoten werden verworfen. Für jedes Netz basiert der Netzname auf der Methode DM_CalculatedNetName des Netzes, die die Netznamen aus den Konnektivitätsinformationen des kompilierten Projekts extrahiert.
Nachfolgend sind zwei Codeausschnitte für die Komponenten- und Netzabschnitte einer Netzliste im Netzlistenformat Version 1 dargestellt. Beachten Sie, dass die Komponenten- und Netzdaten im Objekt NetList gespeichert werden, das vom Typ TStringList ist. Die erzeugte Netzliste besteht aus zwei Abschnitten: dem Abschnitt mit den Komponenteninformationen und dem Abschnitt mit den Netzinformationen.
Komponentenabschnitt
In der Prozedur WriteComponent wird jede im Projekt gefundene Komponente darauf geprüft, ob sie eine tatsächliche Komponente ist; anschließend werden der physische Bezeichner, der Footprint und die Part-Type-Werte extrahiert. Diese werden dem Netlist-Objektcontainer (NetList.Add) hinzugefügt, um die Netzliste selbst aufzubauen.
If Component <> Nil Then
Begin
NetList.Add('[');
NetList.Add(Component.DM_PhysicalDesignator);
NetList.Add(Component.DM_FootPrint);
NetList.Add(Component.DM_PartType);
NetList.Add('');
NetList.Add('');
NetList.Add('');
NetList.Add(']');
End;
Netzabschnitt
Für die Nets-Prozedur werden der NetName und die Designators extrahiert, wenn ein Netz zwei oder mehr Pins hat (INet.DM_PinCount). Die Netz- und Pin-Informationen sowie Formatierungszeichen werden dem Container Netlist hinzugefügt, um die Netzliste aufzubauen. Der folgende Ausschnitt ist die Prozedur zum Schreiben von Netzen für die Version-1-Netzliste.
If Net.DM_PinCount >= 2 Then
Begin
NetList.Add('(');
NetList.Add(Net.DM_CalculatedNetName);
For i := 0 To Net.DM_PinCount – 1 Do
Begin
Pin := Net.DM_Pins(i);
PinDsgn := Pin.DM_PhysicalPartDesignator;
PinNo := Pin.DM_PinNumber;
NetList.Add(PinDsgn + '-' + PinNo);
End;
NetList.Add(')');
End;
Beachten Sie, dass das ausführlichere Netzlistenformat Protel v2 die elektrischen Eigenschaften für Netzpins einschließt (In, Out, Passive, HiZ usw.).
Die Prozedur zum Schreiben von Netzen für das Format Version 2 (WriteNet_Version2) fragt daher die elektrische Eigenschaft jedes Netzpins ab (INet.DM_Electical), die dann durch die aufgerufene Prozedur ConvertElectricToString umgewandelt wird – im Wesentlichen eine Lookup-Tabelle zur Zeichenfolgenkonvertierung. Diese werden dann einer lokalen String-Variablen (ElectricalString) hinzugefügt, die wiederum dem Netlist-Containerobjekt hinzugefügt wird.
Netzlistendatei erstellen
Schließlich schreibt die Prozedur Netlist bei vollständig mit den Komponenten- und Netzinformationen des Projekts im gewählten Format gefülltem Containerobjekt Generate die Daten aus Netlist in eine Datei (TStringList.SaveToFile). Dateipfad und Dateiname werden durch die String-Variable TargetFileName definiert, wie in der Prozedur Generate festgelegt.