#usage "This ULP copies copper wire and/or polygon " "from layer 1 or 16 of selected signals into the solderstop layers in order " "to keep it free from solder stop layer.

" "Use:
" "run copy-wire-to-solder-mask.ulp [signalname] [signalname]
" "run copy-wire-to-solder-mask.ulp $nameoff$
" "run copy-wire-to-solder-mask.ulp -p [signalname] [signalname]
" "run copy-wire-to-solder-mask.ulp +p [signalname] [signalname]
" "run copy-wire-to-solder-mask.ulp -p -f [signalname] [signalname]
" "run copy-wire-to-solder-mask.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 = "ULP-Version: 1.2 (2006.01.20)"; // alf@cadsoft.de int NameOff = 0; // 0 = copy by signal name // 1 = copy without signal name (all) int PolygonOn = 0; // copy also polygon int onlyPolygon = 0; int fillPolygon = 0; // copy only polygon contour or copy polygon filling as wire 2006.01.20 alf int Player[]; string poly[]; int cntp = 0; string isRatsnest; string signals[] = { "" }; string chsignals[] = { "" }; int chngsig = 0; int lastSigCh = -1; int decs; int index[]; int x1[], y1[], x2[], y2[], layer[]; int Wwidth[]; int n = 1; string cmd; string c; // ************************************* int found(string fnam) { int fnd = 0; do { if (chsignals[fnd] == fnam) { return 1; break; } ++fnd; } while (chsignals[fnd]); return 0; } void changeLayer(int l) { if (l == 1) sprintf(c, "CHANGE LAYER 29;\n"); if (l == 16) sprintf(c, "CHANGE LAYER 30;\n"); 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; } void menue() { 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("Copy wire to mask layer") { dlgLabel(Version); dlgHBoxLayout dlgSpacing(250); dlgCheckBox("Copy &all (without signal name)", NameOff); dlgSpacing(10); dlgStretch(0); dlgLabel("&Add signal to list"); dlgComboBox(signals, chngsig) { AddList(signals[chngsig]); dlgRedisplay();} dlgSpacing(30); 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); dlgHBoxLayout { dlgRadioButton("Copy contour", fillPolygon); dlgRadioButton("Copy filling", fillPolygon); } } dlgHBoxLayout { dlgPushButton("+OK") dlgAccept(); dlgPushButton("-Cancel") dlgReject(); dlgStretch(1); dlgPushButton("&Help") dlgMessageBox(usage, "OK"); } dlgStretch(0); }; if (Result == 0) exit (0); } return; } // main if (board) board(B) { isRatsnest = "! Start RATSNEST first!"; B.signals(S) { S.polygons(P) { P.fillings(F) { isRatsnest = ""; break; } break; } } if (isRatsnest) { dlgMessageBox(isRatsnest, "OK"); exit(0); } int s = 0; B.signals(S) { signals[s] = S.name; s++; } menue(); sprintf(c, "GRID MM;\nSET WIRE_BEND 2;\nSET UNDO OFF;\n"); cmd+= c; B.signals(S) { if (found(S.name) || NameOff || onlyPolygon) { if (!onlyPolygon) { S.wires(W) { if (W.layer == 1 || W.layer == 16) { x1[n] = W.x1; y1[n] = W.y1; x2[n] = W.x2; y2[n] = W.y2; Wwidth[n] = W.width; layer[n] = W.layer; ++n; } } } if ( (PolygonOn && NameOff) || (onlyPolygon && !NameOff && found(S.name)) || (PolygonOn && !NameOff && found(S.name)) ) { S.polygons(POL) { if (POL.layer == 1 || POL.layer == 16) { string p; int startx, starty, first = 1; Player[cntp] = POL.layer; if (!fillPolygon) { POL.contours(W) { if (first) { first = 0; startx = W.x1; starty = W.y1; sprintf(poly[cntp], "POLYGON %.4f (%.4f %.4f) (%.4f %.4f)", u2mm(W.width), u2mm(W.x1), u2mm(W.y1), u2mm(W.x2), u2mm(W.y2) ); } else { first = 0; sprintf(p, " (%.4f %.4f)", u2mm(W.x2), u2mm(W.y2) ); poly[cntp] += p; if (startx == W.x2 && starty == W.y2) { sprintf(p, " (%.4f %.4f);\n", u2mm(startx), u2mm(starty) ); poly[cntp] += p; cntp++; break; } } } } else { // Polygon filling with wire POL.contours(W) { x1[n] = W.x1; y1[n] = W.y1; x2[n] = W.x2; y2[n] = W.y2; Wwidth[n] = W.width; layer[n] = W.layer; ++n; } POL.fillings(W) { x1[n] = W.x1; y1[n] = W.y1; x2[n] = W.x2; y2[n] = W.y2; Wwidth[n] = W.width; layer[n] = W.layer; ++n; } } } } } } } sort(n, index, layer); int dl = 0; for (int i = 1; i < n; ++i) { if(dl != layer[index[i]]) { dl = layer[index[i]]; changeLayer(dl); } sprintf(c, "WIRE %.4f (%.4f %.4f) (%.4f %.4f);\n", u2mm(Wwidth[index[i]]), u2mm(x1[index[i]]), u2mm(y1[index[i]]), u2mm(x2[index[i]]), u2mm(y2[index[i]]) ); cmd+= c; } sort(cntp, index, Player); for ( i = 0; i < cntp; ++i) { if(dl != Player[index[i]]) { dl = Player[index[i]]; changeLayer(dl); } sprintf(c, "WIRE %.4f (%.4f %.4f) (%.4f %.4f);\n", u2mm(Wwidth[index[i]]), u2mm(x1[index[i]]), u2mm(y1[index[i]]), u2mm(x2[index[i]]), u2mm(y2[index[i]]) ); cmd+= poly[index[i]]; } sprintf(c, "SET UNDO ON;\nGRID LAST;\n"); cmd+= c; exit (cmd); } else dlgMessageBox("! Start this ULP in a Board", "OK");