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,*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,
128 /* File that will contain the triangle strip data */
129 bands = fopen("stripe.objf","w");
132 Scan the file once to find out the number of vertices,
133 vertice normals, and faces so we can set up some memory
136 /* Interpret the options specified */
137 norm_difference = get_options(argc,argv,&f,&t,&tr,&g);
143 fname = argv[argc-1];
145 printf ("File: %s\n",fname);
146 printf ("Scanning...%s ",file_open);
149 /* File can be in binary for faster reading */
150 if (file = fopen (fname,file_open))
156 fread (buff,sizeof(char) * 255,1, file);
158 fgets (buff, sizeof(char) * 255, file);
170 else if (*(buff+1)=='t')
172 /* At a regular vertex */
177 else if (*buff == 'f')
182 while (strtok(NULL, " ") != NULL) tempi++;
183 num_tris += tempi - 2;
190 printf("Error in the file name\n");
194 printf("%s pass 1\n",fname);
196 /* Allocate structures for the information */
197 Start_Face_Struct(num_faces);
198 vertices = (struct vert_struct *)
199 malloc (sizeof (struct vert_struct) * num_vert);
202 nvertices = (struct vert_struct *)
203 malloc (sizeof (struct vert_struct) * num_nvert);
204 vert_norms = (int *) malloc (sizeof (int) * num_vert);
206 Initialize entries to zero, in case there are 2 hits
207 to the same vertex we will know it - used for determining
208 the normal difference
210 init_vert_norms(num_vert);
215 if (num_texture > 0) {
216 vert_texture = (int *) malloc (sizeof(int) * num_vert);
217 init_vert_texture(num_vert);
221 Set up the temporary 'p' pointers
223 pvertices = vertices;
224 pnvertices = nvertices;
226 /* Load the object into memory */
227 /*printf (" Loading...");*/
229 fprintf(bands,"#%s: a triangle strip representation created by STRIPE.\n#This is a .objf file\n#by Francine Evans\n",fname);
231 /* File will be put in a list for faster execution if file is in binary */
232 if (file = fopen(fname,file_open)) {
234 all = (char *) malloc (sizeof(char) * 255 * num);
235 fread(all,sizeof(char) * 255 * num, 1, file);
238 ptr = (char *) malloc (sizeof(char) * 255 * num);
249 fgets (ptr, sizeof(char) * 255, file);
254 /* Load in vertices/normals */
257 sscanf (ptr+3,"%lf%lf%lf",
261 fprintf(bands,"vn %f %f %f\n",
262 pnvertices->x,pnvertices->y,pnvertices->z);
264 } else if (*(ptr+1)=='t') {
265 sscanf (ptr+3,"%f%f%f",¢er[0],¢er[1],¢er[2]);
266 fprintf(bands,"vt %f %f %f\n",center[0],center[1],center[2]);
268 sscanf (ptr+2,"%lf%lf%lf",
272 fprintf(bands,"v %f %f %f\n",
273 pvertices->x,pvertices->y,pvertices->z);
276 } else if (*ptr == 'f') {
281 normal = FALSE; texture = FALSE, normal_and_texture = FALSE;
283 if (*ptr2 >='0' && *ptr2 <='9') {
286 while (*ptr2 && (*ptr2!=' ' && *ptr2!='/')) {
289 /* There are normals in this line */
291 if (*(ptr2+1) == '/') {
296 } else if (*ptr2 == ' ') {
297 if ((num2 == 3) && (texture)) {
298 normal_and_texture = TRUE;
309 loop on the number of numbers in this line of face data
313 for (loop=0;loop<num2;loop++) {
314 /* skip the whitespace */
315 while (*ptr2<'0' || *ptr2>'9') {
321 vertex = atoi(ptr2)-1;
323 vertex = num_vert + vertex;
328 If there are either normals or textures with the vertices
329 in this file, the data alternates so we must read it this way
331 if ( (normal) && (!normal_and_texture)) {
333 add_norm_id(vertex,vert_count);
335 Test here to see if we added a new vertex, since the
336 vertex has more than one normal and the 2 normals are greater
337 than the threshold specified
339 if (norm_array(vertex,0,norm_difference,nvertices,num_vert)) {
341 Add a new vertex and change the
342 id of the vertex that we just read to the id of the new
343 vertex that we just added
346 Put it in the output file, note the added vertices will
347 be after the normals and separated from the rest of the
348 vertices. Will not affect our viewer
350 fprintf(bands,"v %f %f %f\n",
351 (vertices + temp[vert_count - 1])->x,
352 (vertices + temp[vert_count - 1])->y,
353 (vertices + temp[vert_count - 1])->z);
355 temp[vert_count - 1] = num_vert - 1;
356 if (!(add_vert_id(num_vert - 1,vert_count))) {
362 temp[vert_count] = vertex ;
364 if (!(add_vert_id(vertex,vert_count))) {
367 norm_array(vertex,1,norm_difference,nvertices,num_vert);
369 } else if (normal_and_texture) {
370 /* Else there are vertices and textures with the data */
372 add_norm_id(vertex,vert_count);
374 Test here to see if we added a new vertex, since the
375 vertex has more than one normal and the 2 normals are greater
376 than the threshold specified
378 if (norm_array(vertex,0,norm_difference,nvertices,num_vert)) {
380 Add a new vertex and change the
381 id of the vertex that we just read to the id of the new
382 vertex that we just added
385 Put it in the output file, note the added vertices will
386 be after the normals and separated from the rest of the
387 vertices. Will not affect our viewer
389 fprintf(bands,"v %f %f %f\n",
390 (vertices + temp[vert_count - 1])->x,
391 (vertices + temp[vert_count - 1])->y,
392 (vertices + temp[vert_count - 1])->z);
394 temp[vert_count - 1] = num_vert - 1;
395 if (!(add_vert_id(num_vert - 1,vert_count))) {
399 } else if ((loop == 0) || (*(ptr2-1) == ' ')) {
401 temp[vert_count] = vertex ;
403 if (vert_count == 4) {
406 if (!(add_vert_id(vertex,vert_count))) {
409 add_texture(vertex,TRUE);
410 norm_array(vertex,1,norm_difference,nvertices,num_vert);
413 add_texture(vertex,FALSE);
415 } else if ( texture ) {
418 temp[vert_count] = vertex ;
422 add_texture(vertex,TRUE);
423 if (!(add_vert_id(vertex,vert_count)))
425 norm_array(vertex,1,norm_difference,nvertices,num_vert);
428 add_texture(vertex,FALSE);
431 /*** no nvertices ***/
432 temp[vert_count] = vertex ;
436 if (!(add_vert_id(vertex,vert_count)))
439 while (*ptr2>='0' && *ptr2<='9')
442 /* Done with the polygon */
443 num_edges += vert_count;
444 /* add it to face structure */
446 AddNewFace(ids,vert_count,face_id,norms);
452 else if ((g == TRUE) && (face_id > 0)
453 && ((*ptr == 'g') || (*ptr == 's') || (*ptr == 'm') || (*ptr == 'o')))
456 The user specified that the strips will be contained in each group
457 from the data file, so we just finished a group and will find the
458 triangle strips in it.
460 Start_Edge_Struct(num_vert);
461 Find_Adjacencies(face_id);
465 Build_SGI_Table(num_vert,face_id);
466 /* Code for lengths of walks in each direction */
467 /* Save_Walks(face_id,TRUE); */
470 /* Code for finding the bands */
471 Find_Bands(face_id,bands,&swaps,&strips,&cost,&triangles,num_nvert,vert_norms,num_texture,vert_texture);
474 Remove the faces that we did so that we can
475 run the strip code on the rest of the faces that are left
479 printf("Total %d triangles with %d cost\n",triangles,cost);
481 printf("We saved %d .... now doing the local algorithm\n",face_id);
482 fprintf(bands,"\n#local\n");
483 End_Edge_Struct(num_vert);
484 Start_Edge_Struct(num_vert);
485 Find_Adjacencies(face_id);
489 SGI_Strip(num_vert,face_id,bands,t,tr);
491 /* Get the total cost */
492 Output_TriEx(-1,-2,-3,NULL,-1,-20,cost);
494 End_Face_Struct(num_faces);
495 End_Edge_Struct(num_vert);
499 Start_Face_Struct(num_faces-face_id);
500 num_faces = num_faces - face_id;
505 /* Done reading in all the information into data structures */
509 printf("Input Done.\n\n");
514 printf ("Vertices: %d\nNormals: %d\nFaces: %d\n",num_vert,num_nvert,num_faces);
516 Start_Edge_Struct(num_vert);
517 Find_Adjacencies(num_faces);
522 Build_SGI_Table(num_vert,num_faces);
527 /* Code for lengths of walks in each direction */
528 /* Save_Walks(num_faces,TRUE); */
529 Save_Walks(num_faces);
531 /* Code for finding the bands */
532 Find_Bands(num_faces,bands,&swaps,&strips,&cost,&triangles,num_nvert,vert_norms,num_texture,vert_texture);
533 /*printf("Total %d triangles with %d cost\n",triangles,cost);*/
536 Remove the faces that we did so that we can
537 run the strip code on the rest of the faces that are left
539 Save_Rest(&num_faces);
540 /*printf("We saved %d .... now doing the local algorithm\n",num_faces);*/
541 fprintf(bands,"\n#local\n");
542 End_Edge_Struct(num_vert);
543 Start_Edge_Struct(num_vert);
544 Find_Adjacencies(num_faces);
547 SGI_Strip(num_vert,num_faces,bands,t,tr);
549 /* Get the total cost */
550 Output_TriEx(-1,-2,-3,NULL,-1,-20,cost);
552 End_Face_Struct(num_faces);
553 End_Edge_Struct(num_vert);