fabmodules/src/core/png_drl.c

268 wiersze
6.6 KiB
C

/*
% Rewind and Stop
X#Y# Move and Drill
T# Tool Selection
M30 End of Program
M00 End of Program
R#X#Y# Repeat Hole
G05, G81 Select Drill Mode
G90 Absolute Mode
G91 Incremental Mode
G92 X#Y# Set Zero
G93 X#Y# Set Zero
M48 Program Header to first "%"
M72 English-Imperial Mode
*/
/*
% Rewind and Stop
X#Y# Move and Drill
T# Tool Selection
M30 End of Program
M00 End of Program
M25 Beginning of Pattern
M31 Beginning of Pattern
M01 End of Pattern
M02 X#Y# Repeat Pattern
R#M02X#Y# Multiple Repeat Pattern
M02 X#Y# M70 Swap Axis
M02 X#Y# M80 Mirror Image X Axis
M02 X#Y# M90 Mirror Image Y Axis
M08 End of Step and Repeat
N# Block Sequence Number
/ Block Delete
R#X#Y# Repeat Hole
G05, G81 Select Drill Mode
G04 X# Variable Dwell (ignored)
G90 Absolute Mode
G91 Incremental Mode
G92 X#Y# Set Zero
G93 X#Y# Set Zero
M48 Program Header to first "%"
M47 Operator Message CRT Display
M71 Metric Mode
M72 English-Imperial Mode
Snn Spindle Speed (RPM)
Fnn Z axis feed speed (IPM)
*/
/*
M48 Program Header
M72, LZ English measurement Leading 0's
T03C0.038 T03 .0380"
T04C0.125 T04 .1250"
T06C0.046 T06 .0460"
T12C0.063 T12 .0630"
T16C0.250 T16 .2500"
% Rewind and Stop (start of drill data)
T03 Drill COMMAND GET TOOL 3
X00581Y0122 Drill location with TOOL 3
T06 Drill COMMAND GET TOOL 6
X01657Y03295 Drill location with TOOL 6
T12 Drill COMMAND GET TOOL 12
X00585Y03311 Drill location with TOOL 12
T04 Drill COMMAND GET TOOL 4
X00873Y02691 Drill location with TOOL 4
T16 Drill COMMAND GET TOOL 16
X00625Y02191 Drill location with TOOL 16
T00 Drill COMMAND UNLOAD TOOL
M30 End of Program
*/
//
// png_drl.c
// PNG to Excellon
//
// Neil Gershenfeld
// CBA MIT 11/22/12
//
// (c) Massachusetts Institute of Technology 2012
// Permission granted for experimental and personal use;
// license for commercial sale available from MIT.
//
#include "fab.h"
#define MAX_HOLES 100000
#define TOLERANCE 0.01 // hole drill match percent tolerance
void fab_write_drl(struct fab_vars *v, char *output_file_name) {
FILE *output_file;
int x,y,edges,points,hole,holes,drill,drills,index[MAX_HOLES];
float units,scale;
float x0[MAX_HOLES],y0[MAX_HOLES],r[MAX_HOLES],d[MAX_HOLES];
output_file = fopen(output_file_name,"w");
//
// threshold array
//
fab_threshold(v,0.5);
//
// find edges
//
edges = fab_edges(v);
if (edges == 0) {
printf("png_drl: oops -- no edges\n");
exit(-1);
}
//
// set edge directions
//
fab_directions(v);
//
// follow edges
//
fab_path_start(v,2);
fab_vectorize(v,1,0);
//
//
//
units = 1.0/25.4; // inches
scale = units*v->dx/(v->nx-1.0);
//
// follow segments to find holes
//
v->path->segment = v->path->first;
hole = 0;
while (1) {
//
// find hole centers
//
v->path->segment->point = v->path->segment->first;
x = v->path->segment->point->first->value;
y = v->ny - v->path->segment->point->first->next->value;
x0[hole] = x;
y0[hole] = y;
points = 1;
while (1) {
if (v->path->segment->point->next == 0) {
x0[hole] = x0[hole] / points;
y0[hole] = y0[hole] / points;
break;
}
v->path->segment->point = v->path->segment->point->next;
x = v->path->segment->point->first->value;
y = v->ny - v->path->segment->point->first->next->value;
x0[hole] += x;
y0[hole] += y;
points += 1;
}
//
// find hole radii
//
v->path->segment->point = v->path->segment->first;
x = v->path->segment->point->first->value;
y = v->ny - v->path->segment->point->first->next->value;
r[hole] = sqrt((x-x0[hole])*(x-x0[hole])+(y-y0[hole])*(y-y0[hole]));
points = 1;
while (1) {
if (v->path->segment->point->next == 0) {
x0[hole] = scale * x0[hole];
y0[hole] = scale * y0[hole];
r[hole] = scale * r[hole] / points;
break;
}
v->path->segment->point = v->path->segment->point->next;
x = v->path->segment->point->first->value;
y = v->ny - v->path->segment->point->first->next->value;
r[hole] += sqrt((x-x0[hole])*(x-x0[hole])+(y-y0[hole])*(y-y0[hole]));
points += 1;
}
hole += 1;
if (v->path->segment->next == 0) {
break;
}
v->path->segment = v->path->segment->next;
}
holes = hole;
//
// find unique drills
//
drills = 0;
for (hole = 0; hole < holes; ++hole) {
drill = 0;
while (1) {
if (drill == drills) {
drills += 1;
d[drill] = 2*r[hole];
index[hole] = drill;
break;
}
if ((fabs(d[drill] - 2*r[hole])/d[drill]) < TOLERANCE) {
index[hole] = drill;
break;
}
drill += 1;
}
}
//
// write header
//
fprintf(output_file,"M48\n"); // program header
fprintf(output_file,"M72, LZ\n"); // inches, leading zeros
//
// write drills
//
for (drill = 0; drill < drills; ++drill) {
fprintf(output_file,"T%.2dC%.3f\n",(1+drill),d[drill]);
}
//
// write holes
//
fprintf(output_file,"%%\n"); // rewind and stop (start hole data)
for (hole = 0; hole < holes; ++hole) {
fprintf(output_file,"T%.2d\n",(1+index[hole])); // tool
x = 10000*x0[hole];
y = 10000*y0[hole];
fprintf(output_file,"X%.6dY%.6d\n",x,y); // location
}
/*
T06 Drill COMMAND GET TOOL 6
X01657Y03295 Drill location with TOOL 6
T12 Drill COMMAND GET TOOL 12
X00585Y03311 Drill location with TOOL 12
T04 Drill COMMAND GET TOOL 4
X00873Y02691 Drill location with TOOL 4
T16 Drill COMMAND GET TOOL 16
X00625Y02191 Drill location with TOOL 16
T00 Drill COMMAND UNLOAD TOOL
*/
//
// close file
//
fprintf(output_file,"M30\n"); // end of program
fclose(output_file);
printf("wrote %s\n",output_file_name);
printf(" holes: %d, drills: %d\n",holes,drills);
}
main(int argc, char **argv) {
//
// local vars
//
struct fab_vars v;
init_vars(&v);
//
// command line args
//
if ((argc < 3) || (argc > 3)) {
printf("command line: png_drl in.png out.drl\n");
printf(" in.png = input PNG file\n");
printf(" out.drl = output Excellon file\n");
exit(-1);
}
//
// read PNG
//
fab_read_png(&v,argv[1]);
//
// copy image to array
//
fab_png_array(&v);
//
// write array to Excellon
//
fab_write_drl(&v,argv[2]);
//
// exit
//
exit(0);
}