Geometry Smoothing Software:

New_Proj(4)
Index ...
Lathe_Work

Following are several outlined steps that show how each model piece was built true to scale...

Break Apart CAD Into Workable Pieces

Process DXF through a program to generate CNC Roughing code.

Process DXF through a program to generate CNC Finishing code.

Process Finishing Code through a smoothing algorythm.

CAD Block Closeup:

This CAD depiciton shows a close up of a single foam block in the CAD. This block is 24"x36". For ease of processing, the software allows an 'X' & 'Y' offset to be provided on the command line so that each successive block does not need to be rotate & translated to the [0,0,0] corrdinate first. This saves much post processing setup time.


CNC Roughing Program:

Here you can see a graphical depiction of the CNC program used to rough the model out. As you can see, the roughing program uses vertical plunges to remove material. Note, in processing the dxf model the user had to specify the diameter of the cutter used to do the actual machining, in order to make sure that the center-line of the cutter stopped so that it's edges would not gogue into rising or falling hillsides.

Code generation was facilitated through the use of a custom program I wrote in C that read in the DXF output from AutoCAD and performed calculations to generate the NC file output.

It is very hard to see through the tool path for plunge routing in the image above. Below, I've cut away all of the G-Code, overlaid only one pass of the plunge routing along the back edge of the foam block. Notice, it is set with a clearance height of 0.5" for a later finishing pass. Just for checking purposes, I've drawn in the 1.5" diameter plunge routing tool in a few places. If the reader looks very close, they can see the single finish pass drawn in in dark green below it.


CNC Finishing Program:

In this frame, the first CNC finishing program is depicted. This program follows along the contours drawing straight line segments between calculated points on 1/4" centers. Here to, the radius of the ball end mill used to contour the foam must be entered. This is because the center of the ball must be offset tangentially from any close points. Further complicating the writing of the software to generate the CNC path was the fact that the data underneath the cutter was sparse and irregular, so specialized weighting functions had to be constructed.

The next two frames show a before and after of the CNC filtering program...

CNC Program #82 Before filtering:

This graphic depiction of a CNC program shows the file generated from the finishing program above before beign processed through a specialized filtering algorithm I wrote to post process CNC files.


CNC Program #82 After filtering:

The filtering program I wrote reads in the Gerber formatted CNC files and calculates 3-D Curvature through every end point on the model in order to provide lookahead smoothing. Additional, height mapping and slope corelation are applied to every output point to ensure that no degredation of geometry takes place.

In this program a user supplied elevation is used to determine at what 'Z' levels to stop processing the file. This is done to keep the steep drop off into the river channel.

And a quick shot of the output of this process:

DXF=>CNC (Gerber) code generator:

Code: ROUGH2.CPP

#include 
#include 
#define maxfname 128

typedef struct pt{
		float x,y,z;
}pt;

typedef struct nfo{
		float x,y,z;
		float zmin,zmax;
		float d1,d2,d3;
		float waterline;
		float oldz;
		float cutrad,cutrad2;
}nfo;

void findpt(struct nfo *info,pt sarray[], int numline)
{
	int f1index=0,i;
	float f1dist=(float)50,f2high=(float)0,t,t2;
	for (i=0;iy-sarray[i].y),(float)2)+pow((info->x-sarray[i].x),(float)2));
		if (t< f1dist)
		{
			f1dist=t;
			f1index=i;
		}
		t2=info->cutrad-(float)sqrt(pow(t,(float)2)+info->cutrad2)+sarray[i].z;
		if (tcutrad && t2 > f2high)
			f2high=t2;
	}
	info->z=sarray[f1index].z;
	if(f2high>info->z)
		info->z=f2high;
	if(info->z>info->zmax)
		info->z=info->zmax;
	if(info->zzmin)
		info->z=info->zmin;
	return;
}

float findpt3(struct nfo *info, pt sarray[], int numline, pt t[],int i)
{
	float tz=(float)0,t1,t2;
	float f1dist=(float)50,f2high=(float)0;
	int f1index=0,j;

	for(j=0;jcutrad-(float)sqrt(pow(t1,(float)2)+info->cutrad2)+sarray[j].z;
		if (t1cutrad && t2 > f2high)
			f2high=t2;
	}
	tz=sarray[f1index].z;
	if(f2high>tz)
		tz=f2high;
	if(tz>info->zmax)
		tz=info->zmax;
	if(tzzmin)
		tz=info->zmin;
	return tz;
}

