1 /********************************************************************/
2 /* STRIPE: converting a polygonal model to triangle strips
5 Advisors: Steven Skiena and Amitabh Varshney
7 /********************************************************************/
9 /*---------------------------------------------------------------------*/
11 This file contains the main procedure code that will read in the
12 object and then call the routines that produce the triangle strips.
14 /*---------------------------------------------------------------------*/
27 #include "triangulate.h"
36 /* TIMING for Windows */
38 #include <sys/timeb.h>
42 #include <sys/types.h>
43 #include <sys/param.h>
44 #include <sys/times.h>
48 static long total = 0;
52 dummy = buffer.tms_utime + buffer.tms_stime +
53 buffer.tms_cutime + buffer.tms_cstime;
54 cpu_time = ((dummy - total) * 1000) / HZ;
70 struct timeb timebuffer;
79 timeline = ctime( & ( timebuffer.time ) );
80 printf( "The time is %.19s.%hu %s", timeline, timebuffer.millitm, &timeline[20] );
83 printf("The time is %ld\n",timer);
89 Here the main program begins. It will start by loading in a .obj file
90 then it will convert the polygonal model into triangle strips.
94 int main (int argc,char *argv[])
96 char *fname, *oname, *all,buff[255], *ptr, *ptr2;
105 int temp[STRIP_MAX],vertex,strips, swaps,tempi,cost,triangles;
115 BOOL texture, normal, normal_and_texture,quads = FALSE;
117 /* Options variables */
118 double norm_difference;
120 /* Structures for the object */
121 struct vert_struct *vertices = NULL,
129 Scan the file once to find out the number of vertices,
130 vertice normals, and faces so we can set up some memory
133 /* Interpret the options specified */
134 norm_difference = get_options(argc,argv,&f,&t,&tr,&g);
140 fname = argv[argc-2];
141 oname = argv[argc-1];
143 printf ("Input file: %s Output file: %s\n", fname, oname);
144 printf ("Scanning...%s ",file_open);
147 /* File that will contain the triangle strip data */
149 bands = fopen(oname, "w");
151 /* File can be in binary for faster reading */
152 if (file = fopen (fname,file_open))
158 fread (buff,sizeof(char) * 255,1, file);
160 fgets (buff, sizeof(char) * 255, file);
172 else if (*(buff+1)=='t')
174 /* At a regular vertex */
179 else if (*buff == 'f')
184 while (strtok(NULL, " ") != NULL) tempi++;
185 num_tris += tempi - 2;
192 printf("Error in the file name\n");
196 printf("%s pass 1\n",fname);
198 /* Allocate structures for the information */
199 Start_Face_Struct(num_faces);
200 vertices = (struct vert_struct *)
201 malloc (sizeof (struct vert_struct) * num_vert);
204 nvertices = (struct vert_struct *)
205 malloc (sizeof (struct vert_struct) * num_nvert);
206 vert_norms = (int *) malloc (sizeof (int) * num_vert);
208 Initialize entries to zero, in case there are 2 hits
209 to the same vertex we will know it - used for determining
210 the normal difference
212 init_vert_norms(num_vert);
217 if (num_texture > 0) {
218 vert_texture = (int *) malloc (sizeof(int) * num_vert);
219 init_vert_texture(num_vert);
223 Set up the temporary 'p' pointers
225 pvertices = vertices;
226 pnvertices = nvertices;
228 /* Load the object into memory */
229 /*printf (" Loading...");*/
231 fprintf(bands,"#%s: a triangle strip representation created by STRIPE.\n#This is a .objf file\n#by Francine Evans\n",fname);
233 /* File will be put in a list for faster execution if file is in binary */
234 if (file = fopen(fname,file_open)) {
236 all = (char *) malloc (sizeof(char) * 255 * num);
237 fread(all,sizeof(char) * 255 * num, 1, file);
240 ptr = (char *) malloc (sizeof(char) * 255 * num);
251 fgets (ptr, sizeof(char) * 255, file);
256 /* Load in vertices/normals */
259 sscanf (ptr+3,"%lf%lf%lf",
263 fprintf(bands,"vn %f %f %f\n",
264 pnvertices->x,pnvertices->y,pnvertices->z);
266 } else if (*(ptr+1)=='t') {
267 sscanf (ptr+3,"%f%f%f",¢er[0],¢er[1],¢er[2]);
268 fprintf(bands,"vt %f %f %f\n",center[0],center[1],center[2]);
270 sscanf (ptr+2,"%lf%lf%lf",
274 fprintf(bands,"v %f %f %f\n",
275 pvertices->x,pvertices->y,pvertices->z);
278 } else if (*ptr == 'f') {
283 normal = FALSE; texture = FALSE, normal_and_texture = FALSE;
285 if (*ptr2 >='0' && *ptr2 <='9') {
288 while (*ptr2 && (*ptr2!=' ' && *ptr2!='/')) {
291 /* There are normals in this line */
293 if (*(ptr2+1) == '/') {
298 } else if (*ptr2 == ' ') {
299 if ((num2 == 3) && (texture)) {
300 normal_and_texture = TRUE;
311 loop on the number of numbers in this line of face data
315 for (loop=0;loop<num2;loop++) {
316 /* skip the whitespace */
317 while (*ptr2<'0' || *ptr2>'9') {
323 vertex = atoi(ptr2)-1;
325 vertex = num_vert + vertex;
330 If there are either normals or textures with the vertices
331 in this file, the data alternates so we must read it this way
333 if ( (normal) && (!normal_and_texture)) {
335 add_norm_id(vertex,vert_count);
337 Test here to see if we added a new vertex, since the
338 vertex has more than one normal and the 2 normals are greater
339 than the threshold specified
341 if (norm_array(vertex,0,norm_difference,nvertices,num_vert)) {
343 Add a new vertex and change the
344 id of the vertex that we just read to the id of the new
345 vertex that we just added
348 Put it in the output file, note the added vertices will
349 be after the normals and separated from the rest of the
350 vertices. Will not affect our viewer
352 fprintf(bands,"v %f %f %f\n",
353 (vertices + temp[vert_count - 1])->x,
354 (vertices + temp[vert_count - 1])->y,
355 (vertices + temp[vert_count - 1])->z);
357 temp[vert_count - 1] = num_vert - 1;
358 if (!(add_vert_id(num_vert - 1,vert_count))) {
364 temp[vert_count] = vertex ;
366 if (!(add_vert_id(vertex,vert_count))) {
369 norm_array(vertex,1,norm_difference,nvertices,num_vert);
371 } else if (normal_and_texture) {
372 /* Else there are vertices and textures with the data */
374 add_norm_id(vertex,vert_count);
376 Test here to see if we added a new vertex, since the
377 vertex has more than one normal and the 2 normals are greater
378 than the threshold specified
380 if (norm_array(vertex,0,norm_difference,nvertices,num_vert)) {
382 Add a new vertex and change the
383 id of the vertex that we just read to the id of the new
384 vertex that we just added
387 Put it in the output file, note the added vertices will
388 be after the normals and separated from the rest of the
389 vertices. Will not affect our viewer
391 fprintf(bands,"v %f %f %f\n",
392 (vertices + temp[vert_count - 1])->x,
393 (vertices + temp[vert_count - 1])->y,
394 (vertices + temp[vert_count - 1])->z);
396 temp[vert_count - 1] = num_vert - 1;
397 if (!(add_vert_id(num_vert - 1,vert_count))) {
401 } else if ((loop == 0) || (*(ptr2-1) == ' ')) {
403 temp[vert_count] = vertex ;
405 if (vert_count == 4) {
408 if (!(add_vert_id(vertex,vert_count))) {
411 add_texture(vertex,TRUE);
412 norm_array(vertex,1,norm_difference,nvertices,num_vert);
415 add_texture(vertex,FALSE);
417 } else if ( texture ) {
420 temp[vert_count] = vertex ;
424 add_texture(vertex,TRUE);
425 if (!(add_vert_id(vertex,vert_count)))
427 norm_array(vertex,1,norm_difference,nvertices,num_vert);
430 add_texture(vertex,FALSE);
433 /*** no nvertices ***/
434 temp[vert_count] = vertex ;
438 if (!(add_vert_id(vertex,vert_count)))
441 while (*ptr2>='0' && *ptr2<='9')
444 /* Done with the polygon */
445 num_edges += vert_count;
446 /* add it to face structure */
448 AddNewFace(ids,vert_count,face_id,norms);
454 else if ((g == TRUE) && (face_id > 0)
455 && ((*ptr == 'g') || (*ptr == 's') || (*ptr == 'm') || (*ptr == 'o')))
458 The user specified that the strips will be contained in each group
459 from the data file, so we just finished a group and will find the
460 triangle strips in it.
462 Start_Edge_Struct(num_vert);
463 Find_Adjacencies(face_id);
467 Build_SGI_Table(num_vert,face_id);
468 /* Code for lengths of walks in each direction */
469 /* Save_Walks(face_id,TRUE); */
472 /* Code for finding the bands */
473 Find_Bands(face_id,bands,&swaps,&strips,&cost,&triangles,num_nvert,vert_norms,num_texture,vert_texture);
476 Remove the faces that we did so that we can
477 run the strip code on the rest of the faces that are left
481 printf("Total %d triangles with %d cost\n",triangles,cost);
483 printf("We saved %d .... now doing the local algorithm\n",face_id);
484 fprintf(bands,"\n#local\n");
485 End_Edge_Struct(num_vert);
486 Start_Edge_Struct(num_vert);
487 Find_Adjacencies(face_id);
491 SGI_Strip(num_vert,face_id,bands,t,tr);
493 /* Get the total cost */
494 Output_TriEx(-1,-2,-3,NULL,-1,-20,cost);
496 End_Face_Struct(num_faces);
497 End_Edge_Struct(num_vert);
501 Start_Face_Struct(num_faces-face_id);
502 num_faces = num_faces - face_id;
507 /* Done reading in all the information into data structures */
511 printf("Input Done.\n\n");
516 printf ("Vertices: %d\nNormals: %d\nFaces: %d\n",num_vert,num_nvert,num_faces);
518 Start_Edge_Struct(num_vert);
519 Find_Adjacencies(num_faces);
524 Build_SGI_Table(num_vert,num_faces);
529 /* Code for lengths of walks in each direction */
530 /* Save_Walks(num_faces,TRUE); */
531 Save_Walks(num_faces);
533 /* Code for finding the bands */
534 Find_Bands(num_faces,bands,&swaps,&strips,&cost,&triangles,num_nvert,vert_norms,num_texture,vert_texture);
535 /*printf("Total %d triangles with %d cost\n",triangles,cost);*/
538 Remove the faces that we did so that we can
539 run the strip code on the rest of the faces that are left
541 Save_Rest(&num_faces);
542 /*printf("We saved %d .... now doing the local algorithm\n",num_faces);*/
543 fprintf(bands,"\n#local\n");
544 End_Edge_Struct(num_vert);
545 Start_Edge_Struct(num_vert);
546 Find_Adjacencies(num_faces);
549 SGI_Strip(num_vert,num_faces,bands,t,tr);
551 /* Get the total cost */
552 Output_TriEx(-1,-2,-3,NULL,-1,-20,cost);
554 End_Face_Struct(num_faces);
555 End_Edge_Struct(num_vert);