View Single Post
Old 12th November 2005, 04:18 AM   #2
Andy
Administrator
Professional user
 
Andy's Avatar
 
Join Date: Jun 2003
Posts: 4,563
Default

An exporter is quite simple to code.

I've appended a sample. It quite simple but would be even simpler if each polygon wasn't triangulated.

Feel free to post any questions here.

Andy

--------------------------------------------------------
Code:
/**************************************************************

Shared vertex  (.sv files)	plugin for AC3D  - 

Version 1.1 by Inivis


file will look like:

SV
<NUMVERT>					-|
(numvert of) <X> <Y> <Z>			 | 
<NUMTRIANGLES>					 |--- 1 or more blocks until EOF
(numtriangles of) <V1> <V2> <V3> <HEXRGB>	-|


e.g. white a rectangle (made from two triangles)

SV
4
0.000000 1.000000 0.000000
1.000000 1.000000 0.000000
1.000000 0.000000 0.000000
0.000000 0.000000 0.000000
2
2 0 3 ffffff
0 2 1 ffffff
----------------------------------------------------

the code looks complicated in parts because any polygons that need
triangluating are turned into triangles before output and all these
are gathered together before being output in one block per object

A loader for this format should read the header "SV" then keep 
reading until the end of the file.	Each AC3D object will be represented
by a vertex list and a triangle list.

Note that lights are ignored because they don't have any vertices.
Also - lines are ignored

updated for AC3D 4.5 November 2004

*****************************************************************/


#include <stdio.h>
#include "ac_plugin.h"



static void sv_output_col(FILE *f, int col)
{
ACMaterial *m = ac_palette_get_material(col);
long rgb;

	rgb = ac_material_index_to_rgb(col);
		
	fprintf(f, "%x\n", rgb);
}


static void sv_output_triangle(FILE *f, List *vertices, Surface *s)
{
SVertex *p1, *p2, *p3;
int col;
int id1, id2, id3; 

	// get SVertexes for this triangle
	// SVertex contains vertex pointer, texture cordinates and the normal

	p1 = (SVertex *)(s->vertlist->data);
	p2 = (SVertex *)(s->vertlist->next->data);
	p3 = (SVertex *)(s->vertlist->next->next->data);

	// get int positions of each vertex within the main object list
	id1 = list_index(vertices, p1->v);
	id2 = list_index(vertices, p2->v);
	id3 = list_index(vertices, p3->v);

	fprintf(f, "%d %d %d ", id1, id2, id3); 

	sv_output_col(f, s->col);
}

static void sv_output_surfaces(FILE *f, List *vertices, List *triangs)
{
	/** go through the triangle list and output each **/
	for (List *p = triangs; p != NULL; p = p->next)
		{
		Surface *s = (Surface *)p->data;
		sv_output_triangle(f, vertices, s);
		}
}


static void sv_output_object(FILE *f, ACObject *ob)
{
int numvert, numsurf, numkids;
List *vertices, *surfaces, *kids;
List *p;

	printf("outputing %s\n", ac_object_get_name(ob));

	ac_object_get_contents(ob, &numvert, &numsurf, &numkids,
		&vertices, &surfaces, &kids); 

	// we are only interested in triangles, so we a list of triangulated surfaces
	List *triangs = ac_object_get_triangle_surfaces(ob); // get list of triangles (ignores lines/polyline surfaces)

	int numtri = list_count(triangs);

	if (numtri > 0)
		{
		fprintf(f, "%d\n", numvert); // output number of vertices
		for (p = vertices; p != NULL; p = p->next) // output each vertex
			{
			Vertex *v = (Vertex *)p->data;

			fprintf(f, "%f %f %f\n", v->x, v->y, v->z);
			}
	
		fprintf(f, "%d\n", numtri); /** output the number of triangles **/
		sv_output_surfaces(f, vertices, triangs); // output number of surfaces and each surface
		}

	ac_surfacelist_free(&triangs); // important - free the surfaces (and list) created from ac_object_get_triangle_surfaces

	for (p = kids; p != NULL; p = p->next) // output any children objects
		sv_output_object(f, (ACObject *)p->data);
}




static Boolean do_sv_save(char *fname, ACObject *top)
{
FILE *f;

	f = fopen(fname, "w");
	if (f == NULL)
		{
		message_dialog("SV EXporter: can't open file '%s' for writing", fname);
		return(FALSE);
		}

	fprintf(f, "SV\n"); /** output a header **/
	sv_output_object(f, top );
	fclose(f);
	return(TRUE);
}

/***** hook functions that the AC3D plugin loader looks for *******/

AC3D_PLUGIN_FUNC int AC3DPluginInit()
{
double ver = ac_get_version_number();

	ac_register_file_exporter("SV", ".sv", "SurfaceVertex", do_sv_save, "plugin, version 1.1, by Inivis");

	return(0);
}


AC3D_PLUGIN_FUNC int AC3DPluginExit()
{
	return(0);
}

AC3D_PLUGIN_FUNC char *AC3DPluginAbout()
{
	return("SV Export Plugin - Version 1.1 - by Inivis");
}


AC3D_PLUGIN_FUNC char *AC3DPluginInfo()
{
return("SV is a simple file format that is used to demonstrate how to write AC3D geometry import/export plugins.\
The structure:\n\n\
SV\n\
<NUMVERT>\n\
(numvert of) <X> <Y> <Z>\n\
<NUMTRIANGLES>					 ( 1 or more blocks until EOF)\n\
(numtriangles of) <V1> <V2> <V3> <HEXRGB>\n\
\n\
\n\
e.g. white a rectangle (made from two triangles)\n\
SV\n\
4\n\
0.000000 1.000000 0.000000\n\
1.000000 1.000000 0.000000\n\
1.000000 0.000000 0.000000\n\
0.000000 0.000000 0.000000\n\
2\n\
2 0 3 ffffff\n\
0 2 1 ffffff\n");
}
Andy is offline   Reply With Quote