Advertisement
Guest User

Untitled

a guest
Apr 24th, 2015
327
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.21 KB | None | 0 0
  1. #usage "<h3><br>Export data for KCam or any other CNC software </h3><br>"
  2. "<br>"
  3. "- Bottom layer will be mirrored by Y AXIS<br>"
  4. "- It uses only G00, G01 and G02, even for drilling (G82 it's not backlash compensated in KCam)<br>"
  5. "- If you want holes with complicated shapes in board, use a polygon in dimension layer, with width of drill used to cut the board.<br>"
  6. "- If Drill is checked, all holes will be drilled.<br>"
  7. "- If Cut is checked, all holes (from pads, vias etc.) larger than cut_tool will be milled.<br>"
  8. "<br>- If you do not have a file called gcode.set next to this ulp, at first run, comment #include gcode.set and uncomment folowing definitions.<br>"
  9. "<br>"
  10. "<br>"
  11. "Things left to be implemented: *sort all elements for minimum travel time; *implement fill function<br>"
  12. "<br>"
  13. "<b>Author</b>: eSilviu<br>"
  14. "Work time: 3 nights<br>"
  15.  
  16. //include... OR uncomment below (only at first run)
  17. #include "gcode.set"
  18. /*
  19. int mill_on =1;
  20. int fill_on =1;
  21. real mill_tool =0.5;
  22. real mill_down =0.2;
  23. real mill_up =0.2;
  24. real mill_speed =200;
  25.  
  26. int drill_on =1;
  27. real drill_down =0.2;
  28. real drill_up =0.2;
  29. real drill_speed =200;
  30.  
  31. int cut_on =1;
  32. real cut_depth =2.5;
  33. int cut_steps =2;
  34. real cut_gap =3;
  35. real cut_speed =100;
  36. real cut_tool =1;
  37. real cut_up =1;
  38.  
  39. real tool_up =30;
  40. int layer =-1;*/
  41.  
  42.  
  43. string Layers[] = {"Top","Bottom"};
  44. int Selected_layer;
  45. if (layer==1) Selected_layer=0;
  46. if (layer==-1) Selected_layer=1;
  47.  
  48. string Steps[] = { "1", "2", "3", "4" ,"5", "6", "7", "8" };
  49. int Sel_Cut;
  50. Sel_Cut=cut_steps-1;
  51.  
  52. int step_ulp = 1;
  53. string fileName;
  54. string OutlinesSignalName = "_OUTLINES_";
  55. string final_cmd;
  56.  
  57. if (board) board(B) {fileName = filesetext(B.name, ".gc");}
  58. else {dlgMessageBox("\n Start this ULP in a Board \n"); exit (0);}
  59.  
  60. //parameters passed to ulp at second run
  61. if (argv[1])
  62. {if (argv[2])
  63. {mill_tool = strtod(argv[2]);
  64. if (argv[3])
  65. {layer = strtol(argv[3]);
  66. if (argv[4])
  67. {fileName = argv[4];
  68. if(argv[5])
  69. {step_ulp = 2;
  70. }}}}}
  71.  
  72. //*************************** Functions body ***************************
  73.  
  74. void write_real_param(string name, real value)
  75. { printf("real %s = %f;\n", name, value); }
  76.  
  77. void write_int_param(string name, int value)
  78. { printf("int %s = %d;\n", name, value); }
  79.  
  80. //error message if exist a signal named _OUTLINES_
  81. void Fatal(string Message, string Details)
  82. { dlgMessageBox(usage + "<hr><b>ERROR: " + Message + "</b><p>\n" + Details); exit(1); }
  83.  
  84. //Z->up; stop; Z->0.00 (calibrate Z axis) Z->0.50, ready for start
  85. void DeviceChangeBit(void)
  86. {real x1, x2, y1, y2;
  87. output(fileName, "at")
  88. {printf ("\nG00 Z%2.3f\n",tool_up);
  89. printf ("G00 X0.000 Y0.000\n");
  90. printf ("M00\n");
  91. printf ("G00 Z0.000\n");
  92. printf ("M00\n");
  93. board (B){
  94. x1 = u2mm(B.area.x1); y1 = u2mm(B.area.y1);
  95. x2 = u2mm(B.area.x2); y2 = u2mm(B.area.y2);}
  96.  
  97. // printf("G00 X%.3f Y%.3f\n", x1, y1*layer);
  98. // printf("G00 X%.3f Y%.3f\n", x2, y1*layer);
  99. // printf("G00 X%.3f Y%.3f\n", x2, y2*layer);
  100. // printf("G00 X%.3f Y%.3f\n", x1, y2*layer);
  101. // printf("G00 X%.3f Y%.3f\n", x1, y1*layer);
  102.  
  103. printf ("G00 Z0.500\n");
  104. printf ("\n(Bit changed, zero set.)\n");
  105. }}
  106.  
  107. //create file for gcode output, write first lines
  108. void DeviceInit(void)
  109. {output(fileName, "wt")
  110. {printf ("(%s)\n(%s)\n(%s)\n", fileName, Layers[Selected_layer], t2string(time()));
  111. if (layer==-1) printf ("(X/Y/Z home should be at upper left corner of the board, with the tip just touching board)\n");
  112. else printf ("(X/Y/Z home should be at lower left corner of the board, with the tip just touching board)\n");
  113. printf ("(Mm, Absolute mode, lift cutter above work, rapid to X/Y home, spindle on.)\n");
  114. printf ("G21\n");
  115. printf ("G90\n");
  116. }}
  117.  
  118. //write the necessary stuff for machine STOP
  119. void DeviceEnd(void)
  120. { output(fileName, "at")
  121. {printf("(Finished.)\n");
  122. printf("G00 Z%.3f\n",tool_up);
  123. printf("M05\n");
  124. printf("G00 X0 Y0\n");
  125. printf("M30\n");
  126. }}
  127.  
  128. void CutDrillHole(real h_x, real h_y, real h_d, real tool, real cut_depth)
  129. { real raza=(h_d-tool)/2;
  130. real cut_down=0;
  131. for (int i = 0; i<cut_steps; ++i)
  132. {cut_down=cut_down+cut_depth/cut_steps;
  133. if (h_d > tool)
  134. {printf("G00 X%.3f Y%.3f\n", h_x, (h_y+raza)*layer);
  135. printf("G01 Z-%.3f F%.1f\n",cut_down, cut_speed);
  136. printf("G02 X%.3f Y%.3f R%3f F%.1f\n", h_x+raza*layer, h_y*layer, raza, cut_speed);
  137. printf("G02 X%.3f Y%.3f R%3f F%.1f\n", h_x, (h_y-raza)*layer, raza, cut_speed);
  138. printf("G02 X%.3f Y%.3f R%3f F%.1f\n", h_x-raza*layer, h_y*layer, raza, cut_speed);
  139. printf("G02 X%.3f Y%.3f R%3f F%.1f\n", h_x, (h_y+raza)*layer, raza, cut_speed);
  140. printf("G00 Z%.3f\n\n", cut_up);
  141. }}}
  142.  
  143.  
  144. //add a hole to the output file
  145. void AddHole(int x, int y)
  146. { real x_int, y_int;
  147. x_int = u2mm(x);
  148. y_int = u2mm(y);
  149. printf("G00 X%.3f Y%.3f\n", x_int, y_int*layer);
  150. printf("G01 Z-%.3f F%.1f\n", drill_down, cut_speed);
  151. printf("G00 Z%.3f\n\n", drill_up);
  152. }
  153.  
  154. //cut the board, as the wires in DIMENSION layer says; gap is used to keep board in place until end
  155. void DeviceCut(void)
  156. { real a, b, c, d, gap1, gap2, cut_down, x_old=REAL_EPSILON, y_old=REAL_EPSILON;
  157. gap1=(50-cut_gap/2)/100;
  158. gap2=(50+cut_gap/2)/100;
  159. cut_down=0;
  160. output(fileName, "at")
  161. {printf("(Start cutting holes)\n");
  162. board(B)
  163. {B.holes(H) CutDrillHole(u2mm(H.x), u2mm(H.y), u2mm(H.drill), cut_tool, cut_depth);
  164. B.signals(S) S.vias(V) CutDrillHole(u2mm(V.x),u2mm(V.y),u2mm(V.drill),cut_tool, cut_depth);
  165. B.elements(E)
  166. {E.package.contacts(C) if (C.pad) CutDrillHole(u2mm(C.pad.x),u2mm(C.pad.y),u2mm(C.pad.drill),cut_tool, cut_depth);
  167. E.package.holes(H) CutDrillHole(u2mm(H.x),u2mm(H.y),u2mm(H.drill),cut_tool, cut_depth);
  168. }
  169. printf("(Start cutting polygons)\n");
  170. for (int i = 0; i<cut_steps; ++i)
  171. {cut_down=cut_down+cut_depth/cut_steps;
  172. B.polygons(P)
  173. {int x_0, y_0, first_p = 1;
  174. P.contours(W)
  175. {if (W.layer == LAYER_DIMENSION)
  176. {if (first_p)
  177. {x_0 = W.x1; y_0 = W.y1;
  178. printf("G00 X%.3f Y%.3f\n", u2mm(x_0), layer*u2mm(y_0));
  179. printf("G01 Z-%.3f F%.1f\n",cut_down, cut_speed);
  180. first_p = 0;}
  181. printf("G01 X%.3f Y%.3f F%.1f\n", u2mm(W.x1), layer*u2mm(W.y1), cut_speed);
  182. if (W.x2 == x_0 && W.y2 == y_0)
  183. {first_p = 1;
  184. printf("G01 X%.3f Y%.3f F%.1f\n", u2mm(W.x2), layer*u2mm(W.y2), cut_speed);
  185. printf("G00 Z%.3f\n\n", cut_up);
  186. }}}}
  187. printf("(Start cutting wires)\n");
  188. B.wires(W)
  189. {if (W.layer == LAYER_DIMENSION)
  190. {
  191. //optimizare linii
  192. // if ((pow(abs(u2mm(W.x1)-x_old),2)+pow(abs(u2mm(W.y1)-y_old),2))>=(pow(abs(u2mm(W.x2)-x_old),2)+pow(abs(u2mm(W.y2)-y_old),2)))
  193. // {a=u2mm(W.x2); b=u2mm(W.y2); c=u2mm(W.x1); d=u2mm(W.y1);}
  194. // else
  195. {a=u2mm(W.x1); b=u2mm(W.y1); c=u2mm(W.x2); d=u2mm(W.y2);};
  196. if ((x_old==a)&&(y_old==b)) {printf("G01 Z-%.3f F%.1f\n",cut_down, cut_speed);}
  197. else {printf("G00 Z%.3f\n\n", cut_up);
  198. printf("G00 X%.3f Y%.3f\n", a, b*layer);
  199. printf("G01 Z-%.3f F%.1f\n",cut_down, cut_speed);};
  200. if (abs(a-c)>=10 || abs(b-d)>=10)
  201. {printf("G01 X%.3f Y%.3f F%.1f\n", a+(c-a)*gap1, (b+(d-b)*gap1)*layer, cut_speed);
  202. if (cut_gap>0) {printf("G00 Z-%.3f\n", cut_down/2);
  203. printf("G00 X%.3f Y%.3f\n", a+(c-a)*gap2, (b+(d-b)*gap2)*layer);
  204. printf("G01 Z-%.3f F%.1f\n",cut_down, cut_speed);}
  205. }
  206. printf("G01 X%.3f Y%.3f F%.1f\n", c, d*layer, cut_speed);
  207. x_old=c; y_old=d;
  208. }}
  209. printf("G00 Z%.3f\n\n", cut_up);
  210. }}}}
  211.  
  212. //function that reads drill positions and call AddHole() function
  213. void DeviceDrill(void)
  214. { output(fileName, "at")
  215. {printf("(Start drilling)\n");
  216. board(B)
  217. {printf("G00 Z%.3f\n", drill_up);
  218. B.holes(H) AddHole(H.x, H.y);
  219. B.signals(S) S.vias(V) AddHole(V.x, V.y);
  220. B.elements(E)
  221. {E.package.contacts(C)
  222. {if (C.pad)AddHole(C.pad.x, C.pad.y);}
  223. E.package.holes(H) AddHole(H.x, H.y);
  224. }}}}
  225.  
  226.  
  227.  
  228. //function that create a single poligon on selected layer
  229. void GenerateOutlines(void)
  230. { board(B) {
  231. real f = 0.01, //qwert
  232. x1 = u2mm(B.area.x1) - f, y1 = u2mm(B.area.y1) - f,
  233. x2 = u2mm(B.area.x2) + f, y2 = u2mm(B.area.y2) + f;
  234. B.signals(S) {
  235. if (S.name == OutlinesSignalName)
  236. Fatal("There is already a signal named " + OutlinesSignalName + " in this board!", "Please make sure that there is no such signal in this board.");
  237. }
  238. step_ulp=2;
  239. string Cmd;
  240. int displ_;
  241. if (layer ==1) displ_=1;
  242. if (layer ==-1) displ_=16;
  243. sprintf(Cmd, "grid mm;\n"
  244. "window fit;\n"
  245. "change isolate 0;\n"
  246. "change rank 6;\n"
  247. "change pour solid;\n"
  248. "change orphans on;\n"
  249. "SET WIRE_BEND 2;\n"
  250. "layer %d;\n"
  251. "polygon %s %f (%f %f) (%f %f) (%f %f) (%f %f) (%f %f);\n"
  252. "ratsnest;\n"
  253. "run '%s' argv[1] '%f' '%d' '%s' '%d';",
  254. displ_,
  255. OutlinesSignalName, mill_tool, x1, y1, x2, y1, x2, y2, x1, y2, x1, y1,
  256. argv[0], mill_tool, layer, fileName, step_ulp);
  257. exit(Cmd);
  258. }
  259. }
  260.  
  261. //function that write outlines in output file
  262. void DeviceDraw(int x1, int y1, int x2, int y2, int state_mill)
  263. { if (state_mill == 0)
  264. {printf("G00 Z%.3f\n\n",mill_up);
  265. printf("G00 X%.3f Y%.3f\n",u2mm(x1),layer*u2mm(y1));
  266. printf("G01 Z-%f F%.1f\n",mill_down, cut_speed);
  267. printf("G01 X%.3f Y%.3f F%.1f\n",u2mm(x2), layer*u2mm(y2), cut_speed);
  268. }
  269. else printf("G01 X%.3f Y%.3f F%.1f\n", u2mm(x2), layer*u2mm(y2), cut_speed);
  270. }
  271.  
  272. //function that generate coordinates for outlines (it will be executed right after second run of the ulp)
  273. void WriteOutlines(void)
  274. {
  275. output(fileName, "at") {
  276. board(B){
  277. B.signals(S) {
  278. if (S.name == OutlinesSignalName) {
  279. S.polygons(P) {
  280. int x1 = INT_MAX, y1 = INT_MAX, x2 = INT_MIN, y2 = INT_MIN;
  281. int x0, y0, first = 1;
  282. int FrameWire;
  283. int State;
  284. P.wires(W) {
  285. x1 = min(x1, W.x1);
  286. x2 = max(x2, W.x1);
  287. y1 = min(y1, W.y1);
  288. y2 = max(y2, W.y1);
  289. }
  290. P.contours(W) {
  291. if (first) {
  292. x0 = W.x1;
  293. y0 = W.y1;
  294. FrameWire = (x1 == x0 || x2 == x0) && (y1 == y0 || y2 == y0);
  295. State = 0;
  296. first = 0;
  297. }
  298. else if (W.x2 == x0 && W.y2 == y0) {
  299. State = 2;
  300. first = 1;
  301. }
  302. else
  303. State = 1;
  304. if (!FrameWire)
  305. DeviceDraw(W.x1, W.y1, W.x2, W.y2, State);
  306. }
  307.  
  308. sprintf(final_cmd, "delete (%f %f) (%f %f); window fit;\n", u2mm(x1), u2mm(y1), u2mm(x2), u2mm(y2));
  309. }
  310. break;
  311. }}}}}
  312.  
  313. void Fill(void)
  314. {real old_x=REAL_EPSILON, old_y=REAL_EPSILON, a, b, c, d;
  315. output(fileName, "at") {
  316. board(B){
  317. B.signals(S) {
  318. if (S.name == OutlinesSignalName) {
  319. S.polygons(P) {
  320. int x1 = INT_MAX, y1 = INT_MAX, x2 = INT_MIN, y2 = INT_MIN;
  321. P.wires(W) {
  322. x1 = min(x1, W.x1);
  323. x2 = max(x2, W.x1);
  324. y1 = min(y1, W.y1);
  325. y2 = max(y2, W.y1);
  326. }
  327. printf("\nStart filling empty spaces\n");
  328. P.fillings(W) {
  329. if ((pow(abs(W.x1-old_x),2)+pow(abs(W.y1-old_y),2))>=(pow(abs(W.x2-old_x),2)+pow(abs(W.y2-old_y),2)))
  330. {a=W.x2; b=W.y2; c=W.x1; d=W.y1;}
  331. else {a=W.x1; b=W.y1; c=W.x2; d=W.y2;}
  332.  
  333. DeviceDraw(a, b, c, d, 0);
  334. old_x=c; old_y=d;
  335. }
  336. if (!mill_on) sprintf(final_cmd, "delete (%f %f) (%f %f); window fit;\n", u2mm(x1), u2mm(y1), u2mm(x2), u2mm(y2));
  337. }
  338. }}}}}
  339.  
  340.  
  341.  
  342. //---------------------------------GRAPHICAL INTERFACE, will appear only at first run of the ulp----------------------------------------------
  343. if (step_ulp==1)
  344. { int Result = dlgDialog("Select Parameters")
  345. {dlgHBoxLayout
  346.  
  347. {dlgLabel("Layer: ");
  348. dlgComboBox(Layers, Selected_layer) {if (Selected_layer==0) layer=1; if (Selected_layer==1) layer=-1;};
  349. dlgStretch(1);
  350. }
  351.  
  352. dlgHBoxLayout {
  353. dlgGroup("Mill") {
  354. dlgGridLayout {dlgCell(0, 0) dlgCheckBox("&Active", mill_on); dlgCell(0, 1) dlgCheckBox("Clear unused area", fill_on);}
  355. dlgGridLayout {
  356. dlgCell(0, 0) dlgLabel("&Tool");
  357. dlgCell(0, 1) dlgRealEdit(mill_tool, 0.01, 50);
  358. dlgCell(1, 0) dlgLabel("&Depth");
  359. dlgCell(1, 1) dlgRealEdit(mill_down, 0, 50);
  360. dlgCell(2, 0) dlgLabel("&Z up");
  361. dlgCell(2, 1) dlgRealEdit(mill_up, 0, 50);
  362. dlgCell(3, 0) dlgLabel(" ");
  363. dlgCell(4, 0) dlgLabel("&Speed");
  364. dlgCell(4, 1) dlgRealEdit(mill_speed, 0, 500);
  365. }}
  366.  
  367. dlgVBoxLayout {
  368. dlgGroup("Drill") {
  369. dlgCheckBox("&Active", drill_on);
  370. dlgGridLayout {
  371. dlgCell(0, 0) dlgLabel("&Depth");
  372. dlgCell(0, 1) dlgRealEdit(drill_down, 0, 50);
  373. dlgCell(1, 0) dlgLabel("&Z up");
  374. dlgCell(1, 1) dlgRealEdit(drill_up, 0, 50);
  375. dlgCell(2, 0) dlgLabel("&Speed");
  376. dlgCell(2, 1) dlgRealEdit(drill_speed, 0, 500);
  377. }}
  378. dlgGroup("Misc") {
  379. dlgGridLayout {
  380. dlgCell(0, 1) dlgLabel("&Tool up");
  381. dlgCell(0, 2) dlgRealEdit(tool_up, 0, 50);
  382. dlgCell(0, 3) dlgStretch(500);
  383. }}}
  384.  
  385. dlgGroup("Cut") {
  386. dlgCheckBox("&Active", cut_on);
  387. dlgGridLayout {
  388. dlgCell(0, 0) dlgLabel("&Tool");
  389. dlgCell(0, 1) dlgRealEdit(cut_tool, 0.1, 50);
  390. dlgCell(1, 0) dlgLabel("&Depth");
  391. dlgCell(1, 1) dlgRealEdit(cut_depth, 0, 50);
  392. dlgCell(2, 0) dlgLabel("&Steps");
  393. dlgCell(2, 1) dlgComboBox(Steps, Sel_Cut) {cut_steps = Sel_Cut+1;};
  394. dlgCell(3, 0) dlgLabel("&Gap [%]");
  395. dlgCell(3, 1) dlgRealEdit(cut_gap, 0, 50);
  396. dlgCell(4, 0) dlgLabel("&Z up");
  397. dlgCell(4, 1) dlgRealEdit(cut_up, 0, 50);
  398. dlgCell(5, 0) dlgLabel("&Speed");
  399. dlgCell(5, 1) dlgRealEdit(cut_speed, 0, 500);
  400. }}}
  401.  
  402. dlgHBoxLayout {
  403. dlgLabel("Output file:");
  404. dlgStringEdit(fileName);
  405. dlgPushButton("Bro&wse") {string fn = dlgFileSave("Save Output file", fileName);if (fn) fileName = fn;}
  406. }
  407.  
  408. dlgSpacing(10);
  409. dlgHBoxLayout {
  410. dlgLabel("Note: All dimension are in milimeters. Speed is [mm/min]");
  411. dlgStretch(1);
  412. dlgPushButton("+OK") dlgAccept(1);
  413. dlgPushButton("Cancel") { dlgReject(0); exit(1); }
  414. }
  415. } ;
  416.  
  417. //save parameters in gcode.set file
  418. if (Result==1)
  419. { fileerror();
  420. output(path_ulp[0] + "/gcode.set", "wt")
  421. {printf("//List of usual parameters:\n");
  422. write_int_param("mill_on", mill_on);
  423. write_int_param("fill_on", fill_on);
  424. write_real_param("mill_tool", mill_tool);
  425. write_real_param("mill_down", mill_down);
  426. write_real_param("mill_up", mill_up);
  427. write_real_param("mill_speed", mill_speed);
  428. write_int_param("drill_on", drill_on);
  429. write_real_param("drill_down", drill_down);
  430. write_real_param("drill_up", drill_up);
  431. write_real_param("drill_speed", drill_speed);
  432. write_int_param("cut_on", cut_on);
  433. write_real_param("cut_depth", cut_depth);
  434. write_int_param("cut_steps", cut_steps);
  435. write_real_param("cut_tool", cut_tool);
  436. write_real_param("cut_up", cut_up);
  437. write_real_param("cut_gap", cut_gap);
  438. write_real_param("cut_speed", cut_speed);
  439. write_real_param("tool_up", tool_up);
  440. write_int_param("layer", layer);
  441. }
  442. if (fileerror()) {dlgMessageBox("Save param. error"); exit(1);};
  443. } }
  444.  
  445. //milling part require two run of the ulp
  446. if (mill_on==1 || fill_on==1)
  447. { if (step_ulp==1)
  448. {DeviceInit();
  449. GenerateOutlines();
  450. }
  451. if (step_ulp==2)
  452. {
  453. if (mill_on) {DeviceChangeBit(); WriteOutlines();}
  454. if (fill_on) {DeviceChangeBit(); Fill();}
  455. if (drill_on==1) {DeviceChangeBit(); DeviceDrill();}
  456. if (cut_on==1) {DeviceChangeBit(); DeviceCut();}
  457. DeviceEnd();
  458. //system("cmd.exe opti.exe <fileName>.gc");
  459. dlgMessageBox(";Succes!");
  460. exit(final_cmd);
  461.  
  462. }
  463. }
  464.  
  465. //if no mill is necessary, ulp will run only once
  466. if (mill_on==0)
  467. { DeviceInit();
  468. if (drill_on==1) {DeviceChangeBit(); DeviceDrill();}
  469. if (cut_on==1) {DeviceChangeBit(); DeviceCut();}
  470. DeviceEnd();
  471. //system("cmd.exe /c opti.exe <fileName>.gc");
  472. dlgMessageBox(";Succes!");
  473. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement