#usage "Snap objects in schematic to default grid\n" "

" "Snaps symbols, junctions, nets and busses to the " "given grid (default: 0.1 inch)." "

" "Author: support@cadsoft.de" // THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED // English Description string eHelp = "This EAGLE User Language Program can be used to " "snap the symbols, the nets, and the busses of the current " "schematic to default grid (0.1 Inch).

" "The first run snaps all the devices and all the net lines " "that are connected to a pin to default grid. " "The second run snaps the rest of the net lines that are " "not tied to a pin directly (like bends and junctions)." "This avoids that elements will be snapped more than once.

" " 1. with the device

" " 2. with the net lines

" " The end of the net tied to the pin can not be moved." " Thus EAGLE would only move the free end of a net segment" " again." "The coordinates will be stored in an array and searched for" "multiple occurences.

" "If devices do not snap to default grid, they are defined" "offgrid in the libary (symbol) editor. In this case please" "correct your library definition.

" "If it happens that net lines do not snap, they might be" "connected to a pin (as mentioned above). Or there are" "superimposed nets at this point. Use the SHOW command to" "check this closely


"; // * ---------------------------------------------------------- // Deutsche Anleitung: string dHelp = "Dieses EAGLE ULP verschiebt Symbole, " "Netz-Linien und Bus-Linien im aktuellen Schaltplan auf " "das Default-Grid (0.1 Inch).

" "Der erste Durchlauf snapt die Devices (Symbole). " "Dabei werden auch alle an Pins angeschlossenen Netzsegmente " "automatisch gesnapt. Der zweite Durchlauf snapt nur " "noch die Knickpunkte, Abzweigungen und Kreuzungen der " "Netze. Andernfalls würden die Netz-Segmente durch die " "Mehrfachinformation mehrmals verschoben werden.

" " 1. mit dem Device.

" " 2. mit dem Netz-Segment.

" " Das Segment-Ende, das an einem Pin kontaktiert ist, " " kann nicht verschoben werden. So würde EAGLE nur das " " freie Segment-Ende ein weiteres Mal verschieben. " "Die Koordinaten werden zuerst in einer Tabelle gesammelt " "und nach mehrfachem Vorkommen durchsucht." "

" "Sollten Devices nicht auf das Default Grid gesnapt werden, " "sind sie in der Library (Symbol) ausserhalb des Grids " "definiert worden.

" "Sollten Netz-Elemente nicht verschoben werden, " "sind sie - wie oben erwaehnt - an einem Pin angeschlossen, " "oder an dieser Koordinate doppelt vorhanden. " "In diesem Fall ueberpruefen Sie mit SHOW, ob es sich um " "das gleiche Netz handelt.


