#usage "Copy Wire (Polygon Wire) to any layer

" "This ULP copies copper wire and/or polygon from layer (1 or 16) of selected signals into " "any layer in order.

" "If the selected layer not a copper layer, than copies also RECT, CIRCLE and TEXT.
" "Use:
" "run copy-wire-to-any-layer.ulp [signalname] [signalname]
" "run copy-wire-to-any-layer.ulp $nameoff$
" "run copy-wire-to-any-layer.ulp -p [signalname] [signalname]
" "run copy-wire-to-any-layer.ulp +p [signalname] [signalname]
" "run copy-wire-to-any-layer.ulp -p -f [signalname] [signalname]
" "run copy-wire-to-any-layer.ulp +p +f [signalname] [signalname]
" "$nameoff$ switches off the checking of net names

" "Options are case sensitive.
" "$nameoff$ copy all signals.
" "-p copies also polygons.
" "+p copies only polygons.
" "-f copies only polygon contour as polygon.
" "-f copies polygon contour and filling as wire.
" "
" "Author: support@cadsoft.de" // THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED. string Version = "Version 1.5"; // 2008-04-23 check is a polygon placed // changed menu to copy to any layer // 2008-05-05 renamed from "copy-wire-to-solder-mask.ulp" to // "copy-wire-to-any-layer.ulp" // 2008-10-24 renamed to copy-layer-to-any-layer.ulp // copy also rect, circle, text and non copper layer // 2009-01-28 check polygon filling on orphan // 2009-04-28 copy also not copper layer with RECT, CIRCLE, TEXT int NameOff = 0; // 0 = copy by signal name // 1 = copy without signal name (all) int PolygonOn = 1; // copy also polygon int onlyPolygon = 0; int fillPolygon = 0; // copy only polygon contour or copy polygon filling as wire 2006.01.20 alf int PolygonAsPolygon = 1; // 2009.-04-28 alf int PolygonContours = 0; int ploycontourleft = 0; int cntp = 0; string isRatsnest; string isLayer = ""; int isLayerNb = 0; string toLayer = ""; string fromName[], toName[]; fromName[0] = ""; toName[0] = ""; int fromNumber; int toNumber; int fcntLay = 0; int fromlNumber[]; int lNumber[]; int cntLay = 0; int selisLayer = 0, seltoLayer = 0; string signals[] = { "" }; string chsignals[] = { "" }; int chngsig = 0; int lastSigCh = -1; int decs; int n = 1; string cmd; string c; string Tfont[] = { "VECTOR", "PROPORTIONAL", "FIXED" }; // ************************************* int found(string fnam) { int fnd = 0; do { if (chsignals[fnd] == fnam) { return 1; break; } ++fnd; } while (chsignals[fnd]); return 0; } int getlayernumber(string isL) { board(B) B.layers(L) if (L.name == isL) return (L.number); return 0; } void changeLayer(void) { sprintf(c, "CHANGE LAYER %d;\n", toNumber); cmd+= c; return; } int delfromList(int selct) { if (lastSigCh >= 0) { lastSigCh--; for (int r = selct; r <= lastSigCh; r++) { chsignals[r] = chsignals[r + 1]; } chsignals[lastSigCh + 1] = ""; } return selct; } void AddList (string SigName) { int nofound = 1; for (int r = 0; r <= lastSigCh; r++) { if (chsignals[r] == SigName) { nofound = 0; break; } } if (nofound) { lastSigCh++; if (lastSigCh > 0) { for (int x = lastSigCh; x > 0; x--) { chsignals[x] = chsignals[x - 1]; } } chsignals[0] = SigName; } return; } void AddArgument(int n) { do { AddList(strupr(argv[n])); n++; } while(argv[n]); return; } // 2009-04-28 die print funktionen void printW(UL_WIRE W) { if (W.layer == fromNumber) { sprintf(c, "WIRE %.4f (%.4f %.4f) %+.1f (%.4f %.4f);\n", u2mm(W.width), u2mm(W.x1), u2mm(W.y1), W.curve, u2mm(W.x2), u2mm(W.y2) ); cmd+= c; } return; } void printC(UL_CIRCLE C) { if (C.layer == fromNumber) { sprintf(c, "CIRCLE %.4f (%.4f %.4f) (%.4f %.4f);\n", u2mm(C.width), u2mm(C.x), u2mm(C.y), u2mm(C.x + C.radius), u2mm(C.y) ); cmd+= c; } return; } void printR(UL_RECTANGLE R) { if (R.layer == fromNumber) { sprintf(c, "RECT R%.1f (%.4f %.4f) (%.4f %.4f);\n", R.angle, u2mm(R.x1), u2mm(R.y1), u2mm(R.x2), u2mm(R.y2) ); cmd+= c; } return; } void printT(UL_TEXT T) { if (T.layer == fromNumber) { string Spin = ""; if (T.spin) Spin = "S"; sprintf(c, "CHANGE SIZE %.4f;\n", u2mm(T.size) ); cmd+= c; sprintf(c, "CHANGE FONT %s;\n", Tfont[T.font] ); cmd+= c; sprintf(c, "TEXT %sR%.1f '%s' (%.4f %.4f);\n", Spin, T.angle, T.value, u2mm(T.x), u2mm(T.y) ); cmd+= c; } return; } void printP(UL_POLYGON P) { if (PolygonAsPolygon) { if (PolygonContours) { int i = -1; int active; int first = 0; if (ploycontourleft) i = -1; else i = 1; do { active = 0; P.contours(W, i) { active = i; if (first != i) { sprintf(c, "POLYGON %.4f (%.4f %.4f) %+.1f (%.4f %.4f) \n", u2mm(W.width), u2mm(W.x1), u2mm(W.y1), W.curve, u2mm(W.x2), u2mm(W.y2) ); cmd+=c; first = i; } else { sprintf(c, " %+.1f (%.4f %.4f) \n", W.curve, u2mm(W.x2), u2mm(W.y2) ); cmd+=c; } } if (ploycontourleft) i--; else i++; cmd += ";\n"; // close the polygon command } while (active); } else { int first = 1; P.wires(W) { if (first) { sprintf(c, "POLYGON %.4f (%.4f %.4f) %+.1f (%.4f %.4f) \n", u2mm(W.width), u2mm(W.x1), u2mm(W.y1), W.curve, u2mm(W.x2), u2mm(W.y2) ); cmd+=c; first = 0; } else { sprintf(c, " %+.1f (%.4f %.4f) \n", W.curve, u2mm(W.x2), u2mm(W.y2) ); cmd+=c; } } cmd += ";\n"; // close the polygon command } } else { P.contours(W) printW(W); if (fillPolygon) P.fillings(W) printW(W); } return; } // die Contacts werden noch nicht ausgegeben 2009-04-28 alf void printCon(UL_CONTACT C) { if (C.smd) { if (C.smd.layer == fromNumber) { // angle } } else { // Pad if (fromNumber >= 1 && fromNumber <= 16) { // diameter[fromNumber] // shape[fromNumber] // angle } } return; } // alle nicht Kupferlayer ausgeben void copy_any_layer(void) { board(B) { B.wires(W) printW(W); B.circles(C) printC(C); B.rectangles(R) printR(R); B.texts(T) printT(T); B.polygons(P) printP(P); B.elements(E) { E.package.wires(W) printW(W); E.package.circles(C) printC(C); E.package.rectangles(R) printR(R); E.package.texts(T) printT(T); E.package.polygons(P) printP(P); E.package.contacts(C) printCon(C); } } return; } void collectlayer(void) { board(B) B.layers(L) { if (L.used) { fromName[fcntLay] = L.name; fromlNumber[fcntLay] = L.number; fcntLay++; fromName[fcntLay] = ""; fromlNumber[fcntLay] = 0; } toName[cntLay] = L.name; lNumber[cntLay] = L.number; cntLay++; toName[cntLay] = ""; lNumber[cntLay] = 0; } return; } void menue() { string tempSignal0 = signals[0]; string tempSignal1 = signals[1]; int srt = 0; int tempNameOff = NameOff; string CopyAllInfo = "also without signal name"; if (argc > 1) { if (argv[1] == "-p" || argv[1] == "+p" || argv[1] == "$nameoff$") { if (argv[1] == "-p") PolygonOn = 1; if (argv[1] == "+p") onlyPolygon = 1; if (argv[2] == "-f") fillPolygon = 0; // 2006.01.20 alf if (argv[2] == "+f") fillPolygon = 1; if (argv[1] == "$nameoff$") { NameOff = 1; AddArgument(2); } else if (argv[2] == "$nameoff$") { NameOff = 1; AddArgument(3); } else AddArgument(2); if (argv[2] == "$nameoff$") { NameOff = 1; AddArgument(3); } else if (argv[3] == "$nameoff$") { NameOff = 1; AddArgument(4); } else AddArgument(3); } else AddArgument(1); } else { string slist[]; int Result = dlgDialog(filename(argv[0])) { dlgHBoxLayout dlgSpacing(250); dlgHBoxLayout { dlgCheckBox("&Copy all ", NameOff); dlgLabel(CopyAllInfo, 1); dlgStretch(1); } dlgSpacing(10); dlgStretch(0); dlgLabel("&Add signal to list"); dlgComboBox(signals, chngsig) { AddList(signals[chngsig]); dlgRedisplay();} dlgSpacing(12); dlgLabel("&Delete signal from list"); dlgComboBox(chsignals, decs) decs = delfromList(decs); dlgGroup("Polygon") { dlgCheckBox("Copy &polygon with signal name", PolygonOn); dlgCheckBox("Copy &only polygons", onlyPolygon); dlgGroup("wire/poly") { dlgHBoxLayout { dlgRadioButton("Copy polygon as &wire",PolygonAsPolygon); dlgRadioButton("Copy polygon &as polygon",PolygonAsPolygon); } } dlgGroup("outline/inner") { dlgHBoxLayout { dlgRadioButton("Copy polygon defintition",PolygonContours); dlgRadioButton("Copy polygon contours",PolygonContours); } } dlgGroup("outer/inner rotation") { dlgHBoxLayout { dlgRadioButton("left rotation (outer) contour", ploycontourleft); dlgRadioButton("right rotation (inner) contour", ploycontourleft); } } dlgHBoxLayout { dlgRadioButton("Copy conto&ur", fillPolygon); dlgRadioButton("Copy &filling", fillPolygon); } } dlgHBoxLayout { dlgListView("from Layer", fromName, selisLayer, srt) { fromNumber = getlayernumber(fromName[selisLayer]); if (fromNumber > 16) { tempSignal0 = signals[0]; tempSignal1 = signals[1]; signals[0] = "Kein Kupferlayer"; signals[1] = ""; tempNameOff = NameOff; NameOff = 1; } else if (signals[0] = "Kein Kupferlayer") { signals[0] = tempSignal0; signals[1] = tempSignal1; NameOff = tempNameOff; } } dlgListView("to Layer", toName, seltoLayer, srt) toNumber = getlayernumber(toName[seltoLayer]); dlgStretch(1); } dlgLabel("If you want to change the default setting, type in the appropriate layer numbers here."); dlgHBoxLayout { dlgIntEdit(fromNumber); dlgIntEdit(toNumber); dlgStretch(1); } dlgSpacing(10); dlgHBoxLayout { dlgPushButton("+OK") { if (!fromNumber || !toNumber) dlgMessageBox("!Select a valid layer", "OK"); else if(fromNumber == toNumber) dlgMessageBox("!Select a differnt layer from <-> to", "OK"); else if(fromNumber <= 16 && lastSigCh < 0 && !NameOff) dlgMessageBox("!Select one or more signal(s)", "OK"); else dlgAccept(); } dlgPushButton("-Cancel") dlgReject(); dlgStretch(1); dlgLabel(Version); dlgStretch(1); dlgPushButton("&Help") dlgMessageBox(usage, "OK"); } dlgStretch(0); }; if (Result == 0) exit (0); } isLayerNb = fromNumber; // 2009-04-24 return; } // main if (board) board(B) { isRatsnest = "! Start RATSNEST first!"; int cntPoly = 0; B.signals(S) { S.polygons(P) { cntPoly++; P.fillings(F) { isRatsnest = ""; break; } if (isRatsnest) { // check a orphan 2009-01-28 alf@cadsoft.de P.wires(W) { sprintf(isRatsnest, "Start RATSNEST and check polygon on (%.4f %.4f) mm!", u2mm(W.x1), u2mm(W.y1) ); dlgMessageBox(isRatsnest, "OK"); sprintf(isRatsnest, "GRID MM;\nWIN (%.4f %.4f);\nGRID LAST;\n", u2mm(W.x1), u2mm(W.y1) ); exit(isRatsnest); } } } } if (cntPoly) { if (isRatsnest) { dlgMessageBox(isRatsnest, "OK"); exit(0); } } int s = 0; B.signals(S) { signals[s] = S.name; s++; } collectlayer(); menue(); sprintf(c, "GRID MM;\nSET WIRE_BEND 2;\nSET UNDO OFF;\n"); cmd+= c; changeLayer(); if (isLayerNb > 16) copy_any_layer(); else { B.signals(S) { if (found(S.name) || NameOff || onlyPolygon) { if (!onlyPolygon) { S.wires(W) { if (fromNumber == W.layer) printW(W); } } // ##### ACHTUNG ##### // POLYGONE die kein *echtes* SIGNAL sind, also nicht an einen PAD oder SMD angebunden sind, // werden nicht ausgegeben, weil signals(S) nur durch echte Signale läuft. /**************************************************************************/ if (PolygonOn) { S.polygons(POL) { if (fromNumber == POL.layer) { printP(POL); } } } } } } sprintf(c, "SET UNDO ON;\nGRID LAST;\n"); cmd+= c; dlgDialog("test") { dlgTextEdit(cmd); dlgHBoxLayout { dlgPushButton("+OK") dlgAccept(); dlgPushButton("-Cancel") { dlgReject(); exit(-1); } dlgStretch(1); } }; exit (cmd); } else dlgMessageBox("! Start this ULP in a Board", "OK");