#usage "en:Generate 3D data for export generate_3d_datav13.ulp on the current package.

" "

" "Author: alf@cadsoft.de" , "de:Erzeuge die Daten für die 3D-Ausgabe des generate_3d_data(v13).ulp in dem " "geladenen Package.

" "RUN gen-3D-pac-idf [high-top high-bottom]

" "high top high bottom == mm. Die tatsächliche Höhe des Bauteil.
" "Beachten Sie auch die interne Auflösung von Eagle V6 (3.125 Nanometer), und daß WIRE immer eine " "Breite von 2 Einheiten benötigen. Dadurch ergeben sich WIRE-Breiten mit einem mehrfachen von " "6.25 Nanometer.

" "

" "Es werden nur Objekte (WIRE/RECT) im Layer 21/51 & 22/52 im Layr 57/58 nachgezeichnet.
" "Das generate_3d_data_v13.ulp von Herrn Naubacher benutzt die Layer 57 und 58, " "um die Daten für die 3. Dimension (Z-Achse) im .PAC zu hinterlegen.
" "Das generate_3d_data(v13).ulp liest im Board diese Daten (WIRE-Breite) und multipliziert sie mit 1000. " "Der Trick ist, die Linienbreite der Bestückungsdruck (Layer 57 für Top und Layer 58 für Bottom) " "in micrometer abzulegen. Diese dünnen Linien stören später die grafische Ansicht nicht, wenn goße Werte " "für die 3. Dimension (Z-Achse) angegeben werden müssen, und man mit DISPLAY 57 58 die komplette Zeichnung " "(alle Layer) anzeigt." "Da die Lötbeinchen typischerweise mit RECT gezeichnet werden, bietet sich an, für RECT eine eigene " "Höhenangabe zu berücksichtigen, wobei hier das Problem besteht, das EAGLE an einem Koorinatenpaar nur " "eine Wirebreite zulässt. Hier muß dafür gesorgt werden, daß WIRE im Layer 57/58 die die gleiche " "ausrichtung besitzen aber unterschiedlich breit sein müssen (wegen Z) nicht an den gleichen Koordinaten " "beginnen bzw. Enden wie die RECTs. EAGLE würde sonst die Wirekoordinaten integrieren und eine " "resultierende Wirebreite erzeugen. Es muß also dafür gesorgt werden, das die unterschiedlichen Wirebreiten " "mindestens mit einen Versatz von einer Eagle-Einheit (3.125nanometer) gezeichnet werden." "Author: alf@cadsoft.de" string Verison = "1.0.2"; // 2013-01-14 alf@cadsoft.de // 2013-04-23 now with menu // 2014-03-13 draw also RECT as wire with "high" as line int Test = 0; // Benutzung : Xneu(X, Y, X-drehpunkt, Y-drehpunkt, UserWinkel) real Xneu(real Xalt, real Yalt, real Xorigin, real Yorigin, real UserWinkel) { real RADIUS = sqrt(((Xalt - Xorigin) * (Xalt - Xorigin)) + ((Yalt - Yorigin) * (Yalt - Yorigin))); real WinkelNeu; /* alter Cosinus Winkel = (Xalt - Xorigin) / RADIUS; */ if ((Xalt > Xorigin) && (Yalt >= Yorigin)) { /* Quadrant 1 */ WinkelNeu = acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel; real rad = PI / 180 * WinkelNeu; return (RADIUS * cos(rad)); } if ((Xalt < Xorigin) && (Yalt >= Yorigin)) { /* Quadrant 2 */ WinkelNeu = acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel; real rad = PI / 180 * WinkelNeu; return (RADIUS * cos(rad)); } if ((Xalt < Xorigin) && (Yalt < Yorigin)) { /* Quadrant 3 */ WinkelNeu = 360 - acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel; real rad = PI / 180 * WinkelNeu; return (RADIUS * cos(rad)); } if ((Xalt > Xorigin) && (Yalt < Yorigin)) { /* Quadrant 4 */ WinkelNeu = 360 - acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel; real rad = PI / 180 * WinkelNeu; return (RADIUS * cos(rad)); } if ((Xalt == Xorigin) && (Yalt == Yorigin)) { /* Ursprung */ WinkelNeu = (Xalt - Xorigin) + UserWinkel; real rad = PI / 180 * WinkelNeu; return (RADIUS * cos(rad)); } if ((Xalt == Xorigin) && (Yalt > Yorigin)) { /* 90° */ WinkelNeu = (Xalt - Xorigin + 90) + UserWinkel; real rad = PI / 180 * WinkelNeu; return (RADIUS * cos(rad)); } if ((Xalt == Xorigin) && (Yalt < Yorigin)) { /* 270° */ WinkelNeu = (Xalt - Xorigin + 270)+ UserWinkel; real rad = PI / 180 * WinkelNeu; return (RADIUS * cos(rad)); } } // Benutzung : Yneu(X, Y, X-drehpunkt, Y-drehpunkt, UserWinkel) real Yneu(real Xalt, real Yalt, real Xorigin, real Yorigin, real UserWinkel) { real RADIUS = sqrt(((Xalt - Xorigin) * (Xalt - Xorigin)) + ((Yalt - Yorigin) * (Yalt - Yorigin))); real WinkelNeu; /* alter Cosinus Winkel = (Xalt - Xorigin) / RADIUS; */ if ((Xalt > Xorigin) && (Yalt >= Yorigin)) { /* Quadrant 1 */ WinkelNeu = acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel; real rad = PI / 180 * WinkelNeu; return (RADIUS * sin(rad)); } if ((Xalt < Xorigin) && (Yalt >= Yorigin)) { /* Quadrant 2 */ WinkelNeu = acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel; real rad = PI / 180 * WinkelNeu; return (RADIUS * sin(rad)); } if ((Xalt < Xorigin) && (Yalt < Yorigin)) { /* Quadrant 3 */ WinkelNeu = 360 - acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel; real rad = PI / 180 * WinkelNeu; return (RADIUS * sin(rad)); } if ((Xalt > Xorigin) && (Yalt < Yorigin)) { /* Quadrant 4 */ WinkelNeu = 360 - acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel; real rad = PI / 180 * WinkelNeu; return (RADIUS * sin(rad)); } if ((Xalt == Xorigin) && (Yalt == Yorigin)) { /* Ursprung */ WinkelNeu = (Xalt - Xorigin) + UserWinkel; real rad = PI / 180 * WinkelNeu; return (RADIUS * sin(rad)); } if ((Xalt == Xorigin) && (Yalt > Yorigin)) { /* 90° */ WinkelNeu = (Xalt - Xorigin + 90) + UserWinkel; real rad = PI / 180 * WinkelNeu; return (RADIUS * sin(rad)); } if ((Xalt == Xorigin) && (Yalt < Yorigin)) { /* 270° */ WinkelNeu = (Xalt - Xorigin + 270) + UserWinkel; real rad = PI / 180 * WinkelNeu; return (RADIUS * sin(rad)); } } if (package) { real Ztop = strtod(argv[1]); real Zbottom = strtod(argv[1]); if (argc == 1) { int optg, optb; dlgDialog("IDF 3D Package") { dlgLabel(usage); dlgLabel("


