#usage "Snap parts, junctions, nets in schematic

\n" "This program snaps parts, junctions and nets of the current " "schematic to a given grid. " "If 'Show script' is checked, you can edit the MOVE commands " "before they are executed.

" "The program runs in three steps: parts, junctions, nets. " "After each step you can terminate the program. So, if you " "only want to move the parts, quit after the first step.

" "Note: with EAGLE Version 4.0 you need write permission in the library directory.

" "Author: support@cadsoft.de" real GridDist = 100.0; enum {unitINCH, unitMIL, unitMM, unitMIC}; string h, cmd = ""; int unit = unitMIL; // predefined unit, can be changed to unitMM, unitINCH, unitMIC int show_script; int Result; string Status = ""; enum {PART_INSTANCE, JUNCTION_INSTANCE , NET_INSTANCE, NET_INSTANCE2}; int run_instance = PART_INSTANCE; int n; real x[], y[]; // previous move coords int version_4_0 = 0; // get project path, if in board or schematic, otherwise library path string get_project_path() { string s = "", p = "";; if (library) { library(L) s = L.name;} if (board) { board(B) s = B.name;} if (schematic){ schematic(S) s = S.name;} char c = '/'; int pos = strrchr(s, c); if (pos >= 0) { p = strsub(s, 0, pos + 1); } return p; } string get_ulp_name(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; } real u2unit(int u) { if (unit == unitMIL) return u2mil(u); if (unit == unitMM) return u2mm(u); if (unit == unitINCH) return u2inch(u); if (unit == unitMIC) return u2mic(u); } real snap(int n) { // returns next grid point return round(u2unit(n) / GridDist) * GridDist; } void save_dialog(string cm) { Result = dlgDialog("Edit Commands") { dlgVBoxLayout { dlgLabel("Edit only if you are sure what you do!"); dlgTextEdit(cmd); } dlgHBoxLayout { dlgPushButton("+Execute") dlgAccept(); dlgPushButton("-Quit") dlgReject(); dlgPushButton("+Save") { string dest = dlgFileSave("Save Script File", get_project_path()+"snap.scr", "*.scr"); if (dest != "") output(dest, "wt") {printf(cmd);} } } }; if (!Result) exit(0); } int is_new(void) { int i; if (n == 0) return 1; for (i = 0; i < n; i++) { if (x[n] == x[i] && y[n] == y[i]) { return(0); } } return 1; } // ------------------------------------------------------------------------------- void snap_schematic (void) { if (unit == unitMIL) {h = ""; sprintf(h, "GRID MIL FINEST;\n"); cmd += h;} if (unit == unitMM) {h = ""; sprintf(h, "GRID MM FINEST;\n"); cmd += h;} if (unit == unitINCH) {h = ""; sprintf(h, "GRID INCH FINEST;\n"); cmd += h;} if (unit == unitMIC) {h = ""; sprintf(h, "GRID MIC FINEST;\n"); cmd += h;} if (run_instance == PART_INSTANCE) { sheet(SH) { h = ""; sprintf(h, "DISPLAY NONE SYMBOL;\n"); cmd += h; SH.parts(P) { Status = "Part: "+P.name; dlgRedisplay(); P.instances(I) { if (u2unit(I.x) != snap(I.x) || u2unit(I.y) != snap(I.y)) { h = ""; sprintf(h, "MOVE (%f %f) (%f %f);\n", u2unit(I.x), u2unit(I.y), snap(I.x), snap(I.y)); cmd += h; } } } } h = ""; sprintf(h, "GRID LAST;\nDISPLAY ALL -PINS;\n"); cmd += h; if (show_script) save_dialog(cmd); if (!version_4_0) { exit(cmd); } else { output(get_project_path()+"$$$.scr", "wt") printf("%s", cmd); cmd = "RUN "+get_ulp_name()+" 1"; // call junction instance h = ""; sprintf(h, " %d", show_script); cmd += h; exit("SCRIPT "+get_project_path()+"$$$.scr;\n"+cmd); } } //********* 2nd run if (run_instance == JUNCTION_INSTANCE) { sheet(SH) { h = ""; sprintf(h, "DISPLAY NONE NETS;\n"); cmd += h; SH.nets(N) { Status = "Net: "+N.name; dlgRedisplay(); N.segments(SEG) { SEG.junctions(J) { if (u2unit(J.x) != snap(J.x) || u2unit(J.y) != snap(J.y)) { h = ""; sprintf(h, "MOVE (%f %f) (%f %f);\n", u2unit(J.x), u2unit(J.y), snap(J.x), snap(J.y)); cmd += h; } } } } } h = ""; sprintf(h, "GRID LAST;\nDISPLAY ALL -PINS;\n"); cmd += h; if (show_script) save_dialog(cmd); if (!version_4_0) { exit(cmd); } else { output(get_project_path()+"$$$.scr", "wt") printf("%s", cmd); cmd = "RUN "+get_ulp_name()+" 2"; // call net instance h = ""; sprintf(h, " %d", show_script); cmd += h; exit("SCRIPT "+get_project_path()+"$$$.scr;\n"+cmd); } } //********* 3rd run x[0] = 0; y[0] = 0; n = 0; if (run_instance == NET_INSTANCE) { sheet(SH) { h = ""; sprintf(h, "DISPLAY NONE NETS;\n"); cmd += h; SH.nets(N) { Status = "Net: "+N.name; dlgRedisplay(); N.segments(SEG) { SEG.wires(W) { x[n] = u2unit(W.x1); y[n] = u2unit(W.y1); if (is_new() && (u2unit(W.x1) != snap(W.x1) || u2unit(W.y1) != snap(W.y1))) { h = ""; sprintf(h, "MOVE (%f %f) (%f %f);\n", u2unit(W.x1), u2unit(W.y1), snap(W.x1), snap(W.y1)); cmd += h; n++; } } } } } sheet(SH) { h = ""; sprintf(h, "DISPLAY NONE NETS;\n"); cmd += h; SH.nets(N) { Status = "Net: "+N.name; dlgRedisplay(); N.segments(SEG) { SEG.wires(W) { x[n] = u2unit(W.x2); y[n] = u2unit(W.y2); if (is_new() && (u2unit(W.x2) != snap(W.x2) || u2unit(W.y2) != snap(W.y2))) { h = ""; sprintf(h, "MOVE (%f %f) (%f %f);\n", u2unit(W.x2), u2unit(W.y2), snap(W.x2), snap(W.y2)); cmd += h; n++; } } } } } h = ""; sprintf(h, "GRID LAST;\nDISPLAY ALL -PINS;\n"); cmd += h; if (show_script) save_dialog(cmd); if (!version_4_0) { exit(cmd); } else { output(get_project_path()+"$$$.scr", "wt") printf("%s", cmd); cmd = "RUN "+get_ulp_name()+" 4"; h = ""; sprintf(h, " %d", show_script); cmd += h; exit("SCRIPT "+get_project_path()+"$$$.scr;\n"+cmd); } } } //---- main ---------------------------------------------------------------------- if ((EAGLE_VERSION == 4 && EAGLE_RELEASE == 0) || (EAGLE_VERSION == 3 && EAGLE_RELEASE >96)) version_4_0 = 1; // used for workaround if (!schematic) { dlgMessageBox(usage + "


