#usage "DRILL G-CODE Generager V1.1\n"
"
"
"Create G-Code for drillings. "
"
"
"Usage: RUN cnc-drill-gcode"
"
"
"Author: http://www.mi-ra-i.com/OPEN-JMM/"
// THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED
//////////////////////////////////////////////////////
//////////////////// ユーザー設定 ////////////////////
//////////////////////////////////////////////////////
string DefaultSuffix = "_shortdrill.tap"; // お使いのCNCに合わせた拡張子に変更してください
real argv_z1 = 1; // 空転移動時の高さを指定してください
real argv_z2 = -0.4; // ドリルの下限を指定してください
int s_speed = 3000; // ドリルの回転数を指定してください
int g_fg_file_append = 1; // 0)穴径ごとにファイルを作成 1)まとめてファイルを作成
int down_f = 50; // ドリルを下げる時のF値を指定してください
int up_f = 400; // ドリルを上げる時のF値を指定してください
///////////////////////////////////////////////////////
////////////////////// ここまで ///////////////////////
///////////////////////////////////////////////////////
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;
// string gDebugFileName = "c:\debug.txt";
//-------------------------------------------------------------------------------
//
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 += 10;
}
//-------------------------------------------------------------------------------
//
void put_nc_code( int x, int y )
{
put_line_number();
printf("G00 X%.3f Y%.3f\n" , u2mm(x),u2mm(-y) );
put_line_number();
printf("G1Z%.2ff%d\n" , argv_z2 , down_f );
put_line_number();
printf("G00 Z%.2f F%d\n" , argv_z1 , up_f );
}
//-------------------------------------------------------------------------------
//
//
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 ("M03 S%d\n", s_speed );
printf ("G00 Z2.00 F%d\n" , up_f );
}
//-------------------------------------------------------------------------------
//
//
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 F%d\n" , up_f );
put_line_number();
printf ("G00 X0 Y0 F%d\n" , up_f );
put_line_number();
printf ("M05 \n" );
}
//-------------------------------------------------------------------------------
// output g-code
//
void output_g_code()
{
int j;
for (j=0; j < g_xy_array_size; j++ ) {
put_nc_code(g_x[j], g_y[j] );
}
}
//-------------------------------------------------------------------------------
//
if ( board ) board( B )
{
int j;
int n;
string tFileName;
if (argv[1])
{
argv_z1 = strtod(argv[1]);
argv_z2 = strtod(argv[2]);
if (argv[4])
{
gFileName = argv[4];
}else
{
gFileName = dlgFileOpen("G Code output ", path_cam[0]+"/*.cnc", "*.*");
}
}else
{
if (!gFileName)
{
board(B) gFileName = filesetext(B.name, DefaultSuffix);
}
int Result = dlgDialog("CNC-DRILL-GCODE V1.0")
{
dlgLabel(usage);
dlgVBoxLayout
{
dlgGroup("Output options")
{
dlgHBoxLayout
{
dlgCheckBox("&Append ", g_fg_file_append );
dlgCheckBox("&Line number ", g_fg_line_number);
}
}
dlgGroup("Sort order")
{
dlgHBoxLayout
{
dlgCheckBox("&Sort ", g_fg_sort);
dlgRadioButton("&X ", g_fg_sort_x_or_y);
dlgRadioButton("&Y ", g_fg_sort_x_or_y);
}
}
dlgSpacing(10);
dlgGroup("NC Code Options")
{
dlgGridLayout
{
dlgCell(0, 0) dlgLabel("Z1 mm");
dlgCell(0, 1) dlgRealEdit( argv_z1 );
dlgCell(1, 0) dlgLabel("Z2 mm");
dlgCell(1, 1) dlgRealEdit( argv_z2 );
dlgCell(2, 0) dlgLabel("Z Up Speed");
dlgCell(2, 1) dlgIntEdit( up_f );
dlgCell(3, 0) dlgLabel("Z Down Speed");
dlgCell(3, 1) dlgIntEdit( down_f );
dlgCell(4, 0) dlgLabel("Spendle RPM");
dlgCell(4, 1) dlgIntEdit( s_speed );
}
}
dlgStretch(1);
dlgHBoxLayout
{
dlgPushButton("+&OK") dlgAccept();
dlgStretch(1);
dlgPushButton("-&Cancel") dlgReject();
dlgSpacing(10);
}
}
};
if (!Result) exit (0);
}
// output( gDebugFileName ) {
g_drill_size_list_array_size = create_drill_size_list();
if ( g_fg_file_append )
{
// 1つにまとめたファイルにする
gFileName = filesetext( B.name, DefaultSuffix );
output( gFileName )
{
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();
}
output_nc_footer();
}
}else
{
// セパレートファイル
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 );
board(B)
{
tFileName = filesetext( B.name, "");
sprintf( gFileName, "%s-%02d%s", tFileName, j , DefaultSuffix );
}
output( gFileName )
{
output_nc_header();
output_nc_sepaleter( g_drill_size_list[ j ] );
output_g_code();
output_nc_footer();
}
}
}
// }
}else
{
dlgMessageBox("Start this ULP in a Board!", "OK");
}
exit (0);