void findpt2 (struct nfo *info, pt sarray[], int numline)
{
	int i;
	float z;
	pt t[11];

	t[1].x=info->x-info->d1;
	t[1].y=info->y;
	t[2].x=info->x+info->d1;
	t[2].y=info->y;
	t[3].x=info->x;
	t[3].y=info->y-info->d1;
	t[4].x=info->x;
	t[4].y=info->y+info->d1;
	t[5].x=info->x-info->d2;
	t[5].y=info->y+info->d2;
	t[6].x=info->x+info->d2;
	t[6].y=info->y-info->d2;
	t[7].x=info->x-info->d2;
	t[7].y=info->y-info->d2;
	t[8].x=info->x+info->d2;
	t[8].y=info->y+info->d2;
	t[9].x=info->x-info->d3;
	t[9].y=info->y;
	t[10].x=info->x+info->d3;
	t[10].y=info->y;
	
	z=(float)0;
	for (i=1;i<=10;i++)
	{
		z+=findpt3(info,sarray,numline,t,i);
	}
	z+=(info->z*(float)2);
	z/=(float)12;
	info->oldz=info->z;
	info->z=z;

	if (info->z > (info->oldz + (float).33))
		info->z=info->oldz+(float).33;
	if (info->z < (info->oldz - (float) .33))
		info->z=info->oldz-(float).33;
	if (info->z < info->waterline)
		info->z=info->waterline;
	return;
}


int main(int argc, char *argv[])
{

FILE *f1ptr,*f2ptr;
char *f1name=argv[1],*f2name=argv[2],*f3name=argv[3],*f4name=argv[4];
int	i,numline,xsize,ysize,dir,linenum=0;
float xstep=(float)0.2,ystep=(float)0.4,tempx;
pt sarray[5000];
nfo info;

info.zmax=(float)12;
info.zmin=(float).25;
info.waterline=(float)6;
info.d1=(float)2*xstep;
info.d2=(float)4*xstep;
info.d3=(float)5*xstep;
info.cutrad=(float)0.5;
info.cutrad2=(float)0.25;

printf("(%d,argc) Number of command line parameters.\n\r",argc);
f1ptr=fopen(f1name,"r");
fscanf(f1ptr,"%d",&numline);
fscanf(f1ptr,"%d",&xsize);
fscanf(f1ptr,"%d",&ysize);
fclose(f1ptr);

f1ptr=fopen(f2name,"r");
for(i=0;i<= numline - 1;i++)
{
	fscanf(f1ptr,"%f",&sarray[i].x);
	fscanf(f1ptr,"%f",&sarray[i].y);
	fscanf(f1ptr,"%f",&sarray[i].z);
}
printf("Sucessfuly retrieved (%d) array points\nfrom the file (%s)\n",numline,f2name);
printf("X-block size (%d),  Y-blocksize (%d)\n",xsize,ysize);
printf("X-stepover (%f),  Y-stepover (%f)\n",xstep,ystep);
printf("Cutter radius (%f)\n",info.cutrad);
fclose(f1ptr);

f1ptr=fopen(f3name,"w");
f2ptr=fopen(f4name,"w");
fprintf(f1ptr,"(cutter rad=%f set G32 high)\n)",info.cutrad);
fprintf(f1ptr,"G1G43H1Z12F120\n");
fprintf(f1ptr,"G0X0Y0f120\n");
dir=1;
for (info.y=(float)0;info.y<(float)ysize;info.y+=ystep)
{
	fprintf(f2ptr,"line ");
	if (dir==1)
		dir=0;
	else
		dir=1;
	for (tempx=(float)0;tempx<(float)xsize;tempx+=xstep)
	{
		linenum++;
		if(dir==0)
			info.x=tempx;
		else
			info.x=(float)xsize-tempx;
		findpt(&info,sarray,numline);
		if (info.z > info.waterline)
			findpt2(&info,sarray,numline);
		if (info.z < info.waterline)
			info.z=info.waterline;
		info.z+=(float).15;
		fprintf(f1ptr,"N%dG01X%.1fY%.1fZ%.2f\n",linenum,info.x,info.y,info.z);
		fprintf(f2ptr,"%.1f,%.1f,%.2f ",info.x,info.y,info.z);
		printf("N%dG01X%.1fY%.1fZ%.2f unfiltered %.4f\n\r",linenum,info.x,info.y,info.z,info.oldz);
	}
	fprintf(f2ptr,"\n");
}
fprintf(f1ptr,"G32\nM05\nM30\n");
fclose(f1ptr);
fclose(f2ptr);
return 0;
}


The argument passed in is the name of a DXF file

Sample Dat file used above:

File: Foam8_2.DAT

 3393
 36
 24

The format is 3 numbers, 1-number of entrys, 2-number of inches in X to process, 3-number of inches in Y to process.

Snippet from an intermediate "*.MID" file:

File format (snippet): Foam8_2.MID


; FILE:FOAM8_2.MID temp file in X  Y  Z  format 15:35:37 08-25-1994
30.68876
11.3747
3.773715
29.06779
11.2796
5.178673
29.38928
11.0921
4.827409
29.72827
11.2052
4.47624
30.01077
11.4595
4.124978
27.82427
11.3956
5.529906
33.73103
11.2796
2.720042
32.79838
11.3956
3.071275
32.33206
11.1635
3.422508
35.59632
5.4771
3.77374
32.41199
5.5805
3.773715
34.19735
5.8252
3.071275
32.64294
5.5931
3.422508
33.10926
5.4771
3.071275

More To Come:

This section is ever evolving. I'll post updates from time to time as new equipment and toys are moved into and out of the shop.

New_Proj(4)
Index ...
Lathe_Work