Ich hasse es, meine eigene Frage zu beantworten, aber jetzt gehe ich. Ich hoffe, ich bekomme keine Punkte für die Beantwortung, das wäre komisch, nur für die Annahme einer Antwort? (Übrigens habe ich im Element14-Forum keine Antwort erhalten.)
Die Lösung besteht darin, den Befehl DRAW und nicht ROUTE zu verwenden. DRAW platziert ein Kabelsegment genau dort, wo Sie es angegeben haben (im Gegensatz zu ROUTE, bei dem versucht wird, eine Verbindung zu einem nicht gerouteten Airwire herzustellen. ROUTE ist in einem Skript im Wesentlichen nutzlos.). Das nächste Problem ist die Via: Ich kann (oder möchte) nicht zwischen einer manuellen Via und einer autorisierten Via unterscheiden, daher behalte ich alle Via, die zwei (oder mehr) manuelle Kabelsegmente verbinden. Andere Via werden gelöscht.
Was mein letztes Skript macht, ist:
prepare a ripup command
for all copper segments that are not 0.01 wide (the width I use for autorouting)
check both endpoints for a via at that location
prepare the via to be resurrected when it is visited the 2nd time
prepare a command that resurrects the copper segment
execute the prepared commands
Beachten Sie, dass es wahrscheinlich nicht für mehr als zwei Schichten oder für andere Dinge als Drahtsegmente an der Kupferschicht funktioniert.
IMHO ist das gesamte Konzept der Adler-ULP und der Befehlssprachen problematisch. Ein ULP wird in einer schreibgeschützten Umgebung ausgeführt. Die einzige Möglichkeit, die Schaltung, Karte oder Bibliothek zu beeinflussen, besteht darin, eine Liste von Befehlen zu erstellen. Dies eliminiert einige nützliche Programmiertechniken, aber schlimmer ist, dass die Befehle nicht so konzipiert wurden, dass sie einfach aus einem ULP erstellt werden können. Sie benötigen alle Arten von Transformationen (in diesem Fall: Koordinaten, Formnamen), um von der ULP-Welt in die CMD-Welt zu übersetzen.
(Bearbeiten) Bevor Sie dieses ULP ausführen, stellen Sie die Auswahl "Drahtbiegung" so ein, dass beliebige Winkel zulässig sind. Andernfalls versucht Eagle, die auferstandenen Drähte an die zulässigen Winkel anzupassen, was zu einem blutigen Durcheinander führen kann. IMHO ist dies ein weiteres Beispiel für das Problem mit ULP / SCR.
Dies ist der ULP-Code:
// gather the commands that must be run on exit
string RunOnExit = "";
void cmd( string s ) { RunOnExit += s + "\n"; }
// return an x or y position in the form that can be used in a command
real f( int x ){
board( B ) switch( B.grid.unit ) {
case 0: return u2mic(x);
case 1: return u2mm(x);
case 2: return u2mil(x);
case 3: return u2inch(x);
}
}
// return the string form of the a via's shape
string sn( int x ){
if( x == VIA_SHAPE_SQUARE ) return "square";
if( x == VIA_SHAPE_ROUND ) return "round";
if( x == VIA_SHAPE_OCTAGON ) return "octagon";
if( x == VIA_SHAPE_ANNULUS ) return "annulus";
if( x == VIA_SHAPE_THERMAL ) return "thermal";
return "unknown-via-shape";
}
// count the number of times x occurs in s
int n_ocurrences( string s, string x ){
int i, n = 0;
while( 1 ){
i = strstr( s, x );
if( i == -1 ) return n;
s = strsub( s, i + strlen( x ));
n++;
}
}
// add a via, but only when it is visited the second time
string via_list = "";
void add_via( int a, int b ){
// for all via's
board( B ) B.signals( S ) S.vias( V ){
// if the via is at the current location
if(( V.x == a ) && ( V.y == b )){
string s, coo;
// the coordinates of the via are used as its identification
sprintf( coo, "(%.6f %.6f)", f( V.x ), f( V.y ));
// if this is the second visit to this via
via_list += coo;
if( n_ocurrences( via_list, coo ) == 2 ){
// resurrect this via
sprintf( s, "VIA '%s' %f %s %s;",
S.name, f( V.drill ), sn( V.shape[ 1 ] ), coo );
cmd( s );
}
}
}
}
if( !board ){
dlgMessageBox("start this ULP in Board", "OK");
exit( 0 );
}
board( B ){
// first delete all coper segments,
// later we will resurrect what we want to keep
cmd( "RIPUP;" );
// for all wire segments in the top and bottom copper layers
B.signals(S) S.wires(W) {
if( ( W.layer == 1 ) || ( W.layer == 16 ) ){
// that are not 0.01 width (that is what the autorouter uses)
if( f( W.width ) != 0.01 ){
string s;
// resurrect via's adjacent to this wire segment
add_via( W.x1, W.y1 );
add_via( W.x2, W.y2 );
sprintf( s, "CHANGE LAYER %d;", W.layer );
cmd( s );
// resurrect this wire segment
sprintf(
s, "WIRE '%s' %f (%.6f %.6f) (%.6f %.6f);",
S.name, f( W.width),
f(W.x1), f(W.y1), f(W.x2), f(W.y2));
cmd( s );
}
}
}
// dlgMessageBox( RunOnExit, "OK");
exit( RunOnExit );
}