自分の質問に答えるのは嫌いですが、ここに行きます。解答のポイントがもらえないことを願っています。解答を受け入れるだけで、それは奇妙です。(ちなみに、Element14フォーラムでは応答がありませんでした。)
解決策は、ROUTEではなくDRAWコマンドを使用することです。DRAWは、指定された正確な場所にワイヤーセグメントを配置します(ルーティングされていないエアワイヤーに接続しようとするROUTEとは異なります。ROUTEはスクリプトでは基本的に役に立ちません)。次の問題はviaです。手動のviaと自動配線されたviaを区別できない(またはしたくない)ので、2つ(またはそれ以上)の手動ワイヤセグメントを接続するすべてのviaを保持します。他のビアは削除されます。
つまり、私の最終的なスクリプトは次のとおりです。
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
3層以上では機能せず、銅層のワイヤセグメント以外では機能しないことに注意してください。
イーグルULPとコマンド言語の概念全体が面倒です。ULPは読み取り専用環境で実行されます。ULPが回路、ボード、またはライブラリに影響を与える唯一の方法は、コマンドのリストを作成することです。これにより、いくつかの有用なプログラミング手法が不要になりますが、さらに悪いことに、コマンドがULPから簡単に作成できるように設計されていません。ULPの世界からCMDの世界に変換するには、あらゆる種類の変換(この場合は座標、形状名)が必要です。
(編集)このULPを実行する前に、「ワイヤーベンド」の選択を任意の角度を許可するように設定します。そうしないと、イーグルは復活したワイヤーを許可された角度に適合させようとします。私見これはULP / SCRの問題の別の例です。
これは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 );
}