home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
back2roots/padua
/
padua.7z
/
padua
/
gfx
/
dkbutsrc.lzh
/
dxf2dkb.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-05-16
|
17KB
|
520 lines
/* AutoCAD DXF file to DKB Data File Converter */
/* Version 1.0 By Aaron A. Collins. Written 8/13/90 */
/* Version 1.01 Modified to work with DKB 2.10 By Drew Wells 3/20/91 */
/* This program is released to the public domain. */
/*--------------------------------------------------------------------*/
/* Version History */
/*--------------------------------------------------------------------*/
/* 8/19/90 AC Wrote original program.
* 3/20/91 DW Put colors inside texture block for DKB 2.10.
* DW Removed line INCLUDE "Basicshapes.dat".
* DW Added additional comment docs at top of DKB outfile.
* DW Added additional stats as to what DXF types were found.
* 4/29/91 AC Modified usage message and header semantics a bit.
* 5/15/91 AC Removed IBM-ness of filenames/extensions
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 2048
#define FABS(x) ((x<0.0)?-x:x)
int getline (void);
void writeobj (void);
void finishobj (int color);
void lookupcolor (int color, double *red, double *green, double *blue);
int checkdegen(int a, int b, int c);
int groupcode;
char linbuf[BUFSIZE];
FILE *infile, *outfile;
long primitives = 0L, degenerates = 0L;
long num_triangles = 0L, num_points = 0L, num_circles = 0L, num_traces = 0L,
num_solids = 0L, num_lines = 0L, num_3dlines = 0L, num_3dfaces = 0L;
char curobj[80];
int curcolor;
double curthick;
double xcoords[10];
double ycoords[10];
double zcoords[10];
double doubles[10];
double angles[10];
int ints[10];
double max_x, max_y, max_z, min_x, min_y, min_z;
void main(argc, argv)
int argc;
char *argv[];
{
char *index;
printf("\n\nAutoCad DXF to DKB Data file Translator\n");
printf("Version 1.0 Written By Aaron A. Collins, 8/13/90\n");
printf("Version 1.01 Modifications By Drew Wells 3/20/91\n");
printf("Version 1.02 Modifications By Aaron A. Collins 3/20/91\n");
printf("Version 1.03 Modifications By Aaron A. Collins 5/15/91\n");
printf("* Type DXF2DKB with no arguments for more info. *\n");
printf("This program is released to the public domain.\n\n");
if (argc != 3)
{
printf("Usage: %s InputFile OutputFile\n\n", argv[0]);
printf("DXF2DKB does a minimal conversion of AutoCad DXF files into DKB data format.\n");
printf("The following DXF primitives are currently supported:\n");
printf("\t3D Faces\tTriangles\tPoints\n");
printf("\t3D Lines\tCircles \tSolids\n");
printf("\tLines \tTraces\n");
printf("The DKB Raytracer is available on Compuserve's COMART forum lib 16 and\n");
printf("The \"You Can Call Me RAY\" Raytracing BBS at (708) 358-5611.\n");
printf("C source code for this utility is also available at those locations.\n");
exit(1);
}
if (!(infile = fopen(argv[1], "r")))
{
printf("Cannot open input file %s!\n", argv[1]);
exit(1);
}
if (!(outfile = fopen(argv[2], "w")))
{
printf("Cannot create output file %s!\n", argv[2]);
fclose(infile);
exit(1);
}
printf("\nPlease wait; Processing...");
fprintf(outfile, "{ This file is for use with the DKB Ray Tracer.}\n");
fprintf(outfile, "{ %s: Converted from AutoCad DXF File: %s }\n\n", argv[2], argv[1]);
fprintf(outfile, "{ This is a composite object description for use with the DKB }\n");
fprintf(outfile, "{ Ray Tracer. It does not include viewpoint or light source desc-}\n");
fprintf(outfile, "{ riptions. It uses the Dull texture from textures.dat and it }\n");
fprintf(outfile, "{ may use Cylinder_Z from shapes.dat. }\n");
fprintf(outfile, "{ To use this file as an include file uncomment the DECLARE line }\n");
fprintf(outfile, "{ and change DxfObject to an appropriate name.}\n\n");
fprintf(outfile, "INCLUDE \"shapes.dat\"\n");
fprintf(outfile, "INCLUDE \"colors.dat\"\n");
fprintf(outfile, "INCLUDE \"textures.dat\"\n\n");
fprintf(outfile, "{ DECLARE DxfObject = }\n",argv[2]);
fprintf(outfile, "COMPOSITE\n");
curobj[0] = '\0'; /* not working on any object currently */
curcolor = 7; /* and it also doesn't have a color yet... */
max_x = max_y = max_z = -10000000.0; /* init bounding limits */
min_x = min_y = min_z = 10000000.0;
find: while (!feof(infile)) /* run file up to the "ENTITIES" section */
{
if (getline()) /* get a group code and a line */
goto stopit;
if (groupcode == 0) /* file section mark */
{
if (strstr(linbuf, "EOF"))
goto stopit;
if (strstr(linbuf, "SECTION"))
{
if (getline())
goto stopit;
if (groupcode != 2)
continue;
if (strstr(linbuf, "ENTITIES"))
break;
}
}
}
while (!feof(infile)) /* scan ENTITIES section */
{
if (getline()) /* get a group code and a line */
break;
if (groupcode < 10) /* cardinal group codes */
{
switch(groupcode)
{
case 0: /* start of entity, table, file sep */
if (strstr(linbuf, "EOF"))
{
writeobj(); /* dump object */
goto stopit;
}
if (strstr(linbuf, "ENDSEC"))
{
writeobj(); /* dump object */
goto find;
}
writeobj(); /* dump old object */
curobj[0] = '\0'; /* reset object */
curcolor = 7;
strcpy(curobj, linbuf); /* get new */
break;
case 1: /* primary text value for entity (?)*/
break;
case 2: /* block name, attribute tag, etc */
case 3: /* other names */
case 4:
break;
case 5: /* entity handle (hex string) */
break;
case 6: /* line type name */
break;
case 7: /* text style name */
break;
case 8: /* layer name */
break;
case 9: /* variable name ID (only in header)*/
break;
}
}
else if (groupcode >= 10 && groupcode < 19) /* Some X coord */
{
sscanf(linbuf, "%f", &(xcoords[groupcode-10]));
if (xcoords[groupcode-10] > max_x)
max_x = xcoords[groupcode-10];
if (xcoords[groupcode-10] < min_x)
min_x = xcoords[groupcode-10];
}
else if (groupcode >= 20 && groupcode < 29) /* Some Y coord */
{
sscanf(linbuf, "%f", &(ycoords[groupcode-20]));
if (ycoords[groupcode-20] > max_y)
max_y = ycoords[groupcode-20];
if (ycoords[groupcode-20] < min_y)
min_y = ycoords[groupcode-20];
}
else if (groupcode >= 30 && groupcode < 38) /* Some Z coord */
{
sscanf(linbuf, "%f", &(zcoords[groupcode-30]));
if (zcoords[groupcode-30] > max_z)
max_z = zcoords[groupcode-30];
if (zcoords[groupcode-30] < min_z)
min_z = zcoords[groupcode-30];
}
else if (groupcode == 38) /* entity elevation if nonzero */
{
}
else if (groupcode == 39) /* entity thickness if nonzero */
{
}
else if (groupcode >= 40 && groupcode < 49) /* misc doubles */
{
sscanf(linbuf, "%f", &(doubles[groupcode-40]));
}
else if (groupcode == 49) /* repeated value groups */
{
}
else if (groupcode >= 50 && groupcode < 59) /* misc angles */
{
sscanf(linbuf, "%f", &(angles[groupcode-50]));
}
else if (groupcode == 62) /* Color number */
{
sscanf(linbuf, "%6d", &curcolor);
}
else if (groupcode == 66) /* "entities follow" flag */
{
}
else if (groupcode >= 70 && groupcode < 79) /* misc ints */
{
sscanf(linbuf, "%f", &(ints[groupcode-70]));
}
else if (groupcode == 210 || groupcode == 220 || groupcode == 230)
{ /* X, Y, Z components of extrusion direction */
}
}
stopit: fprintf(outfile, " BOUNDED_BY\n INTERSECTION\n");
fprintf(outfile, " PLANE <1.0 0.0 0.0> %1.04f END_PLANE\n", FABS(max_x) * 1.01);
fprintf(outfile, " PLANE <-1.0 0.0 0.0> %1.04f END_PLANE\n", FABS(min_x) * 1.01);
fprintf(outfile, " PLANE <0.0 1.0 0.0> %1.04f END_PLANE\n", FABS(max_y) * 1.01);
fprintf(outfile, " PLANE <0.0 -1.0 0.0> %1.04f END_PLANE\n", FABS(min_y) * 1.01);
fprintf(outfile, " PLANE <0.0 0.0 1.0> %1.04f END_PLANE\n", FABS(max_z) * 1.01);
fprintf(outfile, " PLANE <0.0 0.0 -1.0> %1.04f END_PLANE\n", FABS(min_z) * 1.01);
fprintf(outfile, " END_INTERSECTION\n END_BOUND\nEND_COMPOSITE\n");
fclose(infile);
fflush(outfile);
fclose(outfile);
printf("Finished.\nTotal DKB objects written to output file: %ld\n\n", primitives);
printf("Total degenerate triangles removed from scene: %ld\n\n", degenerates);
printf ("X bounding values range from %f to %f\n", min_x, max_x);
printf ("Y bounding values range from %f to %f\n", min_y, max_y);
printf ("Z bounding values range from %f to %f\n", min_z, max_z);
printf("\n\t\t\t--- DXF Stats ---\n");
printf("3D Faces = \t%ld\tTriangles = \t%ld\tPoints = \t%ld\n",num_3dfaces,num_triangles,num_points);
printf("3D Lines = \t%ld\tCircles = \t%ld\tSolids = \t%ld\n",num_3dlines,num_circles,num_solids);
printf("Lines = \t%ld\tTraces = \t%ld\n",num_lines,num_traces);
exit(0);
}
int getline() /* read a group code and the next line from infile */
{
fgets(linbuf, BUFSIZE, infile); /* get a line from .DXF */
if (feof(infile))
return(1);
sscanf(linbuf, "%3d", &groupcode); /* scan out group code */
fgets(linbuf, BUFSIZE, infile); /* get a line from .DXF */
if (feof(infile))
return(1);
return(0);
}
void writeobj() /* dump out current object we should have all info on */
{
if (strstr(curobj, "LINE")) /* a VERY skinny triangle! */
{
if (xcoords[0] == xcoords[1] && ycoords[0] == ycoords[1] && zcoords[0] == zcoords[1])
{
degenerates++;
return;
}
fprintf(outfile, " OBJECT\n");
fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[1], ycoords[1], zcoords[1], xcoords[1]+0.01, ycoords[1], zcoords[1]);
finishobj(curcolor);
num_lines++;
return;
}
else if (strstr(curobj, "POINT")) /* an itty, bitty sphere! */
{
fprintf(outfile, " OBJECT\n");
fprintf(outfile, " SPHERE <%1.06f %1.06f %1.06f> 0.1 END_SPHERE\n", xcoords[0], ycoords[0], zcoords[0]);
finishobj(curcolor);
num_points++;
return;
}
else if (strstr(curobj, "CIRCLE")) /* a VERY short cylinder! */
{
fprintf(outfile, " OBJECT\n");
fprintf(outfile, " INTERSECTION\n");
fprintf(outfile, " QUADRIC Cylinder_Z SCALE <%1.06f %1.06f %1.06f> END_QUADRIC\n", doubles[0], doubles[0], doubles[0]);
fprintf(outfile, " PLANE <0.0 0.0 1.0> 0.1 END_PLANE\n");
fprintf(outfile, " PLANE <0.0 0.0 -1.0> 0.1 END_PLANE\n");
fprintf(outfile, " END_INTERSECTION\n");
fprintf(outfile, " TRANSLATE <%1.06f %1.06f %1.06f>\n", xcoords[0], ycoords[0], zcoords[0]);
finishobj(curcolor);
num_circles++;
return;
}
else if (strstr(curobj, "ARC")) /* not implemented for now */
{
return;
}
else if (strstr(curobj, "TRACE")) /* 2 back-to-back triangles */
{
if (checkdegen(0, 1, 2))
{
degenerates++;
return;
}
fprintf(outfile, " OBJECT\n");
fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[1], ycoords[1], zcoords[1], xcoords[2], ycoords[2], zcoords[2]);
num_traces++;
finishobj(curcolor);
if (checkdegen(0, 3, 2))
{
degenerates++;
return;
}
fprintf(outfile, " OBJECT\n");
fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[3], ycoords[3], zcoords[3], xcoords[2], ycoords[2], zcoords[2]);
finishobj(curcolor);
return;
}
else if (strstr(curobj, "SOLID")) /* 1 or 2 triangles */
{
if (checkdegen(0, 1, 2))
{
degenerates++;
return;
}
fprintf(outfile, " OBJECT\n");
fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[1], ycoords[1], zcoords[1], xcoords[2], ycoords[2], zcoords[2]);
finishobj(curcolor);
num_solids++;
if (xcoords[2] == xcoords[3] && ycoords[2] == ycoords[3] && zcoords[2] == zcoords[3])
return; /* one triangle was enough... */
if (checkdegen(0, 3, 2))
{
degenerates++;
return;
}
fprintf(outfile, " OBJECT\n");
fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[3], ycoords[3], zcoords[3], xcoords[2], ycoords[2], zcoords[2]);
finishobj(curcolor);
return;
}
else if (strstr(curobj, "TEXT")) /* not implemented for now */
{
return;
}
else if (strstr(curobj, "SHAPE")) /* these look very hard */
{
return;
}
else if (strstr(curobj, "BLOCK")) /* these look very hard */
{
return;
}
else if (strstr(curobj, "ENDBLK")) /* these look very hard */
{
return;
}
else if (strstr(curobj, "INSERT")) /* these look very hard */
{
return;
}
else if (strstr(curobj, "ATTDEF")) /* not implemented for now */
{
return;
}
else if (strstr(curobj, "ATTRIB")) /* not implemented for now */
{
return;
}
else if (strstr(curobj, "POLYLINE")) /* these look fairly hard */
{
return;
}
else if (strstr(curobj, "VERTEX")) /* these look fairly hard */
{
return;
}
else if (strstr(curobj, "SEQEND")) /* these look fairly hard */
{
return;
}
else if (strstr(curobj, "3DLINE")) /* a VERY skinny triangle! */
{
if (xcoords[0] == xcoords[1] && ycoords[0] == ycoords[1] && zcoords[0] == zcoords[1])
{
degenerates++;
return;
}
fprintf(outfile, " OBJECT\n");
fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[1], ycoords[1], zcoords[1], xcoords[1]+0.1, ycoords[1], zcoords[1]);
finishobj(curcolor);
num_3dlines++;
return;
}
else if (strstr(curobj, "3DFACE")) /* 1 or 2 triangles */
{
if (checkdegen(0, 1, 2))
{
degenerates++;
return;
}
fprintf(outfile, " OBJECT\n");
fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[1], ycoords[1], zcoords[1], xcoords[2], ycoords[2], zcoords[2]);
finishobj(curcolor);
num_3dfaces++;
if (xcoords[2] == xcoords[3] && ycoords[2] == ycoords[3] && zcoords[2] == zcoords[3])
return; /* one triangle was enough... */
if (checkdegen(0, 3, 2))
{
degenerates++;
return;
}
fprintf(outfile, " OBJECT\n");
fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[3], ycoords[3], zcoords[3], xcoords[2], ycoords[2], zcoords[2]);
finishobj(curcolor);
return;
}
else if (strstr(curobj, "DIMENSION")) /* not implemented for now */
{
return;
}
return; /* no current object defined... */
}
void finishobj(color) /* conclude a DKB-style object definition */
int color;
{
double red, green, blue;
lookupcolor(color, &red, &green, &blue);
fprintf(outfile, " TEXTURE Dull\n"); /* default surf. */
fprintf(outfile, " COLOR RED %1.06f GREEN %1.06f BLUE %1.06f\n", red, green, blue);
fprintf(outfile, " END_TEXTURE\n"); /* default surf. */
fprintf(outfile, " END_OBJECT\n\n");
printf("."); /* activity echo (happy dots) */
primitives++; /* count another output file primitive */
}
void lookupcolor(color, red, green, blue) /* basic AutoCAD 9-color pallette */
int color;
double *red, *green, *blue;
{
switch (color)
{
case 0: /* black */
*red = *green = *blue = 0.0;
break;
case 1: /* red */
*red = 1.0;
*blue = *green = 0.0;
break;
case 2: /* yellow */
*red = *green = 1.0;
*blue = 0.0;
break;
case 3: /* green */
*green = 1.0;
*red = *blue = 0.0;
break;
case 4: /* cyan */
*blue = *green = 1.0;
*red = 0.0;
break;
case 5: /* blue */
*blue = 1.0;
*red = *green = 0.0;
break;
case 6: /* magenta */
*blue = *red = 1.0;
*green = 0.0;
break;
case 8: /* dk. grey */
*red = *green = *blue = 0.5;
break;
case 9: /* lt. grey */
*red = *green = *blue = 0.75;
break;
case 7: /* white */
default: /* make anything else white (?) */
*red = *green = *blue = 1.0;
}
return;
}
int checkdegen(a, b, c) /* check for degenerate triangle structure */
int a, b, c;
{
if (
(xcoords[a] == xcoords[b] &&
ycoords[a] == ycoords[b] &&
zcoords[a] == zcoords[b]) ||
(xcoords[b] == xcoords[c] &&
ycoords[b] == ycoords[c] &&
zcoords[b] == zcoords[c]) ||
(xcoords[a] == xcoords[c] &&
ycoords[a] == ycoords[c] &&
zcoords[a] == zcoords[c]))
return(1);
return(0);
}