Saya benci menjawab pertanyaan saya sendiri, tetapi ini dia. Saya harap saya tidak mendapatkan poin untuk menjawab, itu akan aneh, hanya karena menerima jawaban? (BTW, saya tidak mendapat jawaban di forum Element14.)
Solusinya adalah dengan menggunakan perintah DRAW, bukan ROUTE. DRAW akan menempatkan segmen kawat, tepat di tempat yang Anda tentukan (tidak seperti ROUTE, yang mencoba menyambung ke airwire yang tidak diretas. ROUTE pada dasarnya tidak berguna dalam skrip.). Masalah berikutnya adalah via: Saya tidak bisa (atau tidak mau) membedakan antara manual via dan autorouted via, jadi saya menyimpan semua via yang menghubungkan dua (atau lebih) segmen kawat manual. Via via lainnya dihapus.
Jadi yang dilakukan skrip terakhir saya adalah:
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
Perhatikan bahwa itu mungkin tidak akan berfungsi lebih dari dua lapisan, atau untuk hal lain selain segmen kawat pada lapisan tembaga.
IMHO seluruh konsep ULP elang dan bahasa perintah merepotkan. ULP berjalan dalam lingkungan baca-saja, satu-satunya cara itu dapat mempengaruhi sirkuit, papan atau pustaka adalah dengan membuat daftar perintah. Ini menghilangkan beberapa teknik pemrograman yang berguna, tetapi yang lebih buruk adalah bahwa perintah tidak dirancang agar mudah dibuat dari ULP. Anda memerlukan semua jenis transformasi (dalam hal ini: koordinat, nama bentuk) untuk menerjemahkan dari dunia ULP ke dunia CMD.
(sunting) Sebelum Anda menjalankan ULP ini, setel pilihan 'bengkokan kawat' untuk memungkinkan sudut yang berubah-ubah, jika tidak elang akan mencoba menyesuaikan kabel yang dibangkitkan dengan sudut yang dibolehkan, yang dapat mengakibatkan kekacauan berdarah. IMHO ini adalah contoh lain masalah dengan ULP / SCR.
Ini adalah kode ULP:
// 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 );
}