📄 cmd-renumber.ulp
字号:
#usage "<b>Renumber board components</b>\n"
"<p>"
"See Help of the ULP for further instructions."
"<p>"
"<author>Author: support@cadsoft.de (based on original code from Michel Dagenais, jcmae@sympatico.ca)</author>"
// THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED
// 16.06.2002 "Scan window"/"Unit" do not take effect in the current instance of the program -- alf@cadsoft.de
string HelpText =
"This ULP will renumber a board's components starting from any corner, renaming from suffix 1, either horizontally or vertically."
"<p>\n"
"If there are names like R01, the program will ask you if it may change those names. "
"Otherwise no renaming can be performed."
"<p>\n"
"Your board MUST be drawn on layer 20 (dimension) and all components MUST be inside it, otherwise the result is unpredictable.\n"
"<p>\n"
"<p>\n"
"<b>Meaning of Parameters</b>\n"
"<p>\n"
"<b>Unit</b>\n"
"<p>\n"
"Unit for the value entered in the Scan window.\n"
"<p>\n"
"<b>Direction</b>\n"
"<p>\n"
"Renumber direction.\n"
"<p>\n"
"<b>Top Side: Start from</b>\n"
"<p>\n"
"Renumber starting point for top (component) side.\n"
"<p>\n"
"<b>Bottom Side: Start from</b>\n"
"<p>\n"
"Renumber starting point for bottom (solder) side.\n"
"<p>\n"
"<b>Scan window</b>\n"
"<p>\n"
"Dimension of the user-defined window to determine row or column width for components scanning.\n"
"<p>\n"
"<b>Bottom suffix</b>\n"
"<p>\n"
"Renumbering starts at the component side.\n"
"If Bottom suffix is 0, the bottom component suffixes are continued in sequence.\n"
"If Bottom suffix is > 0, the bottom component suffixes start with this number, provided there is no overlapping with component names at the top side.\n"
"<p>\n"
"<b>Show scripts</b>\n"
"<p>\n"
"If this box is checked, the respective command scripts are shown before execution of Preview and Renumber.<br>\n"
"The Renumber Script can be saved.\n"
"<p>\n"
"<b>Preview</b>\n"
"<p>\n"
"Highlights all components in the order of the currently selected renumbering sequence.<br>\n"
"Please note that on fast computers Preview might be too fast to watch!\n"
"<p>\n"
"<b>Renumber</b>\n"
"<p>\n"
"Executes the renumber function and quits program.\n"
"<p>\n"
;
//-----------------------------------------------------------------------------------------
real window, win;
int sequence_bottom;
int dir;
int c_top;
int c_bottom;
enum {unitINCH, unitMM};
int unit = unitINCH;
int show_script;
string params;
if (!argv[1]) { // first program instance
//---- edit the following default values to your liking ---------------------------------
window = 0.4 ; // default scan window width
sequence_bottom = 100; // if no overlap, use this new suffix to start on bottom,
// otherwise continue in sequence
dir = 0; // 0 = horizontally, 1 = vertically
c_top = 0; // starting point for top side
c_bottom = 3; // starting point for bottom side
unit = unitINCH; // change to unitMM, if you want mm as default
show_script = 0; // 1 = show script file before execution
}
else {
if (argv[1] == "end") { // last program instance
dlgMessageBox("Renumber finished!", "&OK");
exit(0);
}
sprintf (params, " %s", argv[1]); // other program instances
window = strtod(params);
for (int ix = 2; ix <= 7; ix++) {
string hx = "";
sprintf (hx, " %s", argv[ix]);
params += hx;
}
sequence_bottom = strtol(argv[2]);
dir = strtol(argv[3]);
c_top = strtol(argv[4]);
c_bottom = strtol(argv[5]);
unit = strtol(argv[6]);
show_script = strtol(argv[7]);
if (unit == unitINCH)
win = window;
else
win = window / 25.4;
}
//-----------------------------------------------------------------------------------------
string h, cmd;
int Result, tmp_int, i, j, z, length_of_name, number_prefix, largest_number_prefix;
int i_p_top, index_top[], old_suffix_top[], new_suffix_top[];
real comp_x_abs_top[], comp_y_abs_top[];
int i_p_bottom, index_bottom[], old_suffix_bottom[], new_suffix_bottom[];
real comp_x_abs_bottom[], comp_y_abs_bottom[];
int i_p_both, index_both[], old_suffix_both[], new_suffix_both[];
real tmp_real, w, pcb_min_x, pcb_min_y, pcb_max_x, pcb_max_y, pcb_length, pcb_height;
string tmp_string, ref_name, last_prefix, prefix_top[], prefix_bottom[], prefix_both[];
//-----------------------------------------------------------------------------------------
void DisplayHelp(void)
{
dlgDialog("Renumer Help") {
dlgHBoxLayout dlgSpacing(400);
dlgHBoxLayout {
dlgVBoxLayout dlgSpacing(300);
dlgTextView(HelpText);
}
dlgHBoxLayout {
dlgStretch(1);
dlgPushButton("-Close") dlgReject();
}
};
}
//-----------------------------------------------------------------------------------------
string get_progname(void) {
string s = strsub(argv[0], 0, strlen(argv[0])-4);
string p = s;
char c = '/';
int pos = strrchr(s, c);
if (pos >= 0) {
p = strsub(s, pos + 1);
}
return p;
}
//-----------------------------------------------------------------------------------------
void renumber (void) {
cmd = "";
h = ""; sprintf(h, ";\n"); cmd += h;
h = ""; sprintf(h, "Grid Inch;\n"); cmd += h;
h = ""; sprintf(h, "Display None;\n"); cmd += h;
h = ""; sprintf(h, "Window fit;\n"); cmd += h;
h = ""; sprintf(h, "Display 20 21 22 25 26 -27 -28;\n"); cmd += h;
for (i = 0; i < i_p_both; ++i) {
new_suffix_both[i] = i + 1 ;
}
sort (i_p_both, index_both, prefix_both, new_suffix_both, old_suffix_both);
for (j = 0; j < i_p_both; ++j) { // all parts ------------------------
z = 1;
tmp_int = 1;
tmp_string = prefix_both[index_both[j]];
for (i = j; prefix_both[index_both[i]] == tmp_string; ++i) {
if ((sequence_bottom > largest_number_prefix) && (new_suffix_both[index_both[i]] > i_p_top) && (tmp_int == 1)) {
z = sequence_bottom;
tmp_int = 0;
}
if ((new_suffix_both[index_both[i]] > 0) && (old_suffix_both[index_both[i]] != z)) {
new_suffix_both[index_both[i]] = z * -1;
}
else {
new_suffix_both[index_both[i]] = 0 ;
}
++z;
if (i == i_p_both - 1) break; // added!!!
}
if (i == i_p_both - 1) break; // added!!!
j = i - 1;
}
for (i = 0; i < i_p_both; ++i) {
if (new_suffix_both[index_both[i]] < 0) {
h = ""; sprintf(h, "Name '%s%d' '$$%s%d';\n", prefix_both[index_both[i]], old_suffix_both[index_both[i]], prefix_both[index_both[i]], abs(new_suffix_both[index_both[i]])); cmd += h;
}
}
for (i = 0; i < i_p_both; ++i) {
if (new_suffix_both[index_both[i]] < 0) {
h = ""; sprintf(h, "Name '$$%s%d' '%s%d';\n", prefix_both[index_both[i]], abs(new_suffix_both[index_both[i]]), prefix_both[index_both[i]], abs(new_suffix_both[index_both[i]])); cmd += h;
}
}
h = ""; sprintf(h, "Grid Last;\n"); cmd += h;
if (show_script) {
Result = dlgDialog("Edit Commands") {
dlgVBoxLayout {
dlgLabel("Edit only if you are sure what you do!");
dlgTextEdit(cmd);
}
dlgHBoxLayout {
dlgPushButton("+Ok") dlgAccept();
dlgPushButton("-Quit") dlgReject();
dlgPushButton("+Save") {
string dest = dlgFileSave("Save Script File", "renumber.scr", "*.scr");
if (dest != "") output(dest, "wt") {printf(cmd);}
}
}
};
if (!Result) exit(0);
}
cmd += "RUN "+get_progname()+" end";
exit(cmd);
}
//--------------------------------------------------------------------------------
void preview(void) {
cmd = "";
sprintf (params, " %f %d %d %d %d %d %d",
window, sequence_bottom, dir, c_top, c_bottom, unit, show_script);
h = ""; sprintf(h, ";\n"); cmd += h;
h = ""; sprintf(h, "Grid Inch;\n"); cmd += h;
h = ""; sprintf(h, "Display None;\n"); cmd += h;
h = ""; sprintf(h, "Window fit;\n"); cmd += h;
h = ""; sprintf(h, "Display 20 21 22 25 26 -27 -28;\n"); cmd += h;
for (i = 0; i < i_p_both; ++i)
{
h = ""; sprintf(h, "Show %s%d %s%d;\n", prefix_both[i], old_suffix_both[i], prefix_both[i], old_suffix_both[i]); cmd += h;
}
if (show_script) {
Result = dlgDialog("Edit Commands") {
dlgVBoxLayout {
dlgLabel("Edit only if you are sure what you do!");
dlgTextEdit(cmd);
}
dlgHBoxLayout {
dlgPushButton("+Ok") dlgAccept();
dlgPushButton("-Quit") dlgReject();
}
};
if (!Result) exit(0);
}
cmd += "RUN "+get_progname()+params;
exit(cmd);
}
//--- collect data ---------------------------------------------------------------
void get_data(void) {
board(B) { // Get board size to determine ratio.
tmp_int = 1;
B.wires(W) {
if (W.layer == 20) {
if (tmp_int == 1) {
pcb_min_x = u2inch(W.x1);
pcb_min_y = u2inch(W.y1);
pcb_max_x = u2inch(W.x1);
pcb_max_y = u2inch(W.y1);
tmp_int = 0;
}
if (u2inch(W.x1) < pcb_min_x){pcb_min_x = u2inch(W.x1);}
if (u2inch(W.x1) > pcb_max_x){pcb_max_x = u2inch(W.x1);}
if (u2inch(W.x2) < pcb_min_x){pcb_min_x = u2inch(W.x2);}
if (u2inch(W.x2) > pcb_max_x){pcb_max_x = u2inch(W.x2);}
if (u2inch(W.y1) < pcb_min_y){pcb_min_y = u2inch(W.y1);}
if (u2inch(W.y1) > pcb_max_y){pcb_max_y = u2inch(W.y1);}
if (u2inch(W.y2) < pcb_min_y){pcb_min_y = u2inch(W.y2);}
if (u2inch(W.y2) > pcb_max_y){pcb_max_y = u2inch(W.y2);}
}
}
pcb_length = pcb_max_x - pcb_min_x;
pcb_height = pcb_max_y - pcb_min_y;
number_prefix = 1;
last_prefix = "";
largest_number_prefix = 1;
B.elements(E) {
ref_name = E.name ;
if (!(strlen(ref_name)<=1 || isdigit(ref_name[0]))) { // exclude R, 04 etc.
length_of_name = strlen(ref_name) ;
prefix_top[i_p_top] = "" ;
new_suffix_top[i_p_top] = 0 ;
tmp_string = "" ;
if (isdigit(ref_name[length_of_name - 1]) && E.mirror == 0 ) { // on top & num suffix
for (i = strlen(ref_name) - 1; isdigit(ref_name[i]); --i); // find prefix + suffix
prefix_top[i_p_top] = strsub(ref_name, 0, i+1); // prefix
tmp_string = strsub(ref_name, i+1); // suffix
if (prefix_top[i_p_top] == last_prefix) {
++number_prefix; // inc as long as same prefix
}
else {
last_prefix = prefix_top[i_p_top];
if (number_prefix > largest_number_prefix) {
largest_number_prefix = number_prefix; // update largest_n..
number_prefix = 1;
}
}
old_suffix_top[i_p_top] = strtol(tmp_string) ;
switch (c_top) {
case 1: // Top-Right
{
comp_x_abs_top[i_p_top] = abs(u2inch(E.x) - pcb_max_x) ;
comp_y_abs_top[i_p_top] = abs(u2inch(E.y) - pcb_max_y) ;
break;
}
case 0: // Top-Left
{
comp_x_abs_top[i_p_top] = abs(u2inch(E.x) + abs(pcb_min_x)) ;
comp_y_abs_top[i_p_top] = abs(u2inch(E.y) - pcb_max_y) ;
break;
}
case 2: // Bottom-Left
{
comp_x_abs_top[i_p_top] = abs(u2inch(E.x) + abs(pcb_min_x)) ;
comp_y_abs_top[i_p_top] = abs(u2inch(E.y) + abs(pcb_min_y)) ;
break;
}
case 3: // Bottom-Right
{
comp_x_abs_top[i_p_top] = abs(u2inch(E.x) - pcb_max_x) ;
comp_y_abs_top[i_p_top] = abs(u2inch(E.y) + abs(pcb_min_y)) ;
break;
}
default: // default is Top-Left Corner for Top side.
{
comp_x_abs_top[i_p_top] = abs(u2inch(E.x) + abs(pcb_min_x)) ;
comp_y_abs_top[i_p_top] = abs(u2inch(E.y) - pcb_max_y) ;
}
}
++i_p_top ;
}
}
}
if (number_prefix > largest_number_prefix) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -