/* writedxf.c - dump the internal database to a DXF file
 *            - written by Glenn M. Lewis - 07/07/92
 */

static char rcs_id[] = "$Id: writedxf.c,v 1.5 1993/01/30 12:55:49 glewis Exp $";

#include <stdio.h>
#include <ctype.h>
#include "t3dlib.h"
#ifdef __STDC__
#include <stdlib.h>
#include <strings.h>
#include "writedxf_protos.h"
#endif

static void process_DESC();
static void process_INFO();
static FILE *out;

/* Here are a few necessary utilities */

static void send_XYZ(i, f)			/* Print a common string */
int i;
XYZ_st *f;
{
	fprintf(out, " %d\n%.12g\n", 10+i, f->x);
	fprintf(out, " %d\n%.12g\n", 20+i, f->y);
	fprintf(out, " %d\n%.12g\n", 30+i, f->z);
}

static void send_RGB(rgb)			/* Print a common string */
RGB_st *rgb;
{
	fprintf(out, "%.12g\t%.12g\t%.12g\n",
		((double)rgb->r)/255.0,
		((double)rgb->g)/255.0,
		((double)rgb->b)/255.0);
}

/********************/
/* The MAIN section */
/********************/

int write_DXF(world, file)
WORLD *world;
FILE *file;
{
	register OBJECT *o;

	if (!(out = file) || !world) return(0);

	/* Write header to DXF file: */
	fprintf(out, "  0\nSECTION\n  2\nENTITIES\n");

	if (world->info) process_INFO(world->info);

	for (o=world->object; o; o=o->next)
		if (!o->extr) process_DESC(o);

	fprintf(out, "  0\nENDSEC\n  0\nEOF\n");

	return(1);
}

static void process_DESC(object)
OBJECT *object;
{
	register int i;
	register OBJECT *obj;
	register DESC *desc = object->desc;
	register int p1, p2, p3;

	/* Process children first */
	for (obj=object->child; obj; obj=obj->next) {
		if (!obj->extr) process_DESC(obj);
	}

	if (!desc->pcount || !desc->fcount) return;

/*	fprintf(out, "\n# Start of new object\n");	*/

	for (i=0; i<desc->fcount; i++) {
	/* First check to make sure that this triangle is real */
		p1 = desc->edge[(desc->face[i*3])<<1];
		p2 = desc->edge[((desc->face[i*3])<<1)+1];
		if (p1 == p2) continue;	/* How did *this* happen? */
		p3 = desc->edge[(desc->face[i*3+2])<<1];
		if (p1 == p3 || p2 == p3)
			p3 = desc->edge[((desc->face[i*3+2])<<1)+1];
		if (p1 == p3 || p2 == p3) continue; /* How did *this* happen? */
		/* Now check the actual points for equality */
		if (bcmp(&desc->pnts[p1], &desc->pnts[p2], sizeof(XYZ_st))==0 ||
			bcmp(&desc->pnts[p1], &desc->pnts[p3], sizeof(XYZ_st))==0 ||
			bcmp(&desc->pnts[p2], &desc->pnts[p3], sizeof(XYZ_st))==0)
			continue;

		fprintf(out, "  0\n3DFACE\n  8\n%s\n  6\nCONTINUOUS\n 62\n     4\n",
			(desc->name ? desc->name : "0"));

		send_XYZ(0, &desc->pnts[p1]);
		send_XYZ(1, &desc->pnts[p2]);
		send_XYZ(2, &desc->pnts[p3]);
		send_XYZ(3, &desc->pnts[p3]);
	}
}

static void process_INFO(info)
INFO *info;
{
#ifdef OLD_NFF_CODE
	fprintf(out, "v\n");
	if (info->obsv) {
		fprintf(out, "from "); send_XYZ(&info->obsv->came);
	}
	if (info->ambi)
		{ fprintf(out, "b "); send_RGB(info->ambi); }
#endif
}