"); dlgHBoxLayout { dlgGridLayout { dlgCell( 0, 0) dlgLabel("&Z high top mm"); dlgCell( 0, 1) dlgRealEdit(Ztop); dlgCell( 1, 0) dlgLabel("&Z high bottom mm"); dlgCell( 1, 1) dlgRealEdit(Zbottom); } dlgStretch(1); } dlgHBoxLayout { dlgPushButton("+OK") { Ztop /= 1000; Zbottom /= 1000; if (Ztop >= u2mm(2) || Zbottom >= u2mm(2) ) { dlgAccept(); } else { if (language() != "de") { dlgMessageBox("First type in a real value for Z of Top and/or Bottom.", "OK"); } else { dlgMessageBox("Geben Sie zuerst einen (gültigen) Wert für die Höhe Z von Top bzw. Bottom ein.", "OK"); } } } dlgPushButton("-CANCEL") { dlgReject(); exit(0); } dlgStretch(1); } }; } string cmd, s; string cmdl = ""; int layer3dt, layer3db; library(LIB) LIB.layers(LAY) { if(LAY.number == 57) layer3dt = LAY.number; if(LAY.number == 58) layer3db = LAY.number; } if (!layer3dt && !layer3db) { layer3dt = 57; layer3db = 58; cmdl = "LAYER 57 t3D; SET COLOR_LAYER 57 6; SET FILL_LAYER 57 5; LAYER 58 b3D; SET COLOR_LAYER 58 5; SET FILL_LAYER 58 4;"; } if (Ztop < u2mm(2)) { string h, com; if (language() != "de") { sprintf(h, "!The calculated value for Z-top %.9f is < %.9fmm", Ztop, u2mm(2)); com = "CANCEL"; } else { sprintf(h, "!Der umgerechnete Wert für Z-top %.9f ist < %.9fmm", Ztop, u2mm(2)); com = "ABBRUCH"; } dlgMessageBox(h, com); exit(-1); } if (Ztop < u2mm(2)) { string h, com; if (language() != "de") { sprintf(h, "!The calculated value for Z-bottom %.9f is < %.9fmm", Ztop, u2mm(2)); com = "CANCEL"; } else { sprintf(h, "!Der umgerechnete Wert für Z-bottom %.9f ist < %.9fmm", Ztop, u2mm(2)); com = "ABBRUCH"; } dlgMessageBox(h, com); exit(-1); } package(P) { //sprintf(cmd, "Display NONE 1 16 17 18 20 23 25 27 57;\nSET WIRE_BEND 2;\n"); cmd += cmdl; P.rectangles(R) { real rectcenterx = u2mm((R.x1 + R.x2) / 2); real rectcentery = u2mm((R.y1 + R.y2) / 2); if (R.layer == 21 || R.layer == 51) { sprintf(s, "LAYER %d;\nWIRE %.9fmm (%.9fmm %.9fmm ) (%.9fmm %.9fmm ) (%.9fmm %.9fmm ) (%.9fmm %.9fmm ) (%.9fmm %.9fmm );\n", layer3dt, Ztop, Xneu(u2mm(R.x1) - rectcenterx, u2mm(R.y1) - rectcentery, 0, 0, R.angle) + rectcenterx, Yneu(u2mm(R.x1) - rectcenterx, u2mm(R.y1) - rectcentery, 0, 0, R.angle) + rectcentery, Xneu(u2mm(R.x1) - rectcenterx, u2mm(R.y2) - rectcentery, 0, 0, R.angle) + rectcenterx, Yneu(u2mm(R.x1) - rectcenterx, u2mm(R.y2) - rectcentery, 0, 0, R.angle) + rectcentery, Xneu(u2mm(R.x2) - rectcenterx, u2mm(R.y2) - rectcentery, 0, 0, R.angle) + rectcenterx, Yneu(u2mm(R.x2) - rectcenterx, u2mm(R.y2) - rectcentery, 0, 0, R.angle) + rectcentery, Xneu(u2mm(R.x2) - rectcenterx, u2mm(R.y1) - rectcentery, 0, 0, R.angle) + rectcenterx, Yneu(u2mm(R.x2) - rectcenterx, u2mm(R.y1) - rectcentery, 0, 0, R.angle) + rectcentery, Xneu(u2mm(R.x1) - rectcenterx, u2mm(R.y1) - rectcentery, 0, 0, R.angle) + rectcenterx, Yneu(u2mm(R.x1) - rectcenterx, u2mm(R.y1) - rectcentery, 0, 0, R.angle) + rectcentery ); cmd += s; } else if (R.layer == 22 || R.layer == 52) { sprintf(s, "LAYER %d;\nWIRE %.9fmm (%.9fmm %.9fmm ) (%.9fmm %.9fmm ) (%.9fmm %.9fmm ) (%.9fmm %.9fmm ) (%.9fmm %.9fmm );\n", layer3db, Zbottom, Xneu(u2mm(R.x1) - rectcenterx, u2mm(R.y1) - rectcentery, 0, 0, R.angle) + rectcenterx, Yneu(u2mm(R.x1) - rectcenterx, u2mm(R.y1) - rectcentery, 0, 0, R.angle) + rectcentery, Xneu(u2mm(R.x1) - rectcenterx, u2mm(R.y2) - rectcentery, 0, 0, R.angle) + rectcenterx, Yneu(u2mm(R.x1) - rectcenterx, u2mm(R.y2) - rectcentery, 0, 0, R.angle) + rectcentery, Xneu(u2mm(R.x2) - rectcenterx, u2mm(R.y2) - rectcentery, 0, 0, R.angle) + rectcenterx, Yneu(u2mm(R.x2) - rectcenterx, u2mm(R.y2) - rectcentery, 0, 0, R.angle) + rectcentery, Xneu(u2mm(R.x2) - rectcenterx, u2mm(R.y1) - rectcentery, 0, 0, R.angle) + rectcenterx, Yneu(u2mm(R.x2) - rectcenterx, u2mm(R.y1) - rectcentery, 0, 0, R.angle) + rectcentery, Xneu(u2mm(R.x1) - rectcenterx, u2mm(R.y1) - rectcentery, 0, 0, R.angle) + rectcenterx, Yneu(u2mm(R.x1) - rectcenterx, u2mm(R.y1) - rectcentery, 0, 0, R.angle) + rectcentery ); cmd += s; } } P.wires(W) { if (W.layer == 21 || W.layer == 51) { sprintf(s, "Layer %d;\nWIRE %.9fmm (%.9fmm %.9fmm ) %+.3f (%.9fmm %.9fmm );\n", layer3dt, Ztop, u2mm(W.x1), u2mm(W.y1), W.curve, u2mm(W.x2), u2mm(W.y2) ); cmd += s; } else if (W.layer == 22 || W.layer == 52) { sprintf(s, "Layer %d;\nWIRE %.9fmm (%.9fmm %.9fmm ) %+.3f (%.9fmm %.9fmm );\n", layer3db, Zbottom, u2mm(W.x1), u2mm(W.y1), W.curve, u2mm(W.x2), u2mm(W.y2) ); cmd += s; } } } if (Test) { dlgDialog("3D IDF test") { dlgHBoxLayout dlgSpacing(600); dlgHBoxLayout { dlgVBoxLayout dlgSpacing(600); dlgTextEdit(cmd); } dlgHBoxLayout { dlgPushButton("ok") dlgAccept(); dlgPushButton("esc") { dlgReject(); exit(-273); } dlgStretch(1); } }; } exit(cmd); } else { if (language() == "de") dlgMessageBox("Starten Sie das ULP in einem Package (Bibliothek)", "OK"); else dlgMessageBox("Start this ULP in a package (library)", "OK"); }