ERROR: No schematic!

\nThis program can only work in the schematic editor."); exit(1); } show_script = strtol(argv[2]); if (argv[1] == "") run_instance = PART_INSTANCE; if (argv[1] == "1") run_instance = JUNCTION_INSTANCE; if (argv[1] == "2") run_instance = NET_INSTANCE; if (argv[1] == "3") run_instance = NET_INSTANCE2; if (argv[1] == "4") {dlgMessageBox("Snap finished", "&OK"); exit(0);} dlgDialog("Snap") { if (run_instance == PART_INSTANCE) { Status = " It is strongly recommended to use only 100 mil grid!

Click Snap to snap parts"; dlgRedisplay(); } if (run_instance == JUNCTION_INSTANCE) { Status = " Click Snap to snap Junctions"; dlgRedisplay(); } if (run_instance == NET_INSTANCE) { Status = " Click Snap to snap starting point of nets"; dlgRedisplay(); } if (run_instance == NET_INSTANCE2) { Status = " Click Snap to snap ending point of nets"; dlgRedisplay(); } dlgHBoxLayout { dlgHBoxLayout { dlgGroup("Unit") { dlgRadioButton("&inch", unit); dlgRadioButton("&mil", unit); dlgRadioButton("&mm", unit); dlgRadioButton("&mic", unit); dlgSpacing(20); dlgLabel("Snap grid "); dlgRealEdit(GridDist, 0.0001, 1000); } } dlgSpacing(10); dlgVBoxLayout { dlgSpacing(10); dlgCheckBox("&Show script", show_script); dlgLabel(Status, 1); dlgHBoxLayout { dlgPushButton("+&Snap") {Status = "Busy..."; dlgRedisplay(); snap_schematic(); } dlgPushButton("-&Cancel") exit(0); } dlgSpacing(7); } } };