"; string Version = "1.0.4"; int Grid = strtol(argv[2]); // default 100 Mil int pass = strtol(argv[3]) + 1; real snap(int n) // returns next grid point { return round(u2mil(n) / Grid) * Grid; } void setgridmil (void) { printf("GRID mil finest;\n"); } real onGrid(int g) { return ((u2mil(g)/Grid) - round(u2mil(g)/Grid)) * Grid; } void move_w(int x, int y) { printf("MOVE (%.4f %.4f)\n", u2mil(x), u2mil(y)); printf("(%.4f %.4f);\n", snap(x), snap(y)); } // main if (!schematic) { dlgMessageBox("This program can only work in the schematic editor.", "OK"); exit (0); } if (Grid == 0) { Grid = 100; int Result = dlgDialog("SNAP Elements on Grid") { dlgHBoxLayout { dlgLabel("&Grid"); dlgIntEdit(Grid); dlgLabel("mil"); } dlgHBoxLayout { dlgStretch(0); dlgPushButton("&Help") dlgMessageBox(eHelp, "OK"); dlgStretch(1); dlgPushButton("H&ilfe") dlgMessageBox(dHelp, "OK"); dlgStretch(0); } dlgHBoxLayout { dlgStretch(0); dlgPushButton("+&OK") dlgAccept(); dlgStretch(1); dlgPushButton("-&Cancel") dlgReject(); dlgStretch(0); } }; if (!Result) exit(-1); } schematic(S) { string fileName; fileName = filesetext(S.name, "_snap.scr"); int shift = 0; output(fileName) { printf("# This file is generated by %s %s, exported from;\n", filename(argv[0]), Version); printf("# %s at %s;\n", S.name, t2string(time())); printf("# %s;\n\n", EAGLE_SIGNATURE); setgridmil (); // *** switch grid to finest int snapshift = 0; S.sheets(SH) { printf("EDIT .S%d;\n", SH.number); printf("Text '#Symbol snap\nDISPLAY NONE 94 -95 -96;\n"); SH.parts(PA) { PA.instances(S) { // *** check Grid real xoff = onGrid(S.x); real yoff = onGrid(S.y); if (xoff || yoff) { move_w(S.x,S.y); snapshift =1 ; // flag for non Wire-Snap shift = 1; } } } printf("Text '#Junction snap\nDISPLAY NONE 91;\n"); SH.nets(N) { N.segments(SEG) { SEG.junctions(J) { real xoff = onGrid(J.x); real yoff = onGrid(J.y); if (xoff || yoff) { move_w(J.x,J.y); snapshift =1 ; // flag for non Wire-Snap shift = 1; } } } } // * zuerst die Devices und Junctions verschieben * // * damit werden alle Wire die an Pins angeschlossen * // * sind, auch gleich mitverschoben. * // * Jeder weitere Durchlauf verschieb dann nur noch * // * die Netzsegmente die immer noch nicht auf dem * // * Default-Grid liegen * if (snapshift == 0) { // *** check Net-Wire on Grid // 2. snap all Wires printf("Text '#Net snap\nDISPLAY NONE 91;\n"); SH.nets(N) { real x[], y[]; int countw = 0; N.segments(SEG) { SEG.wires(W) { int notfoundx = 1; int notfoundy = 1; int cnt = 0; // * alle mehrfach vorhandenen Koordinaten ausfiltern // * mehrere Segmentverbindungen muessen als // * eine Koordinate behandelt werden, // * um ein mehrfaches verschieben zu vermeiden for (cnt = 0; cnt < countw; cnt ++) { if (W.x1 == x[cnt] && W.y1 == y[cnt] ) { // 1. Segmentende notfoundx = 0; break; } } for (cnt = 0; cnt < countw; cnt ++) { if (W.x2 == x[cnt] && W.y2 == y[cnt] ) { // 2. Segmentende notfoundy = 0; break; } } if (notfoundx) { x[countw] =W.x1; y[countw]= W.y1; countw++; real x1off = onGrid(W.x1); real y1off = onGrid(W.y1); if (x1off || y1off) { move_w(W.x1,W.y1); shift = 1; } } if (notfoundy) { x[countw] =W.x2; y[countw]= W.y2; countw++; real x2off = onGrid(W.x2); real y2off = onGrid(W.y2); if (x2off || y2off) { move_w(W.x2,W.y2); shift = 1; } } } } } // 2. snap all busses printf("Text '#Bus snap\nDISPLAY NONE 92;\n"); SH.busses(B) { real x[], y[]; int countw = 0; B.segments(SEG) { SEG.wires(W) { int notfoundx = 1; int notfoundy = 1; int cnt = 0; // * alle mehrfach vorhandenen Koordinaten ausfiltern // * mehrere Segmentverbindungen muessen als // * eine Koordinate behandelt werden, // * um ein mehrfaches verschieben zu vermeiden for (cnt = 0; cnt < countw; cnt ++) { if (W.x1 == x[cnt] && W.y1 == y[cnt] ) { // 1. Segmentende notfoundx = 0; break; } } for (cnt = 0; cnt < countw; cnt ++) { if (W.x2 == x[cnt] && W.y2 == y[cnt] ) { // 2. Segmentende notfoundy = 0; break; } } if (notfoundx) { x[countw] =W.x1; y[countw]= W.y1; countw++; real x1off = onGrid(W.x1); real y1off = onGrid(W.y1); if (x1off || y1off) { move_w(W.x1,W.y1); shift = 1; } } if (notfoundy) { x[countw] =W.x2; y[countw]= W.y2; countw++; real x2off = onGrid(W.x2); real y2off = onGrid(W.y2); if (x2off || y2off) { move_w(W.x2,W.y2); shift = 1; } } } } } } } printf("GRID INCH;\n"); printf("GRID 0.1;\n"); printf("DISPLAY 91 92 94 95 96 -93;\n"); } string h = ""; if (shift) { sprintf(h, "run '%s' '%d' '%d' '%d';\n", argv[0], shift, Grid, pass); if (pass == 4) { sprintf(h, "# nach 3 Durchlaeufen muessen alle Elemente gesnapt sein,\n" "# ueberpruefen Sie den Schaltplan auf doppelt vorkommende,\n" "# oder sich überlappende Net-Wires, bzw. Junctions\n" "# in der untenstehenden Liste.\n"); string text; int nChars = fileread(text, fileName); dlgDialog(fileName) { dlgTextView(h + text); dlgHBoxLayout { dlgPushButton("&OK") dlgAccept(); dlgSpacing(300); } exit (-1); }; } exit ("script '" + fileName + "';" + h); // do it } int Result =(dlgMessageBox("Nothing to do

" + S.name , "OK")); if (Result) exit(0); }