#usage "outline_drill_holes_cutoff \n" "

" "Usage: RUN outline_drill_holes_cutoff" "

" "Author: http://www.mi-ra-i.com/OPEN-JMM/" "

" "Author: miracute@hotmail.co.jp

" ////////////////////////////////////////////////////// //////////////////// ユーザー設定 //////////////////// ////////////////////////////////////////////////////// string DefaultSuffix = "_cut.tap"; // お使いのCNC似合わせた拡張子に変更してください real dtool = 0.8; // エンドミルの直径を指定してください real zstep = 0.4; // Z軸のステップ値を指定してください real depth = -1.5; // 基板の厚さを指定してください int fvalue = 200; // XY軸のF値を指定してください int z_fvalue = 50; // Z軸のF値を指定してください real cut_up = 1; // 空転移動時の高さを指定してください int drill_cut = 1; // 取り付け穴のパスが必要ない場合は0にしてください int drill_on = 1; // エンドミルによるドリルのオンオフ int pecker_mode = 1; // キツツキドリルのオンオフ /////////////////////////////////////////////////////// ////////////////////// ここまで /////////////////////// /////////////////////////////////////////////////////// real pai = 3.14159265358979; real tool = dtool / 2.0; real zpos = 0.0; int layer =-1; int into = 1; real g_line_number = 10; int g_fg_line_number = 1; int g_fg_sort = 1; int g_fg_sort_x_or_y = 1; int g_x[], g_y[]; // coordinate of hole int g_xy_array_size; real g_round = 0.1; real g_drill_size_list[]; int g_drill_size_list_array_size; string gFileName; //------------------------------------------------------------------------------- // void add_to_drill_list( int size ) { real x; int i; x = ( u2mm( size ) / g_round ) * g_round; // printf (">add_to_drill_list( size=%.3f ) \n" , x ); for (i=0; i < g_drill_size_list_array_size; i++ ) { if ( g_drill_size_list[i] == x ) return; } g_drill_size_list[g_drill_size_list_array_size] = x; g_drill_size_list_array_size++; } //------------------------------------------------------------------------------- // void sort_drill_size_list() { int i, j; real a1,a2; for(i=0; ii; j--){ if( g_drill_size_list[ j-1 ] > g_drill_size_list[ j ] ){ a1 = g_drill_size_list[ j - 1]; a2 = g_drill_size_list[ j ]; g_drill_size_list[ j - 1] = a2; g_drill_size_list[ j ] = a1; } } } } //------------------------------------------------------------------------------- // int create_drill_size_list() { // printf (">create_drill_size_list() \n"); g_drill_size_list_array_size = 0; if ( board ) board( B ) { B.holes(H) { add_to_drill_list( H.drill ); } B.elements(E) { E.package.holes(H) { add_to_drill_list( H.drill ); } E.package.contacts(C) { if (C.pad) { add_to_drill_list( C.pad.drill ); } } } B.signals(S) { S.vias(V) { add_to_drill_list( V.drill ); } } } sort_drill_size_list(); return g_drill_size_list_array_size; } //------------------------------------------------------------------------------- // ULP のSortにはバグがあり、エレメントのサイズが 0xffff より // 大きいと駄目である、int は32bitなのだが、Sortできるのは16Bitの // ようである。 // 単純にBubble Sortする。(エレメントが少ないからOKかな) // void bubble_sort( int begin, int num_of_record , int option ) { int i, j; int a1,a2; if ( option ) { // Yを基準にソートする for(i=begin; ii; j--){ if( g_y[ j-1 ] > g_y[ j ] ){ a1 = g_y[ j - 1]; a2 = g_y[ j ]; g_y[ j - 1] = a2; g_y[ j ] = a1; a1 = g_x[ j - 1]; a2 = g_x[ j ]; g_x[ j - 1] = a2; g_x[ j ] = a1; } } } } else { // Xを基準にソートする for(i=begin; ii; j--){ if( g_x[ j-1 ] > g_x[ j ] ){ a1 = g_x[ j - 1]; a2 = g_x[ j ]; g_x[ j - 1] = a2; g_x[ j ] = a1; a1 = g_y[ j - 1]; a2 = g_y[ j ]; g_y[ j - 1] = a2; g_y[ j ] = a1; } } } } } //------------------------------------------------------------------------------- // // ある程度グループ化して、その中で二次元ソートを行う // void block_sort( int number_of_record ) { int step_count = 0; int block_step; int block_number_of_record; int j,i,n; int begin; // 始めに、1次元のソートを行う。 bubble_sort( 0, number_of_record , g_fg_sort_x_or_y ); // 次に、1次元ソートの結果をある程度グループ化して、その中で // 2次元目のソートを行う。 begin = 0; if ( g_fg_sort_x_or_y ) { // Yを基準にXをソートする // block のレコード数を数える // とりあえず、5等分してブロック化する。 block_step = g_y[ number_of_record - 1 ] / 5; for (j=1; j <= 10; j++ ) { n = 0; for (i = begin; i < number_of_record; i++ , n++) { if ( g_y[i] > block_step ) { //printf ("(block_step=%d)\n", block_step ); //printf ("(j=%d i=%d n=%d)\n", j,i,n ); bubble_sort( begin, n, 0 ); begin = i; block_step += block_step; break; } } } } else { // Xを基準にソートする // とりあえず、5等分してブロック化する。 block_step = g_x[ number_of_record - 1 ] / 5; for (j=1; j <= 10; j++ ) { n = 0; for (i = begin; i < number_of_record; i++ , n++) { if ( g_x[i] > block_step ) { //printf ("(block_step=%d)\n", block_step ); //printf ("(j=%d i=%d n=%d)\n", j,i,n ); bubble_sort( begin, n, 1 ); begin = i; block_step += block_step; break; } } } } } //------------------------------------------------------------------------------- // void create_xy_data_by_drill_size( real d_size ) { real d; g_xy_array_size = 0; if ( board ) board( B ) { B.holes(H) { d = ( u2mm( H.drill ) / g_round ) * g_round; if ( d == d_size ) { g_x[g_xy_array_size] = H.x; g_y[g_xy_array_size] = H.y; g_xy_array_size++; } } B.elements(E) { E.package.holes(H) { d = ( u2mm( H.drill ) / g_round ) * g_round; if ( d == d_size ) { g_x[g_xy_array_size] = H.x; g_y[g_xy_array_size] = H.y; g_xy_array_size++; } } E.package.contacts(C) { if (C.pad) { d = ( u2mm( C.pad.drill ) / g_round ) * g_round; if ( d == d_size ) { g_x[g_xy_array_size] = C.pad.x; g_y[g_xy_array_size] = C.pad.y; g_xy_array_size++; } } } } B.signals(S) { S.vias(V) { d = ( u2mm( V.drill ) / g_round ) * g_round; if ( d == d_size ) { g_x[g_xy_array_size] = V.x; g_y[g_xy_array_size] = V.y; g_xy_array_size++; } } } } } //------------------------------------------------------------------------------- // void put_line_number() { if ( g_fg_line_number ) { printf("N%05.0f ", g_line_number ); } g_line_number += 1; } //------------------------------------------------------------------------------- // void put_nc_code( int x, int y ) { if (drill_on == 1) { put_line_number(); printf("G00 X%.3f Y%.3f\n", u2mm(x), u2mm(-y)); if (1 == pecker_mode) { while ((depth + 0.000001) < (zpos -= zstep)) { if ( 1 == into ) { put_line_number(); printf("G00 Z%.3f\n",0.2); zpos = -0.2; put_line_number(); printf("G01 Z%.3f F%d\n",zpos, z_fvalue/2); into = 0; }else { put_line_number(); printf("G01 Z%.3f F%d\n",zpos, z_fvalue); } put_line_number(); printf("G00 Z%.3f\n", zpos + zstep); put_line_number(); printf("G00 Z%.3f\n", zpos); } }else { put_line_number(); printf("G00 Z%.3f\n",0.2); zpos = -0.2; into = 0; } put_line_number(); printf("G1Z%.3f F%d\n" , depth , z_fvalue ); put_line_number(); printf("G00 Z%.3f\n" , cut_up ); zpos = 0; into = 1; } } //------------------------------------------------------------------------------- // // void output_nc_header() { printf ("(This G-Code generated with CNC-DRILL-GCODE.ulp program)\n"); printf ("(running under Eagle CAD.)\n"); printf ("\n" ); put_line_number(); printf ("G00 Z2.00\n"); } //------------------------------------------------------------------------------- // // void output_nc_sepaleter( real d_size ) { printf ("(----------------------------------------------------------)\n" ); printf ("( Drill size=%.3fmm )\n", d_size ); printf ("(----------------------------------------------------------)\n" ); } //------------------------------------------------------------------------------- // // void output_nc_footer() { printf ("\n" ); printf ("(----------------------------------------------------------)\n" ); put_line_number(); printf ("G00 Z2.00\n"); put_line_number(); printf ("G00 X0 Y0\n"); put_line_number(); printf ("M05 \n" ); } void holes_cut(int x, int y, real h_d) { real h_x = u2mm(x); real h_y = u2mm(y); real raza=(h_d-dtool)/2; if (h_d > dtool) { put_line_number(); printf("G00 X%.3f Y%.3f\n", h_x, (h_y + raza) * layer); while ((depth + 0.000001) < (zpos -= zstep)) { if ( 1 == into ) { put_line_number(); printf("G00 Z%.3f\n",0.2); zpos = -0.2; into = 0; } put_line_number(); printf("G01 Z%.3f F%d\n",zpos, z_fvalue); put_line_number(); printf("G02 X%.3f Y%.3f R%3f F%d\n", h_x - raza , h_y * layer , raza, fvalue); put_line_number(); printf("G02 X%.3f Y%.3f R%3f F%d\n", h_x , (h_y - raza) * layer, raza, fvalue); put_line_number(); printf("G02 X%.3f Y%.3f R%3f F%d\n", h_x + raza , h_y * layer , raza, fvalue); put_line_number(); printf("G02 X%.3f Y%.3f R%3f F%d\n", h_x , (h_y + raza) * layer, raza, fvalue); } zpos = depth; put_line_number(); printf("G01 Z%.3f F%d\n",zpos, z_fvalue); put_line_number(); printf("G02 X%.3f Y%.3f R%3f F%d\n", h_x - raza , h_y * layer , raza, fvalue); put_line_number(); printf("G02 X%.3f Y%.3f R%3f F%d\n", h_x , (h_y - raza) * layer, raza, fvalue); put_line_number(); printf("G02 X%.3f Y%.3f R%3f F%d\n", h_x + raza , h_y * layer , raza, fvalue); put_line_number(); printf("G02 X%.3f Y%.3f R%3f F%d\n", h_x , (h_y + raza) * layer, raza, fvalue); put_line_number(); printf("G00 Z%.3f\n\n", cut_up); zpos = 0; into = 1; } } real ver_x[]; real ver_y[]; int count = 0; int state = 0; void line_counter() { board(B) { B.wires(W) { if (W.layer == LAYER_DIMENSION) { if (state == 0) { ver_x[count] = u2mm(W.x1); ver_y[count] = -u2mm(W.y1); //printf("G00 X%f Y%f\n", ver_x[count] , ver_y[count] ); state = 1; count ++; } ver_x[count] = u2mm(W.x2); ver_y[count] = -u2mm(W.y2); //printf("G01 X%f Y%f\n", ver_x[count] , ver_y[count] ); count ++; } } count --; printf("\n"); } } real ax, ay, bx, by, res_0, res_1; real total_l = 0; real total_r = 0; int cou_l = 0; int cou_r = 0; int cc0, cc1, ioo, fc; void checkturn_right_or_left() { for (fc = 0; fc <= count; fc ++) { if (fc == 0) cc0 = count - 1; else cc0 = fc - 1; if (fc == count) cc1 = 1; else cc1 = fc + 1; ax = ver_x[cc0] - ver_x[fc]; ay = ver_y[cc0] - ver_y[fc]; bx = ver_x[cc1] - ver_x[fc]; by = ver_y[cc1] - ver_y[fc]; res_0 = asin(( ax * by - ay * bx ) / ( sqrt(ax*ax + ay*ay) * sqrt(bx*bx + by*by))); res_1 = acos(( ax * bx + ay * by ) / ( sqrt(ax*ax + ay*ay) * sqrt(bx*bx + by*by))); if (res_0 < 0) res_1 = 360 - res_1; //printf("%f\n\n", res_1 * 180 / pai ); if (res_0 > 0) cou_l ++; else cou_r ++; total_l += res_0 * 180 / pai; total_r += 360 + res_0 * 180 / pai; } if (cou_l > cou_r) { //printf("turn right!\n"); ioo = 0; }else { //printf("turn left!\n"); ioo = 1; } } int fc2; real ang_0, ang_1, xd, yd, xr, yr, xroot, yroot, at; real x_arg[], y_arg[], ret[], fir[] , bacv[]; real arct; void write_outline() { for (fc = 0; fc < count; fc ++) { fc2 = fc + 1; x_arg[0] = ver_x[fc]; x_arg[1] = ver_x[fc2]; y_arg[0] = ver_y[fc]; y_arg[1] = ver_y[fc2]; xroot = x_arg[1] - x_arg[0]; yroot = y_arg[1] - y_arg[0]; if (xroot == 0.0 || yroot == 0.0) { if (xroot == 0 && y_arg[0] < y_arg[1]) ang_0 = 0; if (xroot == 0 && y_arg[0] > y_arg[1]) ang_0 = 0; if (yroot == 0 && x_arg[0] < x_arg[1]) ang_0 = 90; if (yroot == 0 && x_arg[0] > x_arg[1]) ang_0 = 90; }else { at = atan( yroot / xroot ); ang_0 = at * 180 / pai; //printf("%f\n", ang_0 ); ang_0 = 90 - sqrt(ang_0*ang_0); } ret[0] = cos( ang_0 / 180 * pai ) * tool; ret[1] = sin( ang_0 / 180 * pai ) * tool; if (xroot > 0 && yroot > 0) { ret[0] = -ret[0]; ret[1] = ret[1]; } if (xroot < 0 && yroot > 0) { ret[0] = ret[0]; ret[1] = ret[1]; } if (xroot < 0 && yroot < 0) { ret[0] = -ret[0]; ret[1] = ret[1]; } if (xroot > 0 && yroot < 0) { ret[0] = ret[0]; ret[1] = ret[1]; } ax = xroot; ay = yroot; bx = ret[0]; by = ret[1]; arct = ( ax * by - ay * bx ) / ( sqrt(ax*ax + ay*ay) * sqrt(bx*bx + by*by)); if ( arct < -1 ) arct = -1; if ( arct > 1 ) arct = 1; //printf("%f\n", arct ); res_0 = asin( arct ); //printf("%f\n", xroot ); //printf("%f\n", yroot ); //printf("%f\n", ret[0] ); //printf("%f\n\n", ret[1] ); //printf("%f\n", res_0 ); if (ioo == 0) { if (res_0 < 0) { if (fc != 0) printf("G02 X%f Y%f I%f J%f\n\n", x_arg[0] - ret[0], y_arg[0] - ret[1], bacv[2], bacv[3] ); else { printf("G00 X%f Y%f\n", x_arg[0] - ret[0] , y_arg[0] - ret[1]); printf("G01 Z%f F%d\n", zpos , z_fvalue); fir[0] = x_arg[0] - ret[0]; fir[1] = y_arg[0] - ret[1]; } printf("G01 X%f Y%f F%d\n", x_arg[1] - ret[0] , y_arg[1] - ret[1] , fvalue); bacv[2] = ret[0]; bacv[3] = ret[1]; }else { if (fc != 0) printf("G02 X%f Y%f I%f J%f\n\n", x_arg[0] + ret[0], y_arg[0] + ret[1], bacv[2], bacv[3] ); else { printf("G00 X%f Y%f\n", x_arg[0] + ret[0] , y_arg[0] + ret[1]); printf("G01 Z%f F%d\n", zpos , z_fvalue); fir[0] = x_arg[0] + ret[0]; fir[1] = y_arg[0] + ret[1]; } printf("G01 X%f Y%f F%d\n", x_arg[1] + ret[0] , y_arg[1] + ret[1] , fvalue); bacv[2] = -ret[0]; bacv[3] = -ret[1]; } }else { if (res_0 > 0) { if (fc != 0) printf("G03 X%f Y%f I%f J%f\n\n", x_arg[0] - ret[0], y_arg[0] - ret[1], bacv[2], bacv[3] ); else { printf("G00 X%f Y%f\n", x_arg[0] - ret[0] , y_arg[0] - ret[1]); printf("G01 Z%f F%d\n", zpos , z_fvalue); fir[0] = x_arg[0] - ret[0]; fir[1] = y_arg[0] - ret[1]; } printf("G01 X%f Y%f F%d\n", x_arg[1] - ret[0] , y_arg[1] - ret[1] , fvalue); bacv[2] = ret[0]; bacv[3] = ret[1]; }else { if (fc != 0) printf("G03 X%f Y%f I%f J%f\n\n", x_arg[0] + ret[0], y_arg[0] + ret[1], bacv[2], bacv[3] ); else { printf("G00 X%f Y%f\n", x_arg[0] + ret[0] , y_arg[0] + ret[1]); printf("G01 Z%f F%d\n", zpos , z_fvalue); fir[0] = x_arg[0] + ret[0]; fir[1] = y_arg[0] + ret[1]; } printf("G01 X%f Y%f F%d\n", x_arg[1] + ret[0] , y_arg[1] + ret[1] , fvalue); bacv[2] = -ret[0]; bacv[3] = -ret[1]; } } } if (ioo == 0) printf("G02 X%f Y%f I%f J%f\n\n", fir[0], fir[1], bacv[2], bacv[3] ); else printf("G03 X%f Y%f I%f J%f\n\n", fir[0], fir[1], bacv[2], bacv[3] ); } //------------------------------------------------------------------------------- // output g-code // void output_g_code(real size) { int j; for (j=0; j < g_xy_array_size; j++ ) { if (size == dtool)put_nc_code(g_x[j], g_y[j] ); if (size > dtool)holes_cut(g_x[j], g_y[j], size); } } /////////////main///////////// board(B) { int j; int n; output(filesetext(B.name, DefaultSuffix)) { line_counter(); checkturn_right_or_left(); printf("T2 M06 S0 M03\n"); if (drill_cut == 1) { g_drill_size_list_array_size = create_drill_size_list(); output_nc_header(); for (j=0; j < g_drill_size_list_array_size; j++ ) { create_xy_data_by_drill_size( g_drill_size_list[ j ] ); block_sort( g_xy_array_size ); output_nc_sepaleter( g_drill_size_list[ j ] ); output_g_code(g_drill_size_list[ j ]); } } printf("G00 Z%f\n", 2.0 ); if ( depth < zstep) while ((depth + 0.000001) < (zpos -= zstep)) write_outline(); zpos = depth; write_outline(); printf("G00 Z%f\n", 2.0 ); } }