ivcon.c
Go to the documentation of this file.
1 /* ivcon.c 24 May 2001 */
2 
3 /*
4  Purpose:
5 
6  IVCON converts various 3D graphics files.
7 
8  Acknowledgements:
9 
10  Coding, comments, and advice were supplied by a number of collaborators.
11 
12  John F Flanagan made some corrections to the 3D Studio Max routines.
13 
14  Zik Saleeba (zik@zikzak.net) enhanced the DXF routines, and added the
15  Golgotha GMOD routines.
16 
17  Thanks to Susan M. Fisher, University of North Carolina,
18  Department of Computer Science, for pointing out a coding error
19  in FACE_NULL_DELETE that was overwriting all the data!
20 
21  Modified:
22 
23  04 July 2000
24 
25  Author:
26 
27  John Burkardt
28 */
29 
30 #include <ctype.h>
31 #include <math.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 
36 #define FALSE 0
37 #define TRUE 1
38 
39 #define ERROR 1
40 #define G1_SECTION_MODEL_QUADS 18
41 #define G1_SECTION_MODEL_TEXTURE_NAMES 19
42 #define G1_SECTION_MODEL_VERT_ANIMATION 20
43 #define GMOD_MAX_SECTIONS 32
44 #define GMOD_UNUSED_VERTEX 65535
45 #define PI 3.141592653589793238462643
46 #define SUCCESS 0
47 
48 #define DEG_TO_RAD ( PI / 180.0 )
49 #define RAD_TO_DEG ( 180.0 / PI )
50 
51 /******************************************************************************/
52 
53 /* GLOBAL DATA */
54 
55 /******************************************************************************/
56 
57 /*
58  BACKGROUND_RGB[3], the background color.
59 
60  BYTE_SWAP, byte swapping option.
61 
62  COR3[3][COR3_MAX], the coordinates of nodes.
63 
64  COR3_MATERIAL[COR3_MAX], the index of the material of each node.
65 
66  COR3_MAX, the maximum number of points.
67 
68  COR3_NORMAL[3][COR3_MAX], normal vectors associated with nodes.
69 
70  COR3_NUM, the number of points.
71 
72  COR3_RGB[3][COR3_MAX], RGB colors associated with nodes.
73 
74  COR3_TEX_UV[2][COR3_MAX], texture coordinates associated with nodes.
75 
76  FACE[ORDER_MAX][FACE_MAX] contains the index of the I-th node making up face J.
77 
78  FACE_AREA(FACE_MAX), the area of each face.
79 
80  FACE_MATERIAL[FACE_MAX]; the material of each face.
81 
82  FACE_MAX, the maximum number of faces.
83 
84  FACE_NORMAL[3][FACE_MAX], the face normal vectors.
85 
86  FACE_NUM, the number of faces.
87 
88  FACE_ORDER[FACE_MAX], the number of vertices per face.
89 
90  FACE_TEX_UV[2][FACE_MAX], texture coordinates associated with faces.
91 
92  LINE_DEX[LINES_MAX], node indices, denoting polylines, each terminated by -1.
93 
94  LINE_MATERIAL[LINES_MAX], index into RGBCOLOR for line color.
95 
96  LINES_MAX, the maximum number of line definition items.
97 
98  LINE_NUM, the number of line definition items.
99 
100  LINE_PRUNE, pruning option ( 0 = no pruning, nonzero = pruning).
101 
102  MATERIAL_MAX, the maximum number of materials.
103 
104  MATERIAL_NUM, the number of materials.
105 
106  ORDER_MAX, the maximum number of vertices per face.
107 
108  TEXTURE_MAX, the maximum number of textures.
109 
110  TEXTURE_NAME[TEXTURE_MAX][LINE_MAX_LEN], ...
111 
112  TEXTURE_NUM, the number of textures.
113 
114  TRANSFORM_MATRIX[4][4], the current transformation matrix.
115 
116  VERTEX_MATERIAL[ORDER_MAX][FACE_MAX]; the material of vertices of faces.
117 
118  VERTEX_NORMAL[3][ORDER_MAX][FACE_MAX], normals at vertices of faces.
119 
120  VERTEX_RGB[3][ORDER_MAX][FACE_MAX], colors of vertices of faces.
121 
122  VERTEX_TEX_UV[2][ORDER_MAX][FACE_MAX], texture coordinates of vertices of faces.
123 */
124 
125 #define COLOR_MAX 1000
126 #define COR3_MAX 200000
127 #define FACE_MAX 200000
128 #define LINE_MAX_LEN 256
129 #define LEVEL_MAX 10
130 #define LINES_MAX 100000
131 #define MATERIAL_MAX 100
132 #define ORDER_MAX 10
133 #define TEXTURE_MAX 100
134 
136 float background_rgb[3];
142 
143 float cor3[3][COR3_MAX];
148 
149 int debug;
150 
152 
163 
164 char filein_name[1024];
165 char fileout_name[1024];
166 
168 
169 int i;
171 int k;
173 
178 
180 
185 
186 char mat_name[81];
188 
189 char normal_binding[80];
191 
192 char object_name[81];
194 
195 float origin[3];
196 float pivot[3];
197 float rgbcolor[3][COLOR_MAX];
198 char temp_name[81];
199 
201 
206 
207 float transform_matrix[4][4];
208 
213 
214 /******************************************************************************/
215 
216 /* FUNCTION PROTOTYPES */
217 
218 /******************************************************************************/
219 
220 int main ( int argc, char **argv );
221 int ase_read ( FILE *filein );
222 int ase_write ( FILE *fileout );
223 int byu_read ( FILE *filein );
224 int byu_write ( FILE *fileout );
225 int char_index_last ( char* string, char c );
226 int char_pad ( int *char_index, int *null_index, char *string,
227  int STRING_MAX );
228 char char_read ( FILE *filein );
229 int char_write ( FILE *fileout, char c );
230 int command_line ( char **argv );
231 void cor3_normal_set ( void );
232 void cor3_range ( void );
233 void data_check ( void );
234 void data_init ( void );
235 int data_read ( void );
236 void data_report ( void );
237 int data_write ( void );
238 int dxf_read ( FILE *filein );
239 int dxf_write ( FILE *fileout );
240 void edge_null_delete ( void );
241 void face_area_set ( void );
242 void face_normal_ave ( void );
243 void face_null_delete ( void );
244 int face_print ( int iface );
245 void face_reverse_order ( void );
246 int face_subset ( void );
247 void face_to_line ( void );
248 void face_to_vertex_material ( void );
249 char *file_ext ( char *file_name );
250 float float_read ( FILE *filein );
251 float float_reverse_bytes ( float x );
252 int float_write ( FILE *fileout, float float_val );
253 int gmod_arch_check ( void );
254 int gmod_read ( FILE *filein );
255 float gmod_read_float ( FILE *filein );
256 unsigned short gmod_read_w16 ( FILE *filein );
257 unsigned long gmod_read_w32 ( FILE *filein );
258 int gmod_write ( FILE *fileout );
259 void gmod_write_float ( float Val, FILE *fileout );
260 void gmod_write_w16 ( unsigned short Val, FILE *fileout );
261 void gmod_write_w32 ( unsigned long Val, FILE *fileout );
262 void hello ( void );
263 void help ( void );
264 int hrc_read ( FILE *filein );
265 int hrc_write ( FILE *fileout );
266 void init_program_data ( void );
267 int interact ( void );
268 int iv_read ( FILE *filein );
269 int iv_write ( FILE *fileout );
270 int ivec_max ( int n, int *a );
271 int leqi ( char* string1, char* string2 );
272 long int long_int_read ( FILE *filein );
273 int long_int_write ( FILE *fileout, long int int_val );
274 void news ( void );
275 void node_to_vertex_material ( void );
276 int obj_read ( FILE *filein );
277 int obj_write ( FILE *fileout );
278 int pov_write ( FILE *fileout );
279 int rcol_find ( float a[][COR3_MAX], int m, int n, float r[] );
280 float rgb_to_hue ( float r, float g, float b );
281 short int short_int_read ( FILE *filein );
282 int short_int_write ( FILE *fileout, short int int_val );
283 int smf_read ( FILE *filein );
284 int smf_write ( FILE *fileout );
285 int stla_read ( FILE *filein );
286 int stla_write ( FILE *fileout );
287 int stlb_read ( FILE *filein );
288 int stlb_write ( FILE *fileout );
289 void tds_pre_process ( void );
290 int tds_read ( FILE *filein );
291 unsigned long int tds_read_ambient_section ( FILE *filein );
292 unsigned long int tds_read_background_section ( FILE *filein );
293 unsigned long int tds_read_boolean ( unsigned char *boolean, FILE *filein );
294 unsigned long int tds_read_camera_section ( FILE *filein );
295 unsigned long int tds_read_edit_section ( FILE *filein, int *views_read );
296 unsigned long int tds_read_keyframe_section ( FILE *filein, int *views_read );
297 unsigned long int tds_read_keyframe_objdes_section ( FILE *filein );
298 unsigned long int tds_read_light_section ( FILE *filein );
299 unsigned long int tds_read_u_long_int ( FILE *filein );
300 int tds_read_long_name ( FILE *filein );
301 unsigned long int tds_read_matdef_section ( FILE *filein );
302 unsigned long int tds_read_material_section ( FILE *filein );
303 int tds_read_name ( FILE *filein );
304 unsigned long int tds_read_obj_section ( FILE *filein );
305 unsigned long int tds_read_object_section ( FILE *filein );
306 unsigned long int tds_read_tex_verts_section ( FILE *filein );
307 unsigned long int tds_read_texmap_section ( FILE *filein );
308 unsigned short int tds_read_u_short_int ( FILE *filein );
309 unsigned long int tds_read_spot_section ( FILE *filein );
310 unsigned long int tds_read_unknown_section ( FILE *filein );
311 unsigned long int tds_read_view_section ( FILE *filein, int *views_read );
312 unsigned long int tds_read_vp_section ( FILE *filein, int *views_read );
313 int tds_write ( FILE *fileout );
314 int tds_write_string ( FILE *fileout, char *string );
315 int tds_write_u_short_int ( FILE *fileout,
316  unsigned short int int_val );
317 int tec_write ( FILE *fileout );
318 void tmat_init ( float a[4][4] );
319 void tmat_mxm ( float a[4][4], float b[4][4], float c[4][4] );
320 void tmat_mxp ( float a[4][4], float x[4], float y[4] );
321 void tmat_mxp2 ( float a[4][4], float x[][3], float y[][3], int n );
322 void tmat_mxv ( float a[4][4], float x[4], float y[4] );
323 void tmat_rot_axis ( float a[4][4], float b[4][4], float angle,
324  char axis );
325 void tmat_rot_vector ( float a[4][4], float b[4][4], float angle,
326  float v1, float v2, float v3 );
327 void tmat_scale ( float a[4][4], float b[4][4], float sx, float sy,
328  float sz );
329 void tmat_shear ( float a[4][4], float b[4][4], char *axis,
330  float s );
331 void tmat_trans ( float a[4][4], float b[4][4], float x, float y,
332  float z );
333 int tria_read ( FILE *filein );
334 int tria_write ( FILE *fileout );
335 int trib_read ( FILE *filein );
336 int trib_write ( FILE *fileout );
337 int txt_write ( FILE *fileout );
338 int ucd_write ( FILE *fileout );
339 void vertex_normal_set ( void );
340 void vertex_to_face_material ( void );
341 void vertex_to_node_material ( void );
342 int vla_read ( FILE *filein );
343 int vla_write ( FILE *fileout );
344 int wrl_write ( FILE *filout );
345 int xgl_write ( FILE *fileout );
346 
347 /******************************************************************************/
348 
349 int main ( int argc, char **argv )
350 
351 /******************************************************************************/
352 
353 /*
354  Purpose:
355 
356  MAIN is the main program for converting graphics files.
357 
358  Modified:
359 
360  26 May 1999
361 
362  Author:
363 
364  John Burkardt
365 */
366 {
367  int result;
368 /*
369  Initialize the program data.
370 */
371  init_program_data ( );
372 /*
373  If there are at least two command line arguments, call COMMAND_LINE.
374  Otherwise call INTERACT and get information from the user.
375 */
376  if ( argc >= 2 ) {
377  result = command_line ( argv );
378  }
379  else {
380  result = interact ( );
381  }
382 
383  return result;
384 }
385 /******************************************************************************/
386 
387 int ase_read ( FILE *filein )
388 
389 /******************************************************************************/
390 
391 /*
392  Purpose:
393 
394  ASE_READ reads an AutoCAD ASE file.
395 
396  Modified:
397 
398  22 May 1999
399 
400  Author:
401 
402  John Burkardt
403 */
404 {
405  float bval;
406  int count;
407  float gval;
408  int i;
409  int iface;
410  int ivert;
411  int iword;
412  int level;
413  char *next;
414  int nlbrack;
415  int nrbrack;
416  int cor3_num_old;
417  int face_num_old;
418  float rval;
419  float temp;
420  int width;
421  char word[LINE_MAX_LEN];
422  char word1[LINE_MAX_LEN];
423  char word2[LINE_MAX_LEN];
424  char wordm1[LINE_MAX_LEN];
425  float x;
426  float y;
427  float z;
428 
429  level = 0;
430  strcpy ( level_name[0], "Top" );
431  cor3_num_old = cor3_num;
432  face_num_old = face_num;
433  nlbrack = 0;
434  nrbrack = 0;
435 
436  strcpy ( word, " " );
437  strcpy ( wordm1, " " );
438 /*
439  Read a line of text from the file.
440 */
441 
442  for ( ;; ) {
443 
444  if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) {
445  break;
446  }
447 
448  text_num = text_num + 1;
449  next = input;
450  iword = 0;
451 /*
452  Read the next word from the line.
453 */
454  for ( ;; ) {
455 
456  strcpy ( wordm1, word );
457  strcpy ( word, " " );
458 
459  count = sscanf ( next, "%s%n", word, &width );
460  next = next + width;
461 
462  if ( count <= 0 ) {
463  break;
464  }
465 
466  iword = iword + 1;
467 
468  if ( iword == 1 ) {
469  strcpy ( word1, word );
470  }
471 /*
472  In case the new word is a bracket, update the bracket count.
473 */
474  if ( strcmp ( word, "{" ) == 0 ) {
475 
476  nlbrack = nlbrack + 1;
477  level = nlbrack - nrbrack;
478  strcpy ( level_name[level], wordm1 );
479  }
480  else if ( strcmp ( word, "}" ) == 0 ) {
481 
482  nrbrack = nrbrack + 1;
483 
484  if ( nlbrack < nrbrack ) {
485 
486  printf ( "\n" );
487  printf ( "ASE_READ - Fatal error!\n" );
488  printf ( " Extraneous right bracket on line %d\n", text_num );
489  printf ( " Currently processing field:\n" );
490  printf ( "%s\n", level_name[level] );
491  return ERROR;
492  }
493 
494  }
495 /*
496  *3DSMAX_ASCIIEXPORT 200
497 */
498  if ( strcmp ( word1, "*3DSMAX_ASCIIEXPORT" ) == 0 ) {
499  break;
500  }
501 /*
502  *COMMENT
503 */
504  else if ( strcmp ( word1, "*COMMENT" ) == 0 ) {
505  break;
506  }
507 /*
508  *GEOMOBJECT
509 */
510  else if ( strcmp ( level_name[level], "*GEOMOBJECT" ) == 0 ) {
511 
512  if ( strcmp ( word, "{" ) == 0 ) {
513  continue;
514  }
515  else if ( strcmp ( word, "}" ) == 0 ) {
516  level = nlbrack - nrbrack;
517  continue;
518  }
519 /*
520  Why don't you read and save this name?
521 */
522  else if ( strcmp ( word, "*NODE_NAME" ) == 0 ) {
523  break;
524  }
525  else if ( strcmp ( word, "*NODE_TM" ) == 0 ) {
526  continue;
527  }
528  else if ( strcmp ( word, "*MESH" ) == 0 ) {
529  continue;
530  }
531  else if ( strcmp ( word, "*PROP_CASTSHADOW" ) == 0 ) {
532  break;
533  }
534  else if ( strcmp ( word, "*PROP_MOTIONBLUR" ) == 0 ) {
535  break;
536  }
537  else if ( strcmp ( word, "*PROP_RECVSHADOW" ) == 0 ) {
538  break;
539  }
540  else {
541  bad_num = bad_num + 1;
542  printf ( "Bad data in GEOMOBJECT, line %d\n", text_num );
543  break;
544  }
545  }
546 /*
547  *MESH
548 */
549  else if ( strcmp ( level_name[level], "*MESH" ) == 0 ) {
550 
551  if ( strcmp ( word, "{" ) == 0 ) {
552  continue;
553  }
554  else if ( strcmp ( word, "}" ) == 0 ) {
555  level = nlbrack - nrbrack;
556  continue;
557  }
558  else if ( strcmp ( word, "*MESH_CFACELIST" ) == 0 ) {
559  continue;
560  }
561  else if ( strcmp ( word, "*MESH_CVERTLIST" ) == 0 ) {
562  continue;
563  }
564  else if ( strcmp ( word, "*MESH_FACE_LIST" ) == 0 ) {
565  continue;
566  }
567  else if ( strcmp ( word, "*MESH_NORMALS" ) == 0 ) {
568  continue;
569  }
570  else if ( strcmp ( word, "*MESH_NUMCVERTEX" ) == 0 ) {
571  break;
572  }
573  else if ( strcmp ( word, "*MESH_NUMCVFACES" ) == 0 ) {
574  break;
575  }
576  else if ( strcmp ( word, "*MESH_NUMFACES" ) == 0 ) {
577  break;
578  }
579  else if ( strcmp ( word, "*MESH_NUMTVERTEX" ) == 0 ) {
580  break;
581  }
582  else if ( strcmp ( word, "*MESH_NUMTVFACES" ) == 0 ) {
583  break;
584  }
585  else if ( strcmp ( word, "*MESH_NUMVERTEX" ) == 0 ) {
586  break;
587  }
588  else if ( strcmp ( word, "*MESH_TFACELIST" ) == 0 ) {
589  continue;
590  }
591  else if ( strcmp ( word, "*MESH_TVERTLIST" ) == 0 ) {
592  continue;
593  }
594  else if ( strcmp ( word, "*MESH_VERTEX_LIST" ) == 0 ) {
595  continue;
596  }
597  else if ( strcmp ( word, "*TIMEVALUE" ) == 0 ) {
598  break;
599  }
600  else {
601  bad_num = bad_num + 1;
602  printf ( "Bad data in MESH, line %d\n", text_num );
603  break;
604  }
605  }
606 /*
607  *MESH_CFACELIST
608 */
609  else if ( strcmp ( level_name[level], "*MESH_CFACELIST" ) == 0 ) {
610 
611  if ( strcmp ( word, "{" ) == 0 ) {
612  continue;
613  }
614  else if ( strcmp ( word, "}" ) == 0 ) {
615  level = nlbrack - nrbrack;
616  continue;
617  }
618  else if ( strcmp ( word, "*MESH_CFACE" ) == 0 ) {
619  break;
620  }
621  else {
622  bad_num = bad_num + 1;
623  printf ( "Bad data in MESH_CFACE, line %d\n", text_num );
624  break;
625  }
626  }
627 /*
628  *MESH_CVERTLIST
629 
630  Mesh vertex indices must be incremented by COR3_NUM_OLD before being stored
631  in the internal array.
632 */
633  else if ( strcmp ( level_name[level], "*MESH_CVERTLIST" ) == 0 ) {
634 
635  if ( strcmp ( word, "{" ) == 0 ) {
636  continue;
637  }
638  else if ( strcmp ( word, "}" ) == 0 ) {
639  level = nlbrack - nrbrack;
640  continue;
641  }
642  else if ( strcmp ( word, "*MESH_VERTCOL" ) == 0 ) {
643 
644  count = sscanf ( next, "%d%n", &i, &width );
645  next = next + width;
646 
647  i = i + cor3_num_old;
648 
649  count = sscanf ( next, "%f%n", &rval, &width );
650  next = next + width;
651 
652  count = sscanf ( next, "%f%n", &gval, &width );
653  next = next + width;
654 
655  count = sscanf ( next, "%f%n", &bval, &width );
656  next = next + width;
657 
658  if ( material_num < MATERIAL_MAX ) {
659  material_rgba[0][material_num] = rval;
660  material_rgba[1][material_num] = gval;
661  material_rgba[2][material_num] = bval;
662  material_rgba[3][material_num] = 1.0;
663  }
664 
667  }
668  else {
669  bad_num = bad_num + 1;
670  printf ( "\n" );
671  printf ( "ASE_READ - Warning!\n" );
672  printf ( " Bad data in MESH_CVERTLIST, line %d\n", text_num );
673  break;
674  }
675 
676  }
677 /*
678  *MESH_FACE_LIST
679  This coding assumes a face is always triangular or quadrilateral.
680 */
681  else if ( strcmp ( level_name[level], "*MESH_FACE_LIST" ) == 0 ) {
682 
683  if ( strcmp ( word, "{" ) == 0 ) {
684  continue;
685  }
686  else if ( strcmp ( word, "}" ) == 0 ) {
687  level = nlbrack - nrbrack;
688  continue;
689  }
690  else if ( strcmp ( word, "*MESH_FACE" ) == 0 ) {
691 
692  if ( face_num < FACE_MAX ) {
693 
694  face_material[face_num] = 0;
695  face_order[face_num] = 0;
696 
697  count = sscanf ( next, "%d%n", &i, &width );
698  next = next + width;
699 
700  count = sscanf ( next, "%s%n", word2, &width );
701  next = next + width;
702  count = sscanf ( next, "%s%n", word2, &width );
703  next = next + width;
704 
705  count = sscanf ( next, "%d%n", &i, &width );
706  next = next + width;
707  face[0][face_num] = i + cor3_num_old;
709 
710  count = sscanf ( next, "%s%n", word2, &width );
711  next = next + width;
712 
713  count = sscanf ( next, "%d%n", &i, &width );
714  next = next + width;
715  face[1][face_num] = i + cor3_num_old;
717 
718  count = sscanf ( next, "%s%n", word2, &width );
719  next = next + width;
720 
721  count = sscanf ( next, "%d%n", &i, &width );
722  next = next + width;
723  face[2][face_num] = i + cor3_num_old;
725 
726  count = sscanf ( next, "%s%n", word2, &width );
727  next = next + width;
728 
729  if ( strcmp ( word2, "D:" ) == 0 ) {
730  count = sscanf ( next, "%d%n", &i, &width );
731  next = next + width;
732  face[3][face_num] = i + cor3_num_old;
734  }
735  }
736 
737  face_num = face_num + 1;
738 
739  break;
740 
741  }
742  else {
743  bad_num = bad_num + 1;
744  printf ( "Bad data in MESH_FACE_LIST, line %d\n", text_num );
745  break;
746  }
747  }
748 /*
749  *MESH_NORMALS
750 */
751  else if ( strcmp ( level_name[level], "*MESH_NORMALS" ) == 0 ) {
752 
753  if ( strcmp ( word, "{" ) == 0 ) {
754  continue;
755  }
756  else if ( strcmp ( word, "}" ) == 0 ) {
757  level = nlbrack - nrbrack;
758  continue;
759  }
760  else if ( strcmp ( word, "*MESH_FACENORMAL" ) == 0 ) {
761 
762  count = sscanf ( next, "%d%n", &iface, &width );
763  next = next + width;
764 
765  count = sscanf ( next, "%f%n", &x, &width );
766  next = next + width;
767 
768  count = sscanf ( next, "%f%n", &y, &width );
769  next = next + width;
770 
771  count = sscanf ( next, "%f%n", &z, &width );
772  next = next + width;
773 
774  iface = iface + face_num_old;
775  ivert = 0;
776 
777  face_normal[0][iface] = x;
778  face_normal[1][iface] = y;
779  face_normal[2][iface] = z;
780 
781  break;
782 
783  }
784  else if ( strcmp ( word, "*MESH_VERTEXNORMAL" ) == 0 ) {
785 
786  count = sscanf ( next, "%d%n", &i, &width );
787  next = next + width;
788 
789  count = sscanf ( next, "%f%n", &x, &width );
790  next = next + width;
791 
792  count = sscanf ( next, "%f%n", &y, &width );
793  next = next + width;
794 
795  count = sscanf ( next, "%f%n", &z, &width );
796  next = next + width;
797 
798  vertex_normal[0][ivert][iface] = x;
799  vertex_normal[1][ivert][iface] = y;
800  vertex_normal[2][ivert][iface] = z;
801  ivert = ivert + 1;
802 
803  break;
804  }
805  else {
806  bad_num = bad_num + 1;
807  printf ( "Bad data in MESH_NORMALS, line %d\n", text_num );
808  break;
809  }
810  }
811 /*
812  *MESH_TFACELIST
813 */
814  else if ( strcmp ( level_name[level], "*MESH_TFACELIST" ) == 0 ) {
815 
816  if ( strcmp ( word, "{" ) == 0 ) {
817  continue;
818  }
819  else if ( strcmp ( word, "}" ) == 0 ) {
820  level = nlbrack - nrbrack;
821  continue;
822  }
823  else if ( strcmp ( word1, "*MESH_TFACE" ) == 0 ) {
824  break;
825  }
826  else {
827  bad_num = bad_num + 1;
828  printf ( "Bad data in MESH_TFACE_LIST, line %d\n", text_num );
829  break;
830  }
831  }
832 /*
833  *MESH_TVERTLIST
834 */
835  else if ( strcmp ( level_name[level], "*MESH_TVERTLIST" ) == 0 ) {
836 
837  if ( strcmp ( word, "{" ) == 0 ) {
838  continue;
839  }
840  else if ( strcmp ( word, "}" ) == 0 ) {
841  level = nlbrack - nrbrack;
842  continue;
843  }
844  else if ( strcmp ( word1, "*MESH_TVERT" ) == 0 ) {
845  break;
846  }
847  else {
848  bad_num = bad_num + 1;
849  printf ( "Bad data in MESH_TVERTLIST, line %d\n", text_num );
850  break;
851  }
852  }
853 /*
854  *MESH_VERTEX_LIST
855 */
856  else if ( strcmp ( level_name[level], "*MESH_VERTEX_LIST" ) == 0 ) {
857 
858  if ( strcmp ( word, "{" ) == 0 ) {
859  cor3_num_old = cor3_num;
860  continue;
861  }
862  else if ( strcmp ( word, "}" ) == 0 ) {
863  level = nlbrack - nrbrack;
864  continue;
865  }
866  else if ( strcmp ( word1, "*MESH_VERTEX" ) == 0 ) {
867 
868  count = sscanf ( next, "%d%n", &i, &width );
869  next = next + width;
870 
871  count = sscanf ( next, "%f%n", &x, &width );
872  next = next + width;
873 
874  count = sscanf ( next, "%f%n", &y, &width );
875  next = next + width;
876 
877  count = sscanf ( next, "%f%n", &z, &width );
878  next = next + width;
879 
880  i = i + cor3_num_old;
881  if ( cor3_num < i + 1 ) {
882  cor3_num = i + 1;
883  }
884 
885  if ( i < COR3_MAX ) {
886 
887  cor3[0][i] =
888  transform_matrix[0][0] * x
889  + transform_matrix[0][1] * y
890  + transform_matrix[0][2] * z
891  + transform_matrix[0][3];
892 
893  cor3[1][i] =
894  transform_matrix[1][0] * x
895  + transform_matrix[1][1] * y
896  + transform_matrix[1][2] * z
897  + transform_matrix[1][3];
898 
899  cor3[2][i] =
900  transform_matrix[2][0] * x
901  + transform_matrix[2][1] * y
902  + transform_matrix[2][2] * z
903  + transform_matrix[2][3];
904  }
905 
906  break;
907  }
908  else {
909  bad_num = bad_num + 1;
910  printf ( "Bad data in MESH_VERTEX_LIST, line %d\n", text_num );
911  break;
912  }
913  }
914 /*
915  *NODE_TM
916 
917  Each node should start out with a default transformation matrix.
918 */
919  else if ( strcmp ( level_name[level], "*NODE_TM" ) == 0 ) {
920 
921  if ( strcmp ( word, "{" ) == 0 ) {
922 
924 
925  continue;
926  }
927  else if ( strcmp ( word, "}" ) == 0 ) {
928  level = nlbrack - nrbrack;
929  continue;
930  }
931  else if ( strcmp ( word, "*INHERIT_POS" ) == 0 ) {
932  break;
933  }
934  else if ( strcmp ( word, "*INHERIT_ROT" ) == 0 ) {
935  break;
936  }
937  else if ( strcmp ( word, "*INHERIT_SCL" ) == 0 ) {
938  break;
939  }
940  else if ( strcmp ( word, "*NODE_NAME" ) == 0 ) {
941  break;
942  }
943  else if ( strcmp ( word, "*TM_POS" ) == 0 ) {
944  break;
945  }
946  else if ( strcmp ( word, "*TM_ROTANGLE" ) == 0 ) {
947  break;
948  }
949  else if ( strcmp ( word, "*TM_ROTAXIS" ) == 0 ) {
950  break;
951  }
952  else if ( strcmp ( word, "*TM_ROW0" ) == 0 ) {
953 
954  count = sscanf ( next, "%f%n", &temp, &width );
955  next = next + width;
956  transform_matrix[0][0] = temp;
957 
958  count = sscanf ( next, "%f%n", &temp, &width );
959  next = next + width;
960  transform_matrix[1][0] = temp;
961 
962  count = sscanf ( next, "%f%n", &temp, &width );
963  next = next + width;
964  transform_matrix[2][0] = temp;
965 
966  break;
967  }
968  else if ( strcmp ( word, "*TM_ROW1" ) == 0 ) {
969 
970  count = sscanf ( next, "%f%n", &temp, &width );
971  next = next + width;
972  transform_matrix[0][1] = temp;
973 
974  count = sscanf ( next, "%f%n", &temp, &width );
975  next = next + width;
976  transform_matrix[1][1] = temp;
977 
978  count = sscanf ( next, "%f%n", &temp, &width );
979  next = next + width;
980  transform_matrix[2][1] = temp;
981 
982  break;
983  }
984  else if ( strcmp ( word, "*TM_ROW2" ) == 0 ) {
985 
986  count = sscanf ( next, "%f%n", &temp, &width );
987  next = next + width;
988  transform_matrix[0][2] = temp;
989 
990  count = sscanf ( next, "%f%n", &temp, &width );
991  next = next + width;
992  transform_matrix[1][2] = temp;
993 
994  count = sscanf ( next, "%f%n", &temp, &width );
995  next = next + width;
996  transform_matrix[2][2] = temp;
997 
998  break;
999  }
1000  else if ( strcmp ( word, "*TM_ROW3" ) == 0 ) {
1001 
1002  count = sscanf ( next, "%f%n", &temp, &width );
1003  next = next + width;
1004  transform_matrix[0][3] = temp;
1005 
1006  count = sscanf ( next, "%f%n", &temp, &width );
1007  next = next + width;
1008  transform_matrix[1][3] = temp;
1009 
1010  count = sscanf ( next, "%f%n", &temp, &width );
1011  next = next + width;
1012  transform_matrix[2][3] = temp;
1013 
1014  break;
1015  }
1016  else if ( strcmp ( word, "*TM_SCALE" ) == 0 ) {
1017  break;
1018  }
1019  else if ( strcmp ( word, "*TM_SCALEAXIS" ) == 0 ) {
1020  break;
1021  }
1022  else if ( strcmp ( word, "*TM_SCALEAXISANG" ) == 0 ) {
1023  break;
1024  }
1025  else {
1026  bad_num = bad_num + 1;
1027  printf ( "Bad data in NODE_TM, line %d\n", text_num );
1028  break;
1029  }
1030  }
1031 /*
1032  *SCENE
1033 */
1034  else if ( strcmp ( level_name[level], "*SCENE" ) == 0 ) {
1035 
1036  if ( strcmp ( word, "{" ) == 0 ) {
1037  continue;
1038  }
1039  else if ( strcmp ( word, "}" ) == 0 ) {
1040  level = nlbrack - nrbrack;
1041  continue;
1042  }
1043  else if ( strcmp ( word, "*SCENE_AMBIENT_STATIC" ) == 0 ) {
1044  break;
1045  }
1046  else if ( strcmp ( word, "*SCENE_BACKGROUND_STATIC" ) == 0 ) {
1047  break;
1048  }
1049  else if ( strcmp ( word, "*SCENE_FILENAME" ) == 0 ) {
1050  break;
1051  }
1052  else if ( strcmp ( word, "*SCENE_FIRSTFRAME" ) == 0 ) {
1053  break;
1054  }
1055  else if ( strcmp ( word, "*SCENE_FRAMESPEED" ) == 0 ) {
1056  break;
1057  }
1058  else if ( strcmp ( word, "*SCENE_LASTFRAME" ) == 0 ) {
1059  break;
1060  }
1061  else if ( strcmp ( word, "*SCENE_TICKSPERFRAME" ) == 0 ) {
1062  break;
1063  }
1064  else {
1065  bad_num = bad_num + 1;
1066  printf ( "Bad data in SCENE, line %d\n", text_num );
1067  break;
1068  }
1069 
1070  }
1071 
1072  }
1073 /*
1074  End of loop reading words from the line.
1075 */
1076  }
1077 /*
1078  End of loop reading lines from input file.
1079 */
1080 
1081  return SUCCESS;
1082 }
1083 /******************************************************************************/
1084 
1085 int ase_write ( FILE *fileout )
1086 
1087 /******************************************************************************/
1088 
1089 /*
1090  Purpose:
1091 
1092  ASE_WRITE writes graphics information to an AutoCAD ASE file.
1093 
1094  Modified:
1095 
1096  30 September 1998
1097 
1098  Author:
1099 
1100  John Burkardt
1101 
1102 */
1103 {
1104  int i1;
1105  int i2;
1106  int i3;
1107  int i4;
1108  int iface;
1109  int ivert;
1110  int j;
1111  int text_num;
1112 
1113  text_num = 0;
1114 /*
1115  Write the header.
1116 */
1117  fprintf ( fileout, "*3DSMAX_ASCIIEXPORT 200\n" );
1118  fprintf ( fileout, "*COMMENT \"%s, created by IVCON.\"\n", fileout_name );
1119  fprintf ( fileout, "*COMMENT \"Original data in %s\"\n", filein_name );
1120 
1121  text_num = text_num + 3;
1122 /*
1123  Write the scene block.
1124 */
1125  fprintf ( fileout, "*SCENE {\n" );
1126  fprintf ( fileout, " *SCENE_FILENAME \"\"\n" );
1127  fprintf ( fileout, " *SCENE_FIRSTFRAME 0\n" );
1128  fprintf ( fileout, " *SCENE_LASTFRAME 100\n" );
1129  fprintf ( fileout, " *SCENE_FRAMESPEED 30\n" );
1130  fprintf ( fileout, " *SCENE_TICKSPERFRAME 160\n" );
1131  fprintf ( fileout, " *SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000\n" );
1132  fprintf ( fileout, " *SCENE_AMBIENT_STATIC 0.0431 0.0431 0.0431\n" );
1133  fprintf ( fileout, "}\n" );
1134 
1135  text_num = text_num + 9;
1136 /*
1137  Begin the big geometry block.
1138 */
1139  fprintf ( fileout, "*GEOMOBJECT {\n" );
1140  fprintf ( fileout, " *NODE_NAME \"%s\"\n", object_name );
1141 
1142  text_num = text_num + 2;
1143 /*
1144  Sub block NODE_TM:
1145 */
1146  fprintf ( fileout, " *NODE_TM {\n" );
1147  fprintf ( fileout, " *NODE_NAME \"Object01\"\n" );
1148  fprintf ( fileout, " *INHERIT_POS 0 0 0\n" );
1149  fprintf ( fileout, " *INHERIT_ROT 0 0 0\n" );
1150  fprintf ( fileout, " *INHERIT_SCL 0 0 0\n" );
1151  fprintf ( fileout, " *TM_ROW0 1.0000 0.0000 0.0000\n" );
1152  fprintf ( fileout, " *TM_ROW1 0.0000 1.0000 0.0000\n" );
1153  fprintf ( fileout, " *TM_ROW2 0.0000 0.0000 1.0000\n" );
1154  fprintf ( fileout, " *TM_ROW3 0.0000 0.0000 0.0000\n" );
1155  fprintf ( fileout, " *TM_POS 0.0000 0.0000 0.0000\n" );
1156  fprintf ( fileout, " *TM_ROTAXIS 0.0000 0.0000 0.0000\n" );
1157  fprintf ( fileout, " *TM_ROTANGLE 0.0000\n" );
1158  fprintf ( fileout, " *TM_SCALE 1.0000 1.0000 1.0000\n" );
1159  fprintf ( fileout, " *TM_SCALEAXIS 0.0000 0.0000 0.0000\n" );
1160  fprintf ( fileout, " *TM_SCALEAXISANG 0.0000\n" );
1161  fprintf ( fileout, " }\n" );
1162 
1163  text_num = text_num + 16;
1164 /*
1165  Sub block MESH:
1166  Items
1167 */
1168  fprintf ( fileout, " *MESH {\n" );
1169  fprintf ( fileout, " *TIMEVALUE 0\n" );
1170  fprintf ( fileout, " *MESH_NUMVERTEX %d\n", cor3_num );
1171  fprintf ( fileout, " *MESH_NUMFACES %d\n", face_num );
1172 
1173  text_num = text_num + 4;
1174 /*
1175  Sub sub block MESH_VERTEX_LIST
1176 */
1177  fprintf ( fileout, " *MESH_VERTEX_LIST {\n" );
1178  text_num = text_num + 1;
1179 
1180  for ( j = 0; j < cor3_num; j++ ) {
1181  fprintf ( fileout, " *MESH_VERTEX %d %f %f %f\n", j, cor3[0][j],
1182  cor3[1][j], cor3[2][j] );
1183  text_num = text_num + 1;
1184  }
1185 
1186  fprintf ( fileout, " }\n" );
1187  text_num = text_num + 1;
1188 /*
1189  Sub sub block MESH_FACE_LIST
1190  Items MESH_FACE
1191 */
1192  fprintf ( fileout, " *MESH_FACE_LIST {\n" );
1193  text_num = text_num + 1;
1194 
1195  for ( iface = 0; iface < face_num; iface++ ) {
1196 
1197  i1 = face[0][iface];
1198  i2 = face[1][iface];
1199  i3 = face[2][iface];
1200 
1201  if ( face_order[iface] == 3 ) {
1202  fprintf ( fileout, " *MESH_FACE %d: A: %d B: %d C: %d", iface, i1, i2, i3 );
1203  fprintf ( fileout, " AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING *MESH_MTLID 1\n" );
1204  text_num = text_num + 1;
1205  }
1206  else if ( face_order[iface] == 4 ) {
1207  i4 = face[3][iface];
1208  fprintf ( fileout, " *MESH_FACE %d: A: %d B: %d C: %d D: %d", iface, i1, i2, i3, i4 );
1209  fprintf ( fileout, " AB: 1 BC: 1 CD: 1 DA: 1 *MESH_SMOOTHING *MESH_MTLID 1\n" );
1210  text_num = text_num + 1;
1211  }
1212  }
1213 
1214  fprintf ( fileout, " }\n" );
1215  text_num = text_num + 1;
1216 /*
1217  Item MESH_NUMTVERTEX.
1218 */
1219  fprintf ( fileout, " *MESH_NUMTVERTEX 0\n" );
1220  text_num = text_num + 1;
1221 /*
1222  Item NUMCVERTEX.
1223 */
1224  fprintf ( fileout, " *MESH_NUMCVERTEX 0\n" );
1225  text_num = text_num + 1;
1226 /*
1227  Sub block MESH_NORMALS
1228  Items MESH_FACENORMAL, MESH_VERTEXNORMAL (repeated)
1229 */
1230  fprintf ( fileout, " *MESH_NORMALS {\n" );
1231  text_num = text_num + 1;
1232 
1233  for ( iface = 0; iface < face_num; iface++ ) {
1234 
1235  fprintf ( fileout, " *MESH_FACENORMAL %d %f %f %f\n",
1236  iface, face_normal[0][iface], face_normal[1][iface], face_normal[2][iface] );
1237  text_num = text_num + 1;
1238 
1239  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
1240  fprintf ( fileout, " *MESH_VERTEXNORMAL %d %f %f %f\n",
1241  face[ivert][iface], vertex_normal[0][ivert][iface],
1242  vertex_normal[1][ivert][iface], vertex_normal[2][ivert][iface] );
1243  text_num = text_num + 1;
1244  }
1245  }
1246 
1247  fprintf ( fileout, " }\n" );
1248  text_num = text_num + 1;
1249 /*
1250  Close the MESH object.
1251 */
1252  fprintf ( fileout, " }\n" );
1253 /*
1254  A few closing parameters.
1255 */
1256  fprintf ( fileout, " *PROP_MOTIONBLUR 0\n" );
1257  fprintf ( fileout, " *PROP_CASTSHADOW 1\n" );
1258  fprintf ( fileout, " *PROP_RECVSHADOW 1\n" );
1259 /*
1260  Close the GEOM object.
1261 */
1262  fprintf ( fileout, "}\n" );
1263 
1264  text_num = text_num + 5;
1265 /*
1266  Report.
1267 */
1268  printf ( "\n" );
1269  printf ( "ASE_WRITE - Wrote %d text lines;\n", text_num );
1270 
1271  return SUCCESS;
1272 }
1273 /**********************************************************************/
1274 
1275 int byu_read ( FILE *filein )
1276 
1277 /**********************************************************************/
1278 
1279 /*
1280  Purpose:
1281 
1282  BYU_READ reads graphics data from a Movie.BYU surface geometry file.
1283 
1284  Discussion:
1285 
1286  A Movie.BYU surface geometry file contains 4 groups of data.
1287 
1288  The first group of data is a single line, containing 4 integers,
1289  each one left justified in 8 columns. The integers are:
1290 
1291  PART_NUM, VERTEX_NUM, POLY_NUM, EDGE_NUM,
1292 
1293  that is, the number of parts or objects, the number of vertices or nodes,
1294  the number of polygons or faces, and the number of edges.
1295 
1296  The second group of data is a single line, containing 2 integers,
1297  each one left justified in 8 columnes. The integers are:
1298 
1299  POLY1, POLY2,
1300 
1301  the starting and ending polygon numbers. Presumably, this means
1302  that the polygons are labeled POLY1, POLY1+1, ..., POLY2, comprising
1303  a total of POLY_NUM polygons.
1304 
1305  The third group is the X, Y and Z coordinates of all the vertices.
1306  These may be written using a FORTRAN format of 6E12.5, which
1307  crams two sets of (X,Y,Z) data onto each line, with each real value
1308  written in an exponential format with 5 places after the decimal.
1309  However, it is generally possible to write the XYZ coordinate data
1310  for each vertex on a separate line.
1311 
1312  The fourth group defines the polygons in terms of the vertex indices.
1313  For each polygon, the vertices that make up the polygon are listed in
1314  counterclockwise order. The last vertex listed is given with a negative
1315  sign to indicate the end of the list. All the vertices for all the
1316  polygons are listed one after the other, using a format that puts
1317  up to 10 left-justified integers on a line, with each integer occupying
1318  8 spaces.
1319 
1320  This code will certainly read a BYU file created by BYU_WRITE, but
1321  it will not handle more general files. In particular, an object
1322  can have several parts, the coordinate data can be grouped so
1323  that there are 2 sets of (x,y,z) data per line, and so on.
1324 
1325  Example:
1326 
1327  1 8 6 24
1328  1 6
1329  0.00000E+00 0.00000E+00 0.00000E+00
1330  1.00000E+00 0.00000E+00 0.00000E+00
1331  1.00000E+00 2.00000E+00 0.00000E+00
1332  0.00000E+00 2.00000E+00 0.00000E+00
1333  0.00000E+00 0.00000E+00 1.00000E+00
1334  1.00000E+00 0.00000E+00 1.00000E+00
1335  1.00000E+00 2.00000E+00 1.00000E+00
1336  0.00000E+00 2.00000E+00 1.00000E+00
1337  4 3 2 -1
1338  5 6 7 -8
1339  1 5 8 -4
1340  4 8 7 -3
1341  3 7 6 -2
1342  2 6 5 -1
1343 
1344  Modified:
1345 
1346  24 May 2001
1347 
1348  Author:
1349 
1350  John Burkardt
1351 
1352 */
1353 {
1354  int cor3_num_new;
1355  int count;
1356  int edge_num;
1357  int face_num_new;
1358  int iface;
1359  int ival;
1360  int ivert;
1361  int j;
1362  char *next;
1363  int part_num;
1364  int poly1;
1365  int poly2;
1366  int text_num;
1367  int width;
1368  float x;
1369  float y;
1370  float z;
1371 
1372  text_num = 0;
1373 
1374  if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) {
1375  return ERROR;
1376  }
1377  text_num = text_num + 1;
1378 
1379  sscanf ( input, "%d %d %d %d", &part_num, &cor3_num_new, &face_num_new,
1380  &edge_num );
1381 
1382  if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) {
1383  return ERROR;
1384  }
1385  text_num = text_num + 1;
1386 
1387  sscanf ( input, "%d %d", &poly1, &poly2 );
1388 
1389  for ( j = cor3_num; j < cor3_num + cor3_num_new; j++ ) {
1390 
1391  if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) {
1392  return ERROR;
1393  }
1394  text_num = text_num + 1;
1395 
1396  sscanf ( input, "%f %f %f", &x, &y, &z );
1397  cor3[0][j] = x;
1398  cor3[1][j] = y;
1399  cor3[2][j] = z;
1400  }
1401 
1402  for ( iface = face_num; iface < face_num + face_num_new; iface++ ) {
1403 
1404  if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) {
1405  return ERROR;
1406  }
1407  text_num = text_num + 1;
1408 
1409  next = input;
1410  ivert = 0;
1411 
1412  for (;;) {
1413 
1414  count = sscanf ( next, "%d%n", &ival, &width );
1415  next = next + width;
1416 
1417  if ( count <= 0 ) {
1418  return ERROR;
1419  }
1420 
1421  if ( ival > 0 ) {
1422  face[ivert][iface] = ival - 1 + cor3_num;
1423  }
1424  else {
1425  face[ivert][iface] = - ival - 1 - cor3_num;
1426  break;
1427  }
1428 
1429  ivert = ivert + 1;
1430 
1431  }
1432  face_order[iface] = ivert + 1;
1433  }
1434 
1435  cor3_num = cor3_num + cor3_num_new;
1436  face_num = face_num + face_num_new;
1437 /*
1438  Report.
1439 */
1440  printf ( "\n" );
1441  printf ( "BYU_READ - Read %d text lines.\n", text_num );
1442 
1443  return SUCCESS;
1444 }
1445 /**********************************************************************/
1446 
1447 int byu_write ( FILE *fileout )
1448 
1449 /**********************************************************************/
1450 
1451 /*
1452  Purpose:
1453 
1454  BYU_WRITE writes out the graphics data as a Movie.BYU surface geometry file.
1455 
1456  Discussion:
1457 
1458  A Movie.BYU surface geometry file contains 4 groups of data.
1459 
1460  The first group of data is a single line, containing 4 integers,
1461  each one left justified in 8 columns. The integers are:
1462 
1463  PART_NUM, VERTEX_NUM, POLY_NUM, EDGE_NUM,
1464 
1465  that is, the number of parts or objects, the number of vertices or nodes,
1466  the number of polygons or faces, and the number of edges.
1467 
1468  The second group of data is a single line, containing 2 integers,
1469  each one left justified in 8 columnes. The integers are:
1470 
1471  POLY1, POLY2,
1472 
1473  the starting and ending polygon numbers. Presumably, this means
1474  that the polygons are labeled POLY1, POLY1+1, ..., POLY2, comprising
1475  a total of POLY_NUM polygons.
1476 
1477  The third group is the X, Y and Z coordinates of all the vertices.
1478  These may be written using a FORTRAN format of 6E12.5, which
1479  crams two sets of (X,Y,Z) data onto each line, with each real value
1480  written in an exponential format with 5 places after the decimal.
1481  However, it is generally possible to write the XYZ coordinate data
1482  for each vertex on a separate line.
1483 
1484  The fourth group defines the polygons in terms of the vertex indices.
1485  For each polygon, the vertices that make up the polygon are listed in
1486  counterclockwise order. The last vertex listed is given with a negative
1487  sign to indicate the end of the list. All the vertices for all the
1488  polygons are listed one after the other, using a format that puts
1489  up to 10 left-justified integers on a line, with each integer occupying
1490  8 spaces.
1491 
1492  Example:
1493 
1494  1 8 6 24
1495  1 6
1496  0.00000E+00 0.00000E+00 0.00000E+00
1497  1.00000E+00 0.00000E+00 0.00000E+00
1498  1.00000E+00 2.00000E+00 0.00000E+00
1499  0.00000E+00 2.00000E+00 0.00000E+00
1500  0.00000E+00 0.00000E+00 1.00000E+00
1501  1.00000E+00 0.00000E+00 1.00000E+00
1502  1.00000E+00 2.00000E+00 1.00000E+00
1503  0.00000E+00 2.00000E+00 1.00000E+00
1504  4 3 2 -1
1505  5 6 7 -8
1506  1 5 8 -4
1507  4 8 7 -3
1508  3 7 6 -2
1509  2 6 5 -1
1510 
1511  Modified:
1512 
1513  24 May 2001
1514 
1515  Author:
1516 
1517  John Burkardt
1518 */
1519 {
1520  int edge_num;
1521  int iface;
1522  int ivert;
1523  int j;
1524  int jp;
1525  int part_num;
1526  int text_num;
1527 
1528  text_num = 0;
1529 
1530  edge_num = 0;
1531  for ( iface = 0; iface < face_num; iface++ ) {
1532  edge_num = edge_num + face_order[iface];
1533  }
1534 
1535  part_num = 1;
1536 
1537  fprintf ( fileout, "%d %d %d %d\n", part_num, cor3_num, face_num, edge_num );
1538  text_num = text_num + 1;
1539 
1540  fprintf ( fileout, "1 %d\n", face_num );
1541  text_num = text_num + 1;
1542 
1543  for ( j = 0; j < cor3_num; j++ ) {
1544  fprintf ( fileout, "%f %f %f\n", cor3[0][j], cor3[1][j], cor3[2][j] );
1545  text_num = text_num + 1;
1546  }
1547 
1548  for ( iface = 0; iface < face_num; iface++ ) {
1549 
1550  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
1551 
1552  jp = face[ivert][iface] + 1;
1553  if ( ivert == face_order[iface] - 1 ) {
1554  jp = - jp;
1555  }
1556  fprintf ( fileout, "%d ", jp );
1557  }
1558  fprintf ( fileout, "\n" );
1559  text_num = text_num + 1;
1560  }
1561 /*
1562  Report.
1563 */
1564  printf ( "\n" );
1565  printf ( "BYU_WRITE - Wrote %d text lines.\n", text_num );
1566 
1567  return SUCCESS;
1568 }
1569 /******************************************************************************/
1570 
1571 int char_index_last ( char* string, char c )
1572 
1573 /******************************************************************************/
1574 
1575 /*
1576  Purpose:
1577 
1578  CHAR_INDEX_LAST reports the last occurrence of a character in a string.
1579 
1580  Author:
1581 
1582  John Burkardt
1583 */
1584 {
1585  int i;
1586  int j;
1587  int nchar;
1588 
1589  j = -1;
1590 
1591  nchar = strlen ( string );
1592 
1593  for ( i = 0; i < nchar; i++ ) {
1594  if ( string[i] == c ) {
1595  j = i;
1596  }
1597  }
1598 
1599  return j;
1600 
1601 }
1602 /******************************************************************************/
1603 
1604 int char_pad ( int *char_index, int *null_index, char *string,
1605  int STRING_MAX )
1606 
1607 /******************************************************************************/
1608 
1609 /*
1610  Purpose:
1611 
1612  CHAR_PAD "pads" a character in a string with a blank on either side.
1613 
1614  Modified:
1615 
1616  16 October 1998
1617 
1618  Author:
1619 
1620  John Burkardt
1621 
1622  Parameters:
1623 
1624  Input/output, int *CHAR_INDEX, the position of the character to be padded.
1625  On output, this is increased by 1.
1626 
1627  Input/output, int *NULL_INDEX, the position of the terminating NULL in
1628  the string. On output, this is increased by 2.
1629 
1630  Input/output, char STRING[STRING_MAX], the string to be manipulated.
1631 
1632  Input, int STRING_MAX, the maximum number of characters that can be stored
1633  in the string.
1634 
1635  Output, int CHAR_PAD, is SUCCESS if the operation worked, and ERROR otherwise.
1636 */
1637 {
1638  int i;
1639 
1640  if ( *char_index < 0 ||
1641  *char_index >= *null_index ||
1642  *char_index > STRING_MAX-1 ) {
1643  return ERROR;
1644  }
1645 
1646  if ( (*null_index) + 2 > STRING_MAX-1 ) {
1647  return ERROR;
1648  }
1649 
1650  for ( i = *null_index + 2; i > *char_index + 2; i-- ) {
1651  string[i] = string[i-2];
1652  }
1653  string[*char_index+2] = ' ';
1654  string[*char_index+1] = string[*char_index];
1655  string[*char_index] = ' ';
1656 
1657  *char_index = *char_index + 1;
1658  *null_index = *null_index + 2;
1659 
1660  return SUCCESS;
1661 }
1662 /******************************************************************************/
1663 
1664 char char_read ( FILE *filein )
1665 
1666 /******************************************************************************/
1667 
1668 /*
1669  Purpose:
1670 
1671  CHAR_READ reads one character from a binary file.
1672 
1673  Modified:
1674 
1675  24 May 1999
1676 
1677  Author:
1678 
1679  John Burkardt
1680 */
1681 {
1682  char c;
1683 
1684  c = ( char ) fgetc ( filein );
1685 
1686  return c;
1687 }
1688 /******************************************************************************/
1689 
1690 int char_write ( FILE *fileout, char c )
1691 
1692 /******************************************************************************/
1693 
1694 /*
1695  Purpose:
1696 
1697  CHAR_WRITE writes one character to a binary file.
1698 
1699  Modified:
1700 
1701  24 May 1999
1702 
1703  Author:
1704 
1705  John Burkardt
1706 */
1707 {
1708  fputc ( c, fileout );
1709 
1710  return 1;
1711 }
1712 /******************************************************************************/
1713 
1714 int command_line ( char **argv )
1715 
1716 /******************************************************************************/
1717 
1718 /*
1719 
1720  Purpose:
1721 
1722  COMMAND_LINE carries out a command-line session of file conversion.
1723 
1724  Discussion:
1725 
1726  This routine is invoked when the user command is something like
1727 
1728  ivcon filein_name fileout_name
1729 
1730  or
1731 
1732  ivcon -rn filein_name fileout_name
1733 
1734  where "-rn" signals the "reverse normals" option, or
1735 
1736  ivcon -rf filein_name fileout_name
1737 
1738  where "-rf" signals the "reverse faces" option.
1739 
1740  Modified:
1741 
1742  28 June 1999
1743 
1744  Author:
1745 
1746  John Burkardt
1747 */
1748 {
1749  int i;
1750  int iarg;
1751  int icor3;
1752  int ierror;
1753  int iface;
1754  int ivert;
1755  int reverse_faces;
1756  int reverse_normals;
1757 /*
1758  Initialize local data.
1759 */
1760  iarg = 0;
1761  ierror = 0;
1762  reverse_faces = FALSE;
1763  reverse_normals = FALSE;
1764 /*
1765  Initialize the graphics data.
1766 */
1767  data_init ( );
1768 /*
1769  Get the -RN option, -RF option, and the input file name.
1770 */
1771  iarg = iarg + 1;
1772  strcpy ( filein_name, argv[iarg] );
1773 
1774  if ( leqi ( filein_name, "-RN" ) == TRUE ) {
1775  reverse_normals = TRUE;
1776  printf ( "\n" );
1777  printf ( "COMMAND_LINE: Reverse_Normals option requested.\n" );
1778  iarg = iarg + 1;
1779  strcpy ( filein_name, argv[iarg] );
1780  }
1781 
1782  if ( leqi ( filein_name, "-RF" ) == TRUE ) {
1783  reverse_faces = TRUE;
1784  printf ( "\n" );
1785  printf ( "COMMAND_LINE: Reverse_Faces option requested.\n" );
1786  iarg = iarg + 1;
1787  strcpy ( filein_name, argv[iarg] );
1788  }
1789 /*
1790  Read the input.
1791 */
1792  ierror = data_read ( );
1793 
1794  if ( ierror == ERROR ) {
1795  printf ( "\n" );
1796  printf ( "COMMAND_LINE - Fatal error!\n" );
1797  printf ( " Failure while reading input data.\n" );
1798  return ERROR;
1799  }
1800 /*
1801  Reverse the normal vectors if requested.
1802 */
1803  if ( reverse_normals == TRUE ) {
1804 
1805  for ( icor3 = 0; icor3 < cor3_num; icor3++ ) {
1806  for ( i = 0; i < 3; i++ ) {
1807  cor3_normal[i][icor3] = - cor3_normal[i][icor3];
1808  }
1809  }
1810 
1811  for ( iface = 0; iface < face_num; iface++ ) {
1812  for ( i = 0; i < 3; i++ ) {
1813  face_normal[i][iface] = - face_normal[i][iface];
1814  }
1815  }
1816 
1817  for ( iface = 0; iface < face_num; iface++ ) {
1818  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
1819  for ( i = 0; i < 3; i++ ) {
1820  vertex_normal[i][ivert][iface] =
1821  - vertex_normal[i][ivert][iface];
1822  }
1823  }
1824  }
1825  printf ( "\n" );
1826  printf ( "COMMAND_LINE - Note:\n" );
1827  printf ( " Reversed node, face, and vertex normals.\n" );
1828  }
1829 /*
1830  Reverse the faces if requested.
1831 */
1832  if ( reverse_faces == TRUE ) {
1833 
1834  face_reverse_order ( );
1835 
1836  printf ( "\n" );
1837  printf ( "COMMAND_LINE - Note:\n" );
1838  printf ( " Reversed the face definitions.\n" );
1839  }
1840 /*
1841  Write the output file.
1842 */
1843  iarg = iarg + 1;
1844  strcpy ( fileout_name, argv[iarg] );
1845 
1846  ierror = data_write ( );
1847 
1848  if ( ierror == ERROR ) {
1849  printf ( "\n" );
1850  printf ( "COMMAND_LINE - Fatal error!\n" );
1851  printf ( " Failure while writing output data.\n" );
1852  return ERROR;
1853  }
1854  return SUCCESS;
1855 }
1856 /******************************************************************************/
1857 
1858 void cor3_normal_set ( void )
1859 
1860 /******************************************************************************/
1861 
1862 /*
1863  Purpose:
1864 
1865  COR3_NORMAL_SET computes node normal vectors.
1866 
1867  Modified:
1868 
1869  18 November 1998
1870 
1871  Author:
1872 
1873  John Burkardt
1874 */
1875 {
1876  int icor3;
1877  int iface;
1878  int ivert;
1879  int j;
1880  float norm;
1881  float temp;
1882 
1883  for ( icor3 = 0; icor3 < cor3_num; icor3++ ) {
1884  for ( j = 0; j < 3; j++ ) {
1885  cor3_normal[j][icor3] = 0.0;
1886  }
1887  }
1888 /*
1889  Add up the normals at all the faces to which the node belongs.
1890 */
1891  for ( iface = 0; iface < face_num; iface++ ) {
1892 
1893  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
1894 
1895  icor3 = face[ivert][iface];
1896 
1897  for ( j = 0; j < 3; j++ ) {
1898  cor3_normal[j][icor3] = cor3_normal[j][icor3]
1899  + vertex_normal[j][ivert][iface];
1900  }
1901  }
1902  }
1903 /*
1904  Renormalize.
1905 */
1906  for ( icor3 = 0; icor3 < cor3_num; icor3++ ) {
1907 
1908  norm = 0.0;
1909  for ( j = 0; j < 3; j++ ) {
1910  temp = cor3_normal[j][icor3];
1911  norm = norm + temp * temp;
1912  }
1913 
1914  if ( norm == 0.0 ) {
1915  norm = 3.0;
1916  for ( j = 0; j < 3; j++ ) {
1917  cor3_normal[j][icor3] = 1.0;
1918  }
1919  }
1920 
1921  norm = ( float ) sqrt ( norm );
1922 
1923  for ( j = 0; j < 3; j++ ) {
1924  cor3_normal[j][icor3] = cor3_normal[j][icor3] / norm;
1925  }
1926  }
1927 
1928  return;
1929 }
1930 /******************************************************************************/
1931 
1932 void cor3_range ( void )
1933 
1934 /******************************************************************************/
1935 
1936 /*
1937  Purpose:
1938 
1939  COR3_RANGE computes the coordinate minima and maxima.
1940 
1941  Modified:
1942 
1943  31 August 1998
1944 
1945  Author:
1946 
1947  John Burkardt
1948 */
1949 {
1950  int i;
1951  float xave;
1952  float xmax;
1953  float xmin;
1954  float yave;
1955  float ymax;
1956  float ymin;
1957  float zave;
1958  float zmax;
1959  float zmin;
1960 
1961  xave = cor3[0][0];
1962  xmax = cor3[0][0];
1963  xmin = cor3[0][0];
1964 
1965  yave = cor3[1][0];
1966  ymax = cor3[1][0];
1967  ymin = cor3[1][0];
1968 
1969  zave = cor3[2][0];
1970  zmax = cor3[2][0];
1971  zmin = cor3[2][0];
1972 
1973  for ( i = 1; i < cor3_num; i++ ) {
1974 
1975  xave = xave + cor3[0][i];
1976  if ( cor3[0][i] < xmin ) {
1977  xmin = cor3[0][i];
1978  }
1979  if ( cor3[0][i] > xmax ) {
1980  xmax = cor3[0][i];
1981  }
1982 
1983  yave = yave + cor3[1][i];
1984  if ( cor3[1][i] < ymin ) {
1985  ymin = cor3[1][i];
1986  }
1987  if ( cor3[1][i] > ymax ) {
1988  ymax = cor3[1][i];
1989  }
1990 
1991  zave = zave + cor3[2][i];
1992  if ( cor3[2][i] < zmin ) {
1993  zmin = cor3[2][i];
1994  }
1995  if ( cor3[2][i] > zmax ) {
1996  zmax = cor3[2][i];
1997  }
1998  }
1999 
2000  xave = xave / cor3_num;
2001  yave = yave / cor3_num;
2002  zave = zave / cor3_num;
2003 
2004  printf ( "\n" );
2005  printf ( "COR3_RANGE - Data range:\n" );
2006  printf ( "\n" );
2007  printf ( " Minimum Average Maximum Range\n" );
2008  printf ( "\n" );
2009  printf ( "X %f %f %f %f\n", xmin, xave, xmax, xmax-xmin );
2010  printf ( "Y %f %f %f %f\n", ymin, yave, ymax, ymax-ymin );
2011  printf ( "Z %f %f %f %f\n", zmin, zave, zmax, zmax-zmin );
2012 
2013 }
2014 /******************************************************************************/
2015 
2016 void data_check ( void )
2017 
2018 /******************************************************************************/
2019 
2020 /*
2021  Purpose:
2022 
2023  DATA_CHECK checks the input data.
2024 
2025  Modified:
2026 
2027  18 May 1999
2028 
2029  Author:
2030 
2031  John Burkardt
2032 */
2033 {
2034  int iface;
2035  int nfix;
2036 
2037  if ( color_num > COLOR_MAX ) {
2038  printf ( "\n" );
2039  printf ( "DATA_CHECK - Warning!\n" );
2040  printf ( " The input data requires %d colors.\n", color_num );
2041  printf ( " There was only room for %d\n", COLOR_MAX );
2042  color_num = COLOR_MAX;
2043  }
2044 
2045  if ( cor3_num > COR3_MAX ) {
2046  printf ( "\n" );
2047  printf ( "DATA_CHECK - Warning!\n" );
2048  printf ( " The input data requires %d points.\n", cor3_num );
2049  printf ( " There was only room for %d\n", COR3_MAX );
2050  cor3_num = COR3_MAX;
2051  }
2052 
2053  if ( face_num > FACE_MAX ) {
2054  printf ( "\n" );
2055  printf ( "DATA_CHECK - Warning!\n" );
2056  printf ( " The input data requires %d faces.\n", face_num );
2057  printf ( " There was only room for %d\n", FACE_MAX );
2058  face_num = FACE_MAX;
2059  }
2060 
2061  if ( line_num > LINES_MAX ) {
2062  printf ( "\n" );
2063  printf ( "DATA_CHECK - Warning!\n" );
2064  printf ( " The input data requires %d line items.\n", line_num );
2065  printf ( " There was only room for %d.\n", LINES_MAX );
2066  line_num = LINES_MAX;
2067  }
2068 
2069  nfix = 0;
2070 
2071  for ( iface = 0; iface < face_num; iface++ ) {
2072 
2073  if ( face_order[iface] > ORDER_MAX ) {
2074  face_order[iface] = ORDER_MAX;
2075  nfix = nfix + 1;
2076  }
2077 
2078  }
2079 
2080  if ( nfix > 0 ) {
2081  printf ( "\n" );
2082  printf ( "DATA_CHECK - Warning!\n" );
2083  printf ( " Corrected %d faces using more than %d vertices per face.\n",
2084  nfix, ORDER_MAX );
2085  }
2086 
2087  for ( i = 0; i < material_num; i++ ) {
2088  if ( strcmp ( material_name[i], "" ) == 0 ) {
2089  strcpy ( material_name[i], "Material_0000" );
2090  }
2091  }
2092 
2093  for ( i = 0; i < texture_num; i++ ) {
2094  if ( strcmp ( texture_name[i], "" ) == 0 ) {
2095  strcpy ( texture_name[i], "Texture_0000" );
2096  }
2097  }
2098 
2099  printf ( "\n" );
2100  printf ( "DATA_CHECK - Data checked.\n" );
2101 
2102  return;
2103 }
2104 /******************************************************************************/
2105 
2106 void data_init ( void )
2107 
2108 /******************************************************************************/
2109 
2110 /*
2111  Purpose:
2112 
2113  DATA_INIT initializes the internal graphics data.
2114 
2115  Modified:
2116 
2117  04 July 2000
2118 
2119  Author:
2120 
2121  John Burkardt
2122 */
2123 {
2124  int i;
2125  int iface;
2126  int ivert;
2127  int j;
2128  int k;
2129 
2130  strcpy( anim_name, "" );
2131 
2132  for ( i = 0; i < 3; i++ ) {
2133  background_rgb[i] = 0.0;
2134  }
2135 
2136  for ( i = 0; i < 3; i++ ) {
2137  for ( j = 0; j < COR3_MAX; j++ ) {
2138  cor3[i][j] = 0.0;
2139  }
2140  }
2141 
2142  for ( i = 0; i < COR3_MAX; i++ ) {
2143  cor3_material[i] = 0;
2144  }
2145 
2146  for ( i = 0; i < 3; i++ ) {
2147  for ( j = 0; j < COR3_MAX; j++ ) {
2148  cor3_normal[i][j] = 0.0;
2149  }
2150  }
2151 
2152  for ( j = 0; j < COR3_MAX; j++ ) {
2153  cor3_tex_uv[0][j] = 0.0;
2154  cor3_tex_uv[1][j] = 0.0;
2155  }
2156 
2157  for ( iface = 0; iface < FACE_MAX; iface++ ) {
2158  for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) {
2159  face[ivert][iface] = 0;
2160  }
2161  }
2162 
2163  for ( iface = 0; iface < FACE_MAX; iface++ ) {
2164  face_flags[iface] = 6;
2165  }
2166 
2167  for ( iface = 0; iface < FACE_MAX; iface++ ) {
2168  face_material[iface] = 0;
2169  }
2170 
2171  for ( iface = 0; iface < FACE_MAX; iface++ ) {
2172  for ( i = 0; i < 3; i++ ) {
2173  face_normal[i][iface] = 0;
2174  }
2175  }
2176 
2177  for ( iface = 0; iface < FACE_MAX; iface++ ) {
2178  face_object[iface] = -1;
2179  }
2180 
2181  for ( iface = 0; iface < FACE_MAX; iface++ ) {
2182  face_order[iface] = 0;
2183  }
2184 
2185  for ( iface = 0; iface < FACE_MAX; iface++ ) {
2186  face_smooth[iface] = 1;
2187  }
2188 
2189  for ( i = 0; i < LINES_MAX; i++ ) {
2190  line_dex[i] = -1;
2191  }
2192 
2193  for ( i = 0; i < LINES_MAX; i++ ) {
2194  line_material[i] = 0;
2195  }
2196 
2197  strcpy ( material_binding, "DEFAULT" );
2198 
2199  for ( j = 0; j < MATERIAL_MAX; j++ ) {
2200  strcpy ( material_name[j], "Material_0000" );
2201  }
2202 
2203  for ( i = 0; i < 4; i++ ) {
2204  for ( j = 0; j < MATERIAL_MAX; j++ ) {
2205  material_rgba[i][j] = 0.0;
2206  }
2207  }
2208 
2209  strcpy ( normal_binding, "DEFAULT" );
2210 
2211  for ( j = 0; j < ORDER_MAX*FACE_MAX; j++ ) {
2212  for ( i = 0; i < 3; i++ ) {
2213  normal_temp[i][j] = 0;
2214  }
2215  }
2216 
2217  color_num = 0;
2218  cor3_num = 0;
2219  face_num = 0;
2220  group_num = 0;
2221  line_num = 0;
2222  material_num = 0;
2223  object_num = 0;
2224  texture_num = 0;
2225 
2226  strcpy ( object_name, "IVCON" );
2227 
2228  for ( i = 0; i < 3; i++ ) {
2229  origin[i] = 0.0;
2230  }
2231 
2232  for ( i = 0; i < 3; i++ ) {
2233  pivot[i] = 0.0;
2234  }
2235 
2236  for ( j = 0; j < COLOR_MAX; j++ ) {
2237  rgbcolor[0][j] = 0.299;
2238  rgbcolor[1][j] = 0.587;
2239  rgbcolor[2][j] = 0.114;
2240  }
2241 
2242  strcpy ( texture_binding, "DEFAULT" );
2243 
2244  for ( j = 0; j < TEXTURE_MAX; j++ ) {
2245  strcpy ( texture_name[j], "Texture_0000" );
2246  }
2247 
2249 
2250  for ( iface = 0; iface < FACE_MAX; iface++ ) {
2251  for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) {
2252  vertex_material[ivert][iface] = 0;
2253  }
2254  }
2255 
2256  for ( iface = 0; iface < FACE_MAX; iface++ ) {
2257  for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) {
2258  for ( i = 0; i < 3; i++ ) {
2259  vertex_normal[i][ivert][iface] = 0.0;
2260  }
2261  }
2262  }
2263 
2264  for ( j = 0; j < 3; j++ ) {
2265  for ( k = 0; k < FACE_MAX; k++ ) {
2266  vertex_rgb[0][j][k] = 0.299;
2267  vertex_rgb[1][j][k] = 0.587;
2268  vertex_rgb[2][j][k] = 0.114;
2269  }
2270  }
2271 
2272  for ( iface = 0; iface < FACE_MAX; iface++ ) {
2273  for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) {
2274  for ( i = 0; i < 2; i++ ) {
2275  vertex_tex_uv[i][ivert][iface] = 0.0;
2276  }
2277  }
2278  }
2279 
2280  if ( debug ) {
2281  printf ( "\n" );
2282  printf ( "DATA_INIT: Graphics data initialized.\n" );
2283  }
2284 
2285  return;
2286 }
2287 /******************************************************************************/
2288 
2289 int data_read ( void )
2290 
2291 /******************************************************************************/
2292 
2293 /*
2294  Purpose:
2295 
2296  DATA_READ reads a file into internal graphics data.
2297 
2298  Modified:
2299 
2300  26 September 1999
2301 
2302  Author:
2303 
2304  John Burkardt
2305 */
2306 {
2307  FILE *filein;
2308  char *filein_type;
2309  int icor3;
2310  int ierror;
2311  int iface;
2312  int iline;
2313  int ivert;
2314  int ntemp;
2315 /*
2316  Retrieve the input file type.
2317 */
2318  filein_type = file_ext ( filein_name );
2319 
2320  if ( filein_type == NULL ) {
2321  printf ( "\n" );
2322  printf ( "DATA_READ - Fatal error!\n" );
2323  printf ( " Could not determine the type of '%s'.\n", filein_name );
2324  return ERROR;
2325  }
2326  else if ( debug ) {
2327  printf ( "\n" );
2328  printf ( "DATA_READ: Input file has type %s.\n", filein_type );
2329  }
2330 /*
2331  Initialize some data.
2332 */
2333  max_order2 = 0;
2334  bad_num = 0;
2335  bytes_num = 0;
2336  comment_num = 0;
2337  dup_num = 0;
2338  text_num = 0;
2339 /*
2340  Open the file.
2341 */
2342  if ( leqi ( filein_type, "3DS" ) == TRUE ||
2343  leqi ( filein_type, "STLB" ) == TRUE ||
2344  leqi ( filein_type, "TRIB" ) == TRUE ) {
2345  filein = fopen ( filein_name, "rb" );
2346  }
2347  else {
2348  filein = fopen ( filein_name, "r" );
2349  }
2350 
2351  if ( filein == NULL ) {
2352  printf ( "\n" );
2353  printf ( "DATA_READ - Fatal error!\n" );
2354  printf ( " Could not open the input file '%s'!\n", filein_name );
2355  return ERROR;
2356  }
2357 /*
2358  Read the information in the file.
2359 */
2360  if ( leqi ( filein_type, "3DS" ) == TRUE ) {
2361 
2362  ierror = tds_read ( filein );
2363 /*
2364  Cleanup: distribute the node textures to the vertices.
2365 */
2366  if ( ierror == SUCCESS ) {
2367 
2368  for ( iface = 0; iface < face_num; iface++ ) {
2369  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
2370  icor3 = face[ivert][iface];
2371  vertex_tex_uv[0][ivert][iface] = cor3_tex_uv[0][icor3];
2372  vertex_tex_uv[1][ivert][iface] = cor3_tex_uv[1][icor3];
2373  }
2374  }
2375 
2376  }
2377 
2378  }
2379  else if ( leqi ( filein_type, "ASE" ) == TRUE ) {
2380 
2381  ierror = ase_read ( filein );
2382 
2383  if ( ierror == SUCCESS ) {
2384 
2386 
2388 
2389  }
2390 
2391  }
2392  else if ( leqi ( filein_type, "BYU" ) == TRUE ) {
2393 
2394  ierror = byu_read ( filein );
2395 
2396  }
2397  else if ( leqi ( filein_type, "DXF" ) == TRUE ) {
2398 
2399  ierror = dxf_read ( filein );
2400 
2401  }
2402  else if ( leqi ( filein_type, "GMOD" ) == TRUE ) {
2403 
2404  ierror = gmod_read ( filein );
2405 
2406  }
2407  else if ( leqi ( filein_type, "HRC" ) == TRUE ) {
2408 
2409  ierror = hrc_read ( filein );
2410 
2411  }
2412  else if ( leqi ( filein_type, "IV" ) == TRUE ) {
2413 
2414  ierror = iv_read ( filein );
2415 
2416  }
2417  else if ( leqi ( filein_type, "OBJ" ) == TRUE ) {
2418 
2419  ierror = obj_read ( filein );
2420 
2421  }
2422  else if ( leqi ( filein_type, "SMF" ) == TRUE ) {
2423 
2424  ierror = smf_read ( filein );
2425 
2426  }
2427  else if (
2428  leqi ( filein_type, "STL" ) == TRUE ||
2429  leqi ( filein_type, "STLA") == TRUE ) {
2430 
2431  ierror = stla_read ( filein );
2432 
2433  if( ierror ) {
2434  // might be binary
2435  fclose(filein);
2436  filein = fopen ( filein_name, "rb" );
2437  ierror = stlb_read ( filein );
2438  }
2439  }
2440  else if ( leqi ( filein_type, "STLB") == TRUE ) {
2441 
2442  ierror = stlb_read ( filein );
2443 
2444  }
2445  else if (
2446  leqi ( filein_type, "TRI" ) == TRUE ||
2447  leqi ( filein_type, "TRIA") == TRUE ) {
2448 
2449  ierror = tria_read ( filein );
2450 
2451  }
2452  else if ( leqi ( filein_type, "TRIB") == TRUE ) {
2453 
2454  ierror = trib_read ( filein );
2455 
2456  }
2457  else if ( leqi ( filein_type, "VLA" ) == TRUE ) {
2458 
2459  ierror = vla_read ( filein );
2460 
2461  }
2462  else {
2463  printf ( "\n" );
2464  printf ( "DATA_READ - Fatal error!\n" );
2465  printf ( " Unacceptable input file type.\n" );
2466  return ERROR;
2467  }
2468 
2469  fclose ( filein );
2470 
2471  if ( debug ) {
2472  printf ( "DATA_READ: Finished reading the data file.\n" );
2473  }
2474 /*
2475  Catch errors reported by the various reading routines.
2476 */
2477  if ( ierror == ERROR ) {
2478  return ierror;
2479  }
2480 /*
2481  Restore the transformation matrix.
2482 */
2484 /*
2485  Report on what we read.
2486 */
2487  if ( face_num < FACE_MAX ) {
2488  ntemp = face_num;
2489  }
2490  else {
2491  ntemp = FACE_MAX;
2492  }
2493 
2494  max_order2 = ivec_max ( ntemp, face_order );
2495 
2496  data_report ( );
2497 /*
2498  Warn about any errors that occurred during reading.
2499 */
2500  if ( ierror == ERROR ) {
2501  printf ( "\n" );
2502  printf ( "DATA_READ - Fatal error!\n" );
2503  printf ( " An error occurred while reading the input file.\n" );
2504  return ERROR;
2505  }
2506 /*
2507  Check the data.
2508  You MUST wait until after this check before doing other computations,
2509  since COR3_NUM and other variables could be much larger than the legal
2510  maximums, until corrected by DATA_CHECK.
2511 */
2512  data_check ( );
2513 /*
2514  MATERIALS FIXUPS:
2515 
2516  If there are no materials at all, define one.
2517 */
2518  if ( material_num < 1 ) {
2519  material_num = 1;
2520  strcpy ( material_name[0], "Material_0000" );
2521  material_rgba[0][0] = 0.7;
2522  material_rgba[1][0] = 0.7;
2523  material_rgba[2][0] = 0.7;
2524  material_rgba[3][0] = 1.0;
2525  }
2526 /*
2527  If a node has not been assigned a material, set it to material 0.
2528 */
2529  for ( icor3 = 0; icor3 < cor3_num; icor3++ ) {
2530  if ( cor3_material[icor3] < 0 || cor3_material[icor3] > material_num - 1 ) {
2531  cor3_material[icor3] = 0;
2532  }
2533  }
2534 /*
2535  If a vertex has not been assigned a material, set it to material 0.
2536 */
2537  for ( iface = 0; iface < face_num; iface++ ) {
2538  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
2539  if ( vertex_material[ivert][iface] < 0 || vertex_material[ivert][iface] > material_num - 1 ) {
2540  vertex_material[ivert][iface] = 0;
2541  }
2542  }
2543  }
2544 /*
2545  If a face has not been assigned a material, set it to material 0.
2546 */
2547  for ( iface = 0; iface < face_num; iface++ ) {
2548  if ( face_material[iface] < 0 || face_material[iface] > material_num - 1 ) {
2549  face_material[iface] = 0;
2550  }
2551  }
2552 /*
2553  If a line item has not been assigned a material, set it to material 0.
2554 */
2555  for ( iline = 0; iline < line_num; iline++ ) {
2556  if ( line_dex[iline] == -1 ) {
2557  line_material[iline] = -1;
2558  }
2559  else if ( line_material[iline] < 0 || line_material[iline] > material_num - 1 ) {
2560  line_material[iline] = 0;
2561  }
2562  }
2563 /*
2564  Delete edges of zero length.
2565 */
2566  edge_null_delete ( );
2567 /*
2568  Compute the area of each face.
2569 */
2570  face_area_set ( );
2571 /*
2572  Delete faces with zero area.
2573 */
2574  face_null_delete ( );
2575 /*
2576  Recompute zero face-vertex normals from vertex positions.
2577 */
2578  vertex_normal_set ( );
2579 /*
2580  Compute the node normals from the vertex normals.
2581 */
2582  cor3_normal_set ( );
2583 /*
2584  Recompute zero face normals by averaging face-vertex normals.
2585 */
2586  face_normal_ave ( );
2587 /*
2588  Report on the nodal coordinate range.
2589 */
2590  cor3_range ( );
2591 
2592  return SUCCESS;
2593 }
2594 /**********************************************************************/
2595 
2596 void data_report ( void )
2597 
2598 /**********************************************************************/
2599 
2600 /*
2601  Purpose:
2602 
2603  DATA_REPORT gives a summary of the contents of the data file.
2604 
2605  Modified:
2606 
2607  24 May 1999
2608 
2609  Author:
2610 
2611  John Burkardt
2612 */
2613 {
2614  printf ( "\n" );
2615  printf ( "DATA_REPORT - The input file contains:\n" );
2616  printf ( "\n" );
2617  printf ( " Bad data items %d\n", bad_num );
2618  printf ( " Text lines %d\n", text_num );
2619  printf ( " Text bytes (binary data) %d\n", bytes_num );
2620  printf ( " Colors %d\n", color_num );
2621  printf ( " Comments %d\n", comment_num );
2622  printf ( " Duplicate points %d\n", dup_num );
2623  printf ( " Faces %d\n", face_num );
2624  printf ( " Groups %d\n", group_num );
2625  printf ( " Vertices per face, maximum %d\n", max_order2 );
2626  printf ( " Line items %d\n", line_num );
2627  printf ( " Points %d\n", cor3_num );
2628  printf ( " Objects %d\n", object_num );
2629 
2630  return;
2631 }
2632 /******************************************************************************/
2633 
2634 int data_write ( void )
2635 
2636 /******************************************************************************/
2637 
2638 /*
2639  Purpose:
2640 
2641  DATA_WRITE writes the internal graphics data to a file.
2642 
2643  Modified:
2644 
2645  22 May 1999
2646 
2647  Author:
2648 
2649  John Burkardt
2650 */
2651 {
2652  FILE *fileout;
2653  char *fileout_type;
2654  int line_num_save;
2655  int result;
2656 
2657  result = SUCCESS;
2658 /*
2659  Retrieve the output file type.
2660 */
2661  fileout_type = file_ext ( fileout_name );
2662 
2663  if ( fileout_type == NULL ) {
2664  printf ( "\n" );
2665  printf ( "DATA_WRITE - Fatal error!\n" );
2666  printf ( " Could not determine the output file type.\n" );
2667  return ERROR;
2668  }
2669 /*
2670  Open the output file.
2671 */
2672  if ( leqi ( fileout_type, "3DS" ) == TRUE ||
2673  leqi ( fileout_type, "STLB" ) == TRUE ||
2674  leqi ( fileout_type, "TRIB" ) ) {
2675  fileout = fopen ( fileout_name, "wb" );
2676  }
2677  else {
2678  fileout = fopen ( fileout_name, "w" );
2679  }
2680 
2681  if ( fileout == NULL ) {
2682  printf ( "\n" );
2683  printf ( "DATA_WRITE - Fatal error!\n" );
2684  printf ( " Could not open the output file!\n" );
2685  return ERROR;
2686  }
2687 /*
2688  Write the output file.
2689 */
2690  if ( leqi ( fileout_type, "3DS" ) == TRUE ) {
2691 
2692  tds_pre_process();
2693  result = tds_write ( fileout );
2694 
2695  }
2696  else if ( leqi ( fileout_type, "ASE" ) == TRUE ) {
2697 
2698  result = ase_write ( fileout );
2699 
2700  }
2701  else if ( leqi ( fileout_type, "BYU" ) == TRUE ) {
2702 
2703  result = byu_write ( fileout );
2704 
2705  }
2706  else if ( leqi ( fileout_type, "DXF" ) == TRUE ) {
2707 
2708  result = dxf_write ( fileout );
2709 
2710  }
2711  else if ( leqi ( fileout_type, "GMOD" ) == TRUE ) {
2712 
2713  result = gmod_write ( fileout );
2714 
2715  }
2716  else if ( leqi ( fileout_type, "HRC" ) == TRUE ) {
2717 
2718  result = hrc_write ( fileout );
2719 
2720  }
2721  else if ( leqi ( fileout_type, "IV" ) == TRUE ) {
2722 
2723  result = iv_write ( fileout );
2724 
2725  }
2726  else if ( leqi ( fileout_type, "OBJ" ) == TRUE ) {
2727 
2728  result = obj_write ( fileout );
2729 
2730  }
2731  else if ( leqi ( fileout_type, "POV" ) == TRUE ) {
2732 
2733  result = pov_write ( fileout );
2734 
2735  }
2736  else if ( leqi ( fileout_type, "SMF" ) == TRUE ) {
2737 
2738  result = smf_write ( fileout );
2739 
2740  }
2741  else if (
2742  leqi ( fileout_type, "STL" ) == TRUE ||
2743  leqi ( fileout_type, "STLA" ) == TRUE ) {
2744 
2745  result = stla_write ( fileout );
2746 
2747  }
2748  else if ( leqi ( fileout_type, "STLB" ) == TRUE ) {
2749 
2750  result = stlb_write ( fileout );
2751 
2752  }
2753  else if ( leqi ( fileout_type, "TEC" ) == TRUE ) {
2754 
2755  result = tec_write ( fileout );
2756 
2757  }
2758  else if (
2759  leqi ( fileout_type, "TRI" ) == TRUE ||
2760  leqi ( fileout_type, "TRIA" ) == TRUE ) {
2761 
2762  result = tria_write ( fileout );
2763 
2764  }
2765  else if ( leqi ( fileout_type, "TRIB" ) == TRUE ) {
2766 
2767  result = trib_write ( fileout );
2768 
2769  }
2770  else if ( leqi ( fileout_type, "TXT" ) == TRUE ) {
2771 
2772  result = txt_write ( fileout );
2773 
2774  }
2775  else if ( leqi ( fileout_type, "UCD" ) == TRUE ) {
2776 
2777  result = ucd_write ( fileout );
2778 
2779  }
2780  else if ( leqi ( fileout_type, "VLA" ) == TRUE ) {
2781 
2782  line_num_save = line_num;
2783 
2784  if ( face_num > 0 ) {
2785 
2786  printf ( "\n" );
2787  printf ( "DATA_WRITE - Note:\n" );
2788  printf ( " Face information will temporarily be converted to\n" );
2789  printf ( " line information for output to a VLA file.\n" );
2790 
2791  face_to_line ( );
2792 
2793  if ( line_num > LINES_MAX ) {
2794  printf ( "\n" );
2795  printf ( "DATA_WRITE - Warning:\n" );
2796  printf ( " Some face information was lost.\n" );
2797  printf ( " The maximum number of lines is %d.\n", LINES_MAX );
2798  printf ( " The number of lines needed is %d.\n", line_num );
2799  line_num = LINES_MAX;
2800  }
2801 
2802  }
2803 
2804  result = vla_write ( fileout );
2805 
2806  line_num = line_num_save;
2807 
2808  }
2809  else if ( leqi ( fileout_type, "WRL" ) == TRUE ) {
2810 
2811  result = wrl_write ( fileout );
2812 
2813  }
2814  else if ( leqi ( fileout_type, "XGL" ) == TRUE ) {
2815 
2816  result = xgl_write ( fileout );
2817 
2818  }
2819  else {
2820 
2821  result = ERROR;
2822  printf ( "\n" );
2823  printf ( "DATA_WRITE - Fatal error!\n" );
2824  printf ( " Unacceptable output file type \"%s\".\n", fileout_type );
2825 
2826  }
2827 /*
2828  Close the output file.
2829 */
2830  fclose ( fileout );
2831 
2832  if ( result == ERROR ) {
2833  return ERROR;
2834  }
2835  else {
2836  return SUCCESS;
2837  }
2838 }
2839 /******************************************************************************/
2840 
2841 int dxf_read ( FILE *filein )
2842 
2843 /******************************************************************************/
2844 
2845 /*
2846  Purpose:
2847 
2848  DXF_READ reads an AutoCAD DXF file.
2849 
2850  Examples:
2851 
2852  0
2853  SECTION
2854  2
2855  HEADER
2856  999
2857  diamond.dxf created by IVREAD.
2858  999
2859  Original data in diamond.obj.
2860  0
2861  ENDSEC
2862  0
2863  SECTION
2864  2
2865  TABLES
2866  0
2867  ENDSEC
2868  0
2869  SECTION
2870  2
2871  BLOCKS
2872  0
2873  ENDSEC
2874  0
2875  SECTION
2876  2
2877  ENTITIES
2878  0
2879  LINE
2880  8
2881  0
2882  10
2883  0.00 (X coordinate of beginning of line.)
2884  20
2885  0.00 (Y coordinate of beginning of line.)
2886  30
2887  0.00 (Z coordinate of beginning of line.)
2888  11
2889  1.32 (X coordinate of end of line.)
2890  21
2891  1.73 (Y coordinate of end of line.)
2892  31
2893  2.25 (Z coordinate of end of line.)
2894  0
2895  3DFACE
2896  8
2897  Cube
2898  10
2899  -0.50 (X coordinate of vertex 1)
2900  20
2901  0.50 (Y coordinate of vertex 1)
2902  30
2903  1.0 (Z coordinate of vertex 1)
2904  11
2905  0.50 (X coordinate of vertex 2)
2906  21
2907  0.50 (Y coordinate of vertex 2)
2908  31
2909  1.0 (Z coordinate of vertex 2)
2910  12
2911  0.50 (X coordinate of vertex 3)
2912  22
2913  0.50 (Y coordinate of vertex 3)
2914  32
2915  0.00 (Z coordinate of vertex 3)
2916  0
2917  ENDSEC
2918  0
2919  EOF
2920 
2921  Modified:
2922 
2923  23 May 1999
2924 
2925  Author:
2926 
2927  John Burkardt
2928 */
2929 {
2930  int code;
2931  int count;
2932  float cvec[3];
2933  int icor3;
2934  char input1[LINE_MAX_LEN];
2935  char input2[LINE_MAX_LEN];
2936  int ivert;
2937  float rval;
2938  int width;
2939  int linemode;
2940  int cpos;
2941 
2942  linemode = 0;
2943  ivert = 0;
2944 /*
2945  Read the next two lines of the file into INPUT1 and INPUT2.
2946 */
2947 
2948  for ( ;; ) {
2949 
2950 /*
2951  INPUT1 should contain a single integer, which tells what INPUT2
2952  will contain.
2953 */
2954  if ( fgets ( input1, LINE_MAX_LEN, filein ) == NULL ) {
2955  break;
2956  }
2957 
2958  text_num = text_num + 1;
2959 
2960  count = sscanf ( input1, "%d%n", &code, &width );
2961  if ( count <= 0 ) {
2962  break;
2963  }
2964 /*
2965  Read the second line, and interpret it according to the code.
2966 */
2967  if ( fgets ( input2, LINE_MAX_LEN, filein ) == NULL ) {
2968  break;
2969  }
2970 
2971  text_num = text_num + 1;
2972 
2973  if ( code == 0 ) {
2974 
2975  if ( ivert > 0 ) {
2976  /* finish off the face */
2977  face_order[face_num] = ivert;
2978  face_num = face_num + 1;
2979  ivert = 0;
2980  }
2981 
2982  if ( strncmp( input2, "LINE", 4 ) == 0 ) {
2983  linemode = 1;
2984  }
2985  else if ( strncmp( input2, "3DFACE", 6 ) == 0 ) {
2986  linemode = 0;
2987  ivert = 0;
2988  }
2989  }
2990  else {
2991 
2992  for (cpos = 0; input1[cpos] == ' '; cpos++)
2993  {};
2994 
2995  if ( input1[cpos] == '1' || input1[cpos] == '2' || input1[cpos] == '3' ) {
2996 
2997  count = sscanf ( input2, "%e%n", &rval, &width );
2998 
2999  switch ( input1[cpos] )
3000  {
3001  case '1':
3002  if ( line_num > 0 ) {
3003  if ( linemode ) {
3004  line_dex[line_num] = - 1;
3005  line_material[line_num] = - 1;
3006  line_num = line_num + 1;
3007  }
3008  }
3009  cvec[0] = rval;
3010  break;
3011 
3012  case '2':
3013  cvec[1] = rval;
3014  break;
3015 
3016  case '3':
3017  cvec[2] = rval;
3018 
3019  if ( cor3_num < 1000 ) {
3020  icor3 = rcol_find ( cor3, 3, cor3_num, cvec );
3021  }
3022  else {
3023  icor3 = -1;
3024  }
3025 
3026  if ( icor3 == -1 ) {
3027  icor3 = cor3_num;
3028  if ( cor3_num < COR3_MAX ) {
3029  cor3[0][cor3_num] = cvec[0];
3030  cor3[1][cor3_num] = cvec[1];
3031  cor3[2][cor3_num] = cvec[2];
3032  }
3033  cor3_num = cor3_num + 1;
3034  }
3035  else {
3036  dup_num = dup_num + 1;
3037  }
3038 
3039  if ( linemode ) {
3040  line_dex[line_num] = icor3;
3041  line_material[line_num] = 0;
3042  line_num = line_num + 1;
3043  }
3044  else {
3045  face[ivert][face_num] = icor3;
3046  ivert = ivert + 1;
3047  }
3048  break;
3049 
3050  default:
3051  break;
3052  }
3053  }
3054  }
3055  }
3056 
3057  if ( line_num > 0 ) {
3058  if ( linemode ) {
3059  line_dex[line_num] = - 1;
3060  line_material[line_num] = - 1;
3061  line_num = line_num + 1;
3062  }
3063  }
3064  return SUCCESS;
3065 }
3066 /******************************************************************************/
3067 
3068 int dxf_write ( FILE *fileout )
3069 
3070 /******************************************************************************/
3071 
3072 /*
3073  Purpose:
3074 
3075  DXF_WRITE writes graphics information to an AutoCAD DXF file.
3076 
3077  Examples:
3078 
3079  0
3080  SECTION
3081  2
3082  HEADER
3083  999
3084  diamond.dxf created by IVREAD.
3085  999
3086  Original data in diamond.obj.
3087  0
3088  ENDSEC
3089  0
3090  SECTION
3091  2
3092  TABLES
3093  0
3094  ENDSEC
3095  0
3096  SECTION
3097  2
3098  BLOCKS
3099  0
3100  ENDSEC
3101  0
3102  SECTION
3103  2
3104  ENTITIES
3105  0
3106  LINE
3107  8
3108  0
3109  10
3110  0.00 (X coordinate of beginning of line.)
3111  20
3112  0.00 (Y coordinate of beginning of line.)
3113  30
3114  0.00 (Z coordinate of beginning of line.)
3115  11
3116  1.32 (X coordinate of end of line.)
3117  21
3118  1.73 (Y coordinate of end of line.)
3119  31
3120  2.25 (Z coordinate of end of line.)
3121  0
3122  3DFACE
3123  8
3124  Cube
3125  10
3126  -0.50 (X coordinate of vertex 1)
3127  20
3128  0.50 (Y coordinate of vertex 1)
3129  30
3130  1.0 (Z coordinate of vertex 1)
3131  11
3132  0.50 (X coordinate of vertex 2)
3133  21
3134  0.50 (Y coordinate of vertex 2)
3135  31
3136  1.0 (Z coordinate of vertex 2)
3137  12
3138  0.50 (X coordinate of vertex 3)
3139  22
3140  0.50 (Y coordinate of vertex 3)
3141  32
3142  0.00 (Z coordinate of vertex 3)
3143  0
3144  ENDSEC
3145  0
3146  EOF
3147 
3148  Modified:
3149 
3150  16 May 1999
3151 
3152  Author:
3153 
3154  John Burkardt
3155 */
3156 {
3157  int icor3;
3158  int iline;
3159  int iface;
3160  int ivert;
3161  int jcor3;
3162  int newline;
3163  int text_num;
3164 
3165 /*
3166  Initialize.
3167 */
3168  text_num = 0;
3169 
3170  fprintf ( fileout, " 0\n" );
3171  fprintf ( fileout, "SECTION\n" );
3172  fprintf ( fileout, " 2\n" );
3173  fprintf ( fileout, "HEADER\n" );
3174  fprintf ( fileout, "999\n" );
3175  fprintf ( fileout, "%s created by IVCON.\n", fileout_name );
3176  fprintf ( fileout, "999\n" );
3177  fprintf ( fileout, "Original data in %s.\n", filein_name );
3178  fprintf ( fileout, " 0\n" );
3179  fprintf ( fileout, "ENDSEC\n" );
3180  text_num = text_num + 10;
3181 
3182  fprintf ( fileout, " 0\n" );
3183  fprintf ( fileout, "SECTION\n" );
3184  fprintf ( fileout, " 2\n" );
3185  fprintf ( fileout, "TABLES\n" );
3186  fprintf ( fileout, " 0\n" );
3187  fprintf ( fileout, "ENDSEC\n" );
3188  text_num = text_num + 6;
3189 
3190  fprintf ( fileout, " 0\n" );
3191  fprintf ( fileout, "SECTION\n" );
3192  fprintf ( fileout, " 2\n" );
3193  fprintf ( fileout, "BLOCKS\n" );
3194  fprintf ( fileout, " 0\n" );
3195  fprintf ( fileout, "ENDSEC\n" );
3196  text_num = text_num + 6;
3197 
3198  fprintf ( fileout, " 0\n" );
3199  fprintf ( fileout, "SECTION\n" );
3200  fprintf ( fileout, " 2\n" );
3201  fprintf ( fileout, "ENTITIES\n" );
3202  text_num = text_num + 4;
3203 /*
3204  Handle lines.
3205 */
3206  jcor3 = 0;
3207  newline = TRUE;
3208 
3209  for ( iline = 0; iline < line_num; iline++ ) {
3210 
3211  icor3 = line_dex[iline];
3212 
3213  if ( icor3 == -1 ) {
3214 
3215  newline = TRUE;
3216  }
3217  else {
3218 
3219  if ( newline == FALSE ) {
3220 
3221  fprintf ( fileout, " 0\n" );
3222  fprintf ( fileout, "LINE\n" );
3223  fprintf ( fileout, " 8\n" );
3224  fprintf ( fileout, " 0\n" );
3225  fprintf ( fileout, " 10\n" );
3226  fprintf ( fileout, "%f\n", cor3[0][jcor3] );
3227  fprintf ( fileout, " 20\n" );
3228  fprintf ( fileout, "%f\n", cor3[1][jcor3] );
3229  fprintf ( fileout, " 30\n" );
3230  fprintf ( fileout, "%f\n", cor3[2][jcor3] );
3231  fprintf ( fileout, " 11\n" );
3232  fprintf ( fileout, "%f\n", cor3[0][icor3] );
3233  fprintf ( fileout, " 21\n" );
3234  fprintf ( fileout, "%f\n", cor3[1][icor3] );
3235  fprintf ( fileout, " 31\n" );
3236  fprintf ( fileout, "%f\n", cor3[2][icor3] );
3237 
3238  text_num = text_num + 16;
3239 
3240  }
3241 
3242  jcor3 = icor3;
3243  newline = FALSE;
3244 
3245  }
3246  }
3247 /*
3248  Handle faces.
3249  (If FACE_ORDER is greater than 10, you're sure to have problems here)
3250 */
3251  for ( iface = 0; iface < face_num; iface++ ) {
3252 
3253  fprintf ( fileout, " 0\n" );
3254  fprintf ( fileout, "3DFACE\n" );
3255  fprintf ( fileout, " 8\n" );
3256  fprintf ( fileout, " Cube\n" );
3257  text_num = text_num + 4;
3258 
3259  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
3260 
3261  icor3 = face[ivert][iface];
3262 
3263  fprintf ( fileout, "1%d\n", ivert );
3264  fprintf ( fileout, "%f\n", cor3[0][icor3] );
3265  fprintf ( fileout, "2%d\n", ivert );
3266  fprintf ( fileout, "%f\n", cor3[1][icor3] );
3267  fprintf ( fileout, "3%d\n", ivert );
3268  fprintf ( fileout, "%f\n", cor3[2][icor3] );
3269 
3270  text_num = text_num + 6;
3271  }
3272  }
3273 
3274  fprintf ( fileout, " 0\n" );
3275  fprintf ( fileout, "ENDSEC\n" );
3276  fprintf ( fileout, " 0\n" );
3277  fprintf ( fileout, "EOF\n" );
3278  text_num = text_num + 4;
3279 /*
3280  Report.
3281 */
3282  printf ( "\n" );
3283  printf ( "DXF_WRITE - Wrote %d text lines.\n", text_num );
3284 
3285  return SUCCESS;
3286 }
3287 /**********************************************************************/
3288 
3289 void edge_null_delete ( void )
3290 
3291 /**********************************************************************/
3292 
3293 /*
3294  Purpose:
3295 
3296  EDGE_NULL_DELETE deletes face edges with zero length.
3297 
3298  Modified:
3299 
3300  16 July 1999
3301 
3302  Author:
3303 
3304  John Burkardt
3305 */
3306 {
3307  float distsq;
3308  int face2[ORDER_MAX];
3309  int face_order2;
3310  int iface;
3311  int inode;
3312  int ivert;
3313  int j;
3314  int jnode;
3315  int jvert;
3316  int edge_num;
3317  int edge_num_del;
3318  float vertex_normal2[3][ORDER_MAX];
3319  float x;
3320  float y;
3321  float z;
3322 
3323  edge_num = 0;
3324  edge_num_del = 0;
3325 /*
3326  Consider each face.
3327 */
3328  for ( iface = 0; iface < face_num; iface++ ) {
3329 /*
3330  Consider each pair of consecutive vertices.
3331 */
3332  face_order2 = 0;
3333 
3334  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
3335 
3336  edge_num = edge_num + 1;
3337 
3338  jvert = ivert + 1;
3339  if ( jvert >= face_order[iface] ) {
3340  jvert = 0;
3341  }
3342 
3343  inode = face[ivert][iface];
3344  jnode = face[jvert][iface];
3345 
3346 
3347  x = cor3[0][inode] - cor3[0][jnode];
3348  y = cor3[1][inode] - cor3[1][jnode];
3349  z = cor3[2][inode] - cor3[2][jnode];
3350 
3351  distsq = x * x + y * y + z * z;
3352 
3353  if ( distsq != 0.0 ) {
3354  face2[face_order2] = face[ivert][iface];
3355  vertex_normal2[0][face_order2] = vertex_normal[0][ivert][iface];
3356  vertex_normal2[1][face_order2] = vertex_normal[1][ivert][iface];
3357  vertex_normal2[2][face_order2] = vertex_normal[2][ivert][iface];
3358  face_order2 = face_order2 + 1;
3359  }
3360  else {
3361  edge_num_del = edge_num_del + 1;
3362  }
3363 
3364  }
3365 
3366  face_order[iface] = face_order2;
3367  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
3368  face[ivert][iface] = face2[ivert];
3369  for ( j = 0; j < 3; j++ ) {
3370  vertex_normal[j][ivert][iface] = vertex_normal2[j][ivert];
3371  }
3372  }
3373 
3374  }
3375 
3376  printf ( "\n" );
3377  printf ( "EDGE_NULL_DELETE:\n" );
3378  printf ( " There are a total of %d edges.\n", edge_num );
3379  printf ( " Of these, %d were of zero length, and deleted.\n", edge_num_del );
3380 
3381  return;
3382 }
3383 /**********************************************************************/
3384 
3385 void face_area_set ( void )
3386 
3387 /**********************************************************************/
3388 
3389 /*
3390  Purpose:
3391 
3392  FACE_AREA_SET computes the area of the faces.
3393 
3394  Formula:
3395 
3396  The area is the sum of the areas of the triangles formed by
3397  node N with consecutive pairs of nodes.
3398 
3399  Reference:
3400 
3401  Adrian Bowyer and John Woodwark,
3402  A Programmer's Geometry,
3403  Butterworths, 1983.
3404 
3405  Modified:
3406 
3407  17 July 1999
3408 
3409  Author:
3410 
3411  John Burkardt
3412 */
3413 {
3414  float alpha;
3415  float area_max;
3416  float area_min;
3417  float area_tri;
3418  float base;
3419  float dot;
3420  float height;
3421  int i;
3422  int i1;
3423  int i2;
3424  int i3;
3425  int iface;
3426  int face_num_del;
3427  float tol;
3428  float x;
3429  float x1;
3430  float x2;
3431  float x3;
3432  float y;
3433  float y1;
3434  float y2;
3435  float y3;
3436  float z;
3437  float z1;
3438  float z2;
3439  float z3;
3440 
3441  for ( iface = 0; iface < face_num; iface++ ) {
3442 
3443  face_area[iface] = 0.0;
3444 
3445  for ( i = 0; i < face_order[iface]-2; i++ ) {
3446 
3447  i1 = face[i][iface];
3448  i2 = face[i+1][iface];
3449  i3 = face[i+2][iface];
3450 
3451  x1 = cor3[0][i1];
3452  y1 = cor3[1][i1];
3453  z1 = cor3[2][i1];
3454 
3455  x2 = cor3[0][i2];
3456  y2 = cor3[1][i2];
3457  z2 = cor3[2][i2];
3458 
3459  x3 = cor3[0][i3];
3460  y3 = cor3[1][i3];
3461  z3 = cor3[2][i3];
3462 /*
3463  Find the projection of (P3-P1) onto (P2-P1).
3464 */
3465  dot =
3466  ( x2 - x1 ) * ( x3 - x1 ) +
3467  ( y2 - y1 ) * ( y3 - y1 ) +
3468  ( z2 - z1 ) * ( z3 - z1 );
3469 
3470  base = sqrt (
3471  ( x2 - x1 ) * ( x2 - x1 )
3472  + ( y2 - y1 ) * ( y2 - y1 )
3473  + ( z2 - z1 ) * ( z2 - z1 ) );
3474 /*
3475  The height of the triangle is the length of (P3-P1) after its
3476  projection onto (P2-P1) has been subtracted.
3477 */
3478  if ( base == 0.0 ) {
3479  height = 0.0;
3480  }
3481  else {
3482 
3483  alpha = dot / ( base * base );
3484 
3485  x = x3 - x1 - alpha * ( x2 - x1 );
3486  y = y3 - y1 - alpha * ( y2 - y1 );
3487  z = z3 - z1 - alpha * ( z2 - z1 );
3488 
3489  height = sqrt ( x * x + y * y + z * z );
3490 
3491  }
3492 
3493  area_tri = 0.5 * base * height;
3494 
3495  face_area[iface] = face_area[iface] + area_tri;
3496 
3497  }
3498 
3499  }
3500 
3501  area_min = face_area[0];
3502  area_max = face_area[0];
3503 
3504  for ( iface = 1; iface < face_num; iface++ ) {
3505  if ( area_min > face_area[iface] ) {
3506  area_min = face_area[iface];
3507  }
3508  if ( area_max < face_area[iface] ) {
3509  area_max = face_area[iface];
3510  }
3511  }
3512 
3513  printf ( "\n" );
3514  printf ( "FACE_AREA_SET:\n" );
3515  printf ( " Minimum face area is %f\n", area_min );
3516  printf ( " Maximum face area is %f\n", area_max );
3517 
3518  tol = area_max / 10000.0;
3519 
3520  if ( area_min < tol ) {
3521 
3522  face_num_del = 0;
3523 
3524  for ( iface = 0; iface < face_num; iface++ ) {
3525  if ( face_area[iface] < tol ) {
3526  face_order[iface] = 0;
3527  face_num_del = face_num_del + 1;
3528  }
3529  }
3530 
3531  printf ( " Marked %d tiny faces for deletion.\n", face_num_del );
3532 
3533  }
3534 
3535  return;
3536 }
3537 /******************************************************************************/
3538 
3539 void face_normal_ave ( void )
3540 
3541 /******************************************************************************/
3542 
3543 /*
3544  Purpose:
3545 
3546  FACE_NORMAL_AVE sets face normals as average of face vertex normals.
3547 
3548  Modified:
3549 
3550  09 October 1998
3551 
3552  Author:
3553 
3554  John Burkardt
3555 */
3556 {
3557  int i;
3558  int iface;
3559  int ivert;
3560  int nfix;
3561  float norm;
3562  float x;
3563  float y;
3564  float z;
3565 
3566  if ( face_num <= 0 ) {
3567  return;
3568  }
3569 
3570  nfix = 0;
3571 
3572  for ( iface = 0; iface < face_num; iface++ ) {
3573 
3574 /*
3575  Check the norm of the current normal vector.
3576 */
3577  x = face_normal[0][iface];
3578  y = face_normal[1][iface];
3579  z = face_normal[2][iface];
3580  norm = ( float ) sqrt ( x * x + y * y + z * z );
3581 
3582  if ( norm == 0.0 ) {
3583 
3584  nfix = nfix + 1;
3585 
3586  for ( i = 0; i < 3; i++ ) {
3587  face_normal[i][iface] = 0.0;
3588  }
3589 
3590  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
3591  for ( i = 0; i < 3; i++ ) {
3592  face_normal[i][iface] = face_normal[i][iface] +
3593  vertex_normal[i][ivert][iface];
3594  }
3595  }
3596 
3597  x = face_normal[0][iface];
3598  y = face_normal[1][iface];
3599  z = face_normal[2][iface];
3600  norm = ( float ) sqrt ( x * x + y * y + z * z );
3601 
3602  if ( norm == 0.0 ) {
3603  for ( i = 0; i < 3; i++ ) {
3604  face_normal[i][iface] = ( float ) ( 1.0 / sqrt ( 3.0 ) );
3605  }
3606  }
3607  else {
3608  for ( i = 0; i < 3; i++ ) {
3609  face_normal[i][iface] = face_normal[i][iface] / norm;
3610  }
3611  }
3612  }
3613  }
3614 
3615  if ( nfix > 0 ) {
3616  printf ( "\n" );
3617  printf ( "FACE_NORMAL_AVE: Recomputed %d face normals\n", nfix );
3618  printf ( " by averaging face vertex normals.\n" );
3619  }
3620  return;
3621 }
3622 /**********************************************************************/
3623 
3624 void face_null_delete ( void )
3625 
3626 /**********************************************************************/
3627 
3628 /*
3629  Purpose:
3630 
3631  FACE_NULL_DELETE deletes faces of order less than 3.
3632 
3633  Comments:
3634 
3635  Thanks to Susan M. Fisher, University of North Carolina,
3636  Department of Computer Science, for pointing out a coding error
3637  in FACE_NULL_DELETE that was overwriting all the data!
3638 
3639  Modified:
3640 
3641  30 November 1999
3642 
3643  Author:
3644 
3645  John Burkardt
3646 */
3647 {
3648  int iface;
3649  int ivert;
3650  int j;
3651  int face_num2;
3652 /*
3653  FACE_NUM2 is the number of faces we'll keep.
3654 */
3655  face_num2 = 0;
3656 /*
3657  Check every face.
3658 */
3659  for ( iface = 0; iface < face_num; iface++ ) {
3660 /*
3661  Keep it only if it has order 3 or more.
3662 */
3663  if ( face_order[iface] >= 3 ) {
3664 /*
3665  We don't have to slide data down in the array until
3666  NUMFACE2 and IFACE get out of synch, that is, after
3667  we've discarded at least one face.
3668 */
3669  if ( face_num2 != iface ) {
3670 
3671  face_area[face_num2] = face_area[iface];
3672  face_material[face_num2] = face_material[iface];
3673  face_order[face_num2] = face_order[iface];
3674  for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) {
3675  face[ivert][face_num2] = face[ivert][iface];
3676  vertex_material[ivert][face_num2] = vertex_material[ivert][iface];
3677  for ( j = 0; j < 3; j++ ) {
3678  vertex_normal[j][ivert][face_num2] = vertex_normal[j][ivert][iface];
3679  }
3680  }
3681 
3682  }
3683 /*
3684  Update the count only after we've used the un-incremented value
3685  as a pointer.
3686 */
3687  face_num2 = face_num2 + 1;
3688 
3689  }
3690 
3691  }
3692 
3693  printf ( "\n" );
3694  printf ( "FACE_NULL_DELETE\n" );
3695  printf ( " There are a total of %d faces.\n", face_num );
3696  printf ( " Of these, %d passed the order test.\n", face_num2 );
3697 
3698  face_num = face_num2;
3699 
3700  return;
3701 }
3702 /******************************************************************************/
3703 
3704 int face_print ( int iface )
3705 
3706 /******************************************************************************/
3707 
3708 /*
3709  Purpose:
3710 
3711  FACE_PRINT prints out information about a face.
3712 
3713  Modified:
3714 
3715  31 August 1998
3716 
3717  Author:
3718 
3719  John Burkardt
3720 */
3721 {
3722  int ivert;
3723  int j;
3724  int k;
3725 
3726  if ( iface < 0 || iface > face_num-1 ) {
3727  printf ( "\n" );
3728  printf ( "FACE_PRINT - Fatal error!\n" );
3729  printf ( " Face indices must be between 1 and %d\n", face_num );
3730  printf ( " But your requested value was %d\n", iface );
3731  return ERROR;
3732  }
3733 
3734  printf ( "\n" );
3735  printf ( "FACE_PRINT\n" );
3736  printf ( " Information about face %d\n", iface );
3737  printf ( "\n" );
3738  printf ( " Number of vertices is %d\n", face_order[iface] );
3739  printf ( "\n" );
3740  printf ( " Vertex list:\n" );
3741  printf ( " Vertex #, Node #, Material #, X, Y, Z:\n" );
3742  printf ( "\n" );
3743  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
3744  j = face[ivert][iface];
3745  k = vertex_material[ivert][iface];
3746  printf ( " %d %d %d %f %f %f\n", ivert, j, k, cor3[0][j], cor3[1][j],
3747  cor3[2][j] );
3748  }
3749 
3750  printf ( "\n" );
3751  printf ( " Face normal vector:\n" );
3752  printf ( "\n" );
3753  printf ( " %f %f %f\n", face_normal[0][iface], face_normal[1][iface],
3754  face_normal[2][iface] );
3755 
3756  printf ( "\n" );
3757  printf ( " Vertex face normals:\n" );
3758  printf ( "\n" );
3759  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
3760  printf ( " %d %f %f %f\n", ivert, vertex_normal[0][ivert][iface],
3761  vertex_normal[1][ivert][iface], vertex_normal[2][ivert][iface] );
3762  }
3763 
3764  return SUCCESS;
3765 
3766 }
3767 /**********************************************************************/
3768 
3769 void face_reverse_order ( void )
3770 
3771 /**********************************************************************/
3772 
3773 /*
3774  Purpose:
3775 
3776  FACE_REVERSE_ORDER reverses the order of the nodes in each face.
3777 
3778  Discussion:
3779 
3780  Reversing the order of the nodes requires that the normal vectors
3781  be reversed as well, so this routine will automatically reverse
3782  the normals associated with nodes, vertices and faces.
3783 
3784  Modified:
3785 
3786  28 June 1999
3787 
3788  Author:
3789 
3790  John Burkardt
3791 */
3792 {
3793  int i;
3794  int iface;
3795  int itemp;
3796  int ivert;
3797  int j;
3798  int m;
3799  float temp;
3800 
3801  for ( iface = 0; iface < face_num; iface++ ) {
3802 
3803  m = face_order[iface];
3804 
3805  for ( ivert = 0; ivert < ( m / 2 ); ivert++ ) {
3806 
3807  itemp = face[ivert][iface];
3808  face[ivert][iface] = face[m-1-ivert][iface];
3809  face[m-1-ivert][iface] = itemp;
3810 
3811  itemp = vertex_material[ivert][iface];
3812  vertex_material[ivert][iface] = vertex_material[m-1-ivert][iface];
3813  vertex_material[m-1-ivert][iface] = itemp;
3814 
3815  for ( j = 0; j < 3; j++ ) {
3816  temp = vertex_normal[j][ivert][iface];
3817  vertex_normal[j][ivert][iface] = vertex_normal[j][m-1-ivert][iface];
3818  vertex_normal[j][m-1-ivert][iface] = temp;
3819  }
3820 
3821  for ( j = 0; j < 2; j++ ) {
3822  temp = vertex_tex_uv[j][ivert][iface];
3823  vertex_tex_uv[j][ivert][iface] = vertex_tex_uv[j][m-1-ivert][iface];
3824  vertex_tex_uv[j][m-1-ivert][iface] = temp;
3825  }
3826 
3827  }
3828 
3829  }
3830 
3831  for ( i = 0; i < cor3_num; i++ ) {
3832  for ( j = 0; j < 3; j++ ) {
3833  cor3_normal[j][i] = - cor3_normal[j][i];
3834  }
3835  }
3836 
3837  for ( i = 0; i < face_num; i++ ) {
3838  for ( j = 0; j < 3; j++ ) {
3839  face_normal[j][i] = - face_normal[j][i];
3840  }
3841  }
3842 
3843  printf ( "\n" );
3844  printf ( "FACE_REVERSE_ORDER\n" );
3845  printf ( " Each list of nodes defining a face\n" );
3846  printf ( " has been reversed; related information,\n" );
3847  printf ( " including normal vectors, was also updated.\n" );
3848 
3849  return;
3850 }
3851 
3852 /******************************************************************************/
3853 
3854 int face_subset ( void )
3855 
3856 /******************************************************************************/
3857 
3858 /*
3859  Purpose:
3860 
3861  FACE_SUBSET selects a subset of the current faces as the new object.
3862 
3863  Warning:
3864 
3865  The original graphic object is overwritten by the new one.
3866 
3867  Modified:
3868 
3869  12 October 1998
3870 
3871  Author:
3872 
3873  John Burkardt
3874 
3875 */
3876 {
3877  int i;
3878  int iface;
3879  int iface1;
3880  int iface2;
3881  int inc;
3882  int ivert;
3883  int j;
3884  int k;
3885  int cor3_num2;
3886 
3887  line_num = 0;
3888 /*
3889  Get the first and last faces to save, IFACE1 and IFACE2.
3890 */
3891  printf ( "\n" );
3892  printf ( "Enter lowest face number to save between 0 and %d:\n", face_num-1 );
3893  scanf ( "%d", &iface1 );
3894  if ( iface1 < 0 || iface1 > face_num - 1 ) {
3895  printf ( "Illegal choice!\n" );
3896  return ERROR;
3897  }
3898 
3899  printf ( "\n" );
3900  printf ( "Enter highest face number to save between %d and %d:\n",
3901  iface1, face_num-1 );
3902  scanf ( "%d", &iface2 );
3903  if ( iface2 < iface1 || iface2 > face_num - 1 ) {
3904  printf ( "Illegal choice!\n" );
3905  return ERROR;
3906  }
3907 
3908  inc = iface1;
3909 /*
3910  "Slide" the data for the saved faces down the face arrays.
3911 */
3912  for ( iface = 0; iface < iface2 + 1 - iface1; iface++ ) {
3913  face_order[iface] = face_order[iface+inc];
3914  for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) {
3915  face[ivert][iface] = face[ivert][iface+inc];
3916  vertex_material[ivert][iface] = vertex_material[ivert][iface+inc];
3917  for ( i = 0; i < 3; i++ ) {
3918  vertex_normal[i][ivert][iface] =
3919  vertex_normal[i][ivert][iface+inc];
3920  vertex_rgb[i][ivert][iface] = vertex_rgb[i][ivert][iface+inc];
3921  }
3922  }
3923  for ( i = 0; i < 3; i++ ) {
3924  face_normal[i][iface] = face_normal[i][iface+inc];
3925  }
3926  }
3927 /*
3928  Now reset the number of faces.
3929 */
3930  face_num = iface2 + 1 - iface1;
3931 /*
3932  Now, for each point I, set LIST(I) = J if point I is the J-th
3933  point we are going to save, and 0 otherwise. Then J will be
3934  the new label of point I.
3935 */
3936  for ( i = 0; i < cor3_num; i++ ) {
3937  list[i] = -1;
3938  }
3939 
3940  cor3_num2 = 0;
3941 
3942  for ( iface = 0; iface < face_num; iface++ ){
3943  for ( ivert = 0; ivert < face_order[iface]; ivert++ ){
3944  j = face[ivert][iface];
3945  if ( list[j] == -1 ) {
3946  cor3_num2 = cor3_num2 + 1;
3947  list[j] = cor3_num2;
3948  }
3949  }
3950  }
3951 /*
3952  Now make the nonzero list entries rise in order, so that
3953  we can compress the COR3 data in a minute.
3954 */
3955  cor3_num2 = 0;
3956 
3957  for ( i = 0; i < cor3_num; i++ ) {
3958  if ( list[i] != -1 ) {
3959  list[i] = cor3_num2;
3960  cor3_num2 = cor3_num2 + 1;
3961  }
3962  }
3963 /*
3964  Relabel the FACE array with the new node indices.
3965 */
3966  for ( iface = 0; iface < face_num; iface++ ){
3967  for ( ivert = 0; ivert < face_order[iface]; ivert++ ){
3968  j = face[ivert][iface];
3969  face[ivert][iface] = list[j];
3970  }
3971  }
3972 /*
3973  Rebuild the COR3 array by sliding data down.
3974 */
3975  for ( i = 0; i < cor3_num; i++ ){
3976  k = list[i];
3977  if ( k != -1 ) {
3978  for ( j = 0; j < 3; j++ ) {
3979  cor3[j][k] = cor3[j][i];
3980  }
3981  }
3982  }
3983 
3984  cor3_num = cor3_num2;
3985 
3986  return SUCCESS;
3987 }
3988 /**********************************************************************/
3989 
3990 void face_to_line ( void )
3991 
3992 /**********************************************************************/
3993 
3994 /*
3995  Purpose:
3996 
3997  FACE_TO_LINE converts face information to line information.
3998 
3999  Discussion:
4000 
4001  In some cases, the graphic information represented by polygonal faces
4002  must be converted to a representation based solely on line segments.
4003  This is particularly true if a VLA file is being written.
4004 
4005  Modified:
4006 
4007  26 May 1999
4008 
4009  Author:
4010 
4011  John Burkardt
4012 */
4013 {
4014  int icor3;
4015  int iface;
4016  int ivert;
4017  int jcor3;
4018  int jvert;
4019 /*
4020  Case 0:
4021  No line pruning.
4022 */
4023  if ( line_prune == 0 ) {
4024 
4025  for ( iface = 0; iface < face_num; iface++ ) {
4026 
4027  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
4028 
4029  icor3 = face[ivert][iface];
4030 
4031  line_num = line_num + 1;
4032  if ( line_num <= LINES_MAX ) {
4033  line_dex[line_num] = icor3;
4034  line_material[line_num] = vertex_material[ivert][iface];
4035  }
4036  }
4037 
4038  ivert = 0;
4039  icor3 = face[ivert][iface];
4040 
4041  line_num = line_num + 1;
4042  if ( line_num <= LINES_MAX ) {
4043  line_dex[line_num] = icor3;
4044  line_material[line_num] = vertex_material[ivert][iface];
4045  }
4046 
4047  line_num = line_num + 1;
4048  if ( line_num <= LINES_MAX ) {
4049  line_dex[line_num] = -1;
4050  line_material[line_num] = -1;
4051  }
4052  }
4053 
4054  }
4055 /*
4056  Case 2:
4057  Simple-minded line pruning.
4058  Only draw line (I,J) if I < J.
4059 */
4060  else {
4061 
4062  for ( iface = 0; iface < face_num; iface++ ) {
4063 
4064  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
4065 
4066  icor3 = face[ivert][iface];
4067 
4068  if ( ivert + 1 < face_order[iface] ) {
4069  jvert = ivert + 1;
4070  }
4071  else {
4072  jvert = 0;
4073  }
4074 
4075  jcor3 = face[jvert][iface];
4076 
4077  if ( icor3 < jcor3 ) {
4078 
4079  if ( line_num + 3 < LINES_MAX ) {
4080 
4081  line_num = line_num + 1;
4082  line_dex[line_num] = icor3;
4083  line_material[line_num] = vertex_material[ivert][iface];
4084 
4085  line_num = line_num + 1;
4086  line_dex[line_num] = jcor3;
4087  line_material[line_num] = vertex_material[jvert][iface];
4088 
4089  line_num = line_num + 1;
4090  line_dex[line_num] = -1;
4091  line_material[line_num] = -1;
4092 
4093  }
4094  }
4095  }
4096  }
4097 
4098  }
4099 
4100  return;
4101 }
4102 /**********************************************************************/
4103 
4105 
4106 /**********************************************************************/
4107 
4108 /*
4109  Purpose:
4110 
4111  FACE_TO_VERTEX_MAT extends face material definitions to vertices.
4112 
4113  Discussion:
4114 
4115  Assuming material indices are defined for all the faces, this
4116  routine assigns to each vertex of a face the material of that face.
4117 
4118  Modified:
4119 
4120  22 May 1999
4121 
4122  Author:
4123 
4124  John Burkardt
4125 */
4126 {
4127  int iface;
4128  int ivert;
4129 
4130  for ( iface = 0; iface < face_num; iface++ ) {
4131  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
4132  vertex_material[ivert][iface] = face_material[iface];
4133  }
4134  }
4135 
4136  return;
4137 }
4138 /******************************************************************************/
4139 
4140 char *file_ext ( char *file_name )
4141 
4142 /******************************************************************************/
4143 
4144 /*
4145  Purpose:
4146 
4147  FILE_EXT picks out the extension in a file name.
4148 
4149  Modified:
4150 
4151  21 July 1998
4152 
4153  Author:
4154 
4155  John Burkardt
4156 */
4157 {
4158  int i;
4159 
4160  i = char_index_last ( file_name, '.' );
4161 
4162  if ( i == -1 ) {
4163  return NULL;
4164  }
4165  else {
4166  return file_name + i + 1;
4167  }
4168 }
4169 /******************************************************************************/
4170 
4171 float float_read ( FILE *filein )
4172 
4173 /******************************************************************************/
4174 
4175 /*
4176  Purpose:
4177 
4178  FLOAT_READ reads 1 float from a binary file.
4179 
4180  Modified:
4181 
4182  24 May 1999
4183 */
4184 {
4185  float rval;
4186  float temp;
4187 
4188  fread ( &temp, sizeof ( float ), 1, filein );
4189 
4190  if ( byte_swap == TRUE ) {
4191  rval = float_reverse_bytes ( temp );
4192  }
4193  else {
4194  rval = temp;
4195  }
4196 
4197  return rval;
4198 }
4199 /******************************************************************************/
4200 
4201 float float_reverse_bytes ( float x )
4202 
4203 /******************************************************************************/
4204 
4205 /*
4206  Purpose:
4207 
4208  FLOAT_REVERSE_BYTES reverses the four bytes in a float.
4209 
4210  Modified:
4211 
4212  24 May 1999
4213 
4214  Author:
4215 
4216  John Burkardt
4217 
4218  Parameters:
4219 
4220  X, a float whose bytes are to be reversed.
4221 
4222  FLOAT_REVERSE_BYTES, a float with bytes in reverse order from those in X.
4223 */
4224 {
4225  char c;
4226  union {
4227  float yfloat;
4228  char ychar[4];
4229  } y;
4230 
4231  y.yfloat = x;
4232 
4233  c = y.ychar[0];
4234  y.ychar[0] = y.ychar[3];
4235  y.ychar[3] = c;
4236 
4237  c = y.ychar[1];
4238  y.ychar[1] = y.ychar[2];
4239  y.ychar[2] = c;
4240 
4241  return ( y.yfloat );
4242 }
4243 /******************************************************************************/
4244 
4245 int float_write ( FILE *fileout, float float_val )
4246 
4247 /******************************************************************************/
4248 
4249 /*
4250  Purpose:
4251 
4252  FLOAT_WRITE writes 1 float to a binary file.
4253 
4254  Modified:
4255 
4256  23 September 1998
4257 */
4258 {
4259  int nbyte = sizeof ( float );
4260  float temp;
4261 
4262  if ( byte_swap == TRUE ) {
4263  temp = float_reverse_bytes ( float_val );
4264  }
4265  else {
4266  temp = float_val;
4267  }
4268 
4269  fwrite ( &temp, nbyte, 1, fileout );
4270 
4271  return nbyte;
4272 }
4273 /******************************************************************************/
4274 
4275 int gmod_arch_check ( void )
4276 
4277 /******************************************************************************/
4278 
4279 /*
4280  Purpose:
4281 
4282  GMOD_ARCH_CHECK inquires into some features of the computer architecture.
4283 
4284  Modified:
4285 
4286  19 May 1999
4287 
4288  Author:
4289 
4290  Zik Saleeba (zik@zikzak.net)
4291 */
4292 {
4293  static unsigned char one[4];
4294  int temp;
4295 
4296  temp = sizeof ( float );
4297  if ( temp != 4 ) {
4298  return FALSE;
4299  }
4300 
4301  *(float *)one = 1.0;
4302 
4303  if (one[0] == 0 && one[1] == 0 && one[2] == 128 && one[3] == 63) {
4304  /* little endian IEEE floats */
4305  return TRUE;
4306  }
4307 
4308  if (one[0] == 63 && one[1] == 128 && one[2] == 0 && one[3] == 0) {
4309  /* big endian IEEE floats */
4310  return TRUE;
4311  }
4312 
4313  return FALSE;
4314 }
4315 /******************************************************************************/
4316 
4317 int gmod_read ( FILE *filein )
4318 
4319 /******************************************************************************/
4320 
4321 /*
4322  Purpose:
4323 
4324  GMOD_READ reads a golgotha GMOD file.
4325 
4326  Modified:
4327 
4328  19 May 1999
4329 
4330  Author:
4331 
4332  Zik Saleeba (zik@zikzak.net)
4333 */
4334 
4335 /*
4336 golgotha GMOD file format:
4337 
4338 
4339  FILE HEADER
4340 
4341 w32 magic number f9 fa 63 1e
4342 w32 number of sections
4343 [ number of sections
4344  w32 section id
4345  w32 section offset
4346 ]
4347 
4348 
4349  TEXTURE NAME SECTION - section id = 0x13 (19)
4350 
4351 w16 number of faces
4352 [ number of faces
4353  w16 texture name length
4354  [ texture name length
4355  w8 texture name character
4356  ]
4357 ]
4358 
4359 
4360 
4361  MODEL QUADS SECTION - section id = 0x12 (18)
4362 
4363 w16 number of faces
4364 [ number of faces
4365  [ four vertices
4366  w16 vertex index
4367  float xpos (0.0-1.0)
4368  float ypos (0.0-1.0)
4369  ]
4370  float scale
4371  w16 flags
4372  float xnormal (normal should be normalised)
4373  float ynormal
4374  float znormal
4375 ]
4376 
4377 
4378  VERTEX ARRAY SECTION - section id = 0x14 (20)
4379 
4380 w16 number of vertices
4381 w16 number of animations
4382 w16 length of animation name
4383 [ length of animation name
4384  w8 animation name character
4385 ]
4386 w16 number of frames in animation
4387 [ number of frames in animation
4388  [ number of vertices
4389  float xpos
4390  float ypos
4391  float zpos
4392  float xnormal
4393  float ynormal
4394  float znormal
4395  ]
4396 ]
4397 */
4398 {
4399  unsigned char MagicNumber[4];
4400  unsigned long int NumSections;
4401  int SectionCount;
4402  unsigned long int SectionID[GMOD_MAX_SECTIONS];
4403  unsigned long int SectionOffset[GMOD_MAX_SECTIONS];
4404 
4405  unsigned short NumAnimations;
4406  unsigned short NumFrames;
4407  unsigned short FaceCount;
4408  unsigned short TextureCount;
4409  int VertexCount;
4410 
4411  float Scale;
4412  unsigned short Flags;
4413  unsigned short TextureNameLen;
4414  unsigned short AnimationNameLen;
4415  int Order;
4416  int MaxCor = 0;
4417 
4418  /*
4419  * check if we can handle this architecture
4420  */
4421 
4422  if (!gmod_arch_check()) {
4423  printf("GMOD_READ - This architecture not supported.\n");
4424  return ERROR;
4425  }
4426 
4427  /*
4428  * read the file header
4429  */
4430 
4431  /* read the magic number */
4432  fread(MagicNumber, 1, 4, filein);
4433  if (MagicNumber[0] != 0xf9 ||
4434  MagicNumber[1] != 0xfa ||
4435  MagicNumber[2] != 0x63 ||
4436  MagicNumber[3] != 0x1e) {
4437  printf("GMOD_READ - Bad magic number on GMOD file.\n");
4438  return ERROR;
4439  }
4440 
4441  NumSections = gmod_read_w32(filein);
4442  if (NumSections >= GMOD_MAX_SECTIONS) {
4443  printf("GMOD_READ - Too many sections (%ld) in GMOD file - please increase static limit GMOD_MAX_SECTIONS\n", NumSections);
4444  return ERROR;
4445  }
4446 
4447 /*
4448  Read the sections.
4449 */
4450 
4451  for ( SectionCount = 0; SectionCount < ( int ) NumSections; SectionCount++ ) {
4452  SectionID[SectionCount] = gmod_read_w32(filein);
4453  SectionOffset[SectionCount] = gmod_read_w32(filein);
4454  }
4455 /*
4456  Read each successive section.
4457 */
4458  for ( SectionCount = 0; SectionCount < ( int ) NumSections; SectionCount++ ) {
4459 /*
4460  Go to the start of the section.
4461 */
4462  fseek ( filein, ( long int ) SectionOffset[SectionCount], SEEK_SET );
4463 /*
4464  What type of section is it?
4465 */
4466  switch (SectionID[SectionCount]) {
4467 
4468 /*
4469  Model section.
4470 */
4472 /*
4473  Get the number of faces.
4474 */
4475  face_num = gmod_read_w16 ( filein );
4476 
4477  if (face_num > FACE_MAX) {
4478  printf("GMOD_READ - Too many faces (%d) in GMOD file - please increase static limit FACE_MAX.\n", face_num);
4479  return ERROR;
4480  }
4481 /*
4482  Get the information on each face.
4483 */
4484  for ( FaceCount = 0; FaceCount < ( unsigned short ) face_num; FaceCount++ ) {
4485 
4486  Order = 0;
4487  for ( VertexCount = 0; VertexCount < 4; VertexCount++ ) {
4488 
4489  /* read the vertex index */
4490 
4491  face[VertexCount][FaceCount] = gmod_read_w16(filein);
4492 
4493  if (face[VertexCount][FaceCount] != GMOD_UNUSED_VERTEX) {
4494  Order = VertexCount+1;
4495  if (MaxCor < face[VertexCount][FaceCount])
4496  MaxCor = face[VertexCount][FaceCount];
4497  }
4498 
4499  /* read the texture position */
4500 
4501  vertex_tex_uv[0][VertexCount][FaceCount] = gmod_read_float(filein);
4502  vertex_tex_uv[1][VertexCount][FaceCount] = gmod_read_float(filein);
4503  }
4504 
4505  /* scale and flags */
4506 
4507  fread(&Scale, sizeof(Scale), 1, filein);
4508  Flags = gmod_read_w16(filein);
4509 
4510  if ( debug ) {
4511  printf ( "Flags = %d\n", Flags );
4512  }
4513 
4514  /* normal vector */
4515 
4516  face_normal[0][FaceCount] = gmod_read_float(filein);
4517  face_normal[1][FaceCount] = gmod_read_float(filein);
4518  face_normal[2][FaceCount] = gmod_read_float(filein);
4519 
4520  /* the order is the number of used vertices */
4521 
4522  face_order[FaceCount] = Order;
4523  }
4524  break;
4525 
4526 
4527 /*
4528  Texture name section.
4529 */
4530 
4532 
4533  /* get the number of textures */
4534 
4535  texture_num = gmod_read_w16(filein);
4536  if (texture_num > TEXTURE_MAX) {
4537  printf ( "GMOD_READ - Too many texture maps (%d) in GMOD file.\n", texture_num );
4538  printf ( " Increase static limit TEXTURE_MAX.\n" );
4539  return ERROR;
4540  }
4542 
4543  for (TextureCount = 0; TextureCount < ( unsigned short ) texture_num;
4544  TextureCount++) {
4545 
4546  /* read the texture name */
4547 
4548  TextureNameLen = gmod_read_w16(filein);
4549  fread ( texture_name[TextureCount], sizeof(char), TextureNameLen, filein);
4550  texture_name[TextureCount][TextureNameLen] = '\0';
4551  }
4552  break;
4553 
4554 
4555  /*
4556  * vertex section
4557  */
4558 
4560 
4561  /* get the number of vertices */
4562 
4563  cor3_num = gmod_read_w16(filein);
4564  if (cor3_num > COR3_MAX) {
4565  printf("GMOD_READ - Too many vertices (%d) in GMOD file - please increase static limit COR3_MAX.\n", cor3_num);
4566  return ERROR;
4567  }
4568 
4569 /*
4570  Get the number of animations.
4571 */
4572 
4573  NumAnimations = gmod_read_w16(filein);
4574 
4575  if (NumAnimations > 1) {
4576  printf ( "GMOD_READ - Fatal error!\n" );
4577  printf ( " GMOD files can only handle one animation.\n" );
4578  printf ( " This file contains %d.\n", NumAnimations );
4579  return ERROR;
4580  }
4581 
4582  /* read the animation name */
4583  AnimationNameLen = gmod_read_w16(filein);
4584  fread ( anim_name, sizeof(char), AnimationNameLen, filein);
4585  anim_name[AnimationNameLen] = '\0';
4586 
4587  /* get the number of frames of animation */
4588  NumFrames = gmod_read_w16(filein);
4589  if (NumFrames > 1)
4590  printf("GMOD_READ - Too many frames of animation (%d) in GMOD file - will only use 1.\n", NumFrames);
4591 
4592  /* go through all the vertices, reading each one */
4593  for (VertexCount = 0; VertexCount < cor3_num; VertexCount++) {
4594 
4595  /* read the vertex */
4596  cor3[0][VertexCount] = gmod_read_float(filein);
4597  cor3[1][VertexCount] = gmod_read_float(filein);
4598  cor3[2][VertexCount] = gmod_read_float(filein);
4599 
4600  /* read the normal */
4601  cor3_normal[0][VertexCount] = gmod_read_float(filein);
4602  cor3_normal[1][VertexCount] = gmod_read_float(filein);
4603  cor3_normal[2][VertexCount] = gmod_read_float(filein);
4604  }
4605  break;
4606 
4607  default:
4608  continue;
4609  }
4610  }
4611 
4612 /*
4613  Set some other stray info.
4614 */
4615  line_num = 0;
4616 
4617 /*
4618  Check for sanity.
4619 */
4620  if ( MaxCor >= cor3_num ) {
4621  printf ( "GMOD_READ - Maximum coordinate index (%d)\n", MaxCor );
4622  printf ( " exceeded number of coordinates (%d) in GMOD file.\n", cor3_num );
4623  return ERROR;
4624  }
4625 
4626  return SUCCESS;
4627 }
4628 /******************************************************************************/
4629 
4630 float gmod_read_float ( FILE *filein )
4631 
4632 /******************************************************************************/
4633 
4634 /*
4635  Purpose:
4636 
4637  GMOD_READ_FLOAT reads a float from a Golgotha GMOD file.
4638 
4639  Modified:
4640 
4641  19 May 1999
4642 
4643  Author:
4644 
4645  Zik Saleeba (zik@zikzak.net)
4646 */
4647 {
4648  int endian = 1;
4649  unsigned char *out_pos;
4650  int i;
4651  float Val;
4652 
4653  if (*(char *)&endian == 1) {
4654  /* we're little-endian, which is native for GMOD floats */
4655  fread(&Val, sizeof(Val), 1, filein);
4656  }
4657  else {
4658  /* we're big-endian, flip `em */
4659  out_pos = (unsigned char *)&Val;
4660  for ( i = sizeof(Val)-1; i >= 0; i-- ) {
4661  *(out_pos+i) = fgetc(filein);
4662  }
4663  }
4664 
4665  return Val;
4666 }
4667 /******************************************************************************/
4668 
4669 unsigned short gmod_read_w16 ( FILE *filein )
4670 
4671 /******************************************************************************/
4672 
4673 /*
4674  Purpose:
4675 
4676  GMOD_READ_W16 reads a 16 bit word from a Golgotha GMOD file.
4677 
4678  Modified:
4679 
4680  19 May 1999
4681 
4682  Author:
4683 
4684  Zik Saleeba (zik@zikzak.net)
4685 */
4686 {
4687  unsigned char Byte1;
4688  unsigned char Byte2;
4689 
4690  Byte1 = fgetc ( filein );
4691  Byte2 = fgetc ( filein );
4692 
4693  return Byte1 | (((unsigned short)Byte2) << 8);
4694 }
4695 /******************************************************************************/
4696 
4697 unsigned long gmod_read_w32 ( FILE *filein )
4698 
4699 /******************************************************************************/
4700 
4701 /*
4702  Purpose:
4703 
4704  GMOD_READ_W32 reads a 32 bit word from a Golgotha GMOD file.
4705 
4706  Modified:
4707 
4708  19 May 1999
4709 
4710  Author:
4711 
4712  Zik Saleeba (zik@zikzak.net)
4713 */
4714 {
4715  unsigned char Byte1, Byte2, Byte3, Byte4;
4716 
4717  Byte1 = fgetc(filein);
4718  Byte2 = fgetc(filein);
4719  Byte3 = fgetc(filein);
4720  Byte4 = fgetc(filein);
4721 
4722  return Byte1 |
4723  (((unsigned long)Byte2) << 8) |
4724  (((unsigned long)Byte3) << 16) |
4725  (((unsigned long)Byte4) << 24);
4726 }
4727 
4728 /******************************************************************************/
4729 
4730 int gmod_write ( FILE *fileout ) {
4731 
4732 /******************************************************************************/
4733 
4734 /*
4735  Purpose:
4736 
4737  GMOD_WRITE writes a Golgotha GMOD file.
4738 
4739  Modified:
4740 
4741  19 May 1999
4742 
4743  Author:
4744 
4745  Zik Saleeba (zik@zikzak.net)
4746 */
4747  static unsigned char MagicNumber[4] = { 0xf9, 0xfa, 0x63, 0x1e };
4748  unsigned long NumSections;
4749  unsigned long SectionHeaderPos;
4750  unsigned long TextureNameSectionPos;
4751  unsigned long ModelSectionPos;
4752  unsigned long VertexSectionPos;
4753 
4754  int VertexCount;
4755  int FaceCount;
4756  int TextureCount;
4757  unsigned long SectionCount;
4758  float Scale;
4759  float Min[3];
4760  float Max[3];
4761  int CorNumber;
4762  int DimensionCount;
4763  float MaxWidth;
4764 /*
4765  Check if we can handle this architecture.
4766 */
4767 
4768  if ( !gmod_arch_check() ) {
4769  printf("GMOD_WRITE - This architecture not supported.\n");
4770  return ERROR;
4771  }
4772 
4773 /*
4774  Write the file header.
4775 */
4776 
4777 /*
4778  Write the magic number.
4779 */
4780  fwrite ( MagicNumber, sizeof(char), 4, fileout );
4781 
4782 /*
4783  Write the number of sections.
4784 */
4785  NumSections = 3;
4786  gmod_write_w32 ( NumSections, fileout );
4787 
4788 /*
4789  Write a dummy section header which we'll overwrite later.
4790 */
4791  SectionHeaderPos = ftell ( fileout );
4792  for (SectionCount = 0; SectionCount < NumSections; SectionCount++) {
4793  gmod_write_w32 ( 0, fileout );
4794  gmod_write_w32 ( 0, fileout );
4795  }
4796 /*
4797  Texture name section.
4798 */
4799 
4800 /*
4801  Take note of where we are in the file.
4802 */
4803  TextureNameSectionPos = ftell ( fileout );
4804 
4805 /*
4806  Write the number of textures.
4807 */
4808 
4809  gmod_write_w16 ( ( unsigned short ) face_num, fileout );
4810 /*
4811  Write the texture names.
4812 */
4813  for ( TextureCount = 0; TextureCount < face_num; TextureCount++ ) {
4814 
4815  gmod_write_w16 ( ( unsigned short ) strlen ( texture_name[TextureCount] ),
4816  fileout );
4817 
4818  fwrite ( texture_name[TextureCount], strlen ( texture_name[TextureCount] ),
4819  1, fileout );
4820  }
4821 
4822 /*
4823  Model section.
4824 */
4825 
4826 /*
4827  Take note of where we are in the file.
4828 */
4829 
4830  ModelSectionPos = ftell(fileout);
4831 
4832 /*
4833  Write the number of faces.
4834 */
4835 
4836  gmod_write_w16 ( ( unsigned short ) face_num, fileout );
4837 
4838 /*
4839  Write the information on each face.
4840 */
4841 
4842  for ( FaceCount = 0; FaceCount < face_num; FaceCount++ ) {
4843 
4844  for (VertexCount = 0; VertexCount < ((face_order[FaceCount] < 4) ? face_order[FaceCount] : 4); VertexCount++) {
4845 
4846 /*
4847  Write the vertex index.
4848 */
4849  gmod_write_w16 ( ( unsigned short ) face[VertexCount][FaceCount], fileout );
4850 
4851 /*
4852  Write the texture position.
4853 */
4854 
4855  gmod_write_float ( vertex_tex_uv[0][VertexCount][FaceCount], fileout );
4856  gmod_write_float ( vertex_tex_uv[1][VertexCount][FaceCount], fileout );
4857  }
4858 
4859 /*
4860  Write any extra vertices which are unused.
4861 */
4862 
4863  for ( ; VertexCount < 4; VertexCount++ ) {
4864 
4865 /*
4866  Write the vertex index.
4867 */
4868  gmod_write_w16 ( GMOD_UNUSED_VERTEX, fileout );
4869 /*
4870  Write the texture position.
4871 */
4872  gmod_write_float ( vertex_tex_uv[0][VertexCount][FaceCount], fileout );
4873 
4874  gmod_write_float ( vertex_tex_uv[1][VertexCount][FaceCount], fileout );
4875  }
4876 
4877 /*
4878  Scale and flags.
4879 */
4880 
4881 /*
4882  Find the bounding box.
4883 */
4884 
4885  for ( DimensionCount = 0; DimensionCount < 3; DimensionCount++ ) {
4886 
4887  CorNumber = face[0][FaceCount];
4888  Min[DimensionCount] = cor3[DimensionCount][CorNumber];
4889  Max[DimensionCount] = cor3[DimensionCount][CorNumber];
4890 
4891  for (VertexCount = 1; VertexCount < ((face_order[FaceCount] < 4) ? face_order[FaceCount] : 4); VertexCount++) {
4892 
4893  CorNumber = face[VertexCount][FaceCount];
4894 
4895  if (Min[DimensionCount] > cor3[DimensionCount][CorNumber])
4896  Min[DimensionCount] = cor3[DimensionCount][CorNumber];
4897 
4898  if (Max[DimensionCount] < cor3[DimensionCount][CorNumber])
4899  Max[DimensionCount] = cor3[DimensionCount][CorNumber];
4900  }
4901  }
4902 
4903 /*
4904  The scale is the "width" of the face for mipmapping -
4905  I just take the maximum bounding box dimension.
4906 */
4907  MaxWidth = Max[0] - Min[0];
4908  for ( DimensionCount = 1; DimensionCount < 3; DimensionCount++ ) {
4909 
4910  if ( MaxWidth < Max[DimensionCount] - Min[DimensionCount] )
4911  MaxWidth = Max[DimensionCount] - Min[DimensionCount];
4912  }
4913 
4914  Scale = MaxWidth;
4915  fwrite ( &Scale, sizeof(Scale), 1, fileout );
4916 
4917 /*
4918  Flags are just nothing.
4919 */
4920  gmod_write_w16 ( 0, fileout );
4921 /*
4922  Normal vector.
4923 */
4924  gmod_write_float ( face_normal[0][FaceCount], fileout );
4925  gmod_write_float ( face_normal[1][FaceCount], fileout );
4926  gmod_write_float ( face_normal[2][FaceCount], fileout );
4927  }
4928 
4929 /*
4930  Vertex section.
4931 */
4932 
4933 /*
4934  Take note of where we are in the file.
4935 */
4936 
4937  VertexSectionPos = ftell ( fileout );
4938 
4939 /*
4940  Write the number of vertices.
4941 */
4942 
4943  gmod_write_w16 ( ( unsigned short ) cor3_num, fileout );
4944 
4945 /*
4946  Write the number of animations.
4947 */
4948 
4949  gmod_write_w16 ( 1, fileout );
4950 
4951 /*
4952  Write the animation name.
4953 */
4954 
4955  gmod_write_w16 ( 0, fileout );
4956 
4957 /*
4958  Write the number of frames of animation.
4959 */
4960 
4961  gmod_write_w16 ( 1, fileout );
4962 
4963 /*
4964  Go through all the vertices, writing each one.
4965 */
4966 
4967  for ( VertexCount = 0; VertexCount < cor3_num; VertexCount++ ) {
4968 
4969 /*
4970  Write the vertex.
4971 */
4972  gmod_write_float ( cor3[0][VertexCount], fileout );
4973  gmod_write_float ( cor3[1][VertexCount], fileout );
4974  gmod_write_float ( cor3[2][VertexCount], fileout );
4975 
4976 /*
4977  Write the normal.
4978 */
4979  gmod_write_float ( cor3_normal[0][VertexCount], fileout );
4980  gmod_write_float ( cor3_normal[1][VertexCount], fileout );
4981  gmod_write_float ( cor3_normal[2][VertexCount], fileout );
4982  }
4983 /*
4984  Now rewrite the section header.
4985 */
4986 
4987 /*
4988  Go back to the section header.
4989 */
4990  fseek ( fileout, ( long int ) SectionHeaderPos, SEEK_SET );
4991 
4992 /*
4993  Write the texture name section header.
4994 */
4996  gmod_write_w32 ( TextureNameSectionPos, fileout );
4997 
4998 /*
4999  Write the model section header.
5000 */
5002  gmod_write_w32 ( ModelSectionPos, fileout );
5003 
5004 /*
5005  Write the vertex section header.
5006 */
5008  gmod_write_w32 ( VertexSectionPos, fileout );
5009 
5010  return SUCCESS;
5011 }
5012 
5013 /******************************************************************************/
5014 
5015 void gmod_write_float ( float Val, FILE *fileout )
5016 
5017 /******************************************************************************/
5018 
5019 /*
5020  Purpose:
5021 
5022  GMOD_WRITE_FLOAT writes a float to a Golgotha GMOD file.
5023 
5024  Modified:
5025 
5026  19 May 1999
5027 
5028  Author:
5029 
5030  Zik Saleeba (zik@zikzak.net)
5031 */
5032 {
5033  int endian = 1;
5034  unsigned char *out_pos;
5035  int i;
5036 
5037  if (*(char *)&endian == 1) {
5038  /* we're little-endian, which is native for GMOD floats */
5039  fwrite ( &Val, sizeof(Val), 1, fileout );
5040  }
5041  else {
5042  /* we're big-endian, flip `em */
5043  out_pos = (unsigned char *)&Val;
5044  for ( i = sizeof(Val)-1; i >= 0; i-- ) {
5045  fputc(*(out_pos+i), fileout);
5046  }
5047  }
5048 }
5049 /******************************************************************************/
5050 
5051 void gmod_write_w16 ( unsigned short Val, FILE *fileout )
5052 
5053 /******************************************************************************/
5054 
5055 /*
5056  Purpose:
5057 
5058  GMOD_WRITE_W16 writes a 16 bit word to a Golgotha GMOD file.
5059 
5060  Modified:
5061 
5062  13 September 2000
5063 
5064  Author:
5065 
5066  Zik Saleeba (zik@zikzak.net)
5067 */
5068 {
5069  unsigned char OutByte[2];
5070 
5071  OutByte[0] = (unsigned char)(Val & 0xff);
5072  OutByte[1] = (unsigned char)(Val >> 8);
5073 
5074  fwrite ( OutByte, sizeof(unsigned char), 2, fileout );
5075 }
5076 /******************************************************************************/
5077 
5078 void gmod_write_w32 ( unsigned long Val, FILE *fileout )
5079 
5080 /******************************************************************************/
5081 
5082 /*
5083  Purpose:
5084 
5085  GMOD_WRITE writes a 32 bit word to a Golgotha GMOD file.
5086 
5087  Modified:
5088 
5089  19 May 1999
5090 
5091  Author:
5092 
5093  Zik Saleeba (zik@zikzak.net)
5094 */
5095 {
5096  unsigned char OutByte[4];
5097 
5098  OutByte[0] = (unsigned char)(Val & 0xff);
5099  OutByte[1] = (unsigned char)((Val >> 8) & 0xff);
5100  OutByte[2] = (unsigned char)((Val >> 16) & 0xff);
5101  OutByte[3] = (unsigned char)((Val >> 24) & 0xff);
5102 
5103  fwrite ( OutByte, sizeof(unsigned char), 4, fileout );
5104 }
5105 
5106 /******************************************************************************/
5107 
5108 void hello ( void )
5109 
5110 /******************************************************************************/
5111 /*
5112  Purpose:
5113 
5114  HELLO prints an explanatory header message.
5115 
5116  Modified:
5117 
5118  04 July 2000
5119 
5120  Author:
5121 
5122  John Burkardt
5123 */
5124 {
5125  printf ( "\n" );
5126  printf ( "Hello: This is IVCON,\n" );
5127  printf ( " for 3D graphics file conversion.\n" );
5128  printf ( "\n" );
5129  printf ( " \".3ds\" 3D Studio Max binary;\n" );
5130  printf ( " \".ase\" 3D Studio Max ASCII export;\n" );
5131  printf ( " \".byu\" Movie.BYU surface geometry;\n" );
5132  printf ( " \".dxf\" DXF;\n" );
5133  printf ( " \".gmod\" Golgotha model;\n" );
5134  printf ( " \".hrc\" SoftImage hierarchy;\n" );
5135  printf ( " \".iv\" SGI Open Inventor;\n" );
5136  printf ( " \".obj\" WaveFront Advanced Visualizer;\n" );
5137  printf ( " \".pov\" Persistence of Vision (output only);\n" );
5138  printf ( " \".smf\" Michael Garland's format;\n" );
5139  printf ( " \".stl\" ASCII StereoLithography;\n" );
5140  printf ( " \".stla\" ASCII StereoLithography;\n" );
5141  printf ( " \".stlb\" Binary StereoLithography;\n" );
5142  printf ( " \".tec\" TECPLOT (output only);\n" );
5143  printf ( " \".tri\" [Greg Hood ASCII triangle format];\n" );
5144  printf ( " \".tria\" [Greg Hood ASCII triangle format];\n" );
5145  printf ( " \".trib\" [Greg Hood binary triangle format];\n" );
5146  printf ( " \".txt\" Text (output only);\n" );
5147  printf ( " \".ucd\" AVS UCD file(output only);\n" );
5148  printf ( " \".vla\" VLA;\n" );
5149  printf ( " \".wrl\" VRML (Virtual Reality Modeling Language) (output only).\n" );
5150  printf ( " \".xgl\" XML/OpenGL format (output only);\n" );
5151  printf ( "\n" );
5152  printf ( " Current limits include:\n" );
5153  printf ( " %d faces;\n", FACE_MAX );
5154  printf ( " %d line items;\n", LINES_MAX );
5155  printf ( " %d points;\n", COR3_MAX );
5156  printf ( " %d face order;\n", ORDER_MAX );
5157  printf ( " %d materials;\n", MATERIAL_MAX);
5158  printf ( " %d textures.\n", TEXTURE_MAX );
5159  printf ( "\n" );
5160  printf ( " Last modification: 04 July 2000.\n" );
5161  printf ( "\n" );
5162  printf ( " Send problem reports to burkardt@psc.edu.\n" );
5163 
5164  return;
5165 }
5166 /******************************************************************************/
5167 
5168 void help ( void )
5169 
5170 /******************************************************************************/
5171 
5172 /*
5173  Purpose:
5174 
5175  HELP prints a list of the interactive commands.
5176 
5177  Modified:
5178 
5179  26 May 1999
5180 
5181  Author:
5182 
5183  John Burkardt
5184 */
5185 {
5186  printf ( "\n" );
5187  printf ( "Commands:\n" );
5188  printf ( "\n" );
5189  printf ( "< file Read data from input file;\n" );
5190  printf ( "<< file Append data in input file to current data;\n" );
5191  printf ( "> file Write output file;\n" );
5192  printf ( "B Switch the binary file byte-swapping mode;\n" );
5193  printf ( "D Switch the debugging mode;\n" );
5194  printf ( "F Print information about one face;\n" );
5195  printf ( "H Print this help list;\n" );
5196  printf ( "I Info, print out recent changes;\n" );
5197  printf ( "LINES Convert face information to lines;\n" );
5198  printf ( "N Recompute normal vectors;\n" );
5199  printf ( "P Set LINE_PRUNE option.\n" );
5200  printf ( "Q Quit;\n" );
5201  printf ( "R Reverse the normal vectors.\n" );
5202  printf ( "S Select face subset (NOT WORKING).\n" );
5203  printf ( "T Transform the data.\n" );
5204  printf ( "W Reverse the face node ordering.\n" );
5205 
5206  return;
5207 }
5208 /******************************************************************************/
5209 
5210 int hrc_read ( FILE *filein )
5211 
5212 /******************************************************************************/
5213 
5214 /*
5215  Purpose:
5216 
5217  HRC_READ reads graphics information from a SoftImage HRC file.
5218 
5219  Examples:
5220 
5221  HRCH: Softimage 4D Creative Environment v3.00
5222 
5223 
5224  model
5225  {
5226  name "cube_10x10"
5227  scaling 1.000 1.000 1.000
5228  rotation 0.000 0.000 0.000
5229  translation 0.000 0.000 0.000
5230 
5231  mesh
5232  {
5233  flag ( PROCESS )
5234  discontinuity 60.000
5235 
5236  vertices 8
5237  {
5238  [0] position -5.000 -5.000 -5.000
5239  [1] position -5.000 -5.000 5.000
5240  [2] position -5.000 5.000 -5.000
5241  [3] position -5.000 5.000 5.000
5242  [4] position 5.000 -5.000 -5.000
5243  [5] position 5.000 -5.000 5.000
5244  [6] position 5.000 5.000 -5.000
5245  [7] position 5.000 5.000 5.000
5246  }
5247 
5248  polygons 6
5249  {
5250  [0] nodes 4
5251  {
5252  [0] vertex 0
5253  normal -1.000 0.000 0.000
5254  uvTexture 0.000 0.000
5255  vertexColor 255 178 178 178
5256  [1] vertex 1
5257  normal -1.000 0.000 0.000
5258  uvTexture 0.000 0.000
5259  vertexColor 255 178 178 178
5260  [2] vertex 3
5261  normal -1.000 0.000 0.000
5262  uvTexture 0.000 0.000
5263  vertexColor 255 178 178 178
5264  [3] vertex 2
5265  normal -1.000 0.000 0.000
5266  uvTexture 0.000 0.000
5267  vertexColor 255 178 178 178
5268  }
5269  material 0
5270  [1] nodes 4
5271  {
5272  [0] vertex 1
5273  normal 0.000 0.000 1.000
5274  uvTexture 0.000 0.000
5275  vertexColor 255 178 178 178
5276  [1] vertex 5
5277 
5278  ...etc.....
5279 
5280  [5] nodes 4
5281  {
5282  [0] vertex 2
5283  normal 0.000 1.000 0.000
5284  uvTexture 0.000 0.000
5285  vertexColor 255 178 178 178
5286  [1] vertex 3
5287  normal 0.000 1.000 0.000
5288  uvTexture 0.000 0.000
5289  vertexColor 255 178 178 178
5290  [2] vertex 7
5291  normal 0.000 1.000 0.000
5292  uvTexture 0.000 0.000
5293  vertexColor 255 178 178 178
5294  [3] vertex 6
5295  normal 0.000 1.000 0.000
5296  uvTexture 0.000 0.000
5297  vertexColor 255 178 178 178
5298  }
5299  material 0
5300  }
5301 
5302  edges 12
5303  {
5304  [1] vertices 3 2
5305  [2] vertices 2 0
5306  [3] vertices 0 1
5307  [4] vertices 1 3
5308  [5] vertices 7 3
5309  [6] vertices 1 5
5310  [7] vertices 5 7
5311  [8] vertices 6 7
5312  [9] vertices 5 4
5313  [10] vertices 4 6
5314  [11] vertices 2 6
5315  [12] vertices 4 0
5316  }
5317  }
5318 
5319  material [0]
5320  {
5321  name "kazoo"
5322  type PHONG
5323  ambient 0.0 1.0 0.0
5324  diffuse 1.0 0.0 0.0
5325  specular 0.0 0.0 1.0
5326  exponent 50.0
5327  reflectivity 0.0
5328  transparency 0.0
5329  refracIndex 1.0
5330  glow 0
5331  coc 0.0
5332  }
5333 
5334  texture [0]
5335  {
5336  name "/usr/users/foss/HOUSE/PICTURES/mellon"
5337  glbname "t2d1"
5338  anim STATIC
5339  method XY
5340  repeat 1 1
5341  scaling 1.000 1.000
5342  offset 0.000 0.000
5343  pixelInterp
5344  effect INTENSITY
5345  blending 1.000
5346  ambient 0.977
5347  diffuse 1.000
5348  specular 0.966
5349  reflect 0.000
5350  transp 0.000
5351  roughness 0.000
5352  reflMap 1.000
5353  rotation 0.000
5354  txtsup_rot 0.000 0.000 0.000
5355  txtsup_trans 0.000 0.000 0.000
5356  txtsup_scal 1.000 1.000 1.000
5357  }
5358  }
5359 
5360  Modified:
5361 
5362  25 June 1999
5363 
5364  Author:
5365 
5366  John Burkardt
5367 */
5368 {
5369  float b;
5370  int count;
5371  float g;
5372  int i;
5373  int icor3;
5374  int ivert;
5375  int iword;
5376  int jval;
5377  int level;
5378  char *next;
5379  int nlbrack;
5380  int nrbrack;
5381  int cor3_num_old;
5382  float r;
5383  float t;
5384  float temp[3];
5385  int width;
5386  char word[LINE_MAX_LEN];
5387  char word1[LINE_MAX_LEN];
5388  char word2[LINE_MAX_LEN];
5389  char wordm1[LINE_MAX_LEN];
5390  float x;
5391  float y;
5392  float z;
5393 
5394  level = 0;
5395  strcpy ( level_name[0], "Top" );
5396  nlbrack = 0;
5397  nrbrack = 0;
5398  cor3_num_old = cor3_num;
5399  strcpy ( word, " " );
5400  strcpy ( wordm1, " " );
5401 /*
5402  Read a line of text from the file.
5403 */
5404  for ( ;; ) {
5405 
5406  if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) {
5407  break;
5408  }
5409 
5410  text_num = text_num + 1;
5411  next = input;
5412  iword = 0;
5413 /*
5414  Read a word from the line.
5415 */
5416  for ( ;; ) {
5417 
5418  strcpy ( wordm1, word );
5419 
5420  count = sscanf ( next, "%s%n", word2, &width );
5421  next = next + width;
5422 
5423  if ( count <= 0 ) {
5424  break;
5425  }
5426 
5427  strcpy ( word, word2 );
5428 
5429  iword = iword + 1;
5430 
5431  if ( iword == 1 ) {
5432  strcpy ( word1, word );
5433  }
5434 /*
5435  The first line of the file must be the header.
5436 */
5437  if ( text_num == 1 ) {
5438 
5439  if ( strcmp ( word1, "HRCH:" ) != 0 ) {
5440  printf ( "\n" );
5441  printf ( "HRC_READ - Fatal error!\n" );
5442  printf ( " The input file has a bad header.\n" );
5443  return ERROR;
5444  }
5445  else {
5446  comment_num = comment_num + 1;
5447  }
5448  break;
5449  }
5450 /*
5451  If the word is a curly bracket, count it.
5452 */
5453  if ( strcmp ( word, "{" ) == 0 ) {
5454  nlbrack = nlbrack + 1;
5455  level = nlbrack - nrbrack;
5456  strcpy ( level_name[level], wordm1 );
5457  if ( debug ) {
5458  printf ( "New level: %s\n", level_name[level] );
5459  }
5460  }
5461  else if ( strcmp ( word, "}" ) == 0 ) {
5462  nrbrack = nrbrack + 1;
5463 
5464  if ( nlbrack < nrbrack ) {
5465  printf ( "\n" );
5466  printf ( "HRC_READ - Fatal error!\n" );
5467  printf ( " Extraneous right bracket on line %d.\n", text_num );
5468  printf ( " Currently processing field %s\n.", level_name[level] );
5469  return ERROR;
5470  }
5471  }
5472 /*
5473  CONTROLPOINTS
5474 */
5475  if ( strcmp ( level_name[level], "controlpoints" ) == 0 ) {
5476 
5477  if ( strcmp ( word, "{" ) == 0 ) {
5478  }
5479  else if ( strcmp ( word, "}" ) == 0 ) {
5480 
5481  if ( line_num < LINES_MAX ) {
5482  line_dex[line_num] = -1;
5483  line_material[line_num] = 0;
5484  }
5485  line_num = line_num + 1;
5486  level = nlbrack - nrbrack;
5487  }
5488  else if ( word[0] == '[' ) {
5489  }
5490  else if ( strcmp ( word, "position" ) == 0 ) {
5491 
5492  count = sscanf ( next, "%f%n", &x, &width );
5493  next = next + width;
5494 
5495  count = sscanf ( next, "%f%n", &y, &width );
5496  next = next + width;
5497 
5498  count = sscanf ( next, "%f%n", &z, &width );
5499  next = next + width;
5500 
5501  temp[0] = x;
5502  temp[1] = y;
5503  temp[2] = z;
5504 
5505  if ( cor3_num < 1000 ) {
5506  icor3 = rcol_find ( cor3, 3, cor3_num, temp );
5507  }
5508  else {
5509  icor3 = -1;
5510  }
5511 
5512  if ( icor3 == -1 ) {
5513 
5514  icor3 = cor3_num;
5515  if ( cor3_num < COR3_MAX ) {
5516  cor3[0][cor3_num] = x;
5517  cor3[1][cor3_num] = y;
5518  cor3[2][cor3_num] = z;
5519  }
5520  cor3_num = cor3_num + 1;
5521 
5522  }
5523  else {
5524  dup_num = dup_num + 1;
5525  }
5526 
5527  if ( line_num < LINES_MAX ) {
5528  line_dex[line_num] = icor3;
5529  line_material[line_num] = 0;
5530  }
5531  line_num = line_num + 1;
5532  }
5533  else {
5534  bad_num = bad_num + 1;
5535  printf ( "CONTROLPOINTS: Bad data %s\n", word );
5536  return ERROR;
5537  }
5538 
5539  }
5540 /*
5541  EDGES
5542 */
5543  else if ( strcmp ( level_name[level], "edges" ) == 0 ) {
5544 
5545  if ( strcmp( word, "{" ) == 0 ) {
5546  }
5547  else if ( strcmp ( word, "}" ) == 0 ) {
5548  level = nlbrack - nrbrack;
5549  }
5550  else if ( word[0] == '[' ) {
5551  }
5552  else if ( strcmp ( word, "vertices" ) == 0 ) {
5553 
5554  count = sscanf ( next, "%d%n", &jval, &width );
5555  next = next + width;
5556 
5557  if ( line_num < LINES_MAX ) {
5558  line_dex[line_num] = jval + cor3_num_old;
5559  line_material[line_num] = 0;
5560  }
5561  line_num = line_num + 1;
5562 
5563  count = sscanf ( next, "%d%n", &jval, &width );
5564  next = next + width;
5565 
5566  if ( line_num < LINES_MAX ) {
5567  line_dex[line_num] = jval + cor3_num_old;
5568  line_material[line_num] = 0;
5569  }
5570  line_num = line_num + 1;
5571 
5572  if ( line_num < LINES_MAX ) {
5573  line_dex[line_num] = -1;
5574  line_material[line_num] = -1;
5575  }
5576  line_num = line_num + 1;
5577 
5578  }
5579  else {
5580  bad_num = bad_num + 1;
5581  printf ( "EDGES: Bad data %s\n", word );
5582  return ERROR;
5583  }
5584 
5585  }
5586 /*
5587  MATERIAL
5588 */
5589  else if ( strcmp ( level_name[level], "material" ) == 0 ) {
5590 
5591  if ( strcmp ( word, "{" ) == 0 ) {
5592  material_num = material_num + 1;
5593  }
5594  else if ( strcmp ( word, "}" ) == 0 ) {
5595  level = nlbrack - nrbrack;
5596  }
5597  else if ( word[0] == '[' ) {
5598  }
5599  else if ( strcmp ( word, "ambient" ) == 0 ) {
5600  }
5601  else if ( strcmp ( word, "coc" ) == 0 ) {
5602  }
5603  else if ( strcmp ( word, "diffuse" ) == 0 ) {
5604 
5605  count = sscanf ( next, "%f%n", &r, &width );
5606  next = next + width;
5607  material_rgba[0][material_num-1] = r;
5608 
5609  count = sscanf ( next, "%f%n", &g, &width );
5610  next = next + width;
5611  material_rgba[0][material_num-1] = g;
5612 
5613  count = sscanf ( next, "%f%n", &b, &width );
5614  next = next + width;
5615  material_rgba[0][material_num-1] = b;
5616 
5617  }
5618  else if ( strcmp ( word, "exponent" ) == 0 ) {
5619  }
5620  else if ( strcmp ( word, "glow" ) == 0 ) {
5621  }
5622  else if ( strcmp ( word, "name" ) == 0 ) {
5623  count = sscanf ( next, "%s%n", word, &width );
5624  next = next + width;
5625  strcpy ( material_name[material_num-1], word );
5626  }
5627  else if ( strcmp ( word, "reflectivity" ) == 0 ) {
5628  }
5629  else if ( strcmp ( word, "refracindex" ) == 0 ) {
5630  }
5631  else if ( strcmp ( word, "specular" ) == 0 ) {
5632  }
5633  else if ( strcmp ( word, "transparency" ) == 0 ) {
5634  count = sscanf ( next, "%f%n", &t, &width );
5635  next = next + width;
5636  material_rgba[3][material_num-1] = 1.0 - t;
5637  }
5638  else if ( strcmp ( word, "type" ) == 0 ) {
5639  }
5640  else {
5641  bad_num = bad_num + 1;
5642  printf ( "MATERIAL: Bad data %s\n", word );
5643  return ERROR;
5644  }
5645  }
5646 /*
5647  MESH
5648 */
5649  else if ( strcmp ( level_name[level], "mesh" ) == 0 ) {
5650 
5651  if ( strcmp ( word, "{" ) == 0 ) {
5652  }
5653  else if ( strcmp ( word, "}" ) == 0 ) {
5654  level = nlbrack - nrbrack;
5655  }
5656  else if ( strcmp ( word, "discontinuity" ) == 0 ) {
5657  break;
5658  }
5659  else if ( strcmp ( word, "edges" ) == 0 ) {
5660  break;
5661  }
5662  else if ( strcmp ( word, "flag" ) == 0 ) {
5663  break;
5664  }
5665  else if ( strcmp ( word, "polygons" ) == 0 ) {
5666  break;
5667  }
5668  else if ( strcmp ( word, "vertices" ) == 0 ) {
5669  break;
5670  }
5671  else {
5672  bad_num = bad_num + 1;
5673  printf ( "MESH: Bad data %s\n", word );
5674  return ERROR;
5675  }
5676 
5677  }
5678 /*
5679  MODEL
5680 */
5681  else if ( strcmp ( level_name[level], "model" ) == 0 ) {
5682 
5683  if ( strcmp ( word, "{" ) == 0 ) {
5684  }
5685  else if ( strcmp ( word, "}" ) == 0 ) {
5686  level = nlbrack - nrbrack;
5687  }
5688  else if ( strcmp ( word, "material" ) == 0 ) {
5689  break;
5690  }
5691  else if ( strcmp ( word, "mesh" ) == 0 ) {
5692  break;
5693  }
5694  else if ( strcmp ( word, "name" ) == 0 ) {
5695  break;
5696  }
5697  else if ( strcmp ( word, "patch" ) == 0 ) {
5698  break;
5699  }
5700  else if ( strcmp ( word, "rotation" ) == 0 ) {
5701  break;
5702  }
5703  else if ( strcmp ( word, "scaling" ) == 0 ) {
5704  break;
5705  }
5706  else if ( strcmp ( word, "spline" ) == 0 ) {
5707  break;
5708  }
5709  else if ( strcmp ( word, "translation" ) == 0 ) {
5710  break;
5711  }
5712  else {
5713  bad_num = bad_num + 1;
5714  printf ( "MODEL: Bad data %s\n", word );
5715  return ERROR;
5716  }
5717 
5718  }
5719 /*
5720  NODES
5721 */
5722  else if ( strcmp ( level_name[level], "nodes" ) == 0 ) {
5723 
5724  if ( strcmp ( word, "{" ) == 0 ) {
5725  ivert = 0;
5726  face_order[face_num] = 0;
5727  face_num = face_num + 1;
5728  }
5729  else if ( strcmp ( word, "}" ) == 0 ) {
5730  level = nlbrack - nrbrack;
5731  }
5732  else if ( word[0] == '[' ) {
5733  }
5734  else if ( strcmp ( word, "normal" ) == 0 ) {
5735 
5736  count = sscanf ( next, "%f%n", &x, &width );
5737  next = next + width;
5738 
5739  count = sscanf ( next, "%f%n", &y, &width );
5740  next = next + width;
5741 
5742  count = sscanf ( next, "%f%n", &z, &width );
5743  next = next + width;
5744 
5745  if ( ivert < ORDER_MAX && face_num < FACE_MAX ) {
5746  vertex_normal[0][ivert-1][face_num-1] = x;
5747  vertex_normal[1][ivert-1][face_num-1] = y;
5748  vertex_normal[2][ivert-1][face_num-1] = z;
5749  }
5750 
5751  }
5752  else if ( strcmp ( word, "uvTexture" ) == 0 ) {
5753 
5754  count = sscanf ( next, "%f%n", &x, &width );
5755  next = next + width;
5756 
5757  count = sscanf ( next, "%f%n", &y, &width );
5758  next = next + width;
5759 
5760  if ( ivert < ORDER_MAX && face_num < FACE_MAX ) {
5761  vertex_tex_uv[0][ivert-1][face_num-1] = x;
5762  vertex_tex_uv[1][ivert-1][face_num-1] = y;
5763  }
5764  }
5765  else if ( strcmp ( word, "vertex" ) == 0 ) {
5766 
5767  count = sscanf ( next, "%d%n", &jval, &width );
5768  next = next + width;
5769 
5770  if ( ivert < ORDER_MAX && face_num < FACE_MAX ) {
5771  face_order[face_num-1] = face_order[face_num-1] + 1;
5772  face[ivert][face_num-1] = jval;
5773  }
5774  ivert = ivert + 1;
5775 
5776  }
5777 /*
5778  Right now, we don't do anything with the vertexColor information.
5779 */
5780  else if ( strcmp ( word, "vertexColor" ) == 0 ) {
5781 
5782  count = sscanf ( next, "%d%n", &jval, &width );
5783  next = next + width;
5784 
5785  count = sscanf ( next, "%d%n", &jval, &width );
5786  next = next + width;
5787 
5788  count = sscanf ( next, "%d%n", &jval, &width );
5789  next = next + width;
5790 
5791  count = sscanf ( next, "%d%n", &jval, &width );
5792  next = next + width;
5793  }
5794  else {
5795  bad_num = bad_num + 1;
5796  printf ( "NODES: Bad data %s\n", word );
5797  return ERROR;
5798  }
5799 
5800  }
5801 /*
5802  PATCH
5803  I don't know what to do with this yet.
5804 */
5805  else if ( strcmp ( level_name[level], "patch" ) == 0 ) {
5806 
5807  if ( strcmp ( word, "{" ) == 0 ) {
5808  }
5809  else if ( strcmp ( word, "}" ) == 0 ) {
5810  level = nlbrack - nrbrack;
5811  }
5812  else if ( strcmp ( word, "approx_type" ) == 0 ) {
5813  }
5814  else if ( strcmp ( word, "controlpoints" ) == 0 ) {
5815  }
5816  else if ( strcmp ( word, "curv_u" ) == 0 ) {
5817  }
5818  else if ( strcmp ( word, "curv_v" ) == 0 ) {
5819  }
5820  else if ( strcmp ( word, "recmin" ) == 0 ) {
5821  }
5822  else if ( strcmp ( word, "recmax" ) == 0 ) {
5823  }
5824  else if ( strcmp ( word, "recursion" ) == 0 ) {
5825  }
5826  else if ( strcmp ( word, "spacial" ) == 0 ) {
5827  }
5828  else if ( strcmp ( word, "taggedpoints" ) == 0 ) {
5829  }
5830  else if ( strcmp ( word, "ucurve" ) == 0 ) {
5831  }
5832  else if ( strcmp ( word, "ustep" ) == 0 ) {
5833  }
5834  else if ( strcmp ( word, "utension" ) == 0 ) {
5835  }
5836  else if ( strcmp ( word, "utype" ) == 0 ) {
5837  }
5838  else if ( strcmp ( word, "vclose" ) == 0 ) {
5839  }
5840  else if ( strcmp ( word, "vcurve" ) == 0 ) {
5841  }
5842  else if ( strcmp ( word, "viewdep" ) == 0 ) {
5843  }
5844  else if ( strcmp ( word, "vpoint" ) == 0 ) {
5845  }
5846  else if ( strcmp ( word, "vstep" ) == 0 ) {
5847  }
5848  else if ( strcmp ( word, "vtension" ) == 0 ) {
5849  }
5850  else if ( strcmp ( word, "vtype" ) == 0 ) {
5851  }
5852  else {
5853  bad_num = bad_num + 1;
5854  printf ( "PATCH: Bad data %s\n", word );
5855  return ERROR;
5856  }
5857  }
5858 /*
5859  POLYGONS
5860 */
5861  else if ( strcmp ( level_name[level], "polygons" ) == 0 ) {
5862 
5863  if ( strcmp ( word, "{" ) == 0 ) {
5864  }
5865  else if ( strcmp ( word, "}" ) == 0 ) {
5866  level = nlbrack - nrbrack;
5867  }
5868  else if ( word[0] == '[' ) {
5869  }
5870  else if ( strcmp ( word, "material" ) == 0 ) {
5871 
5872  count = sscanf ( next, "%d%n", &jval, &width );
5873  next = next + width;
5874 
5875  for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) {
5876  vertex_material[ivert][face_num-1] = jval;
5877  }
5878 
5879  }
5880  else if ( strcmp ( word, "nodes" ) == 0 ) {
5881  count = sscanf ( next, "%s%n", word2, &width );
5882  next = next + width;
5883  }
5884  else {
5885  bad_num = bad_num + 1;
5886  printf ( "POLYGONS: Bad data %s\n", word );
5887  return ERROR;
5888  }
5889 
5890  }
5891 /*
5892  SPLINE
5893 */
5894  else if ( strcmp ( level_name[level], "spline" ) == 0 ) {
5895 
5896  if ( strcmp ( word, "{" ) == 0 ) {
5897  }
5898  else if ( strcmp ( word, "}" ) == 0 ) {
5899  level = nlbrack - nrbrack;
5900  }
5901  else if ( strcmp ( word, "controlpoints" ) == 0 ) {
5902  break;
5903  }
5904 /*
5905  WHY DON'T YOU READ IN THE OBJECT NAME HERE?
5906 */
5907  else if ( strcmp ( word, "name" ) == 0 ) {
5908  break;
5909  }
5910  else if ( strcmp ( word, "nbKeys" ) == 0 ) {
5911  break;
5912  }
5913  else if ( strcmp ( word, "step" ) == 0 ) {
5914  break;
5915  }
5916  else if ( strcmp ( word, "tension" ) == 0 ) {
5917  break;
5918  }
5919  else if ( strcmp ( word, "type" ) == 0 ) {
5920  break;
5921  }
5922  else {
5923  bad_num = bad_num + 1;
5924  printf ( "SPLINE: Bad data %s\n", word );
5925  return ERROR;
5926  }
5927 
5928  }
5929 /*
5930  TAGGEDPOINTS
5931 */
5932  else if ( strcmp ( level_name[level], "taggedpoints" ) == 0 ) {
5933 
5934  if ( strcmp ( word, "{" ) == 0 ) {
5935  }
5936  else if ( strcmp ( word, "}" ) == 0 ) {
5937  level = nlbrack - nrbrack;
5938  }
5939  else if ( word[0] == '[' ) {
5940  }
5941  else if ( strcmp ( word, "tagged" ) == 0 ) {
5942  }
5943  else {
5944  bad_num = bad_num + 1;
5945  printf ( "TAGGEDPOINTS: Bad data %s\n", word );
5946  return ERROR;
5947  }
5948 
5949  }
5950 /*
5951  TEXTURE
5952 */
5953  else if ( strcmp ( level_name[level], "texture" ) == 0 ) {
5954 
5955  if ( strcmp ( word, "{" ) == 0 ) {
5956  texture_num = texture_num + 1;
5957  }
5958  else if ( strcmp ( word, "}" ) == 0 ) {
5959  level = nlbrack - nrbrack;
5960  }
5961  else if ( word[0] == '[' ) {
5962  }
5963  else if ( strcmp ( word, "ambient" ) == 0 ) {
5964  }
5965  else if ( strcmp ( word, "anim" ) == 0 ) {
5966  }
5967  else if ( strcmp ( word, "blending" ) == 0 ) {
5968  }
5969  else if ( strcmp ( word, "diffuse" ) == 0 ) {
5970  }
5971  else if ( strcmp ( word, "effect" ) == 0 ) {
5972  }
5973  else if ( strcmp ( word, "glbname" ) == 0 ) {
5974  }
5975  else if ( strcmp ( word, "method" ) == 0 ) {
5976  }
5977  else if ( strcmp ( word, "name" ) == 0 ) {
5978  count = sscanf ( next, "%s%n", word, &width );
5979  next = next + width;
5980  strcpy ( texture_name[texture_num-1], word );
5981  }
5982  else if ( strcmp ( word, "offset" ) == 0 ) {
5983  }
5984  else if ( strcmp ( word, "pixelinterp" ) == 0 ) {
5985  }
5986  else if ( strcmp ( word, "reflect" ) == 0 ) {
5987  }
5988  else if ( strcmp ( word, "reflmap" ) == 0 ) {
5989  }
5990  else if ( strcmp ( word, "repeat" ) == 0 ) {
5991  }
5992  else if ( strcmp ( word, "rotation" ) == 0 ) {
5993  }
5994  else if ( strcmp ( word, "roughness" ) == 0 ) {
5995  }
5996  else if ( strcmp ( word, "scaling" ) == 0 ) {
5997  }
5998  else if ( strcmp ( word, "specular" ) == 0 ) {
5999  }
6000  else if ( strcmp ( word, "transp" ) == 0 ) {
6001  }
6002  else if ( strcmp ( word, "txtsup_rot" ) == 0 ) {
6003  }
6004  else if ( strcmp ( word, "txtsup_scal" ) == 0 ) {
6005  }
6006  else if ( strcmp ( word, "txtsup_trans" ) == 0 ) {
6007  }
6008  else {
6009  bad_num = bad_num + 1;
6010  printf ( "TEXTURE: Bad data %s\n", word );
6011  return ERROR;
6012  }
6013  }
6014 /*
6015  VERTICES
6016 */
6017  else if ( strcmp ( level_name[level], "vertices" ) == 0 ) {
6018 
6019  if ( strcmp ( word, "{" ) == 0 ) {
6020  }
6021  else if ( strcmp ( word, "}" ) == 0 ) {
6022  level = nlbrack - nrbrack;
6023  }
6024  else if ( word[0] == '[' ) {
6025  }
6026  else if ( strcmp ( word, "position" ) == 0 ) {
6027 
6028  count = sscanf ( next, "%f%n", &x, &width );
6029  next = next + width;
6030 
6031  count = sscanf ( next, "%f%n", &y, &width );
6032  next = next + width;
6033 
6034  count = sscanf ( next, "%f%n", &z, &width );
6035  next = next + width;
6036 
6037  if ( cor3_num < COR3_MAX ) {
6038  cor3[0][cor3_num] = x;
6039  cor3[1][cor3_num] = y;
6040  cor3[2][cor3_num] = z;
6041  }
6042  cor3_num = cor3_num + 1;
6043  }
6044  else {
6045  bad_num = bad_num + 1;
6046  printf ( "VERTICES: Bad data %s\n", word );
6047  return ERROR;
6048  }
6049  }
6050 /*
6051  Any other word:
6052 */
6053  else {
6054 
6055  }
6056  }
6057  }
6058 
6059 /*
6060  End of information in file.
6061 
6062  Check the "materials" defining a line.
6063 
6064  If COORDINDEX is -1, so should be the MATERIALINDEX.
6065  If COORDINDEX is not -1, then the MATERIALINDEX shouldn"t be either.
6066 */
6067  for ( i = 0; i < line_num; i++ ) {
6068 
6069  if ( line_dex[i] == -1 ) {
6070  line_material[i] = -1;
6071  }
6072  else if ( line_material[i] == -1 ) {
6073  line_material[i] = 0;
6074  }
6075 
6076  }
6077  return SUCCESS;
6078 }
6079 /******************************************************************************/
6080 
6081 int hrc_write ( FILE* fileout )
6082 
6083 /******************************************************************************/
6084 
6085 /*
6086  Purpose:
6087 
6088  HRC_WRITE writes graphics data to an HRC SoftImage file.
6089 
6090  Examples:
6091 
6092  HRCH: Softimage 4D Creative Environment v3.00
6093 
6094 
6095  model
6096  {
6097  name "cube_10x10"
6098  scaling 1.000 1.000 1.000
6099  rotation 0.000 0.000 0.000
6100  translation 0.000 0.000 0.000
6101 
6102  mesh
6103  {
6104  flag ( PROCESS )
6105  discontinuity 60.000
6106 
6107  vertices 8
6108  {
6109  [0] position -5.000 -5.000 -5.000
6110  [1] position -5.000 -5.000 5.000
6111  [2] position -5.000 5.000 -5.000
6112  [3] position -5.000 5.000 5.000
6113  [4] position 5.000 -5.000 -5.000
6114  [5] position 5.000 -5.000 5.000
6115  [6] position 5.000 5.000 -5.000
6116  [7] position 5.000 5.000 5.000
6117  }
6118 
6119  polygons 6
6120  {
6121  [0] nodes 4
6122  {
6123  [0] vertex 0
6124  normal -1.000 0.000 0.000
6125  uvTexture 0.000 0.000
6126  vertexColor 255 178 178 178
6127  [1] vertex 1
6128  normal -1.000 0.000 0.000
6129  uvTexture 0.000 0.000
6130  vertexColor 255 178 178 178
6131  [2] vertex 3
6132  normal -1.000 0.000 0.000
6133  uvTexture 0.000 0.000
6134  vertexColor 255 178 178 178
6135  [3] vertex 2
6136  normal -1.000 0.000 0.000
6137  uvTexture 0.000 0.000
6138  vertexColor 255 178 178 178
6139  }
6140  material 0
6141  [1] nodes 4
6142  {
6143  [0] vertex 1
6144  normal 0.000 0.000 1.000
6145  uvTexture 0.000 0.000
6146  vertexColor 255 178 178 178
6147  [1] vertex 5
6148 
6149  ...etc.....
6150 
6151  [5] nodes 4
6152  {
6153  [0] vertex 2
6154  normal 0.000 1.000 0.000
6155  uvTexture 0.000 0.000
6156  vertexColor 255 178 178 178
6157  [1] vertex 3
6158  normal 0.000 1.000 0.000
6159  uvTexture 0.000 0.000
6160  vertexColor 255 178 178 178
6161  [2] vertex 7
6162  normal 0.000 1.000 0.000
6163  uvTexture 0.000 0.000
6164  vertexColor 255 178 178 178
6165  [3] vertex 6
6166  normal 0.000 1.000 0.000
6167  uvTexture 0.000 0.000
6168  vertexColor 255 178 178 178
6169  }
6170  material 0
6171  }
6172 
6173  edges 12
6174  {
6175  [1] vertices 3 2
6176  [2] vertices 2 0
6177  [3] vertices 0 1
6178  [4] vertices 1 3
6179  [5] vertices 7 3
6180  [6] vertices 1 5
6181  [7] vertices 5 7
6182  [8] vertices 6 7
6183  [9] vertices 5 4
6184  [10] vertices 4 6
6185  [11] vertices 2 6
6186  [12] vertices 4 0
6187  }
6188  }
6189 
6190  material [0]
6191  {
6192  name "kazoo"
6193  type PHONG
6194  ambient 0.0 1.0 0.0
6195  diffuse 1.0 0.0 0.0
6196  specular 0.0 0.0 1.0
6197  exponent 50.0
6198  reflectivity 0.0
6199  transparency 0.0
6200  refracIndex 1.0
6201  glow 0
6202  coc 0.0
6203  }
6204 
6205  texture [0]
6206  {
6207  name "/usr/users/foss/HOUSE/PICTURES/mellon"
6208  glbname "t2d1"
6209  anim STATIC
6210  method XY
6211  repeat 1 1
6212  scaling 1.000 1.000
6213  offset 0.000 0.000
6214  pixelInterp
6215  effect INTENSITY
6216  blending 1.000
6217  ambient 0.977
6218  diffuse 1.000
6219  specular 0.966
6220  reflect 0.000
6221  transp 0.000
6222  roughness 0.000
6223  reflMap 1.000
6224  rotation 0.000
6225  txtsup_rot 0.000 0.000 0.000
6226  txtsup_trans 0.000 0.000 0.000
6227  txtsup_scal 1.000 1.000 1.000
6228  }
6229  }
6230 
6231  Modified:
6232 
6233  25 June 1998
6234 
6235  Author:
6236 
6237  John Burkardt
6238 
6239 */
6240 {
6241  int iface;
6242  int ivert;
6243  int j;
6244  int jhi;
6245  int jlo;
6246  int jrel;
6247  int k;
6248  int npts;
6249  int nseg;
6250  int text_num;
6251 
6252  nseg = 0;
6253  text_num = 0;
6254 
6255  fprintf ( fileout, "HRCH: Softimage 4D Creative Environment v3.00\n" );
6256  fprintf ( fileout, "\n" );
6257  fprintf ( fileout, "\n" );
6258  text_num = text_num + 3;
6259 
6260  fprintf ( fileout, "model\n" );
6261  fprintf ( fileout, "{\n" );
6262  fprintf ( fileout, " name \"%s\"\n", object_name );
6263  fprintf ( fileout, " scaling 1.000 1.000 1.000\n" );
6264  fprintf ( fileout, " rotation 0.000 0.000 0.000\n" );
6265  fprintf ( fileout, " translation 0.000 0.000 0.000\n" );
6266  text_num = text_num + 6;
6267 
6268  if ( face_num > 0 ) {
6269 
6270  fprintf ( fileout, "\n" );
6271  fprintf ( fileout, " mesh\n" );
6272  fprintf ( fileout, " {\n" );
6273  fprintf ( fileout, " flag ( PROCESS )\n" );
6274  fprintf ( fileout, " discontinuity 60.000\n" );
6275  text_num = text_num + 5;
6276 /*
6277  Point coordinates.
6278 */
6279  if ( cor3_num > 0 ) {
6280 
6281  fprintf ( fileout, "\n" );
6282  fprintf ( fileout, " vertices %d\n", cor3_num );
6283  fprintf ( fileout, " {\n" );
6284  text_num = text_num + 3;
6285 
6286  for ( j = 0; j < cor3_num; j++ ) {
6287 
6288  fprintf ( fileout, " [%d] position %f %f %f\n", j, cor3[0][j],
6289  cor3[1][j], cor3[2][j] );
6290  text_num = text_num + 1;
6291  }
6292  fprintf ( fileout, " }\n" );
6293  text_num = text_num + 1;
6294  }
6295 /*
6296  Faces.
6297 */
6298  fprintf ( fileout, "\n" );
6299  fprintf ( fileout, " polygons %d\n", face_num );
6300  fprintf ( fileout, " {\n" );
6301  text_num = text_num + 3;
6302 
6303  for ( iface = 0; iface < face_num; iface++ ) {
6304 
6305  fprintf ( fileout, " [%d] nodes %d\n", iface, face_order[iface] );
6306  fprintf ( fileout, " {\n" );
6307  text_num = text_num + 2;
6308 
6309  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
6310 
6311  fprintf ( fileout, " [%d] vertex %d\n", ivert, face[ivert][iface] );
6312  fprintf ( fileout, " normal %f %f %f\n",
6313  vertex_normal[0][ivert][iface],
6314  vertex_normal[1][ivert][iface], vertex_normal[2][ivert][iface] );
6315  fprintf ( fileout, " uvTexture %f %f\n",
6316  vertex_tex_uv[0][ivert][iface], vertex_tex_uv[1][ivert][iface] );
6317  fprintf ( fileout, " vertexColor 255 178 178 178\n" );
6318  text_num = text_num + 4;
6319  }
6320  fprintf ( fileout, " }\n" );
6321  fprintf ( fileout, " material %d\n", face_material[iface] );
6322  text_num = text_num + 2;
6323  }
6324  fprintf ( fileout, " }\n" );
6325  fprintf ( fileout, " }\n" );
6326  text_num = text_num + 2;
6327  }
6328 /*
6329  IndexedLineSet.
6330 */
6331  if ( line_num > 0 ) {
6332 
6333  nseg = 0;
6334 
6335  jhi = -1;
6336 
6337  for ( ;; ) {
6338 
6339  jlo = jhi + 1;
6340 /*
6341  Look for the next index JLO that is not -1.
6342 */
6343  while ( jlo < line_num ) {
6344  if ( line_dex[jlo] != -1 ) {
6345  break;
6346  }
6347  jlo = jlo + 1;
6348  }
6349 
6350  if ( jlo >= line_num ) {
6351  break;
6352  }
6353 /*
6354  Look for the highest following index JHI that is not -1.
6355 */
6356  jhi = jlo + 1;
6357 
6358  while ( jhi < line_num ) {
6359  if ( line_dex[jhi] == -1 ) {
6360  break;
6361  }
6362  jhi = jhi + 1;
6363  }
6364 
6365  jhi = jhi - 1;
6366 /*
6367  Our next line segment involves LINE_DEX indices JLO through JHI.
6368 */
6369  nseg = nseg + 1;
6370  npts = jhi + 1 - jlo;
6371 
6372  fprintf ( fileout, "\n" );
6373  fprintf ( fileout, " spline\n" );
6374  fprintf ( fileout, " {\n" );
6375  fprintf ( fileout, " name \"spl%d\"\n", nseg );
6376  fprintf ( fileout, " type LINEAR\n" );
6377  fprintf ( fileout, " nbKeys %d\n", npts );
6378  fprintf ( fileout, " tension 0.000\n" );
6379  fprintf ( fileout, " step 1\n" );
6380  fprintf ( fileout, "\n" );
6381  text_num = text_num + 9;
6382 
6383  fprintf ( fileout, " controlpoints\n" );
6384  fprintf ( fileout, " {\n" );
6385  text_num = text_num + 2;
6386 
6387  for ( j = jlo; j <= jhi; j++ ) {
6388  jrel = j - jlo;
6389  k = line_dex[j];
6390  fprintf ( fileout, " [%d] position %f %f %f\n", jrel,
6391  cor3[0][k], cor3[1][k], cor3[2][k] );
6392  text_num = text_num + 1;
6393  }
6394 
6395  fprintf ( fileout, " }\n" );
6396  fprintf ( fileout, " }\n" );
6397  text_num = text_num + 2;
6398  }
6399  }
6400 /*
6401  MATERIALS
6402 */
6403  for ( i = 0; i < material_num; i++ ) {
6404 
6405  fprintf ( fileout, " material [%d]\n", i );
6406  fprintf ( fileout, " {\n" );
6407  fprintf ( fileout, " name \"%s\"\n", material_name[i] );
6408  fprintf ( fileout, " type PHONG\n" );
6409  fprintf ( fileout, " ambient %f %f %f\n", material_rgba[0][i],
6410  material_rgba[1][i], material_rgba[2][i] );
6411  fprintf ( fileout, " diffuse %f %f %f\n", material_rgba[0][i],
6412  material_rgba[1][i], material_rgba[2][i] );
6413  fprintf ( fileout, " specular %f %f %f\n", material_rgba[0][i],
6414  material_rgba[1][i], material_rgba[2][i] );
6415  fprintf ( fileout, " exponent 50.0\n" );
6416  fprintf ( fileout, " reflectivity 0.0\n" );
6417  fprintf ( fileout, " transparency %f\n", 1.0 - material_rgba[3][i] );
6418  fprintf ( fileout, " refracIndex 1.0\n" );
6419  fprintf ( fileout, " glow 0\n" );
6420  fprintf ( fileout, " coc 0.0\n" );
6421  fprintf ( fileout, " }\n" );
6422 
6423  text_num = text_num + 14;
6424 
6425  }
6426 /*
6427  TEXTURES
6428 */
6429  for ( i = 0; i < texture_num; i++ ) {
6430 
6431  fprintf ( fileout, " texture [%d]\n", i );
6432  fprintf ( fileout, " {\n" );
6433  fprintf ( fileout, " name \"%s\"\n", texture_name[i] );
6434  fprintf ( fileout, " glbname \"t2d1\"\n" );
6435  fprintf ( fileout, " anim STATIC\n" );
6436  fprintf ( fileout, " method XY\n" );
6437  fprintf ( fileout, " repeat 1 1\n" );
6438  fprintf ( fileout, " scaling 1.000 1.000\n" );
6439  fprintf ( fileout, " offset 0.000 0.000\n" );
6440  fprintf ( fileout, " pixelInterp\n" );
6441  fprintf ( fileout, " effect INTENSITY\n" );
6442  fprintf ( fileout, " blending 1.000\n" );
6443  fprintf ( fileout, " ambient 0.977\n" );
6444  fprintf ( fileout, " diffuse 1.000\n" );
6445  fprintf ( fileout, " specular 0.966\n" );
6446  fprintf ( fileout, " reflect 0.000\n" );
6447  fprintf ( fileout, " transp 0.000\n" );
6448  fprintf ( fileout, " roughness 0.000\n" );
6449  fprintf ( fileout, " reflMap 1.000\n" );
6450  fprintf ( fileout, " rotation 0.000\n" );
6451  fprintf ( fileout, " txtsup_rot 0.000 0.000 0.000\n" );
6452  fprintf ( fileout, " txtsup_trans 0.000 0.000 0.000\n" );
6453  fprintf ( fileout, " txtsup_scal 1.000 1.000 1.000\n" );
6454  fprintf ( fileout, " }\n" );
6455 
6456  text_num = text_num + 25;
6457 
6458  }
6459  fprintf ( fileout, "}\n" );
6460  text_num = text_num + 1;
6461 /*
6462  Report.
6463 */
6464  printf ( "\n" );
6465  printf ( "HRC_WRITE - Wrote %d text lines.\n", text_num );
6466 
6467  return SUCCESS;
6468 }
6469 /******************************************************************************/
6470 
6471 void init_program_data ( void )
6472 
6473 /******************************************************************************/
6474 
6475 /*
6476  Purpose:
6477 
6478  INIT_PROGRAM_DATA initializes the internal program data.
6479 
6480  Modified:
6481 
6482  26 May 1999
6483 
6484  Author:
6485 
6486  John Burkardt
6487 */
6488 {
6489  byte_swap = FALSE;
6490  debug = 0;
6491  line_prune = 1;
6492  color_num = 0;
6493  cor3_num = 0;
6494  face_num = 0;
6495  line_num = 0;
6496 
6497  if ( debug ) {
6498  printf ( "\n" );
6499  printf ( "INIT_PROGRAM_DATA: Program data initialized.\n" );
6500  }
6501 
6502  return;
6503 
6504 }
6505 /******************************************************************************/
6506 
6507 int interact ( void )
6508 
6509 /******************************************************************************/
6510 
6511 /*
6512  Purpose:
6513 
6514  INTERACT carries on an interactive session with the user.
6515 
6516  Modified:
6517 
6518  22 May 1999
6519 
6520  Author:
6521 
6522  John Burkardt
6523 */
6524 {
6525  int i;
6526  int icor3;
6527  int ierror;
6528  int iface;
6529  int itemp;
6530  int ivert;
6531  int j;
6532  int jvert;
6533  int m;
6534  char *next;
6535  float temp;
6536  float x;
6537  float y;
6538  float z;
6539 
6540  strcpy ( filein_name, "NO_IN_NAME" );
6541  strcpy ( fileout_name, "NO_OUT_NAME" );
6542 
6543 /*
6544  Say hello.
6545 */
6546  hello ( );
6547 /*
6548  Get the next user command.
6549 */
6550  printf ( "\n" );
6551  printf ( "Enter command (H for help)\n" );
6552 
6553  while ( fgets ( input, LINE_MAX_LEN, stdin ) != NULL ) {
6554 /*
6555  Advance to the first nonspace character in INPUT.
6556 */
6557  for ( next = input; *next != '\0' && isspace(*next); next++ ) {
6558  }
6559 /*
6560  Skip blank lines and comments.
6561 */
6562  if ( *next == '\0' ) {
6563  continue;
6564  }
6565 /*
6566  Command: << FILENAME
6567  Append new data to current graphics information.
6568 */
6569  if ( *next == '<' && *(next+1) == '<' ) {
6570 
6571  next = next + 2;
6572  sscanf ( next, "%s", filein_name );
6573 
6574  ierror = data_read ( );
6575 
6576  if ( ierror == ERROR ) {
6577  printf ( "\n" );
6578  printf ( "INTERACT - Fatal error!\n" );
6579  printf ( " DATA_READ failed to read input data.\n" );
6580  }
6581  }
6582 /*
6583  Command: < FILENAME
6584 */
6585  else if ( *next == '<' ) {
6586 
6587  next = next + 1;
6588  sscanf ( next, "%s", filein_name );
6589 
6590  data_init ( );
6591 
6592  ierror = data_read ( );
6593 
6594  if ( ierror == ERROR ) {
6595  printf ( "\n" );
6596  printf ( "INTERACT - Fatal error!\n" );
6597  printf ( " DATA_READ failed to read input data.\n" );
6598  }
6599  }
6600 /*
6601  Command: > FILENAME
6602 */
6603  else if ( *next == '>' ) {
6604 
6605  next = next + 1;
6606  sscanf ( next, "%s", fileout_name );
6607 
6608  ierror = data_write ( );
6609 
6610  if ( ierror == ERROR ) {
6611  printf ( "\n" );
6612  printf ( "INTERACT - Fatal error!\n" );
6613  printf ( " OUTPUT_DATA failed to write output data.\n" );
6614  }
6615 
6616  }
6617 /*
6618  B: Switch byte swapping option.
6619 */
6620  else if ( *next == 'B' || *next == 'b' ) {
6621 
6622  if ( byte_swap == TRUE ) {
6623  byte_swap = FALSE;
6624  printf ( "Byte_swapping reset to FALSE.\n" );
6625  }
6626  else {
6627  byte_swap = TRUE;
6628  printf ( "Byte_swapping reset to TRUE.\n" );
6629  }
6630 
6631  }
6632 /*
6633  D: Switch debug option.
6634 */
6635  else if ( *next == 'D' || *next == 'd' ) {
6636  if ( debug ) {
6637  debug = 0;
6638  printf ( "Debug reset to FALSE.\n" );
6639  }
6640  else {
6641  debug = 1;
6642  printf ( "Debug reset to TRUE.\n" );
6643  }
6644  }
6645 /*
6646  F: Check a face.
6647 */
6648  else if ( *next == 'f' || *next == 'F' ) {
6649  printf ( "\n" );
6650  printf ( " Enter a face index between 0 and %d:", face_num-1 );
6651  scanf ( "%d", &iface );
6652  face_print ( iface );
6653  }
6654 /*
6655  H: Help
6656 */
6657  else if ( *next == 'h' || *next == 'H' ) {
6658  help ( );
6659  }
6660 /*
6661  I: Print change information.
6662 */
6663  else if ( *next == 'i' || *next == 'I') {
6664  news ( );
6665  }
6666 /*
6667  LINES:
6668  Convert face information to lines.
6669 */
6670  else if ( *next == 'l' || *next == 'L') {
6671 
6672  if ( face_num > 0 ) {
6673 
6674  printf ( "\n" );
6675  printf ( "INTERACT - Note:\n" );
6676  printf ( " Face information will be converted\n" );
6677  printf ( " to line information.\n" );
6678 
6679  face_to_line ( );
6680 
6681  if ( line_num > LINES_MAX ) {
6682 
6683  printf ( "\n" );
6684  printf ( "INTERACT - Note:\n" );
6685  printf ( " Some face information was lost.\n" );
6686  printf ( " The maximum number of lines is %d,\n", LINES_MAX );
6687  printf ( " but we would need at least %d.\n", line_num );
6688 
6689  line_num = LINES_MAX;
6690 
6691  }
6692 
6693  face_num = 0;
6694  }
6695  else {
6696 
6697  printf ( "\n" );
6698  printf ( "INTERACT - Note:\n" );
6699  printf ( " There were no faces to convert.\n" );
6700 
6701  }
6702 
6703  }
6704 /*
6705  N: Recompute normal vectors.
6706 */
6707  else if ( *next == 'n' || *next == 'N') {
6708 
6709  for ( iface = 0; iface < face_num; iface++ ) {
6710  for ( i = 0; i < 3; i++ ) {
6711  face_normal[i][iface] = 0.0;
6712  }
6713  }
6714 
6715  for ( iface = 0; iface < face_num; iface++ ) {
6716  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
6717  for ( i = 0; i < 3; i++ ) {
6718  vertex_normal[i][ivert][iface] = 0.0;
6719  }
6720  }
6721  }
6722 
6723  vertex_normal_set ( );
6724 
6725  cor3_normal_set ( );
6726 
6727  face_normal_ave ( );
6728  }
6729 /*
6730  P: Line pruning optiont
6731 */
6732  else if ( *next == 'p' || *next == 'P' ) {
6733 
6734  printf ( "\n" );
6735  printf ( "INTERACT - SET LINE PRUNING OPTION.\n" );
6736  printf ( "\n" );
6737  printf ( " LINE_PRUNE = 0 means no line pruning.\n" );
6738  printf ( " nonzero means line pruning.\n" );
6739  printf ( "\n" );
6740  printf ( " Current value is LINE_PRUNE = %d.\n", line_prune );
6741  printf ( "\n" );
6742  printf ( " Enter new value for LINE_PRUNE.\n" );
6743 
6744  if ( fgets ( input, LINE_MAX_LEN, stdin ) == NULL ) {
6745  printf ( " ??? Error trying to read input.\n" );
6746  }
6747  else {
6748  sscanf ( input, "%d", &line_prune );
6749  printf ( " New value is LINE_PRUNE = %d.\n", line_prune );
6750  }
6751  }
6752 /*
6753  Q: Quit
6754 */
6755  else if ( *next == 'q' || *next == 'Q' ) {
6756  printf ( "\n" );
6757  printf ( "INTERACT - Normal end of execution.\n" );
6758  return SUCCESS;
6759  }
6760 /*
6761  R: Reverse normal vectors.
6762 */
6763  else if ( *next == 'r' || *next == 'R' ) {
6764 
6765  for ( icor3 = 0; icor3 < cor3_num; icor3++ ) {
6766  for ( i = 0; i < 3; i++ ) {
6767  cor3_normal[i][icor3] = - cor3_normal[i][icor3];
6768  }
6769  }
6770 
6771  for ( iface = 0; iface < face_num; iface++ ) {
6772  for ( i = 0; i < 3; i++ ) {
6773  face_normal[i][iface] = - face_normal[i][iface];
6774  }
6775  }
6776 
6777  for ( iface = 0; iface < face_num; iface++ ) {
6778  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
6779  for ( i = 0; i < 3; i++ ) {
6780  vertex_normal[i][ivert][iface] =
6781  - vertex_normal[i][ivert][iface];
6782  }
6783  }
6784  }
6785  printf ( "\n" );
6786  printf ( "INTERACT - Note:\n" );
6787  printf ( " Reversed node, face and vertex normals.\n" );
6788  }
6789 /*
6790  S: Select a few faces, discard the rest.
6791 */
6792  else if ( *next == 's' || *next == 'S' ) {
6793  face_subset ( );
6794  }
6795 /*
6796  T: Transform the data.
6797 */
6798  else if ( *next == 't' || *next == 'T' ) {
6799 
6800  printf ( "\n" );
6801  printf ( "For now, we only offer point scaling.\n" );
6802  printf ( "Enter X, Y, Z scale factors:\n" );
6803 
6804  scanf ( "%f %f %f", &x, &y, &z );
6805 
6806  for ( j = 0; j < cor3_num; j++ ) {
6807  cor3[0][j] = x * cor3[0][j];
6808  cor3[1][j] = y * cor3[1][j];
6809  cor3[2][j] = z * cor3[2][j];
6810  }
6811 
6812  for ( iface = 0; iface < face_num; iface++ ) {
6813  for ( i = 0; i < 3; i++ ) {
6814  face_normal[i][iface] = 0.0;
6815  }
6816  }
6817 
6818  for ( iface = 0; iface < face_num; iface++ ) {
6819  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
6820  for ( i = 0; i < 3; i++ ) {
6821  vertex_normal[i][ivert][iface] = 0.0;
6822  }
6823  }
6824  }
6825 
6826  vertex_normal_set ( );
6827 
6828  cor3_normal_set ( );
6829 
6830  face_normal_ave ( );
6831  }
6832 /*
6833  U: Renumber faces, count objects:
6834 */
6835  else if ( *next == 'u' || *next == 'U' ) {
6836  }
6837 /*
6838  V: Convert polygons to triangles:
6839 */
6840  else if ( *next == 'v' || *next == 'V' ) {
6841  }
6842 /*
6843  W: Reverse the face node ordering.
6844 */
6845  else if ( *next == 'w' || *next == 'W' ) {
6846 
6847  if ( face_num > 0 ) {
6848 
6849  for ( iface = 0; iface < face_num; iface++ ) {
6850 
6851  m = face_order[iface];
6852 
6853  for ( ivert = 0; ivert < m/2; ivert++ ) {
6854 
6855  jvert = m - ivert - 1;
6856 
6857  itemp = face[ivert][iface];
6858  face[ivert][iface] = face[jvert][iface];
6859  face[jvert][iface] = itemp;
6860 
6861  itemp = vertex_material[ivert][iface];
6862  vertex_material[ivert][iface] = vertex_material[jvert][iface];
6863  vertex_material[jvert][iface] = itemp;
6864 
6865  for ( i = 0; i < 3; i++ ) {
6866  temp = vertex_normal[i][ivert][iface];
6867  vertex_normal[i][ivert][iface] =
6868  vertex_normal[i][jvert][iface];
6869  vertex_normal[i][jvert][iface] = temp;
6870  }
6871  }
6872  }
6873  printf ( "\n" );
6874  printf ( "INTERACT - Note:\n" );
6875  printf ( " Reversed face node ordering.\n" );
6876  }
6877  }
6878 /*
6879  Command: ???
6880 */
6881  else {
6882  printf ( "\n" );
6883  printf ( "INTERACT: Warning!\n" );
6884  printf ( " Your command was not recognized.\n" );
6885  }
6886 
6887  printf ( "\n" );
6888  printf ( "Enter command (H for help)\n" );
6889 
6890  }
6891  return SUCCESS;
6892 }
6893 /******************************************************************************/
6894 
6895 int iv_read ( FILE *filein )
6896 
6897 /******************************************************************************/
6898 
6899 /*
6900  Purpose:
6901 
6902  IV_READ reads graphics information from an Inventor file.
6903 
6904  Example:
6905 
6906  #Inventor V2.0 ascii
6907 
6908  Separator {
6909  Info {
6910  string "Inventor file generated by IVCON.
6911  Original data in file cube.iv."
6912  }
6913  Separator {
6914  LightModel {
6915  model PHONG
6916  }
6917  MatrixTransform { matrix
6918  0.9 0.0 0.0 0.0
6919  0.0 -0.9 0.0 0.0
6920  0.0 0.0 -1.5 0.0
6921  0.0 0.0 0.0 1.0
6922  }
6923  Material {
6924  ambientColor 0.2 0.2 0.2
6925  diffuseColor [
6926  0.8 0.8 0.8,
6927  0.7 0.1 0.1,
6928  0.1 0.8 0.2,
6929  ]
6930  emissiveColor 0.0 0.0 0.0
6931  specularColor 0.0 0.0 0.0
6932  shininess 0.2
6933  transparency [
6934  0.0, 0.5, 1.0,
6935  ]
6936  }
6937  Texture2 {
6938  filename "fred.rgb"
6939  wrapS REPEAT
6940  wrapT REPEAT
6941  model MODULATE
6942  blendColor 0.0 0.0 0.0
6943  }
6944 
6945  MaterialBinding {
6946  value PER_VERTEX_INDEXED
6947  }
6948  NormalBinding {
6949  value PER_VERTEX_INDEXED
6950  }
6951  TextureCoordinateBinding {
6952  value PER_VERTEX_INDEXED
6953  }
6954 
6955  ShapeHints {
6956  vertexOrdering COUNTERCLOCKWISE
6957  shapeType UNKNOWN_SHAPE_TYPE
6958  faceType CONVEX
6959  creaseAngle 6.28319
6960  }
6961 
6962  Coordinate3 {
6963  point [
6964  8.59816 5.55317 -3.05561,
6965  8.59816 2.49756 0.000000E+00,
6966  ...etc...
6967  2.48695 2.49756 -3.05561,
6968  ]
6969  }
6970 
6971  Normal {
6972  vector [
6973  0.71 0.71 0.0,
6974  ...etc...
6975  0.32 0.32 0.41,
6976  ]
6977  }
6978 
6979  TextureCoordinate2 {
6980  point [
6981  0.0 1.0,
6982  0.1, 0.8,
6983  ...etc...
6984  0.4 0.7,
6985  ]
6986  }
6987 
6988  IndexedLineSet {
6989  coordIndex [
6990  0, 1, 2, -1,
6991  3, 4, 5, -1,
6992  7, 8, 9, -1,
6993  ...etc...
6994  189, 190, 191, -1,
6995  ]
6996  materialIndex [
6997  0, 0, 0, -1,
6998  1, 1, 1, -1,
6999  2, 2, 2, -1,
7000  ...etc...
7001  64, 64, 64, -1,
7002  ]
7003  }
7004 
7005  IndexedFaceSet {
7006  coordIndex [
7007  0, 1, 2, -1,
7008  3, 4, 5, -1,
7009  7, 8, 9, -1,
7010  ...etc...
7011  189, 190, 191, -1,
7012  ]
7013  materialIndex [
7014  0, 0, 0, -1,
7015  1, 1, 1, -1,
7016  2, 2, 2, -1,
7017  ...etc...
7018  64, 64, 64, -1,
7019  ]
7020  normalIndex [
7021  0, 0, 0, -1,
7022  1, 1, 1, -1,
7023  2, 2, 2, -1,
7024  ...etc...
7025  64, 64, 64, -1,
7026  ]
7027  textureCoordIndex [
7028  0, 0, 0, -1,
7029  1, 1, 1, -1,
7030  2, 2, 2, -1,
7031  ...etc...
7032  64, 64, 64, -1,
7033  ]
7034  }
7035 
7036  IndexedTriangleStripSet {
7037  vertexProperty VertexProperty {
7038  vertex [ x y z,
7039  ...
7040  x y z ]
7041  normal [ x y z,
7042  ...
7043  x y z ]
7044  materialBinding OVERALL
7045  normalBinding PER_VERTEX_INDEXED
7046  }
7047  coordIndex [
7048  i, j, k, l, m, -1,
7049  n, o, p, q, r, s, t, u, -1,
7050  v, w, x, -1
7051  ..., -1 ]
7052  normalIndex -1
7053  }
7054 
7055  }
7056  }
7057 
7058  Modified:
7059 
7060  01 July 1999
7061 
7062  Author:
7063 
7064  John Burkardt
7065 */
7066 {
7067  char c;
7068  int count;
7069  int i;
7070  int icol;
7071  int icolor;
7072  int icface;
7073  int inormface;
7074  int iface_num;
7075  int irow;
7076  int iuv;
7077  int ivert;
7078  int iword;
7079  int ix;
7080  int ixyz;
7081  int iy;
7082  int iz;
7083  int j;
7084  int jval;
7085  int level;
7086  char *next;
7087  int nlbrack;
7088  int nrbrack;
7089  int nu;
7090  int null_index;
7091  int cor3_num_old;
7092  int line_num2;
7093  int face_num2;
7094  int normal_num_temp;
7095  int text_numure_temp;
7096  int nv;
7097  int result;
7098  float rval;
7099  int width;
7100  char word[LINE_MAX_LEN];
7101  char word1[LINE_MAX_LEN];
7102  char wordm1[LINE_MAX_LEN];
7103  float xvec[3];
7104 
7105  icface = 0;
7106  icol = -1;
7107  inormface = 0;
7108  iface_num = face_num;
7109  irow = 0;
7110  ix = 0;
7111  ixyz = 0;
7112  iy = 0;
7113  iz = 0;
7114  jval = 0;
7115  level = 0;
7116  strcpy ( level_name[0], "Top" );
7117  nlbrack = 0;
7118  nrbrack = 0;
7119  nu = 0;
7120  cor3_num_old = cor3_num;
7121  face_num2 = face_num;
7122  line_num2 = line_num;
7123  normal_num_temp = 0;
7124  text_numure_temp = 0;
7125  nv = 0;
7126  rval = 0.0;
7127  strcpy ( word, " " );
7128  strcpy ( wordm1, " " );
7129 /*
7130  Read the next line of text from the input file.
7131 */
7132  for ( ;; ) {
7133 
7134  if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) {
7135  break;
7136  }
7137 
7138  text_num = text_num + 1;
7139  next = input;
7140  iword = 0;
7141 /*
7142  Remove all commas from the line, so we can use SSCANF to read
7143  numeric items.
7144 */
7145  i = 0;
7146  while ( input[i] != '\0' ) {
7147  if ( input[i] == ',' ) {
7148  input[i] = ' ';
7149  }
7150  i++;
7151  }
7152 /*
7153  Force brackets and braces to be buffered by spaces.
7154 */
7155  i = 0;
7156  while ( input[i] != '\0' ) {
7157  i++;
7158  }
7159  null_index = i;
7160 
7161  i = 0;
7162  while ( input[i] != '\0' && i < LINE_MAX_LEN ) {
7163 
7164  if ( input[i] == '[' || input[i] == ']' ||
7165  input[i] == '{' || input[i] == '}' ) {
7166 
7167  result = char_pad ( &i, &null_index, input, LINE_MAX_LEN );
7168  if ( result == ERROR ) {
7169  break;
7170  }
7171  }
7172  else {
7173  i++;
7174  }
7175  }
7176 /*
7177  Read a word from the line.
7178 */
7179  for ( ;; ) {
7180 
7181  strcpy ( wordm1, word );
7182  strcpy ( word, " " );
7183 
7184  count = sscanf ( next, "%s%n", word, &width );
7185  next = next + width;
7186 
7187  if ( count <= 0 ) {
7188  break;
7189  }
7190 
7191  iword = iword + 1;
7192 
7193  if ( iword == 1 ) {
7194  strcpy ( word1, word );
7195  }
7196 /*
7197  The first line of the file must be the header.
7198 */
7199  if ( text_num == 1 ) {
7200 
7201  if ( leqi ( word1, "#Inventor" ) != TRUE ) {
7202  printf ( "\n" );
7203  printf ( "IV_READ - Fatal error!\n" );
7204  printf ( " The input file has a bad header.\n" );
7205  return ERROR;
7206  }
7207  else {
7208  comment_num = comment_num + 1;
7209  }
7210  break;
7211  }
7212 /*
7213  A comment begins anywhere with '#'.
7214  Skip the rest of the line.
7215 */
7216  if ( word[1] == '#' ) {
7217  comment_num = comment_num + 1;
7218  break;
7219  }
7220 /*
7221  If the word is a curly or square bracket, count it.
7222  If the word is a left bracket, the previous word is the name of a node.
7223 */
7224  if ( strcmp ( word, "{" ) == 0 || strcmp ( word, "[" ) == 0 ) {
7225  nlbrack = nlbrack + 1;
7226  level = nlbrack - nrbrack;
7227  strcpy ( level_name[level], wordm1 );
7228  if ( debug ) {
7229  printf ( "Begin level: %s\n", wordm1 );
7230  }
7231  }
7232  else if ( strcmp ( word, "}" ) == 0 || strcmp ( word, "]" ) == 0 ) {
7233  nrbrack = nrbrack + 1;
7234 
7235  if ( nlbrack < nrbrack ) {
7236  printf ( "\n" );
7237  printf ( "IV_READ - Fatal error!\n" );
7238  printf ( " Extraneous right bracket on line %d.\n", text_num );
7239  printf ( " Currently processing field %s\n.", level_name[level] );
7240  return ERROR;
7241  }
7242  }
7243 /*
7244  BASECOLOR
7245 */
7246  if ( leqi ( level_name[level], "BASECOLOR" ) == TRUE ) {
7247 
7248  if ( strcmp ( word, "{" ) == 0 ) {
7249  }
7250  else if ( strcmp ( word, "}" ) == 0 ) {
7251  level = nlbrack - nrbrack;
7252  }
7253  else if ( leqi ( word, "RGB" ) == TRUE ) {
7254  }
7255  else {
7256  bad_num = bad_num + 1;
7257  printf ( "Bad data %s\n", word );
7258  }
7259  }
7260 /*
7261  COORDINATE3
7262 */
7263  else if ( leqi ( level_name[level], "COORDINATE3" ) == TRUE ) {
7264 
7265  if ( strcmp ( word, "{" ) == 0 ) {
7266  }
7267  else if ( strcmp ( word, "}" ) == 0 ) {
7268  level = nlbrack - nrbrack;
7269  }
7270  else if ( leqi ( word, "POINT" ) == TRUE ) {
7271  }
7272  else {
7273  bad_num = bad_num + 1;
7274  printf ( "COORDINATE3: Bad data %s\n", word );
7275  }
7276  }
7277 /*
7278  COORDINATE4
7279 */
7280  else if ( leqi ( level_name[level], "COORDINATE4" ) == TRUE ) {
7281 
7282  if ( strcmp ( word, "{" ) == 0 ) {
7283  }
7284  else if ( strcmp ( word, "}" ) == 0 ) {
7285  level = nlbrack - nrbrack;
7286  }
7287  else if ( leqi ( word, "POINT" ) == TRUE ) {
7288  }
7289  else {
7290  bad_num = bad_num + 1;
7291  printf ( "COORDINATE4: Bad data %s\n", word );
7292  }
7293  }
7294 /*
7295  COORDINDEX
7296 */
7297  else if ( leqi ( level_name[level], "COORDINDEX" ) == TRUE ) {
7298 
7299  if ( strcmp ( word, "[" ) == 0 ) {
7300  ivert = 0;
7301  }
7302  else if ( strcmp ( word, "]" ) == 0 ) {
7303  level = nlbrack - nrbrack;
7304  }
7305 /*
7306  (indexedlineset) COORDINDEX
7307 */
7308  else if ( leqi ( level_name[level-1], "INDEXEDLINESET" ) == TRUE ) {
7309 
7310  count = sscanf ( word, "%d%n", &jval, &width );
7311 
7312  if ( count > 0 ) {
7313 
7314  if ( jval < -1 ) {
7315  bad_num = bad_num + 1;
7316  }
7317  else {
7318  if ( line_num < LINES_MAX ) {
7319  if ( jval != -1 ) {
7320  jval = jval + cor3_num_old;
7321  }
7322  line_dex[line_num] = jval;
7323  }
7324  line_num = line_num + 1;
7325  }
7326  }
7327  else {
7328  bad_num = bad_num + 1;
7329  }
7330  }
7331 /*
7332  (indexedfaceset) COORDINDEX
7333  Warning: If the list of indices is not terminated with a final -1, then
7334  the last face won't get counted.
7335 */
7336  else if ( leqi ( level_name[level-1], "INDEXEDFACESET" ) == TRUE ) {
7337 
7338  count = sscanf ( word, "%d%n", &jval, &width );
7339 
7340  if ( count > 0 ) {
7341  if ( jval == -1 ) {
7342  ivert = 0;
7343  face_num = face_num + 1;
7344  }
7345  else {
7346  if ( ivert == 0 ) {
7347  if ( face_num < FACE_MAX ) {
7348  face_order[face_num] = 0;
7349  }
7350  }
7351  if ( face_num < FACE_MAX ) {
7353  face[ivert][face_num] = jval + cor3_num_old;
7354  ivert = ivert + 1;
7355  }
7356  }
7357  }
7358  }
7359 /*
7360  (indexednurbssurface) COORDINDEX
7361 */
7362  else if ( leqi ( level_name[level-1], "INDEXEDNURBSSURFACE" ) == TRUE ) {
7363  }
7364 /*
7365  (indexedtrianglestripset) COORDINDEX
7366 
7367  First three coordinate indices I1, I2, I3 define a triangle.
7368  Next triangle is defined by I2, I3, I4 (actually, I4, I3, I2
7369  to stay with same counterclockwise sense).
7370  Next triangle is defined by I3, I4, I5 ( do not need to reverse
7371  odd numbered triangles) and so on.
7372  List is terminated with -1.
7373 */
7374  else if ( leqi ( level_name[level-1], "INDEXEDTRIANGLESTRIPSET" ) == TRUE ) {
7375 
7376  count = sscanf ( word, "%d%n", &jval, &width );
7377 
7378  if ( count > 0 ) {
7379 
7380  if ( jval == -1 ) {
7381  ivert = 0;
7382  }
7383  else {
7384 
7385  ix = iy;
7386  iy = iz;
7387  iz = jval + cor3_num_old;
7388 
7389  if ( ivert == 0 ) {
7390  if ( face_num < FACE_MAX ) {
7391  face[ivert][face_num] = jval + cor3_num_old;
7392  face_order[face_num] = 3;
7393  }
7394  }
7395  else if ( ivert == 1 ) {
7396  if ( face_num < FACE_MAX ) {
7397  face[ivert][face_num] = jval + cor3_num_old;
7398  }
7399  }
7400  else if ( ivert == 2 ) {
7401  if ( face_num < FACE_MAX ) {
7402  face[ivert][face_num] = jval + cor3_num_old;
7403  }
7404  face_num = face_num + 1;
7405  }
7406  else {
7407 
7408  if ( face_num < FACE_MAX ) {
7409  face_order[face_num] = 3;
7410  if ( ( ivert % 2 ) == 0 ) {
7411  face[0][face_num] = ix;
7412  face[1][face_num] = iy;
7413  face[2][face_num] = iz;
7414  }
7415  else {
7416  face[0][face_num] = iz;
7417  face[1][face_num] = iy;
7418  face[2][face_num] = ix;
7419  }
7420  }
7421  face_num = face_num + 1;
7422  }
7423  ivert = ivert + 1;
7424 /*
7425  Very very tentative guess as to how indices into the normal
7426  vector array are set up...
7427 */
7428  if ( face_num < FACE_MAX && ivert > 2 ) {
7429  for ( i = 0; i < 3; i++ ) {
7430  face_normal[i][face_num] = normal_temp[i][ix];
7431  }
7432  }
7433  }
7434  }
7435  }
7436  }
7437 /*
7438  INDEXEDFACESET
7439 */
7440  else if ( leqi ( level_name[level], "INDEXEDFACESET" ) == TRUE ) {
7441 
7442  if ( strcmp ( word, "{" ) == 0 ) {
7443  }
7444  else if ( strcmp ( word, "}" ) == 0 ) {
7445  level = nlbrack - nrbrack;
7446  }
7447  else if ( leqi ( word, "COORDINDEX" ) == TRUE ) {
7448  ivert = 0;
7449  }
7450  else if ( leqi ( word, "MATERIALINDEX" ) == TRUE ) {
7451  }
7452  else if ( leqi ( word, "NORMALINDEX" ) == TRUE ) {
7453  }
7454  else if ( leqi ( word, "TEXTURECOORDINDEX" ) == TRUE ) {
7455  if ( texture_num <= 0 ) {
7456  texture_num = 1;
7457  strcpy ( texture_name[0], "Texture_0000" );
7458  }
7459  }
7460  else {
7461  bad_num = bad_num + 1;
7462  printf ( "Bad data %s\n", word );
7463  }
7464  }
7465 /*
7466  INDEXEDLINESET
7467 */
7468  else if ( leqi ( level_name[level], "INDEXEDLINESET" ) == TRUE ) {
7469 
7470  if ( strcmp ( word, "{" ) == 0 ) {
7471  }
7472  else if ( strcmp ( word, "}" ) == 0 ) {
7473  level = nlbrack - nrbrack;
7474  }
7475  else if ( leqi ( word, "COORDINDEX" ) == TRUE ) {
7476  }
7477  else if ( leqi ( word, "MATERIALINDEX" ) == TRUE ) {
7478  }
7479  else {
7480  bad_num = bad_num + 1;
7481  printf ( "Bad data %s\n", word );
7482  }
7483  }
7484 /*
7485  INDEXEDNURBSSURFACE
7486 */
7487  else if ( leqi ( level_name[level], "INDEXEDNURBSSURFACE" ) == TRUE ) {
7488 
7489  if ( strcmp ( word, "{" ) == 0 ) {
7490  }
7491  else if ( strcmp ( word, "}" ) == 0 ) {
7492  level = nlbrack - nrbrack;
7493  }
7494  else if ( leqi ( word, "NUMUCONTROLPOINTS") == TRUE ) {
7495 
7496  count = sscanf ( word, "%d%n", &jval, &width );
7497 
7498  if ( count > 0 ) {
7499  nu = jval;
7500  if ( debug ) {
7501  printf ( "NU = %d\n", nu );
7502  }
7503  }
7504  else {
7505  nu = 0;
7506  bad_num = bad_num + 1;
7507  printf ( "Bad data %s\n", word );
7508  }
7509  }
7510  else if ( leqi ( word, "NUMVCONTROLPOINTS" ) == TRUE ) {
7511 
7512  count = sscanf ( word, "%d%n", &jval, &width );
7513 
7514  if ( count > 0 ) {
7515  nv = jval;
7516  if ( debug ) {
7517  printf ( "NV = %d\n", nv );
7518  }
7519  }
7520  else {
7521  nv = 0;
7522  bad_num = bad_num + 1;
7523  }
7524  }
7525  else if ( leqi ( word, "COORDINDEX" ) == TRUE ) {
7526  }
7527  else if ( leqi ( word, "UKNOTVECTOR" ) == TRUE ) {
7528  }
7529  else if ( leqi ( word, "VKNOTVECTOR" ) == TRUE ) {
7530  }
7531  else {
7532  bad_num = bad_num + 1;
7533  printf ( "Bad data %s\n", word );
7534  }
7535  }
7536 /*
7537  INDEXEDTRIANGLESTRIPSET
7538 */
7539  else if ( leqi ( level_name[level], "INDEXEDTRIANGLESTRIPSET" ) == TRUE ) {
7540 
7541  if ( strcmp ( word, "{" ) == 0 ) {
7542  }
7543  else if ( strcmp ( word, "}" ) == 0 ) {
7544  level = nlbrack - nrbrack;
7545  }
7546  else if ( leqi ( word, "VERTEXPROPERTY" ) == TRUE ) {
7547  count = sscanf ( next, "%s%n", word, &width );
7548  next = next + width;
7549  }
7550  else if ( leqi ( word, "COORDINDEX" ) == TRUE ) {
7551  ivert = 0;
7552  }
7553  else if ( leqi ( word, "NORMALINDEX" ) == TRUE ) {
7554  count = sscanf ( next, "%s%n", word, &width );
7555  next = next + width;
7556  }
7557  else {
7558  bad_num = bad_num + 1;
7559  printf ( "Bad data %s\n", word );
7560  }
7561  }
7562 /*
7563  INFO
7564 */
7565  else if ( leqi ( level_name[level], "INFO" ) == TRUE ) {
7566 
7567  if ( strcmp ( word, "{" ) == 0 ) {
7568  }
7569  else if ( strcmp ( word, "}" ) == 0 ) {
7570  level = nlbrack - nrbrack;
7571  }
7572  else if ( leqi ( word, "STRING" ) == TRUE ) {
7573  }
7574  else if ( strcmp ( word, "\"" ) == 0 ) {
7575  }
7576  else {
7577  }
7578  }
7579 /*
7580  LIGHTMODEL
7581  Read, but ignore.
7582 */
7583  else if ( leqi ( level_name[level], "LIGHTMODEL" ) == TRUE ) {
7584 
7585  if ( strcmp ( word, "{" ) == 0 ) {
7586  }
7587  else if ( strcmp ( word, "}" ) == 0 ) {
7588  level = nlbrack - nrbrack;
7589  }
7590  else if ( leqi ( word, "model" ) == TRUE ) {
7591  }
7592  else {
7593  }
7594  }
7595 /*
7596  MATERIAL
7597  Read, but ignore.
7598 */
7599  else if ( leqi ( level_name[level],"MATERIAL" ) == TRUE ) {
7600 
7601  if ( strcmp ( word, "{" ) == 0 ) {
7602  }
7603  else if ( strcmp ( word, "}" ) == 0 ) {
7604  level = nlbrack - nrbrack;
7605  }
7606  else if ( leqi ( word, "AMBIENTCOLOR" ) == TRUE ) {
7607  }
7608  else if ( leqi ( word, "EMISSIVECOLOR" ) == TRUE ) {
7609  }
7610  else if ( leqi ( word, "DIFFUSECOLOR" ) == TRUE ) {
7611  }
7612  else if ( leqi ( word, "SHININESS" ) == TRUE ) {
7613  }
7614  else if ( leqi ( word, "SPECULARCOLOR" ) == TRUE ) {
7615  }
7616  else if ( leqi ( word, "TRANSPARENCY" ) == TRUE ) {
7617  }
7618  else {
7619  }
7620  }
7621 /*
7622  MATERIALBINDING
7623  Read, but ignore
7624 */
7625  else if ( leqi ( level_name[level], "MATERIALBINDING" ) == TRUE ) {
7626 
7627  if ( strcmp ( word, "{" ) == 0 ) {
7628  }
7629  else if ( strcmp ( word, "}" ) == 0 ) {
7630  level = nlbrack - nrbrack;
7631  }
7632  else if ( leqi ( word, "VALUE" ) == TRUE ) {
7633  count = sscanf ( next, "%s%n", material_binding, &width );
7634  next = next + width;
7635  }
7636  else {
7637  count = sscanf ( next, "%f%n", &rval, &width );
7638  next = next + width;
7639 
7640  if ( count > 0 ) {
7641  }
7642  else {
7643  bad_num = bad_num + 1;
7644  printf ( "Bad data %s\n", word );
7645  }
7646  }
7647  }
7648 /*
7649  MATERIALINDEX
7650 */
7651  else if ( leqi ( level_name[level], "MATERIALINDEX" ) == TRUE ) {
7652 
7653  if ( strcmp ( word, "[" ) == 0 ) {
7654  ivert = 0;
7655  }
7656  else if ( strcmp ( word, "]" ) == 0 ) {
7657  level = nlbrack - nrbrack;
7658  }
7659 /*
7660  (indexedfaceset) MATERIALINDEX
7661 */
7662  else if ( leqi ( level_name[level-1], "INDEXEDFACESET" ) == TRUE ) {
7663 
7664  count = sscanf ( word, "%d%n", &jval, &width );
7665 
7666  if ( count > 0 ) {
7667 
7668  if ( jval == -1 ) {
7669  ivert = 0;
7670  face_num2 = face_num2 + 1;
7671  }
7672  else {
7673 
7674  if ( face_num2 < FACE_MAX ) {
7675  if ( jval != -1 ) {
7676  jval = jval + cor3_num_old;
7677  }
7678  vertex_material[ivert][face_num2] = jval;
7679  ivert = ivert + 1;
7680  }
7681  }
7682  }
7683  else {
7684  bad_num = bad_num + 1;
7685  printf ( "Bad data %s\n", word );
7686  }
7687  }
7688 /*
7689  (indexedlineset) MATERIALINDEX
7690 */
7691  else if ( leqi ( level_name[level-1], "INDEXEDLINESET" ) == TRUE ) {
7692 
7693  count = sscanf ( word, "%d%n", &jval, &width );
7694 
7695  if ( count > 0 ) {
7696 
7697  if ( line_num2 < LINES_MAX ) {
7698  if ( jval != -1 ) {
7699  jval = jval + cor3_num_old;
7700  }
7701  line_material[line_num2] = jval;
7702  line_num2 = line_num2 + 1;
7703  }
7704  }
7705  else {
7706  bad_num = bad_num + 1;
7707  printf ( "Bad data %s\n", word );
7708  }
7709  }
7710  else {
7711  count = sscanf ( word, "%d%n", &jval, &width );
7712 
7713  if ( count > 0 ) {
7714  }
7715  else {
7716  bad_num = bad_num + 1;
7717  printf ( "Bad data %s\n", word );
7718  }
7719  }
7720  }
7721 /*
7722  MATRIXTRANSFORM.
7723 */
7724  else if ( leqi ( level_name[level], "MATRIXTRANSFORM" ) == TRUE ) {
7725 
7726  if ( strcmp ( word, "{" ) == 0 ) {
7727  }
7728  else if ( strcmp ( word, "}" ) == 0 ) {
7729  level = nlbrack - nrbrack;
7730  }
7731  else if ( leqi ( word, "MATRIX" ) == TRUE ) {
7732  icol = -1;
7733  irow = 0;
7734  }
7735  else {
7736 
7737  count = sscanf ( word, "%f%n", &rval, &width );
7738 
7739  if ( count > 0 ) {
7740 
7741  icol = icol + 1;
7742  if ( icol > 3 ) {
7743  icol = 0;
7744  irow = irow + 1;
7745  if ( irow > 3 ) {
7746  irow = 0;
7747  }
7748  }
7749 
7750  transform_matrix[irow][icol] = rval;
7751  }
7752 
7753  }
7754  }
7755 /*
7756  NORMAL
7757  The field "VECTOR" may be followed by three numbers,
7758  (handled here), or by a square bracket, and sets of three numbers.
7759 */
7760  else if ( leqi ( level_name[level], "NORMAL" ) == TRUE ) {
7761 /*
7762  (vertexproperty) NORMAL
7763 */
7764  if ( leqi ( level_name[level-1], "VERTEXPROPERTY" ) == TRUE ) {
7765 
7766  if ( strcmp ( word, "[" ) == 0 ) {
7767  ixyz = 0;
7768  }
7769  else if ( strcmp ( word, "]" ) == 0 ) {
7770  level = nlbrack - nrbrack;
7771  }
7772  else {
7773 
7774  count = sscanf ( word, "%f%n", &rval, &width );
7775 
7776  if ( count > 0 ) {
7777 
7778  if ( inormface < FACE_MAX ) {
7779  face_normal[ixyz][inormface] = rval;
7780  }
7781 
7782  ixyz = ixyz + 1;
7783  if ( ixyz > 2 ) {
7784  ixyz = 0;
7785  inormface = inormface + 1;
7786  }
7787  }
7788  }
7789  }
7790 /*
7791  (anythingelse) NORMAL
7792 */
7793  else {
7794 
7795  if ( strcmp ( word, "{" ) == 0 ) {
7796  ixyz = 0;
7797  }
7798  else if ( strcmp ( word, "}" ) == 0 ) {
7799  level = nlbrack - nrbrack;
7800  }
7801  else if ( leqi ( word, "VECTOR" ) == TRUE ) {
7802  }
7803  else {
7804 
7805  count = sscanf ( word, "%f%n", &rval, &width );
7806 
7807  if ( count > 0 ) {
7808 
7809 /* COMMENTED OUT
7810 
7811  if ( nfnorm < FACE_MAX ) {
7812  normal[ixyz][nfnorm] = rval;
7813  }
7814 
7815 */
7816  ixyz = ixyz + 1;
7817  if ( ixyz > 2 ) {
7818  ixyz = 0;
7819  }
7820  }
7821  else {
7822  bad_num = bad_num + 1;
7823  printf ( "Bad data %s\n", word );
7824  }
7825  }
7826  }
7827  }
7828 /*
7829  NORMALBINDING
7830  Read, but ignore
7831 */
7832  else if ( leqi ( level_name[level], "NORMALBINDING" ) == TRUE ) {
7833 
7834  if ( strcmp ( word, "{" ) == 0 ) {
7835  }
7836  else if ( strcmp ( word, "}" ) == 0 ) {
7837  level = nlbrack - nrbrack;
7838  }
7839  else if ( leqi ( word, "VALUE" ) == TRUE ) {
7840  count = sscanf ( next, "%s%n", normal_binding, &width );
7841  next = next + width;
7842  }
7843  else {
7844  count = sscanf ( word, "%f%n", &rval, &width );
7845 
7846  if ( count > 0 ) {
7847  }
7848  else {
7849  bad_num = bad_num + 1;
7850  printf ( "Bad data %s\n", word );
7851  }
7852  }
7853  }
7854 /*
7855  NORMALINDEX
7856 */
7857  else if ( leqi ( level_name[level], "NORMALINDEX" ) == TRUE ) {
7858 /*
7859  (indexedtrianglestripset) NORMALINDEX
7860 */
7861  if ( leqi ( level_name[level-1], "INDEXEDTRIANGLESTRIPSET" ) == TRUE ) {
7862  count = sscanf ( word, "%d%n", &jval, &width );
7863 
7864  if ( count > 0 ) {
7865  }
7866  else if ( strcmp ( word, "[" ) == 0 ) {
7867  }
7868  else if ( strcmp ( word, "]" ) == 0 ) {
7869  }
7870  }
7871 /*
7872  (anythingelse) NORMALINDEX
7873 */
7874  else {
7875 
7876  if ( strcmp ( word, "[" ) == 0 ) {
7877  ivert = 0;
7878  }
7879  else if ( strcmp ( word, "]" ) == 0 ) {
7880  level = nlbrack - nrbrack;
7881  }
7882  else {
7883 
7884  count = sscanf ( word, "%d%n", &jval, &width );
7885 
7886  if ( count > 0 ) {
7887  if ( jval == -1 ) {
7888  ivert = 0;
7889  iface_num = iface_num + 1;
7890  }
7891  else {
7892  if ( iface_num < FACE_MAX ) {
7893  for ( i = 0; i < 3; i++ ){
7894  vertex_normal[i][ivert][iface_num] = normal_temp[i][jval];
7895  }
7896  ivert = ivert + 1;
7897  }
7898  }
7899  }
7900  else {
7901  bad_num = bad_num + 1;
7902  printf ( "Bad data %s\n", word );
7903  }
7904  }
7905  }
7906  }
7907 /*
7908  (coordinate3) POINT
7909 */
7910  else if ( leqi ( level_name[level], "POINT" ) == TRUE ) {
7911 
7912  if ( leqi ( level_name[level-1], "COORDINATE3" ) == TRUE ) {
7913 
7914  if ( strcmp ( word, "[" ) == 0 ) {
7915  ixyz = 0;
7916  cor3_num_old = cor3_num;
7917  }
7918  else if ( strcmp ( word, "]" ) == 0 ) {
7919  level = nlbrack - nrbrack;
7920  }
7921  else {
7922 
7923  count = sscanf ( word, "%f%n", &rval, &width );
7924 
7925  if ( count > 0 ) {
7926 
7927  if ( cor3_num < COR3_MAX ) {
7928  xvec[ixyz] = rval;
7929  }
7930 
7931  ixyz = ixyz + 1;
7932 
7933  if ( ixyz == 3 ) {
7934 
7935  ixyz = 0;
7936 
7937  tmat_mxp ( transform_matrix, xvec, xvec );
7938 
7939  cor3[0][cor3_num] = xvec[0];
7940  cor3[1][cor3_num] = xvec[1];
7941  cor3[2][cor3_num] = xvec[2];
7942 
7943  cor3_num = cor3_num + 1;
7944 
7945  continue;
7946  }
7947  }
7948  else {
7949  bad_num = bad_num + 1;
7950  break;
7951  }
7952  }
7953  }
7954 /*
7955  (texturecoodinate2) POINT
7956 */
7957  else if ( leqi ( level_name[level-1], "TEXTURECOORDINATE2" ) == TRUE ) {
7958 
7959  if ( strcmp ( word, "[" ) == 0 ) {
7960  iuv = 0;
7961  text_numure_temp = 0;
7962  }
7963  else if ( strcmp ( word, "]" ) == 0 ) {
7964  level = nlbrack - nrbrack;
7965  }
7966  else {
7967 
7968  count = sscanf ( word, "%f%n", &rval, &width );
7969 
7970  if ( count > 0 ) {
7971 
7972  texture_temp[iuv][text_numure_temp] = rval;
7973 
7974  iuv = iuv + 1;
7975  if ( iuv == 2 ) {
7976  iuv = 0;
7977  text_numure_temp = text_numure_temp + 1;
7978  }
7979  }
7980  else {
7981  printf ( "TextureCoordinate2 { Point [: Bad data\n" );
7982  bad_num = bad_num + 1;
7983  break;
7984  }
7985  }
7986  }
7987  }
7988 /*
7989  RGB
7990 */
7991  else if ( leqi ( level_name[level],"RGB" ) == TRUE ) {
7992 /*
7993  (basecolor) RGB
7994 */
7995  if ( leqi ( level_name[level-1], "BASECOLOR" ) == TRUE ) {
7996 
7997  if ( strcmp ( word, "[" ) == 0 ) {
7998  icolor = 0;
7999  }
8000  else if ( strcmp ( word, "]" ) == 0 ) {
8001  level = nlbrack - nrbrack;
8002  }
8003  else {
8004 
8005  count = sscanf ( word, "%f%n", &rval, &width );
8006 
8007  if ( count > 0 ) {
8008 
8009  rgbcolor[icolor][color_num] = rval;
8010  icolor = icolor + 1;
8011 
8012  if ( icolor == 3 ) {
8013  icolor = 0;
8014  color_num = color_num + 1;
8015  }
8016  }
8017  else {
8018  bad_num = bad_num + 1;
8019  printf ( "Bad data %s\n", word );
8020  }
8021  }
8022  }
8023 /*
8024  (anythingelse RGB)
8025 */
8026  else {
8027 
8028  printf ( "HALSBAND DES TODES!\n" );
8029 
8030  if ( strcmp ( word, "[" ) == 0 ) {
8031  icolor = 0;
8032  ivert = 0;
8033  }
8034  else if ( strcmp ( word, "]" ) == 0 ) {
8035  level = nlbrack - nrbrack;
8036  }
8037  else {
8038 
8039  count = sscanf ( word, "%f%n", &rval, &width );
8040 
8041  if ( count > 0 ) {
8042 
8043  if ( icface < FACE_MAX ) {
8044 
8045  vertex_rgb[icolor][ivert][icface] = rval;
8046 
8047  icolor = icolor + 1;
8048  if ( icolor == 3 ) {
8049  icolor = 0;
8050  color_num = color_num + 1;
8051  ivert = ivert + 1;
8052  if ( ivert == face_order[icface] ) {
8053  ivert = 0;
8054  icface = icface + 1;
8055  }
8056  }
8057  }
8058  }
8059  else {
8060  bad_num = bad_num + 1;
8061  printf ( "Bad data %s\n", word );
8062  }
8063  }
8064  }
8065 
8066  }
8067 /*
8068  SEPARATOR
8069 */
8070  else if ( leqi ( level_name[level], "SEPARATOR" ) == TRUE ) {
8071 
8072  if ( strcmp ( word, "{" ) == 0 ) {
8073  }
8074  else if ( strcmp ( word, "}" ) == 0 ) {
8075  level = nlbrack - nrbrack;
8076  }
8077  else {
8078  }
8079  }
8080 /*
8081  SHAPEHINTS
8082  Read, but ignore.
8083 */
8084  else if ( leqi ( level_name[level], "SHAPEHINTS" ) == TRUE ) {
8085 
8086  if ( strcmp ( word, "{" ) == 0 ) {
8087  }
8088  else if ( strcmp ( word, "}" ) == 0 ) {
8089  level = nlbrack - nrbrack;
8090  }
8091  else if ( leqi ( word, "CREASEANGLE" ) == TRUE ) {
8092 
8093  count = sscanf ( next, "%f%n", &rval, &width );
8094  next = next + width;
8095 
8096  if ( count <= 0 ) {
8097  bad_num = bad_num + 1;
8098  printf ( "Bad data %s\n", word );
8099  }
8100  }
8101  else if ( leqi ( word, "FACETYPE" ) == TRUE ) {
8102  count = sscanf ( next, "%s%n", word, &width );
8103  next = next + width;
8104  }
8105  else if ( leqi ( word, "SHAPETYPE" ) == TRUE ) {
8106  count = sscanf ( next, "%s%n", word, &width );
8107  next = next + width;
8108  }
8109  else if ( leqi ( word, "VERTEXORDERING" ) == TRUE ) {
8110  count = sscanf ( next, "%s%n", word, &width );
8111  next = next + width;
8112  }
8113  else {
8114  bad_num = bad_num + 1;
8115  printf ( "Bad data %s\n", word );
8116  }
8117  }
8118 /*
8119  TEXTURE2
8120 */
8121  else if ( leqi ( level_name[level], "TEXTURE2" ) == TRUE ) {
8122 
8123  if ( strcmp ( word, "{" ) == 0 ) {
8124  }
8125  else if ( strcmp ( word, "}" ) == 0 ) {
8126  level = nlbrack - nrbrack;
8127  texture_num = texture_num + 1;
8128  }
8129  else if ( leqi ( word, "BLENDCOLOR" ) == TRUE ) {
8130  }
8131 /*
8132  NEED TO REMOVE QUOTES SURROUNDING TEXTURE NAME.
8133 */
8134  else if ( leqi ( word, "FILENAME" ) == TRUE ) {
8135 
8136  count = sscanf ( next, "%s%n", word, &width );
8137  next = next + width;
8138 
8139  strcpy ( texture_name[texture_num], word );
8140 
8141  i = 0;
8142  j = 0;
8143  do {
8144  c = texture_name[texture_num][i];
8145  i = i + 1;
8146  if ( c != '"' ) {
8147  texture_name[texture_num][j] = c;
8148  j = j + 1;
8149  }
8150  } while ( c != '\0' );
8151 
8152  }
8153  else if ( leqi ( word, "IMAGE" ) == TRUE ) {
8154  }
8155  else if ( leqi ( word, "MODEL" ) == TRUE ) {
8156  count = sscanf ( next, "%s%n", word, &width );
8157  next = next + width;
8158  }
8159  else if ( leqi ( word, "WRAPS" ) == TRUE ) {
8160  count = sscanf ( next, "%s%n", word, &width );
8161  next = next + width;
8162  }
8163  else if ( leqi ( word, "WRAPT" ) == TRUE ) {
8164  count = sscanf ( next, "%s%n", word, &width );
8165  next = next + width;
8166  }
8167  else {
8168  }
8169  }
8170 /*
8171  TEXTURECOORDINATE2
8172 */
8173  else if ( leqi ( level_name[level], "TEXTURECOORDINATE2" ) == TRUE ) {
8174 
8175  if ( strcmp ( word, "{" ) == 0 ) {
8176  }
8177  else if ( strcmp ( word, "}" ) == 0 ) {
8178  level = nlbrack - nrbrack;
8179  }
8180  else if ( leqi ( word, "POINT" ) == TRUE ) {
8181  }
8182  else {
8183  bad_num = bad_num + 1;
8184  printf ( "TEXTURECOORDINATE2: Bad data %s\n", word );
8185  }
8186  }
8187 /*
8188  TEXTURECOORDINATEBINDING
8189 */
8190  else if ( leqi ( level_name[level], "TEXTURECOORDINATEBINDING" ) == TRUE ) {
8191 
8192  if ( strcmp ( word, "{" ) == 0 ) {
8193  }
8194  else if ( strcmp ( word, "}" ) == 0 ) {
8195  level = nlbrack - nrbrack;
8196  }
8197  else if ( leqi ( word, "VALUE" ) == TRUE ) {
8198  count = sscanf ( next, "%s%n", texture_binding, &width );
8199  next = next + width;
8200  }
8201  else {
8202  bad_num = bad_num + 1;
8203  printf ( "Bad data %s\n", word );
8204  }
8205  }
8206 /*
8207  TEXTURECOORDINDEX
8208 */
8209  else if ( leqi ( level_name[level], "TEXTURECOORDINDEX" ) == TRUE ) {
8210 
8211  if ( strcmp ( word, "[" ) == 0 ) {
8212  ivert = 0;
8213  iface_num = 0;
8214  }
8215  else if ( strcmp ( word, "]" ) == 0 ) {
8216  level = nlbrack - nrbrack;
8217  }
8218  else {
8219 
8220  count = sscanf ( word, "%d%n", &jval, &width );
8221 
8222  if ( count > 0 ) {
8223 
8224  if ( jval == - 1 ) {
8225  ivert = 0;
8226  }
8227  else {
8228 
8229  if ( iface_num < FACE_MAX ) {
8230  vertex_tex_uv[0][ivert][iface_num] = texture_temp[0][jval];
8231  vertex_tex_uv[1][ivert][iface_num] = texture_temp[1][jval];
8232  }
8233 
8234  ivert = ivert + 1;
8235 
8236  if ( ivert == face_order[iface_num] ) {
8237  ivert = 0;
8238  iface_num = iface_num + 1;
8239  }
8240  }
8241 
8242  }
8243  else {
8244  bad_num = bad_num + 1;
8245  printf ( "Bad data %s\n", word );
8246  }
8247 
8248  }
8249  }
8250 /*
8251  UKNOTVECTOR
8252 */
8253  else if ( leqi ( level_name[level], "UKNOTVECTOR" ) == TRUE ) {
8254 
8255  if ( strcmp ( word, "[" ) == 0 ) {
8256  continue;
8257  }
8258  else if ( strcmp ( word, "]" ) == 0 ) {
8259  level = nlbrack - nrbrack;
8260  continue;
8261  }
8262  else {
8263  count = sscanf ( word, "%d%n", &jval, &width );
8264  }
8265  }
8266 /*
8267  VECTOR
8268 */
8269  else if ( leqi ( level_name[level], "VECTOR" ) == TRUE ) {
8270  if ( strcmp ( word, "[" ) == 0 ) {
8271  }
8272  else if ( strcmp ( word, "]" ) == 0 ) {
8273  level = nlbrack - nrbrack;
8274  }
8275 /*
8276  (normal) VECTOR
8277 */
8278  else if ( leqi ( level_name[level-1], "NORMAL" ) == TRUE ) {
8279 
8280  count = sscanf ( word, "%f%n", &rval, &width );
8281 
8282  if ( count > 0 ) {
8283 
8284  if ( normal_num_temp < ORDER_MAX * FACE_MAX ) {
8285  normal_temp[ixyz][normal_num_temp] = rval;
8286  ixyz = ixyz + 1;
8287  if ( ixyz == 3 ) {
8288  ixyz = 0;
8289  normal_num_temp = normal_num_temp + 1;
8290  }
8291  }
8292  }
8293  else {
8294  bad_num = bad_num + 1;
8295  printf ( "NORMAL VECTOR: bad data %s\n", word );
8296  }
8297  }
8298  }
8299 /*
8300  (vertexproperty) VERTEX
8301 */
8302  else if ( leqi ( level_name[level], "VERTEX" ) == TRUE ) {
8303 
8304  if ( leqi ( level_name[level-1], "VERTEXPROPERTY" ) == TRUE ) {
8305 
8306  if ( strcmp ( word, "[" ) == 0 ) {
8307  ixyz = 0;
8308  cor3_num_old = cor3_num;
8309  }
8310  else if ( strcmp ( word, "]" ) == 0 ) {
8311  level = nlbrack - nrbrack;
8312  }
8313  else {
8314  count = sscanf ( word, "%f%n", &rval, &width );
8315 
8316  if ( count > 0 ) {
8317 
8318  if ( cor3_num < COR3_MAX ) {
8319  cor3[ixyz][cor3_num] = rval;
8320  }
8321  ixyz = ixyz + 1;
8322  if ( ixyz == 3 ) {
8323  ixyz = 0;
8324  cor3_num = cor3_num + 1;
8325  }
8326 
8327  }
8328  else {
8329  bad_num = bad_num + 1;
8330  printf ( "Bad data %s\n", word );
8331  }
8332  }
8333  }
8334  }
8335 /*
8336  (indexedtrianglestripset) VERTEXPROPERTY
8337 */
8338  else if ( leqi ( level_name[level], "VERTEXPROPERTY" ) == TRUE ) {
8339 
8340  if ( strcmp ( word, "{" ) == 0 ) {
8341  }
8342  else if ( strcmp ( word, "}" ) == 0 ) {
8343  level = nlbrack - nrbrack;
8344  }
8345  else if ( leqi ( word, "VERTEX" ) == TRUE ) {
8346  }
8347  else if ( leqi ( word, "NORMAL" ) == TRUE ) {
8348  ixyz = 0;
8349  }
8350  else if ( leqi ( word, "MATERIALBINDING" ) == TRUE ) {
8351  count = sscanf ( next, "%s%n", word, &width );
8352  next = next + width;
8353  }
8354  else if ( leqi ( word, "NORMALBINDING" ) == TRUE ) {
8355  count = sscanf ( next, "%s%n", word, &width );
8356  next = next + width;
8357  }
8358  else {
8359  bad_num = bad_num + 1;
8360  printf ( "Bad data %s\n", word );
8361  }
8362  }
8363 /*
8364  VKNOTVECTOR
8365 */
8366  else if ( leqi ( level_name[level], "VKNOTVECTOR" ) == TRUE ) {
8367 
8368  if ( strcmp ( word, "[" ) == 0 ) {
8369  continue;
8370  }
8371  else if ( strcmp ( word, "]" ) == 0 ) {
8372  level = nlbrack - nrbrack;
8373  continue;
8374  }
8375  else {
8376  count = sscanf ( word, "%d%n", &jval, &width );
8377  }
8378  }
8379 /*
8380  Any other word:
8381 */
8382  else {
8383  }
8384  }
8385  }
8386 /*
8387  Reset the transformation matrix to the identity,
8388  because, presumably, we've applied it by now.
8389 */
8391 
8392  return SUCCESS;
8393 }
8394 /******************************************************************************/
8395 
8396 int iv_write ( FILE *fileout )
8397 
8398 /******************************************************************************/
8399 
8400 /*
8401  Purpose:
8402 
8403  IV_WRITE writes graphics information to an Inventor file.
8404 
8405  Modified:
8406 
8407  29 June 1999
8408 
8409  Author:
8410 
8411  John Burkardt
8412 */
8413 {
8414  int icor3;
8415  int iface;
8416  int itemp;
8417  int ivert;
8418  int j;
8419  int length;
8420  int text_num;
8421 
8422  text_num = 0;
8423 
8424  fprintf ( fileout, "#Inventor V2.0 ascii\n" );
8425  fprintf ( fileout, "\n" );
8426  fprintf ( fileout, "Separator {\n" );
8427  fprintf ( fileout, " Info {\n" );
8428  fprintf ( fileout, " string \"%s generated by IVCON.\"\n", fileout_name );
8429  fprintf ( fileout, " string \"Original data in file %s.\"\n", filein_name );
8430  fprintf ( fileout, " }\n" );
8431  fprintf ( fileout, " Separator {\n" );
8432  text_num = text_num + 8;
8433 /*
8434  LightModel:
8435 
8436  BASE_COLOR ignores light sources, and uses only diffuse color
8437  and transparency. Even without normal vector information,
8438  the object will show up. However, you won't get shadow
8439  and lighting effects.
8440 
8441  PHONG uses the Phong lighting model, accounting for light sources
8442  and surface orientation. This is the default. I believe
8443  you need accurate normal vector information in order for this
8444  option to produce nice pictures.
8445 
8446  DEPTH ignores light sources, and calculates lighting based on
8447  the location of the object within the near and far planes
8448  of the current camera's view volume.
8449 */
8450  fprintf ( fileout, " LightModel {\n" );
8451  fprintf ( fileout, " model PHONG\n" );
8452  fprintf ( fileout, " }\n" );
8453  text_num = text_num + 3;
8454 /*
8455  Transformation matrix.
8456 */
8457  fprintf ( fileout, " MatrixTransform { matrix\n" );
8458  fprintf ( fileout, " %f %f %f %f\n", transform_matrix[0][0],
8459  transform_matrix[0][1], transform_matrix[0][2], transform_matrix[0][3] );
8460  fprintf ( fileout, " %f %f %f %f\n", transform_matrix[1][0],
8461  transform_matrix[1][1], transform_matrix[1][2], transform_matrix[1][3] );
8462  fprintf ( fileout, " %f %f %f %f\n", transform_matrix[2][0],
8463  transform_matrix[2][1], transform_matrix[2][2], transform_matrix[2][3] );
8464  fprintf ( fileout, " %f %f %f %f\n", transform_matrix[3][0],
8465  transform_matrix[3][1], transform_matrix[3][2], transform_matrix[3][3] );
8466  fprintf ( fileout, " }\n" );
8467  text_num = text_num + 6;
8468 /*
8469  Material.
8470 */
8471  fprintf ( fileout, " Material {\n" );
8472  fprintf ( fileout, " ambientColor 0.2 0.2 0.2\n" );
8473  fprintf ( fileout, " diffuseColor 0.8 0.8 0.8\n" );
8474  fprintf ( fileout, " emissiveColor 0.0 0.0 0.0\n" );
8475  fprintf ( fileout, " specularColor 0.0 0.0 0.0\n" );
8476  fprintf ( fileout, " shininess 0.2\n" );
8477  fprintf ( fileout, " transparency 0.0\n" );
8478  fprintf ( fileout, " }\n" );
8479  text_num = text_num + 8;
8480 /*
8481  MaterialBinding
8482 */
8483  fprintf ( fileout, " MaterialBinding {\n" );
8484  fprintf ( fileout, " value PER_VERTEX_INDEXED\n" );
8485  fprintf ( fileout, " }\n" );
8486  text_num = text_num + 3;
8487 /*
8488  NormalBinding
8489 
8490  PER_VERTEX promises that we will write a list of normal vectors
8491  in a particular order, namely, the normal vectors for the vertices
8492  of the first face, then the second face, and so on.
8493 
8494  PER_VERTEX_INDEXED promises that we will write a list of normal vectors,
8495  and then, as part of the IndexedFaceSet, we will give a list of
8496  indices referencing this normal vector list.
8497 */
8498  fprintf ( fileout, " NormalBinding {\n" );
8499  fprintf ( fileout, " value PER_VERTEX_INDEXED\n" );
8500  fprintf ( fileout, " }\n" );
8501  text_num = text_num + 3;
8502 /*
8503  Texture2.
8504 
8505  FLAW: We can only handle on texture right now.
8506 */
8507  if ( texture_num > 0 ) {
8508  fprintf ( fileout, " Texture2 {\n" );
8509  fprintf ( fileout, " filename \"%s\"\n", texture_name[0] );
8510  fprintf ( fileout, " wrapS REPEAT\n" );
8511  fprintf ( fileout, " wrapT REPEAT\n" );
8512  fprintf ( fileout, " model MODULATE\n" );
8513  fprintf ( fileout, " blendColor 0.0 0.0 0.0\n" );
8514  fprintf ( fileout, " }\n" );
8515  text_num = text_num + 7;
8516  }
8517 /*
8518  TextureCoordinateBinding
8519 */
8520  fprintf ( fileout, " TextureCoordinateBinding {\n" );
8521  fprintf ( fileout, " value PER_VERTEX_INDEXED\n" );
8522  fprintf ( fileout, " }\n" );
8523  text_num = text_num + 3;
8524 /*
8525  ShapeHints
8526 */
8527  fprintf ( fileout, " ShapeHints {\n" );
8528  fprintf ( fileout, " vertexOrdering COUNTERCLOCKWISE\n" );
8529  fprintf ( fileout, " shapeType UNKNOWN_SHAPE_TYPE\n" );
8530  fprintf ( fileout, " faceType CONVEX\n" );
8531  fprintf ( fileout, " creaseAngle 6.28319\n" );
8532  fprintf ( fileout, " }\n" );
8533  text_num = text_num + 6;
8534 /*
8535  Point coordinates.
8536 */
8537  fprintf ( fileout, " Coordinate3 {\n" );
8538  fprintf ( fileout, " point [\n" );
8539  text_num = text_num + 2;
8540 
8541  for ( j = 0; j < cor3_num; j++ ) {
8542  fprintf ( fileout, " %f %f %f,\n", cor3[0][j], cor3[1][j], cor3[2][j] );
8543  text_num = text_num + 1;
8544  }
8545  fprintf ( fileout, " ]\n" );
8546  fprintf ( fileout, " }\n" );
8547  text_num = text_num + 2;
8548 /*
8549  Texture coordinates.
8550 */
8551  fprintf ( fileout, " TextureCoordinate2 {\n" );
8552  fprintf ( fileout, " point [\n" );
8553  text_num = text_num + 2;
8554 
8555  for ( iface = 0; iface < face_num; iface++ ) {
8556  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
8557  fprintf ( fileout, " %f %f,\n", vertex_tex_uv[0][ivert][iface],
8558  vertex_tex_uv[1][ivert][iface] );
8559  text_num = text_num + 1;
8560  }
8561  }
8562  fprintf ( fileout, " ]\n" );
8563  fprintf ( fileout, " }\n" );
8564  text_num = text_num + 2;
8565 /*
8566  BaseColor.
8567 */
8568  if ( color_num > 0 ) {
8569 
8570  fprintf ( fileout, " BaseColor {\n" );
8571  fprintf ( fileout, " rgb [\n" );
8572  text_num = text_num + 2;
8573 
8574  for ( j = 0; j < color_num; j++ ) {
8575  fprintf ( fileout, " %f %f %f,\n", rgbcolor[0][j], rgbcolor[1][j],
8576  rgbcolor[2][j] );
8577  text_num = text_num + 1;
8578  }
8579 
8580  fprintf ( fileout, " ]\n" );
8581  fprintf ( fileout, " }\n" );
8582  text_num = text_num + 2;
8583  }
8584 /*
8585  Normal vectors.
8586  Use the normal vectors associated with nodes.
8587 */
8588  if ( face_num > 0 ) {
8589 
8590  fprintf ( fileout, " Normal { \n" );
8591  fprintf ( fileout, " vector [\n" );
8592  text_num = text_num + 2;
8593 
8594  for ( icor3 = 0; icor3 < cor3_num; icor3++ ) {
8595  fprintf ( fileout, " %f %f %f,\n",
8596  cor3_normal[0][icor3],
8597  cor3_normal[1][icor3],
8598  cor3_normal[2][icor3] );
8599  text_num = text_num + 1;
8600  }
8601 
8602  fprintf ( fileout, " ]\n" );
8603  fprintf ( fileout, " }\n" );
8604  text_num = text_num + 2;
8605  }
8606 /*
8607  IndexedLineSet
8608 */
8609  if ( line_num > 0 ) {
8610 
8611  fprintf ( fileout, " IndexedLineSet {\n" );
8612 /*
8613  IndexedLineSet coordIndex
8614 */
8615  fprintf ( fileout, " coordIndex [\n" );
8616  text_num = text_num + 2;
8617 
8618  length = 0;
8619 
8620  for ( j = 0; j < line_num; j++ ) {
8621 
8622  if ( length == 0 ) {
8623  fprintf ( fileout, " " );
8624  }
8625 
8626  fprintf ( fileout, " %d,", line_dex[j] );
8627  length = length + 1;
8628 
8629  if ( line_dex[j] == -1 || length >= 10 || j == line_num-1 ) {
8630  fprintf ( fileout, "\n" );
8631  text_num = text_num + 1;
8632  length = 0;
8633  }
8634  }
8635 
8636  fprintf ( fileout, " ]\n" );
8637  text_num = text_num + 1;
8638 /*
8639  IndexedLineSet materialIndex.
8640 */
8641  fprintf ( fileout, " materialIndex [\n" );
8642  text_num = text_num + 1;
8643 
8644  length = 0;
8645 
8646  for ( j = 0; j < line_num; j++ ) {
8647 
8648  if ( length == 0 ) {
8649  fprintf ( fileout, " " );
8650  }
8651 
8652  fprintf ( fileout, " %d,", line_material[j] );
8653  length = length + 1;
8654 
8655  if ( line_material[j] == -1 || length >= 10 || j == line_num-1 ) {
8656  fprintf ( fileout, "\n" );
8657  text_num = text_num + 1;
8658  length = 0;
8659  }
8660  }
8661 
8662  fprintf ( fileout, " ]\n" );
8663  fprintf ( fileout, " }\n" );
8664  text_num = text_num + 2;
8665  }
8666 /*
8667  IndexedFaceSet.
8668 */
8669  if ( face_num > 0 ) {
8670 
8671  fprintf ( fileout, " IndexedFaceSet {\n" );
8672  fprintf ( fileout, " coordIndex [\n" );
8673  text_num = text_num + 2;
8674 
8675  for ( iface = 0; iface < face_num; iface++ ) {
8676 
8677  fprintf ( fileout, " " );
8678 
8679  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
8680  fprintf ( fileout, " %d,", face[ivert][iface] );
8681  }
8682  fprintf ( fileout, " -1,\n" );
8683  text_num = text_num + 1;
8684  }
8685 
8686  fprintf ( fileout, " ]\n" );
8687  text_num = text_num + 1;
8688 /*
8689  IndexedFaceSet normalIndex
8690 */
8691  fprintf ( fileout, " normalIndex [\n" );
8692  text_num = text_num + 1;
8693 
8694  for ( iface = 0; iface < face_num; iface++ ) {
8695 
8696  fprintf ( fileout, " " );
8697 
8698  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
8699  fprintf ( fileout, " %d,", face[ivert][iface] );
8700  }
8701  fprintf ( fileout, " -1,\n" );
8702  text_num = text_num + 1;
8703  }
8704  fprintf ( fileout, " ]\n" );
8705  text_num = text_num + 1;
8706 /*
8707  IndexedFaceSet materialIndex
8708 */
8709  fprintf ( fileout, " materialIndex [\n" );
8710  text_num = text_num + 1;
8711 
8712  for ( iface = 0; iface < face_num; iface++ ) {
8713 
8714  fprintf ( fileout, " " );
8715 
8716  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
8717  fprintf ( fileout, " %d,", vertex_material[ivert][iface] );
8718  }
8719  fprintf ( fileout, " -1,\n" );
8720  text_num = text_num + 1;
8721  }
8722 
8723  fprintf ( fileout, " ]\n" );
8724  text_num = text_num + 1;
8725 /*
8726  IndexedFaceSet textureCoordIndex
8727 */
8728  fprintf ( fileout, " textureCoordIndex [\n" );
8729  text_num = text_num + 1;
8730 
8731  itemp = 0;
8732 
8733  for ( iface = 0; iface < face_num; iface++ ) {
8734 
8735  fprintf ( fileout, " " );
8736 
8737  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
8738  fprintf ( fileout, " %d,", itemp );
8739  itemp = itemp + 1;
8740  }
8741  fprintf ( fileout, " -1,\n" );
8742  text_num = text_num + 1;
8743  }
8744 
8745  fprintf ( fileout, " ]\n" );
8746 
8747  fprintf ( fileout, " }\n" );
8748  text_num = text_num + 2;
8749  }
8750 /*
8751  Close up the Separator nodes.
8752 */
8753  fprintf ( fileout, " }\n" );
8754  fprintf ( fileout, "}\n" );
8755  text_num = text_num + 2;
8756 /*
8757  Report.
8758 */
8759  printf ( "\n" );
8760  printf ( "IV_WRITE - Wrote %d text lines;\n", text_num );
8761 
8762  return SUCCESS;
8763 }
8764 /******************************************************************************/
8765 
8766 int ivec_max ( int n, int *a )
8767 
8768 /******************************************************************************/
8769 
8770 /*
8771  Purpose:
8772 
8773  IVEC_MAX returns the maximum element in an integer array.
8774 
8775  Modified:
8776 
8777  09 October 1998
8778 
8779  Author:
8780 
8781  John Burkardt
8782 */
8783 {
8784  int i;
8785  int *ia;
8786  int imax;
8787 
8788  if ( n <= 0 ) {
8789  imax = 0;
8790  }
8791  else {
8792  ia = a;
8793  imax = *ia;
8794  for ( i = 1; i < n; i++ ) {
8795  ia = ia + 1;
8796  if ( imax < *ia ) {
8797  imax = *ia;
8798  }
8799  }
8800  }
8801  return imax;
8802 }
8803 /******************************************************************************/
8804 
8805 int leqi ( char* string1, char* string2 )
8806 
8807 /******************************************************************************/
8808 
8809 /*
8810  Purpose:
8811 
8812  LEQI compares two strings for equality, disregarding case.
8813 
8814  Modified:
8815 
8816  15 September 1998
8817 
8818  Author:
8819 
8820  John Burkardt
8821 */
8822 {
8823  int i;
8824  int nchar;
8825  int nchar1;
8826  int nchar2;
8827 
8828  nchar1 = strlen ( string1 );
8829  nchar2 = strlen ( string2 );
8830 
8831  if ( nchar1 < nchar2 ) {
8832  nchar = nchar1;
8833  }
8834  else {
8835  nchar = nchar2;
8836  }
8837 /*
8838  The strings are not equal if they differ over their common length.
8839 */
8840  for ( i = 0; i < nchar; i++ ) {
8841 
8842  if ( toupper ( string1[i] ) != toupper ( string2[i] ) ) {
8843  return FALSE;
8844  }
8845  }
8846 /*
8847  The strings are not equal if the longer one includes nonblanks
8848  in the tail.
8849 */
8850  if ( nchar1 > nchar ) {
8851  for ( i = nchar; i < nchar1; i++ ) {
8852  if ( string1[i] != ' ' ) {
8853  return FALSE;
8854  }
8855  }
8856  }
8857  else if ( nchar2 > nchar ) {
8858  for ( i = nchar; i < nchar2; i++ ) {
8859  if ( string2[i] != ' ' ) {
8860  return FALSE;
8861  }
8862  }
8863  }
8864  return TRUE;
8865 }
8866 /******************************************************************************/
8867 
8868 long int long_int_read ( FILE *filein )
8869 
8870 /******************************************************************************/
8871 
8872 /*
8873  Purpose:
8874 
8875  LONG_INT_READ reads a long int from a binary file.
8876 
8877  Modified:
8878 
8879  24 May 1999
8880 
8881  Author:
8882 
8883  John Burkardt
8884 */
8885 {
8886  union {
8887  long int yint;
8888  char ychar[4];
8889  } y;
8890 
8891  if ( byte_swap == TRUE ) {
8892  y.ychar[3] = fgetc ( filein );
8893  y.ychar[2] = fgetc ( filein );
8894  y.ychar[1] = fgetc ( filein );
8895  y.ychar[0] = fgetc ( filein );
8896  }
8897  else {
8898  y.ychar[0] = fgetc ( filein );
8899  y.ychar[1] = fgetc ( filein );
8900  y.ychar[2] = fgetc ( filein );
8901  y.ychar[3] = fgetc ( filein );
8902  }
8903 
8904  return y.yint;
8905 }
8906 /******************************************************************************/
8907 
8908 int long_int_write ( FILE *fileout, long int int_val )
8909 
8910 /******************************************************************************/
8911 
8912 /*
8913  Purpose:
8914 
8915  LONG_INT_WRITE writes a long int to a binary file.
8916 
8917  Modified:
8918 
8919  14 October 1998
8920 
8921  Author:
8922 
8923  John Burkardt
8924 */
8925 {
8926  union {
8927  long int yint;
8928  char ychar[4];
8929  } y;
8930 
8931  y.yint = int_val;
8932 
8933  if ( byte_swap == TRUE ) {
8934  fputc ( y.ychar[3], fileout );
8935  fputc ( y.ychar[2], fileout );
8936  fputc ( y.ychar[1], fileout );
8937  fputc ( y.ychar[0], fileout );
8938  }
8939  else {
8940  fputc ( y.ychar[0], fileout );
8941  fputc ( y.ychar[1], fileout );
8942  fputc ( y.ychar[2], fileout );
8943  fputc ( y.ychar[3], fileout );
8944  }
8945 
8946  return 4;
8947 }
8948 /******************************************************************************/
8949 
8950 void news ( void )
8951 
8952 /******************************************************************************/
8953 
8954 /*
8955  Purpose:
8956 
8957  NEWS reports the program change history.
8958 
8959  Modified:
8960 
8961  26 September 1999
8962 
8963  Author:
8964 
8965  John Burkardt
8966 */
8967 {
8968  printf ( "\n" );
8969  printf ( "Recent changes:\n" );
8970  printf ( "\n" );
8971  printf ( " 04 July 2000\n" );
8972  printf ( " Added preliminary XGL_WRITE.\n" );
8973  printf ( " 26 September 1999\n" );
8974  printf ( " After ASE_READ, call NODE_TO_VERTEX_MAT and VERTEX_TO_FACE_MATERIAL.\n" );
8975  printf ( " 27 July 1999\n" );
8976  printf ( " Corrected TMAT_ROT_VECTOR.\n" );
8977  printf ( " 17 July 1999\n" );
8978  printf ( " Added null edge and face deletion.\n" );
8979  printf ( " Corrected a string problem in SMF_READ.\n" );
8980  printf ( " 03 July 1999\n" );
8981  printf ( " Fixed a problem with BINDING variables in SMF_READ.\n" );
8982  printf ( " 02 July 1999\n" );
8983  printf ( " Added limited texture support in 3DS/IV.\n" );
8984  printf ( " 26 June 1999\n" );
8985  printf ( " BYU_READ added.\n" );
8986  printf ( " 25 June 1999\n" );
8987  printf ( " BYU_WRITE added.\n" );
8988  printf ( " 22 June 1999\n" );
8989  printf ( " TRIB_READ added.\n" );
8990  printf ( " 16 June 1999\n" );
8991  printf ( " TRIB_WRITE Greg Hood binary triangle output routine added.\n" );
8992  printf ( " 10 June 1999\n" );
8993  printf ( " TRIA_WRITE Greg Hood ASCII triangle output routine added.\n" );
8994  printf ( " 09 June 1999\n" );
8995  printf ( " TEC_WRITE TECPLOT output routine added.\n" );
8996  printf ( " IV_READ and IV_WRITE use TRANSFORM_MATRIX now.\n" );
8997  printf ( " 26 May 1999\n" );
8998  printf ( " LINE_PRUNE option added for VLA_WRITE.\n" );
8999  printf ( " 24 May 1999\n" );
9000  printf ( " Added << command to append new graphics data to old.\n" );
9001  printf ( " Stuck in first draft STLB_READ/STLB_WRITE routines.\n" );
9002  printf ( " STLA_WRITE and STLB_WRITE automatically decompose \n" );
9003  printf ( " non-triangular faces before writing.\n" );
9004  printf ( " 23 May 1999\n" );
9005  printf ( " Stuck in first draft WRL_WRITE routine.\n" );
9006  printf ( " 22 May 1999\n" );
9007  printf ( " Faces converted to lines before calling VLA_WRITE.\n" );
9008  printf ( " Added UCD_WRITE.\n" );
9009  printf ( " Added MATERIAL/PATCH/TAGGEDPOINTS fields in HRC_READ.\n" );
9010  printf ( " 17 May 1999\n" );
9011  printf ( " Updated SMF_WRITE, SMF_READ to match code in IVREAD.\n" );
9012  printf ( " Added transformation matrix routines.\n" );
9013  printf ( " 16 May 1999\n" );
9014  printf ( " Zik Saleeba improved DXF support to handle polygons.\n" );
9015  printf ( " 15 April 1999\n" );
9016  printf ( " Zik Saleeba added Golgotha GMOD file format support.\n" );
9017  printf ( " 03 December 1998\n" );
9018  printf ( " Set up simple hooks in TDS_READ_MATERIAL_SECTION.\n" );
9019  printf ( " 02 December 1998\n" );
9020  printf ( " Set up simple hooks for texture map names.\n" );
9021  printf ( " 19 November 1998\n" );
9022  printf ( " IV_WRITE uses PER_VERTEX normal binding.\n" );
9023  printf ( " 18 November 1998\n" );
9024  printf ( " Added node normals.\n" );
9025  printf ( " Finally added the -RN option.\n" );
9026  printf ( " 17 November 1998\n" );
9027  printf ( " Added face node ordering reversal option.\n" );
9028  printf ( " 20 October 1998\n" );
9029  printf ( " Added DATA_REPORT.\n" );
9030  printf ( " 19 October 1998\n" );
9031  printf ( " SMF_READ and SMF_WRITE added.\n" );
9032  printf ( " 16 October 1998\n" );
9033  printf ( " Fixing a bug in IV_READ that chokes on ]} and other\n" );
9034  printf ( " cases where brackets aren't properly spaced.\n" );
9035  printf ( " 11 October 1998\n" );
9036  printf ( " Added face subset selection option S.\n" );
9037  printf ( " 09 October 1998\n" );
9038  printf ( " Reworking normal vector treatments.\n" );
9039  printf ( " Synchronizing IVREAD and IVCON.\n" );
9040  printf ( " POV_WRITE added.\n" );
9041  printf ( " 02 October 1998\n" );
9042  printf ( " IVCON reproduces BOX.3DS and CONE.3DS exactly.\n" );
9043  printf ( " 30 September 1998\n" );
9044  printf ( " IVCON compiled on the PC.\n" );
9045  printf ( " Interactive BYTE_SWAP option added for binary files.\n" );
9046  printf ( " 25 September 1998\n" );
9047  printf ( " OBJECT_NAME made available to store object name.\n" );
9048  printf ( " 23 September 1998\n" );
9049  printf ( " 3DS binary files can be written.\n" );
9050  printf ( " 15 September 1998\n" );
9051  printf ( " 3DS binary files can be read.\n" );
9052  printf ( " 01 September 1998\n" );
9053  printf ( " COR3_RANGE, FACE_NORMAL_AVE added.\n" );
9054  printf ( " Major modifications to normal vectors.\n" );
9055  printf ( " 24 August 1998\n" );
9056  printf ( " HRC_READ added.\n" );
9057  printf ( " 21 August 1998\n" );
9058  printf ( " TXT_WRITE improved.\n" );
9059  printf ( " 20 August 1998\n" );
9060  printf ( " HRC_WRITE can output lines as linear splines.\n" );
9061  printf ( " 19 August 1998\n" );
9062  printf ( " Automatic normal computation for OBJ files.\n" );
9063  printf ( " Added normal vector computation.\n" );
9064  printf ( " HRC_WRITE is working.\n" );
9065  printf ( " 18 August 1998\n" );
9066  printf ( " IV_READ/IV_WRITE handle BASECOLOR RGB properly now.\n" );
9067  printf ( " Improved treatment of face materials and normals.\n" );
9068  printf ( " 17 August 1998\n" );
9069  printf ( " ORDER_MAX increased to 35.\n" );
9070  printf ( " FACE_PRINT routine added.\n" );
9071  printf ( " INIT_DATA routine added.\n" );
9072  printf ( " 14 August 1998\n" );
9073  printf ( " IV_READ is working.\n" );
9074  printf ( " 13 August 1998\n" );
9075  printf ( " ASE_WRITE is working.\n" );
9076  printf ( " IV_WRITE is working.\n" );
9077  printf ( " 12 August 1998\n" );
9078  printf ( " ASE_READ is working.\n" );
9079  printf ( " 10 August 1998\n" );
9080  printf ( " DXF_WRITE is working.\n" );
9081  printf ( " DXF_READ is working.\n" );
9082  printf ( " 27 July 1998\n" );
9083  printf ( " Interactive mode is working.\n" );
9084  printf ( " OBJ_READ is working.\n" );
9085  printf ( " 25 July 1998\n" );
9086  printf ( " OBJ_WRITE is working.\n" );
9087  printf ( " 24 July 1998\n" );
9088  printf ( " DATA_CHECK checks the input data.\n" );
9089  printf ( " VLA_READ is working.\n" );
9090  printf ( " VLA_WRITE is working.\n" );
9091  printf ( " 23 July 1998\n" );
9092  printf ( " STL_WRITE is working.\n" );
9093  printf ( " 22 July 1998\n" );
9094  printf ( " STL_READ is working.\n" );
9095  printf ( " TXT_WRITE is working.\n" );
9096 }
9097 /**********************************************************************/
9098 
9100 
9101 /**********************************************************************/
9102 
9103 /*
9104  Purpose:
9105 
9106  NODE_TO_VERTEX_MAT extends node material definitions to vertices.
9107 
9108  Discussion:
9109 
9110  A NODE is a point in space.
9111  A VERTEX is a node as used in a particular face.
9112  One node may be used as a vertex in several faces, or none.
9113 
9114  Modified:
9115 
9116  22 May 1999
9117 
9118  Author:
9119 
9120  John Burkardt
9121 */
9122 {
9123  int iface;
9124  int ivert;
9125  int node;
9126 
9127  for ( iface = 0; iface < face_num; iface++ ) {
9128  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
9129  node = face[ivert][iface];
9130  vertex_material[ivert][iface] = cor3_material[node];
9131  }
9132  }
9133 
9134  return;
9135 }
9136 /******************************************************************************/
9137 
9138 int obj_read ( FILE *filein )
9139 
9140 /******************************************************************************/
9141 
9142 /*
9143  Purpose:
9144 
9145  OBJ_READ reads a Wavefront OBJ file.
9146 
9147  Example:
9148 
9149  # magnolia.obj
9150 
9151  mtllib ./vp.mtl
9152 
9153  g
9154  v -3.269770 -39.572201 0.876128
9155  v -3.263720 -39.507999 2.160890
9156  ...
9157  v 0.000000 -9.988540 0.000000
9158  g stem
9159  s 1
9160  usemtl brownskn
9161  f 8 9 11 10
9162  f 12 13 15 14
9163  ...
9164  f 788 806 774
9165 
9166  Modified:
9167 
9168  20 October 1998
9169 
9170  Author:
9171 
9172  John Burkardt
9173 */
9174 {
9175  int count;
9176  int i;
9177  int ivert;
9178  char *next;
9179  char *next2;
9180  char *next3;
9181  int node;
9182  int vertex_normal_num;
9183  float r1;
9184  float r2;
9185  float r3;
9186  char token[LINE_MAX_LEN];
9187  char token2[LINE_MAX_LEN];
9188  int width;
9189 /*
9190  Initialize.
9191 */
9192  vertex_normal_num = 0;
9193 /*
9194  Read the next line of the file into INPUT.
9195 */
9196  while ( fgets ( input, LINE_MAX_LEN, filein ) != NULL ) {
9197 
9198  text_num = text_num + 1;
9199 /*
9200  Advance to the first nonspace character in INPUT.
9201 */
9202  for ( next = input; *next != '\0' && isspace(*next); next++ ) {
9203  }
9204 /*
9205  Skip blank lines and comments.
9206 */
9207 
9208  if ( *next == '\0' ) {
9209  continue;
9210  }
9211 
9212  if ( *next == '#' || *next == '$' ) {
9213  comment_num = comment_num + 1;
9214  continue;
9215  }
9216 /*
9217  Extract the first word in this line.
9218 */
9219  sscanf ( next, "%s%n", token, &width );
9220 /*
9221  Set NEXT to point to just after this token.
9222 */
9223 
9224  next = next + width;
9225 /*
9226  BEVEL
9227  Bevel interpolation.
9228 */
9229  if ( leqi ( token, "BEVEL" ) == TRUE ) {
9230  continue;
9231  }
9232 /*
9233  BMAT
9234  Basis matrix.
9235 */
9236  else if ( leqi ( token, "BMAT" ) == TRUE ) {
9237  continue;
9238  }
9239 /*
9240  C_INTERP
9241  Color interpolation.
9242 */
9243  else if ( leqi ( token, "C_INTERP" ) == TRUE ) {
9244  continue;
9245  }
9246 /*
9247  CON
9248  Connectivity between free form surfaces.
9249 */
9250  else if ( leqi ( token, "CON" ) == TRUE ) {
9251  continue;
9252  }
9253 /*
9254  CSTYPE
9255  Curve or surface type.
9256 */
9257  else if ( leqi ( token, "CSTYPE" ) == TRUE ) {
9258  continue;
9259  }
9260 /*
9261  CTECH
9262  Curve approximation technique.
9263 */
9264  else if ( leqi ( token, "CTECH" ) == TRUE ) {
9265  continue;
9266  }
9267 /*
9268  CURV
9269  Curve.
9270 */
9271  else if ( leqi ( token, "CURV" ) == TRUE ) {
9272  continue;
9273  }
9274 /*
9275  CURV2
9276  2D curve.
9277 */
9278  else if ( leqi ( token, "CURV2" ) == TRUE ) {
9279  continue;
9280  }
9281 /*
9282  D_INTERP
9283  Dissolve interpolation.
9284 */
9285  else if ( leqi ( token, "D_INTERP" ) == TRUE ) {
9286  continue;
9287  }
9288 /*
9289  DEG
9290  Degree.
9291 */
9292  else if ( leqi ( token, "DEG" ) == TRUE ) {
9293  continue;
9294  }
9295 /*
9296  END
9297  End statement.
9298 */
9299  else if ( leqi ( token, "END" ) == TRUE ) {
9300  continue;
9301  }
9302 /*
9303  F V1 V2 V3
9304  or
9305  F V1/VT1/VN1 V2/VT2/VN2 ...
9306  or
9307  F V1//VN1 V2//VN2 ...
9308 
9309  Face.
9310  A face is defined by the vertices.
9311  Optionally, slashes may be used to include the texture vertex
9312  and vertex normal indices.
9313 
9314  OBJ line node indices are 1 based rather than 0 based.
9315  So we have to decrement them before loading them into FACE.
9316 */
9317 
9318  else if ( leqi ( token, "F" ) == TRUE ) {
9319 
9320  ivert = 0;
9321  face_order[face_num] = 0;
9322 /*
9323  Read each item in the F definition as a token, and then
9324  take it apart.
9325 */
9326  for ( ;; ) {
9327 
9328  count = sscanf ( next, "%s%n", token2, &width );
9329  next = next + width;
9330 
9331  if ( count != 1 ) {
9332  break;
9333  }
9334 
9335  count = sscanf ( token2, "%d%n", &node, &width );
9336  next2 = token2 + width;
9337 
9338  if ( count != 1 ) {
9339  break;
9340  }
9341 
9342  if ( ivert < ORDER_MAX && face_num < FACE_MAX ) {
9343  face[ivert][face_num] = node-1;
9344  vertex_material[ivert][face_num] = 0;
9346  }
9347 /*
9348  If there's a slash, skip to the next slash, and extract the
9349  index of the normal vector.
9350 */
9351  if ( *next2 == '/' ) {
9352 
9353  for ( next3 = next2 + 1; next3 < token2 + LINE_MAX_LEN; next3++ ) {
9354 
9355  if ( *next3 == '/' ) {
9356  next3 = next3 + 1;
9357  count = sscanf ( next3, "%d%n", &node, &width );
9358 
9359  node = node - 1;
9360  if ( 0 <= node && node < vertex_normal_num ) {
9361  for ( i = 0; i < 3; i++ ) {
9362  vertex_normal[i][ivert][face_num] = normal_temp[i][node];
9363  }
9364  }
9365  break;
9366  }
9367  }
9368  }
9369  ivert = ivert + 1;
9370  }
9371  face_num = face_num + 1;
9372  }
9373 
9374 /*
9375  G
9376  Group name.
9377 */
9378 
9379  else if ( leqi ( token, "G" ) == TRUE ) {
9380  continue;
9381  }
9382 /*
9383  HOLE
9384  Inner trimming hole.
9385 */
9386  else if ( leqi ( token, "HOLE" ) == TRUE ) {
9387  continue;
9388  }
9389 /*
9390  L
9391  I believe OBJ line node indices are 1 based rather than 0 based.
9392  So we have to decrement them before loading them into LINE_DEX.
9393 */
9394 
9395  else if ( leqi ( token, "L" ) == TRUE ) {
9396 
9397  for ( ;; ) {
9398 
9399  count = sscanf ( next, "%d%n", &node, &width );
9400  next = next + width;
9401 
9402  if ( count != 1 ) {
9403  break;
9404  }
9405 
9406  if ( line_num < LINES_MAX ) {
9407  line_dex[line_num] = node-1;
9408  line_material[line_num] = 0;
9409  }
9410  line_num = line_num + 1;
9411 
9412  }
9413 
9414  if ( line_num < LINES_MAX ) {
9415  line_dex[line_num] = -1;
9416  line_material[line_num] = -1;
9417  }
9418  line_num = line_num + 1;
9419 
9420  }
9421 
9422 /*
9423  LOD
9424  Level of detail.
9425 */
9426  else if ( leqi ( token, "LOD" ) == TRUE ) {
9427  continue;
9428  }
9429 /*
9430  MG
9431  Merging group.
9432 */
9433  else if ( leqi ( token, "MG" ) == TRUE ) {
9434  continue;
9435  }
9436 /*
9437  MTLLIB
9438  Material library.
9439 */
9440 
9441  else if ( leqi ( token, "MTLLIB" ) == TRUE ) {
9442  continue;
9443  }
9444 /*
9445  O
9446  Object name.
9447 */
9448  else if ( leqi ( token, "O" ) == TRUE ) {
9449  continue;
9450  }
9451 /*
9452  P
9453  Point.
9454 */
9455  else if ( leqi ( token, "P" ) == TRUE ) {
9456  continue;
9457  }
9458 /*
9459  PARM
9460  Parameter values.
9461 */
9462  else if ( leqi ( token, "PARM" ) == TRUE ) {
9463  continue;
9464  }
9465 /*
9466  S
9467  Smoothing group
9468 */
9469  else if ( leqi ( token, "S" ) == TRUE ) {
9470  continue;
9471  }
9472 /*
9473  SCRV
9474  Special curve.
9475 */
9476  else if ( leqi ( token, "SCRV" ) == TRUE ) {
9477  continue;
9478  }
9479 /*
9480  SHADOW_OBJ
9481  Shadow casting.
9482 */
9483  else if ( leqi ( token, "SHADOW_OBJ" ) == TRUE ) {
9484  continue;
9485  }
9486 /*
9487  SP
9488  Special point.
9489 */
9490  else if ( leqi ( token, "SP" ) == TRUE ) {
9491  continue;
9492  }
9493 /*
9494  STECH
9495  Surface approximation technique.
9496 */
9497  else if ( leqi ( token, "STECH" ) == TRUE ) {
9498  continue;
9499  }
9500 /*
9501  STEP
9502  Stepsize.
9503 */
9504  else if ( leqi ( token, "CURV" ) == TRUE ) {
9505  continue;
9506  }
9507 /*
9508  SURF
9509  Surface.
9510 */
9511  else if ( leqi ( token, "SURF" ) == TRUE ) {
9512  continue;
9513  }
9514 /*
9515  TRACE_OBJ
9516  Ray tracing.
9517 */
9518  else if ( leqi ( token, "TRACE_OBJ" ) == TRUE ) {
9519  continue;
9520  }
9521 /*
9522  TRIM
9523  Outer trimming loop.
9524 */
9525  else if ( leqi ( token, "TRIM" ) == TRUE ) {
9526  continue;
9527  }
9528 /*
9529  USEMTL
9530  Material name.
9531 */
9532  else if ( leqi ( token, "USEMTL" ) == TRUE ) {
9533  continue;
9534  }
9535 
9536 /*
9537  V X Y Z W
9538  Geometric vertex.
9539  W is optional, a weight for rational curves and surfaces.
9540  The default for W is 1.
9541 */
9542 
9543  else if ( leqi ( token, "V" ) == TRUE ) {
9544 
9545  sscanf ( next, "%e %e %e", &r1, &r2, &r3 );
9546 
9547  if ( cor3_num < COR3_MAX ) {
9548  cor3[0][cor3_num] = r1;
9549  cor3[1][cor3_num] = r2;
9550  cor3[2][cor3_num] = r3;
9551  }
9552 
9553  cor3_num = cor3_num + 1;
9554 
9555  }
9556 /*
9557  VN
9558  Vertex normals.
9559 */
9560 
9561  else if ( leqi ( token, "VN" ) == TRUE ) {
9562 
9563  sscanf ( next, "%e %e %e", &r1, &r2, &r3 );
9564 
9565  if ( vertex_normal_num < ORDER_MAX * FACE_MAX ) {
9566  normal_temp[0][vertex_normal_num] = r1;
9567  normal_temp[1][vertex_normal_num] = r2;
9568  normal_temp[2][vertex_normal_num] = r3;
9569  }
9570 
9571  vertex_normal_num = vertex_normal_num + 1;
9572 
9573  }
9574 /*
9575  VT
9576  Vertex texture.
9577 */
9578  else if ( leqi ( token, "VT" ) == TRUE ) {
9579  continue;
9580  }
9581 /*
9582  VP
9583  Parameter space vertices.
9584 */
9585  else if ( leqi ( token, "VP" ) == TRUE ) {
9586  continue;
9587  }
9588 /*
9589  Unrecognized
9590 */
9591  else {
9592  bad_num = bad_num + 1;
9593  }
9594 
9595  }
9596  return SUCCESS;
9597 }
9598 /******************************************************************************/
9599 
9600 int obj_write ( FILE *fileout )
9601 
9602 /******************************************************************************/
9603 
9604 /*
9605  Purpose:
9606 
9607  OBJ_WRITE writes a Wavefront OBJ file.
9608 
9609  Example:
9610 
9611  # magnolia.obj
9612 
9613  mtllib ./vp.mtl
9614 
9615  g
9616  v -3.269770 -39.572201 0.876128
9617  v -3.263720 -39.507999 2.160890
9618  ...
9619  v 0.000000 -9.988540 0.000000
9620  g stem
9621  s 1
9622  usemtl brownskn
9623  f 8 9 11 10
9624  f 12 13 15 14
9625  ...
9626  f 788 806 774
9627 
9628  Modified:
9629 
9630  01 September 1998
9631 
9632  Author:
9633 
9634  John Burkardt
9635 */
9636 {
9637  int i;
9638  int iface;
9639  int indexvn;
9640  int ivert;
9641  int k;
9642  int new;
9643  int text_num;
9644  float w;
9645 /*
9646  Initialize.
9647 */
9648  text_num = 0;
9649  w = 1.0;
9650 
9651  fprintf ( fileout, "# %s created by IVCON.\n", fileout_name );
9652  fprintf ( fileout, "# Original data in %s.\n", filein_name );
9653  fprintf ( fileout, "\n" );
9654  fprintf ( fileout, "g %s\n", object_name );
9655  fprintf ( fileout, "\n" );
9656 
9657  text_num = text_num + 5;
9658 /*
9659  V: vertex coordinates.
9660 */
9661  for ( i = 0; i < cor3_num; i++ ) {
9662  fprintf ( fileout, "v %f %f %f\n",
9663  cor3[0][i], cor3[1][i], cor3[2][i]);
9664  text_num = text_num + 1;
9665  }
9666 
9667 /*
9668  VN: Vertex face normal vectors.
9669 */
9670  if ( face_num > 0 ) {
9671  fprintf ( fileout, "\n" );
9672  text_num = text_num + 1;
9673  }
9674 
9675  for ( iface = 0; iface < face_num; iface++ ) {
9676 
9677  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
9678 
9679  fprintf ( fileout, "vn %f %f %f\n", vertex_normal[0][ivert][iface],
9680  vertex_normal[1][ivert][iface], vertex_normal[2][ivert][iface] );
9681  text_num = text_num + 1;
9682  }
9683  }
9684 /*
9685  F: faces.
9686 */
9687  if ( face_num > 0 ) {
9688  fprintf ( fileout, "\n" );
9689  text_num = text_num + 1;
9690  }
9691 
9692  indexvn = 0;
9693 
9694  for ( iface = 0; iface < face_num; iface++ ) {
9695 
9696  fprintf ( fileout, "f" );
9697  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
9698  indexvn = indexvn + 1;
9699  fprintf ( fileout, " %d//%d", face[ivert][iface]+1, indexvn );
9700  }
9701  fprintf ( fileout, "\n" );
9702  text_num = text_num + 1;
9703  }
9704 /*
9705  L: lines.
9706 */
9707  if ( line_num > 0 ) {
9708  fprintf ( fileout, "\n" );
9709  text_num = text_num + 1;
9710  }
9711 
9712  new = TRUE;
9713 
9714  for ( i = 0; i < line_num; i++ ) {
9715 
9716  k = line_dex[i];
9717 
9718  if ( k == -1 ) {
9719  fprintf ( fileout, "\n" );
9720  text_num = text_num + 1;
9721  new = TRUE;
9722  }
9723  else {
9724  if ( new == TRUE ) {
9725  fprintf ( fileout, "l" );
9726  new = FALSE;
9727  }
9728  fprintf ( fileout, " %d", k+1 );
9729  }
9730 
9731  }
9732 
9733  fprintf ( fileout, "\n" );
9734  text_num = text_num + 1;
9735 /*
9736  Report.
9737 */
9738  printf ( "\n" );
9739  printf ( "OBJ_WRITE - Wrote %d text lines.\n", text_num );
9740 
9741  return SUCCESS;
9742 }
9743 /******************************************************************************/
9744 
9745 int pov_write ( FILE *fileout )
9746 
9747 /******************************************************************************/
9748 
9749 /*
9750  Purpose:
9751 
9752  POV_WRITE writes graphics information to a POV file.
9753 
9754  Example:
9755 
9756  // cone.pov created by IVCON.
9757  // Original data in cone.iv
9758 
9759  #version 3.0
9760  #include "colors.inc"
9761  #include "shapes.inc"
9762  global_settings { assumed_gamma 2.2 }
9763 
9764  camera {
9765  right < 4/3, 0, 0>
9766  up < 0, 1, 0 >
9767  sky < 0, 1, 0 >
9768  angle 20
9769  location < 0, 0, -300 >
9770  look_at < 0, 0, 0>
9771  }
9772 
9773  light_source { < 20, 50, -100 > color White }
9774 
9775  background { color SkyBlue }
9776 
9777  #declare RedText = texture {
9778  pigment { color rgb < 0.8, 0.2, 0.2> }
9779  finish { ambient 0.2 diffuse 0.5 }
9780  }
9781 
9782  #declare BlueText = texture {
9783  pigment { color rgb < 0.2, 0.2, 0.8> }
9784  finish { ambient 0.2 diffuse 0.5 }
9785  }
9786  mesh {
9787  smooth_triangle {
9788  < 0.29, -0.29, 0.0>, < 0.0, 0.0, -1.0 >,
9789  < 38.85, 10.03, 0.0>, < 0.0, 0.0, -1.0 >,
9790  < 40.21, -0.29, 0.0>, < 0.0, 0.0, -1.0 >
9791  texture { RedText } }
9792  ...
9793  smooth_triangle {
9794  < 0.29, -0.29, 70.4142 >, < 0.0, 0.0, 1.0 >,
9795  < 8.56, -2.51, 70.4142 >, < 0.0, 0.0, 1.0 >,
9796  < 8.85, -0.29, 70.4142 >, < 0.0, 0.0, 1.0 >
9797  texture { BlueText } }
9798  }
9799 
9800  Modified:
9801 
9802  08 October 1998
9803 
9804  Author:
9805 
9806  John Burkardt
9807 */
9808 {
9809  int i;
9810  int j;
9811  int jj;
9812  int jlo;
9813  int k;
9814  int text_num;
9815 
9816  text_num = 0;
9817  fprintf ( fileout, "// %s created by IVCON.\n", fileout_name );
9818  fprintf ( fileout, "// Original data in %s.\n", filein_name );
9819  text_num = text_num + 2;
9820 /*
9821  Initial declarations.
9822 */
9823  fprintf ( fileout, "\n" );
9824  fprintf ( fileout, "#version 3.0\n" );
9825  fprintf ( fileout, "#include \"colors.inc\"\n" );
9826  fprintf ( fileout, "#include \"shapes.inc\"\n" );
9827  fprintf ( fileout, "global_settings { assumed_gamma 2.2 }\n" );
9828  fprintf ( fileout, "\n" );
9829  fprintf ( fileout, "camera {\n" );
9830  fprintf ( fileout, " right < 4/3, 0, 0>\n" );
9831  fprintf ( fileout, " up < 0, 1, 0 >\n" );
9832  fprintf ( fileout, " sky < 0, 1, 0 >\n" );
9833  fprintf ( fileout, " angle 20\n" );
9834  fprintf ( fileout, " location < 0, 0, -300 >\n" );
9835  fprintf ( fileout, " look_at < 0, 0, 0>\n" );
9836  fprintf ( fileout, "}\n" );
9837  fprintf ( fileout, "\n" );
9838  fprintf ( fileout, "light_source { < 20, 50, -100 > color White }\n" );
9839  fprintf ( fileout, "\n" );
9840  fprintf ( fileout, "background { color SkyBlue }\n" );
9841 
9842  text_num = text_num + 15;
9843 /*
9844  Declare RGB textures.
9845 */
9846  fprintf ( fileout, "\n" );
9847  fprintf ( fileout, "#declare RedText = texture {\n" );
9848  fprintf ( fileout, " pigment { color rgb < 0.8, 0.2, 0.2> }\n" );
9849  fprintf ( fileout, " finish { ambient 0.2 diffuse 0.5 }\n" );
9850  fprintf ( fileout, "}\n" );
9851  fprintf ( fileout, "\n" );
9852  fprintf ( fileout, "#declare GreenText = texture {\n" );
9853  fprintf ( fileout, " pigment { color rgb < 0.2, 0.8, 0.2> }\n" );
9854  fprintf ( fileout, " finish { ambient 0.2 diffuse 0.5 }\n" );
9855  fprintf ( fileout, "}\n" );
9856  fprintf ( fileout, "\n" );
9857  fprintf ( fileout, "#declare BlueText = texture {\n" );
9858  fprintf ( fileout, " pigment { color rgb < 0.2, 0.2, 0.8> }\n" );
9859  fprintf ( fileout, " finish { ambient 0.2 diffuse 0.5 }\n" );
9860  fprintf ( fileout, "}\n" );
9861 /*
9862  Write one big object.
9863 */
9864  fprintf ( fileout, "mesh {\n" );
9865  text_num = text_num + 1;
9866 /*
9867  Do the next face.
9868 */
9869  for ( i = 0; i < face_num; i++ ) {
9870 /*
9871  Break the face up into triangles, anchored at node 1.
9872 */
9873  for ( jlo = 0; jlo < face_order[i] - 2; jlo++ ) {
9874  fprintf ( fileout, " smooth_triangle {\n" );
9875  text_num = text_num + 1;
9876 
9877  for ( j = jlo; j < jlo + 3; j++ ) {
9878 
9879  if ( j == jlo ) {
9880  jj = 0;
9881  }
9882  else {
9883  jj = j;
9884  }
9885 
9886  k = face[jj][i];
9887 
9888  fprintf ( fileout, "<%f, %f, %f>, <%f, %f, %f>",
9889  cor3[0][k], cor3[1][k], cor3[2][k],
9890  vertex_normal[0][jj][i],
9891  vertex_normal[1][jj][i],
9892  vertex_normal[2][jj][i] );
9893 
9894  if ( j < jlo + 2 ) {
9895  fprintf ( fileout, ",\n" );
9896  }
9897  else {
9898  fprintf ( fileout, "\n" );
9899  }
9900  text_num = text_num + 1;
9901 
9902  }
9903 
9904  if (i%6 == 1 ) {
9905  fprintf ( fileout, "texture { RedText } }\n" );
9906  }
9907  else if ( i%2 == 0 ) {
9908  fprintf ( fileout, "texture { BlueText } }\n" );
9909  }
9910  else {
9911  fprintf ( fileout, "texture { GreenText } }\n" );
9912  }
9913  text_num = text_num + 1;
9914 
9915  }
9916 
9917  }
9918 
9919  fprintf ( fileout, "}\n" );
9920  text_num = text_num + 1;
9921 /*
9922  Report.
9923 */
9924  printf ( "\n" );
9925  printf ( "POV_WRITE - Wrote %d text lines.\n", text_num );
9926 
9927  return SUCCESS;
9928 }
9929 /******************************************************************************/
9930 
9931 int rcol_find ( float a[][COR3_MAX], int m, int n, float r[] )
9932 
9933 /******************************************************************************/
9934 
9935 /*
9936  Purpose:
9937 
9938  RCOL_FIND finds if a vector occurs in a table.
9939 
9940  Comment:
9941 
9942  Explicitly forcing the second dimension to be COR3_MAX is a kludge.
9943  I have to figure out how to do this as pointer references.
9944 
9945  Also, since the array is not sorted, this routine should not be carelessly
9946  called repeatedly for really big values of N, because you'll waste a
9947  lot of time.
9948 
9949  Modified:
9950 
9951  27 April 1999
9952 
9953  Author:
9954 
9955  John Burkardt
9956 */
9957 {
9958  int i;
9959  int icol;
9960  int j;
9961 
9962  icol = -1;
9963 
9964  for ( j = 0; j < n; j++ ) {
9965  for ( i = 0; i < m; i++ ) {
9966  if ( a[i][j] != r[i] ) {
9967  break;
9968  }
9969  if ( i == m-1 ) {
9970  return j;
9971  }
9972  }
9973  }
9974 
9975  return icol;
9976 }
9977 /**********************************************************************/
9978 
9979 float rgb_to_hue ( float r, float g, float b )
9980 
9981 /**********************************************************************/
9982 
9983 /*
9984  Purpose:
9985 
9986  RGB_TO_HUE converts (R,G,B) colors to a hue value between 0 and 1.
9987 
9988  Discussion:
9989 
9990  The hue computed here should be the same as the H value computed
9991  for HLS and HSV, except that it ranges from 0 to 1 instead of
9992  0 to 360.
9993 
9994  A monochromatic color ( white, black, or a shade of gray) does not
9995  have a hue. This routine will return a special value of H = -1
9996  for such cases.
9997 
9998  Examples:
9999 
10000  Color R G B H
10001 
10002  red 1.0 0.0 0.0 0.00
10003  yellow 1.0 1.0 0.0 0.16
10004  green 0.0 1.0 0.0 0.33
10005  cyan 0.0 1.0 1.0 0.50
10006  blue 0.0 0.0 1.0 0.67
10007  magenta 1.0 0.0 1.0 0.83
10008 
10009  black 0.0 0.0 0.0 -1.00
10010  gray 0.5 0.5 0.5 -1.00
10011  white 1.0 1.0 1.0 -1.00
10012 
10013  Modified:
10014 
10015  22 May 1999
10016 
10017  Author:
10018 
10019  John Burkardt
10020 
10021  Parameters:
10022 
10023  Input, float R, G, B, the red, green and blue values of the color.
10024  These values should be between 0 and 1.
10025 
10026  Output, float RGB_TO_HUE, the corresponding hue of the color, or -1.0 if
10027  the color is monochromatic.
10028 */
10029 {
10030  float h;
10031  float rgbmax;
10032  float rgbmin;
10033 /*
10034  Make sure the colors are between 0 and 1.
10035 */
10036  if ( r < 0.0 ) {
10037  r = 0.0;
10038  }
10039  else if ( r > 1.0 ) {
10040  r = 1.0;
10041  }
10042 
10043  if ( g < 0.0 ) {
10044  g = 0.0;
10045  }
10046  else if ( g > 1.0 ) {
10047  g = 1.0;
10048  }
10049 
10050  if ( b < 0.0 ) {
10051  b = 0.0;
10052  }
10053  else if ( b > 1.0 ) {
10054  b = 1.0;
10055  }
10056 /*
10057  Compute the minimum and maximum of R, G and B.
10058 */
10059  rgbmax = r;
10060  if ( g > rgbmax ) {
10061  rgbmax = g;
10062  }
10063  if ( b > rgbmax ) {
10064  rgbmax = b;
10065  }
10066 
10067  rgbmin = r;
10068  if ( g < rgbmin ) {
10069  rgbmin = g;
10070  }
10071  if ( b < rgbmin ) {
10072  rgbmin = b;
10073  }
10074 /*
10075  If RGBMAX = RGBMIN, { the color has no hue.
10076 */
10077  if ( rgbmax == rgbmin ) {
10078  h = - 1.0;
10079  }
10080 /*
10081  Otherwise, we need to determine the dominant color.
10082 */
10083  else {
10084 
10085  if ( r == rgbmax ) {
10086  h = ( g - b ) / ( rgbmax - rgbmin );
10087  }
10088  else if ( g == rgbmax ) {
10089  h = 2.0 + ( b - r ) / ( rgbmax - rgbmin );
10090  }
10091  else if ( b == rgbmax ) {
10092  h = 4.0 + ( r - g ) / ( rgbmax - rgbmin );
10093  }
10094 
10095  h = h / 6.0;
10096 /*
10097  Make sure H lies between 0 and 1.0.
10098 */
10099  if ( h < 0.0 ) {
10100  h = h + 1.0;
10101  }
10102  else if ( h > 1.0 ) {
10103  h = h - 1.0;
10104  }
10105 
10106  }
10107 
10108  return h;
10109 }
10110 /******************************************************************************/
10111 
10112 short int short_int_read ( FILE *filein )
10113 
10114 /******************************************************************************/
10115 /*
10116  Purpose:
10117 
10118  SHORT_INT_READ reads a short int from a binary file.
10119 
10120  Modified:
10121 
10122  14 October 1998
10123 
10124  Author:
10125 
10126  John Burkardt
10127 */
10128 {
10129  unsigned char c1;
10130  unsigned char c2;
10131  short int ival;
10132 
10133  c1 = fgetc ( filein );
10134  c2 = fgetc ( filein );
10135 
10136  ival = c1 | ( c2 << 8 );
10137 
10138  return ival;
10139 }
10140 /******************************************************************************/
10141 
10142 int short_int_write ( FILE *fileout, short int short_int_val )
10143 
10144 /******************************************************************************/
10145 
10146 /*
10147  Purpose:
10148 
10149  SHORT_INT_WRITE writes a short int to a binary file.
10150 
10151  Modified:
10152 
10153  14 October 1998
10154 
10155  Author:
10156 
10157  John Burkardt
10158 */
10159 {
10160  union {
10161  short int yint;
10162  char ychar[2];
10163  } y;
10164 
10165  y.yint = short_int_val;
10166 
10167  if ( byte_swap == TRUE ) {
10168  fputc ( y.ychar[1], fileout );
10169  fputc ( y.ychar[0], fileout );
10170  }
10171  else {
10172  fputc ( y.ychar[0], fileout );
10173  fputc ( y.ychar[1], fileout );
10174  }
10175 
10176  return 2;
10177 }
10178 /******************************************************************************/
10179 
10180 int smf_read ( FILE *filein )
10181 
10182 /******************************************************************************/
10183 
10184 /*
10185  Purpose:
10186 
10187  SMF_READ reads an SMF file.
10188 
10189  Example:
10190 
10191  #SMF2.0
10192  # cube_face.smf
10193  # This example demonstrates how an RGB color can be assigned to
10194  # each face of an object.
10195  #
10196  # First, define the geometry of the cube.
10197  #
10198  v 0.0 0.0 0.0
10199  v 1.0 0.0 0.0
10200  v 0.0 1.0 0.0
10201  v 1.0 1.0 0.0
10202  v 0.0 0.0 1.0
10203  v 1.0 0.0 1.0
10204  v 0.0 1.0 1.0
10205  v 1.0 1.0 1.0
10206  f 1 4 2
10207  f 1 3 4
10208  f 5 6 8
10209  f 5 8 7
10210  f 1 2 6
10211  f 1 6 5
10212  f 2 4 8
10213  f 2 8 6
10214  f 4 3 7
10215  f 4 7 8
10216  f 3 1 5
10217  f 3 5 7
10218  #
10219  # Colors will be bound 1 per face.
10220  #
10221  bind c face
10222  c 1.0 0.0 0.0
10223  c 1.0 0.0 0.0
10224  c 0.0 1.0 0.0
10225  c 0.0 1.0 0.0
10226  c 0.0 0.0 1.0
10227  c 0.0 0.0 1.0
10228  c 1.0 1.0 0.0
10229  c 1.0 1.0 0.0
10230  c 0.0 1.0 1.0
10231  c 0.0 1.0 1.0
10232  c 1.0 0.0 1.0
10233  c 1.0 0.0 1.0
10234  #
10235  # Normal vectors will be bound 1 per face.
10236  #
10237  bind n face
10238  n 0.0 0.0 -1.0
10239  n 0.0 0.0 -1.0
10240  n 0.0 0.0 1.0
10241  n 0.0 0.0 1.0
10242  n 0.0 -1.0 0.0
10243  n 0.0 -1.0 0.0
10244  n 1.0 0.0 0.0
10245  n 1.0 0.0 0.0
10246  n 0.0 1.0 0.0
10247  n 0.0 1.0 0.0
10248  n -1.0 0.0 0.0
10249  n -1.0 0.0 0.0
10250  #
10251  # Texture coordinate pairs will be bound 1 per face.
10252  #
10253  bind r face
10254  r 0.0 0.0
10255  r 0.0 0.1
10256  r 0.0 0.2
10257  r 0.0 0.3
10258  r 0.1 0.0
10259  r 0.1 0.1
10260  r 0.1 0.2
10261  r 0.1 0.3
10262  r 0.2 0.0
10263  r 0.2 0.1
10264  r 0.2 0.2
10265  r 0.2 0.3
10266 
10267  Modified:
10268 
10269  03 July 1999
10270 
10271  Author:
10272 
10273  John Burkardt
10274 */
10275 {
10276  float angle;
10277  char axis;
10278  float b;
10279  char cnr[LINE_MAX_LEN];
10280  int count;
10281  float dx;
10282  float dy;
10283  int face_count;
10284  float g;
10285  int icor3_normal;
10286  int icor3_tex_uv;
10287  int iface_normal;
10288  int iface_tex_uv;
10289  int imat;
10290  int ivert;
10291  int level;
10292  char *next;
10293  int node;
10294  int node_count;
10295  float r;
10296  float r1;
10297  float r2;
10298  float r3;
10299  float rgba[4];
10300  char *string;
10301  float sx;
10302  float sy;
10303  float sz;
10304  char token[LINE_MAX_LEN];
10305  char token2[LINE_MAX_LEN];
10306  char type[LINE_MAX_LEN];
10307  float u;
10308  float v;
10309  int vertex_base;
10310  int vertex_correction;
10311  int width;
10312  float x;
10313  float xvec[3];
10314  float y;
10315  float z;
10316 
10317  face_count = 0;
10318  icor3_normal = 0;
10319  icor3_tex_uv = 0;
10320  iface_normal = 0;
10321  iface_tex_uv = 0;
10322  level = 0;
10323  node_count = 0;
10324  vertex_base = 0;
10325  vertex_correction = 0;
10326 /*
10327  Read the next line of the file into INPUT.
10328 */
10329  while ( fgets ( input, LINE_MAX_LEN, filein ) != NULL ) {
10330 
10331  text_num = text_num + 1;
10332 
10333  if ( debug ) {
10334  printf ( "SMF_READ: DEBUG: Reading line #%d\n", text_num );
10335  }
10336 /*
10337  Advance to the first nonspace character in INPUT.
10338 */
10339  for ( next = input; *next != '\0' && isspace(*next); next++ ) {
10340  }
10341 /*
10342  Skip blank lines.
10343 */
10344 
10345  if ( *next == '\0' ) {
10346  continue;
10347  }
10348 /*
10349  Skip comment lines.
10350 */
10351  if ( *next == '#' || *next == '$' ) {
10352  comment_num = comment_num + 1;
10353  continue;
10354  }
10355 /*
10356  Extract the first word in this line.
10357 */
10358  sscanf ( next, "%s%n", token, &width );
10359 /*
10360  Set NEXT to point to just after this token.
10361 */
10362  next = next + width;
10363 /*
10364  BEGIN
10365  Reset the transformation matrix to identity.
10366  Node numbering starts at zero again. (Really, this is level based)
10367  (Really should define a new transformation matrix, and concatenate.)
10368  (Also, might need to keep track of level.)
10369 */
10370  if ( leqi ( token, "BEGIN" ) == TRUE ) {
10371 
10372  level = level + 1;
10373 
10374  vertex_base = cor3_num;
10375  group_num = group_num + 1;
10377 
10378  }
10379 /*
10380  BIND [c|n|r] [vertex|face]
10381  Specify the binding for RGB color, Normal, or Texture.
10382  Options are "vertex" or "face"
10383 */
10384  else if ( leqi ( token, "BIND" ) == TRUE ) {
10385 
10386  sscanf ( next, "%s%n", cnr, &width );
10387  next = next + width;
10388 
10389  if ( debug ) {
10390  printf ( "CNR = %s\n", cnr );
10391  }
10392 
10393  sscanf ( next, "%s%n", type, &width );
10394  next = next + width;
10395 
10396  if ( debug ) {
10397  printf ( "TYPE = %s\n", type );
10398  }
10399 
10400  if ( leqi ( cnr, "C" ) == TRUE ) {
10401 
10402  if ( leqi ( type, "VERTEX" ) == TRUE ) {
10403  strcpy ( material_binding, "PER_VERTEX" );
10404  }
10405  else if ( leqi ( type, "FACE" ) == TRUE ) {
10406  strcpy ( material_binding, "PER_FACE" );
10407  }
10408 
10409  }
10410  else if ( leqi ( cnr, "N" ) == TRUE ) {
10411 
10412  if ( leqi ( type, "VERTEX" ) == TRUE ) {
10413  strcpy ( normal_binding, "PER_VERTEX" );
10414  }
10415  else if ( leqi ( type, "FACE" ) == TRUE ) {
10416  strcpy ( normal_binding, "PER_FACE" );
10417  }
10418 
10419  }
10420  else if ( leqi ( cnr, "R" ) == TRUE ) {
10421 
10422  if ( leqi ( type, "VERTEX" ) == TRUE ) {
10423  strcpy ( texture_binding, "PER_VERTEX" );
10424  }
10425  else if ( leqi ( type, "FACE" ) == TRUE ) {
10426  strcpy ( texture_binding, "PER_FACE" );
10427  }
10428 
10429  }
10430 
10431  }
10432 /*
10433  C <r> <g> <b>
10434  Specify an RGB color, with R, G, B between 0.0 and 1.0.
10435 */
10436  else if ( leqi ( token, "C" ) == TRUE ) {
10437 
10438  sscanf ( next, "%f%n", &r, &width );
10439  next = next + width;
10440 
10441  sscanf ( next, "%f%n", &g, &width );
10442  next = next + width;
10443 
10444  sscanf ( next, "%f%n", &b, &width );
10445  next = next + width;
10446 /*
10447  Set up a temporary material (R,G,B,1.0).
10448  Add the material to the material database, or find the index of
10449  a matching material already in.
10450  Assign the material of the node or face to this index.
10451 */
10452  rgba[0] = r;
10453  rgba[1] = g;
10454  rgba[2] = b;
10455  rgba[3] = 1.0;
10456 
10457  if ( material_num < MATERIAL_MAX ) {
10458 
10459  for ( k = 0; k < 4; k++ ) {
10460  material_rgba[k][material_num] = rgba[k];
10461  }
10462 
10463  imat = material_num;
10464  material_num = material_num + 1;
10465 
10466  }
10467  else {
10468 
10469  imat = 0;
10470 
10471  }
10472 
10473  if ( leqi ( material_binding, "PER_FACE" ) == TRUE ) {
10474 
10475  face_count = face_count + 1;
10476  face_material[face_count] = imat;
10477 
10478  }
10479  else if ( leqi ( material_binding, "PER_VERTEX" ) == TRUE ) {
10480 
10481  node_count = node_count + 1;
10482  cor3_material[node_count] = imat;
10483 
10484  }
10485  else {
10486 
10487  printf ( "\n" );
10488  printf ( "SMF_READ - Fatal error!\n" );
10489  printf ( " Material binding undefined!\n" );
10490  return ERROR;
10491 
10492  }
10493 
10494  }
10495 /*
10496  END
10497  Drop down a level.
10498 */
10499  else if ( leqi ( token, "END" ) == TRUE ) {
10500 
10501  level = level - 1;
10502 
10503  if ( level < 0 ) {
10504  printf ( "\n" );
10505  printf ( "SMF_READ - Fatal error!\n" );
10506  printf ( " More END statements than BEGINs!\n" );
10507  return ERROR;
10508  }
10509  }
10510 /*
10511  F V1 V2 V3
10512 
10513  Face.
10514  A face is defined by the vertices.
10515  Node indices are 1 based rather than 0 based.
10516  So we have to decrement them before loading them into FACE.
10517  Note that vertex indices start back at 0 each time a BEGIN is entered.
10518  The strategy here won't handle nested BEGIN's, just one at a time.
10519 */
10520 
10521  else if ( leqi ( token, "F" ) == TRUE ) {
10522 
10523  ivert = 0;
10524  face_order[face_num] = 0;
10525 /*
10526  Read each item in the F definition as a token, and then
10527  take it apart.
10528 */
10529  for ( ;; ) {
10530 
10531  count = sscanf ( next, "%s%n", token2, &width );
10532  next = next + width;
10533 
10534  if ( count != 1 ) {
10535  break;
10536  }
10537 
10538  count = sscanf ( token2, "%d%n", &node, &width );
10539 
10540  if ( count != 1 ) {
10541  break;
10542  }
10543 
10544  if ( ivert < ORDER_MAX && face_num < FACE_MAX ) {
10545  face[ivert][face_num] = node - 1 + vertex_base;
10546  vertex_material[ivert][face_num] = 0;
10548  }
10549  ivert = ivert + 1;
10550  }
10551  face_num = face_num + 1;
10552  }
10553 /*
10554  N <x> <y> <z>
10555  Specify a normal vector.
10556 */
10557  else if ( leqi ( token, "N" ) == TRUE ) {
10558 
10559  sscanf ( next, "%f%n", &x, &width );
10560  next = next + width;
10561 
10562  sscanf ( next, "%f%n", &y, &width );
10563  next = next + width;
10564 
10565  sscanf ( next, "%f%n", &z, &width );
10566  next = next + width;
10567 
10568  if ( leqi ( normal_binding, "PER_FACE" ) == TRUE ) {
10569 
10570  face_normal[0][iface_normal] = x;
10571  face_normal[1][iface_normal] = y;
10572  face_normal[2][iface_normal] = z;
10573 
10574  iface_normal = iface_normal + 1;
10575 
10576  }
10577  else if ( leqi ( normal_binding, "PER_VERTEX" ) == TRUE ) {
10578 
10579  cor3_normal[0][icor3_normal] = x;
10580  cor3_normal[1][icor3_normal] = y;
10581  cor3_normal[2][icor3_normal] = z;
10582 
10583  icor3_normal = icor3_normal + 1;
10584 
10585  }
10586  else {
10587 
10588  printf ( "\n" );
10589  printf ( "SMF_READ - Fatal error!\n" );
10590  printf ( " Normal binding undefined!\n" );
10591  return ERROR;
10592 
10593  }
10594  }
10595 /*
10596  R <u> <v>
10597  Specify a texture coordinate.
10598 */
10599  else if ( leqi ( token, "R" ) == TRUE ) {
10600 
10601  sscanf ( next, "%f%n", &u, &width );
10602  next = next + width;
10603 
10604  sscanf ( next, "%f%n", &v, &width );
10605  next = next + width;
10606 
10607  if ( leqi ( texture_binding, "PER_FACE" ) == TRUE ) {
10608 
10609  face_tex_uv[0][iface_tex_uv] = u;
10610  face_tex_uv[1][iface_tex_uv] = v;
10611 
10612  icor3_tex_uv = icor3_tex_uv + 1;
10613 
10614  }
10615  else if ( leqi ( texture_binding, "PER_VERTEX" ) == TRUE ) {
10616 
10617  cor3_tex_uv[0][icor3_tex_uv] = u;
10618  cor3_tex_uv[1][icor3_tex_uv] = v;
10619 
10620  icor3_tex_uv = icor3_tex_uv + 1;
10621  }
10622  else {
10623  printf ( "\n" );
10624  printf ( "SMF_READ - Fatal error!\n" );
10625  printf ( " Texture binding undefined!\n" );
10626  return ERROR;
10627  }
10628 
10629  }
10630 /*
10631  ROT [x|y|z] <theta>
10632 */
10633  else if ( leqi ( token, "ROT" ) == TRUE ) {
10634 
10635  sscanf ( next, "%c%n", &axis, &width );
10636  next = next + width;
10637 
10638  sscanf ( next, "%f%n", &angle, &width );
10639  next = next + width;
10640 
10642 
10643  }
10644 /*
10645  SCALE <sx> <sy> <sz>
10646 */
10647  else if ( leqi ( token, "SCALE" ) == TRUE ) {
10648 
10649  sscanf ( next, "%f%n", &sx, &width );
10650  next = next + width;
10651 
10652  sscanf ( next, "%f%n", &sy, &width );
10653  next = next + width;
10654 
10655  sscanf ( next, "%f%n", &sz, &width );
10656  next = next + width;
10657 
10658  tmat_scale ( transform_matrix, transform_matrix, sx, sy, sz );
10659  }
10660 /*
10661  SET VERTEX_CORRECTION <i>
10662  Specify increment to add to vertex indices in file.
10663 */
10664  else if ( leqi ( token, "SET" ) == TRUE ) {
10665 
10666  sscanf ( next, "%s%n", cnr, &width );
10667  next = next + width;
10668 
10669  sscanf ( next, "%d%n", &vertex_correction, &width );
10670  next = next + width;
10671 
10672  }
10673 /*
10674  T_SCALE <dx> <dy>
10675  Specify a scaling to texture coordinates.
10676 */
10677  else if ( leqi ( token, "T_SCALE" ) == TRUE ) {
10678 
10679  sscanf ( next, "%f%n", &dx, &width );
10680  next = next + width;
10681 
10682  sscanf ( next, "%f%n", &dy, &width );
10683  next = next + width;
10684 
10685  }
10686 /*
10687  T_TRANS <dx> <dy>
10688  Specify a translation to texture coordinates.
10689 */
10690  else if ( leqi ( token, "T_TRANS" ) == TRUE ) {
10691 
10692  sscanf ( next, "%f%n", &dx, &width );
10693  next = next + width;
10694 
10695  sscanf ( next, "%f%n", &dy, &width );
10696  next = next + width;
10697 
10698  }
10699 /*
10700  TEX <filename>
10701  Specify a filename containing the texture.
10702  (ANY CHANCE THIS IS RIGHT?)
10703 */
10704  else if ( leqi ( token, "TEX" ) == TRUE ) {
10705 
10706  sscanf ( next, "%s%n", string, &width );
10707 
10708  for ( i = 0; i < LINE_MAX_LEN; i++ ) {
10709  texture_name[texture_num][i] = string[i];
10710  if ( string[i] == '\0' ) {
10711  break;
10712  }
10713  }
10714 
10715  texture_num = texture_num + 1;
10716 
10717  }
10718 /*
10719  TRANS <dx> <dy> <dz>
10720 */
10721  else if ( leqi ( token, "TRANS" ) == TRUE ) {
10722 
10723  sscanf ( next, "%f%n", &x, &width );
10724  next = next + width;
10725 
10726  sscanf ( next, "%f%n", &y, &width );
10727  next = next + width;
10728 
10729  sscanf ( next, "%f%n", &z, &width );
10730  next = next + width;
10731 
10733  }
10734 /*
10735  V X Y Z
10736  Geometric vertex.
10737 */
10738  else if ( leqi ( token, "V" ) == TRUE ) {
10739 
10740  sscanf ( next, "%e %e %e", &r1, &r2, &r3 );
10741 
10742  xvec[0] = r1;
10743  xvec[1] = r2;
10744  xvec[2] = r3;
10745 /*
10746  Apply current transformation matrix.
10747  Right now, we can only handle one matrix, not a stack of
10748  matrices representing nested BEGIN/END's.
10749 */
10750  tmat_mxp ( transform_matrix, xvec, xvec );
10751 
10752  if ( cor3_num < COR3_MAX ) {
10753  for ( i = 0; i < 3; i++ ) {
10754  cor3[i][cor3_num] = xvec[i];
10755  }
10756  }
10757 
10758  cor3_num = cor3_num + 1;
10759 
10760  }
10761 /*
10762  Unrecognized keyword.
10763 */
10764  else {
10765 
10766  bad_num = bad_num + 1;
10767 
10768  if ( bad_num <= 10 ) {
10769  printf ( "\n" );
10770  printf ( "SMF_READ: Bad data on line %d.\n", text_num );
10771  }
10772  }
10773 
10774  }
10775 /*
10776  Extend the material definition
10777  * from the face to the vertices and nodes, or
10778  * from the vertices to the faces and nodes.
10779 */
10780  if ( strcmp ( material_binding, "PER_FACE" ) == 0 ) {
10781 
10783 
10785 
10786  }
10787  else if ( strcmp ( material_binding, "PER_VERTEX" ) == 0 ) {
10788 
10790 
10792 
10793  }
10794 
10795  return SUCCESS;
10796 }
10797 /******************************************************************************/
10798 
10799 int smf_write ( FILE *fileout )
10800 
10801 /******************************************************************************/
10802 
10803 /*
10804  Purpose:
10805 
10806  SMF_WRITE writes graphics information to an SMF file.
10807 
10808  Example:
10809 
10810  #SMF2.0
10811  # cube_face.smf
10812  # This example demonstrates how an RGB color can be assigned to
10813  # each face of an object.
10814  #
10815  # First, define the geometry of the cube.
10816  #
10817  v 0.0 0.0 0.0
10818  v 1.0 0.0 0.0
10819  v 0.0 1.0 0.0
10820  v 1.0 1.0 0.0
10821  v 0.0 0.0 1.0
10822  v 1.0 0.0 1.0
10823  v 0.0 1.0 1.0
10824  v 1.0 1.0 1.0
10825  f 1 4 2
10826  f 1 3 4
10827  f 5 6 8
10828  f 5 8 7
10829  f 1 2 6
10830  f 1 6 5
10831  f 2 4 8
10832  f 2 8 6
10833  f 4 3 7
10834  f 4 7 8
10835  f 3 1 5
10836  f 3 5 7
10837  #
10838  # Colors will be bound 1 per face.
10839  #
10840  bind c face
10841  c 1.0 0.0 0.0
10842  c 1.0 0.0 0.0
10843  c 0.0 1.0 0.0
10844  c 0.0 1.0 0.0
10845  c 0.0 0.0 1.0
10846  c 0.0 0.0 1.0
10847  c 1.0 1.0 0.0
10848  c 1.0 1.0 0.0
10849  c 0.0 1.0 1.0
10850  c 0.0 1.0 1.0
10851  c 1.0 0.0 1.0
10852  c 1.0 0.0 1.0
10853  #
10854  # Normal vectors will be bound 1 per face.
10855  #
10856  bind n face
10857  n 0.0 0.0 -1.0
10858  n 0.0 0.0 -1.0
10859  n 0.0 0.0 1.0
10860  n 0.0 0.0 1.0
10861  n 0.0 -1.0 0.0
10862  n 0.0 -1.0 0.0
10863  n 1.0 0.0 0.0
10864  n 1.0 0.0 0.0
10865  n 0.0 1.0 0.0
10866  n 0.0 1.0 0.0
10867  n -1.0 0.0 0.0
10868  n -1.0 0.0 0.0
10869  #
10870  # Texture coordinate pairs will be bound 1 per face.
10871  #
10872  bind r face
10873  r 0.0 0.0
10874  r 0.0 0.1
10875  r 0.0 0.2
10876  r 0.0 0.3
10877  r 0.1 0.0
10878  r 0.1 0.1
10879  r 0.1 0.2
10880  r 0.1 0.3
10881  r 0.2 0.0
10882  r 0.2 0.1
10883  r 0.2 0.2
10884  r 0.2 0.3
10885 
10886  Modified:
10887 
10888  05 July 1999
10889 
10890  Author:
10891 
10892  John Burkardt
10893 */
10894 {
10895  int i;
10896  int icor3;
10897  int iface;
10898  int imat;
10899  int ivert;
10900  int text_num;
10901 /*
10902  Initialize.
10903 */
10904  text_num = 0;
10905 
10906  fprintf ( fileout, "#$SMF 2.0\n" );
10907  fprintf ( fileout, "#$vertices %d\n", cor3_num );
10908  fprintf ( fileout, "#$faces %d\n", face_num );
10909  fprintf ( fileout, "#\n" );
10910  fprintf ( fileout, "# %s created by IVCON.\n", fileout_name );
10911  fprintf ( fileout, "# Original data in %s.\n", filein_name );
10912  fprintf ( fileout, "#\n" );
10913 
10914  text_num = text_num + 7;
10915 /*
10916  V: vertex coordinates.
10917 */
10918  for ( i = 0; i < cor3_num; i++ ) {
10919  fprintf ( fileout, "v %f %f %f\n",
10920  cor3[0][i], cor3[1][i], cor3[2][i] );
10921  text_num = text_num + 1;
10922  }
10923 /*
10924  F: faces.
10925 */
10926  if ( face_num > 0 ) {
10927  fprintf ( fileout, "\n" );
10928  text_num = text_num + 1;
10929  }
10930 
10931  for ( iface = 0; iface < face_num; iface++ ) {
10932 
10933  fprintf ( fileout, "f" );
10934  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
10935  fprintf ( fileout, " %d", face[ivert][iface]+1 );
10936  }
10937  fprintf ( fileout, "\n" );
10938  text_num = text_num + 1;
10939  }
10940 /*
10941  Material binding.
10942 */
10943  fprintf ( fileout, "bind c vertex\n" );
10944  text_num = text_num + 1;
10945 /*
10946  Material RGB values at each node.
10947 */
10948  for ( icor3 = 0; icor3 < cor3_num; icor3++ ) {
10949 
10950  imat = cor3_material[icor3];
10951 
10952  fprintf ( fileout, "c %f %f %f\n", material_rgba[0][imat],
10953  material_rgba[1][imat], material_rgba[2][imat] );
10954 
10955  text_num = text_num + 1;
10956  }
10957 /*
10958  Normal binding.
10959 */
10960  fprintf ( fileout, "bind n vertex\n" );
10961  text_num = text_num + 1;
10962 /*
10963  Normal vector at each node.
10964 */
10965  for ( icor3 = 0; icor3 < cor3_num; icor3++ ) {
10966 
10967  fprintf ( fileout, "n %f %f %f\n", cor3_normal[0][icor3],
10968  cor3_normal[1][icor3], cor3_normal[2][icor3] );
10969 
10970  text_num = text_num + 1;
10971  }
10972 
10973  if ( texture_num > 0 ) {
10974 /*
10975  Texture filename.
10976 */
10977  fprintf ( fileout, "tex %s\n", texture_name[0] );
10978  text_num = text_num + 1;
10979 /*
10980  Texture binding.
10981 */
10982  fprintf ( fileout, "bind r vertex\n" );
10983  text_num = text_num + 1;
10984 /*
10985  Texture coordinates at each node.
10986 */
10987  for ( icor3 = 0; icor3 < cor3_num; icor3++ ) {
10988  fprintf ( fileout, "r %f %f\n", cor3_tex_uv[0][icor3],
10989  cor3_tex_uv[1][icor3] );
10990  text_num = text_num + 1;
10991  }
10992 
10993  }
10994 /*
10995  Report.
10996 */
10997  printf ( "\n" );
10998  printf ( "SMF_WRITE - Wrote %d text lines.\n", text_num );
10999 
11000  return SUCCESS;
11001 }
11002 /******************************************************************************/
11003 
11004 int stla_read ( FILE *filein )
11005 
11006 /******************************************************************************/
11007 
11008 /*
11009  Purpose:
11010 
11011  STLA_READ reads an ASCII STL (stereolithography) file.
11012 
11013  Examples:
11014 
11015  solid MYSOLID
11016  facet normal 0.4 0.4 0.2
11017  outerloop
11018  vertex 1.0 2.1 3.2
11019  vertex 2.1 3.7 4.5
11020  vertex 3.1 4.5 6.7
11021  endloop
11022  endfacet
11023  ...
11024  facet normal 0.2 0.2 0.4
11025  outerloop
11026  vertex 2.0 2.3 3.4
11027  vertex 3.1 3.2 6.5
11028  vertex 4.1 5.5 9.0
11029  endloop
11030  endfacet
11031  endsolid MYSOLID
11032 
11033  Modified:
11034 
11035  20 October 1998
11036 
11037  Author:
11038 
11039  John Burkardt
11040 */
11041 {
11042  int count;
11043  int i;
11044  int icor3;
11045  int ivert;
11046  char *next;
11047  float r1;
11048  float r2;
11049  float r3;
11050  float r4;
11051  float temp[3];
11052  char token[LINE_MAX_LEN];
11053  int width;
11054 /*
11055  Read the next line of the file into INPUT.
11056 */
11057  while ( fgets ( input, LINE_MAX_LEN, filein ) != NULL ) {
11058 
11059  text_num = text_num + 1;
11060 /*
11061  Advance to the first nonspace character in INPUT.
11062 */
11063  for ( next = input; *next != '\0' && isspace(*next); next++ ) {
11064  }
11065 /*
11066  Skip blank lines and comments.
11067 */
11068  if ( *next == '\0' || *next == '#' || *next == '!' || *next == '$' ) {
11069  continue;
11070  }
11071 /*
11072  Extract the first word in this line.
11073 */
11074  sscanf ( next, "%s%n", token, &width );
11075 /*
11076  Set NEXT to point to just after this token.
11077 */
11078  next = next + width;
11079 /*
11080  FACET
11081 */
11082  if ( leqi ( token, "facet" ) == TRUE ) {
11083 /*
11084  Get the XYZ coordinates of the normal vector to the face.
11085 */
11086  sscanf ( next, "%*s %e %e %e", &r1, &r2, &r3 );
11087 
11088  if ( face_num < FACE_MAX ) {
11089  face_normal[0][face_num] = r1;
11090  face_normal[1][face_num] = r2;
11091  face_normal[2][face_num] = r3;
11092  }
11093 
11094  fgets ( input, LINE_MAX_LEN, filein );
11095  text_num = text_num + 1;
11096 
11097  ivert = 0;
11098 
11099  for ( ;; ) {
11100 
11101  fgets ( input, LINE_MAX_LEN, filein );
11102  text_num = text_num + 1;
11103 
11104  count = sscanf ( input, "%*s %e %e %e", &r1, &r2, &r3 );
11105 
11106  if ( count != 3 ) {
11107  break;
11108  }
11109 
11110  temp[0] = r1;
11111  temp[1] = r2;
11112  temp[2] = r3;
11113 
11114  if ( cor3_num < 1000 ) {
11115  icor3 = rcol_find ( cor3, 3, cor3_num, temp );
11116  }
11117  else {
11118  icor3 = -1;
11119  }
11120 
11121  if ( icor3 == -1 ) {
11122 
11123  icor3 = cor3_num;
11124 
11125  if ( cor3_num < COR3_MAX ) {
11126  for ( i = 0; i < 3; i++ ) {
11127  cor3[i][cor3_num] = temp[i];
11128  }
11129  }
11130  cor3_num = cor3_num + 1;
11131  }
11132  else {
11133  dup_num = dup_num + 1;
11134  }
11135 
11136  if ( ivert < ORDER_MAX && face_num < FACE_MAX ) {
11137  face[ivert][face_num] = icor3;
11138  vertex_material[ivert][face_num] = 0;
11139  for ( i = 0; i < 3; i++ ) {
11141  }
11142  }
11143 
11144  ivert = ivert + 1;
11145  }
11146 
11147  fgets ( input, LINE_MAX_LEN, filein );
11148  text_num = text_num + 1;
11149 
11150  if ( face_num < FACE_MAX ) {
11151  face_order[face_num] = ivert;
11152  }
11153 
11154  face_num = face_num + 1;
11155 
11156  }
11157 /*
11158  COLOR
11159 */
11160 
11161  else if ( leqi ( token, "color" ) == TRUE ) {
11162  sscanf ( next, "%*s %f %f %f %f", &r1, &r2, &r3, &r4 );
11163  }
11164 /*
11165  SOLID
11166 */
11167  else if ( leqi ( token, "solid" ) == TRUE ) {
11168  object_num = object_num + 1;
11169  }
11170 /*
11171  ENDSOLID
11172 */
11173  else if ( leqi ( token, "endsolid" ) == TRUE ) {
11174  }
11175 /*
11176  Unexpected or unrecognized.
11177 */
11178  else {
11179  printf ( "\n" );
11180  printf ( "STLA_READ - Fatal error!\n" );
11181  printf ( " Unrecognized first word on line.\n" );
11182  return ERROR;
11183  }
11184 
11185  }
11186  return SUCCESS;
11187 }
11188 /******************************************************************************/
11189 
11190 int stla_write ( FILE *fileout )
11191 
11192 /******************************************************************************/
11193 
11194 /*
11195  Purpose:
11196 
11197  STLA_WRITE writes an ASCII STL (stereolithography) file.
11198 
11199  Examples:
11200 
11201  solid MYSOLID
11202  facet normal 0.4 0.4 0.2
11203  outerloop
11204  vertex 1.0 2.1 3.2
11205  vertex 2.1 3.7 4.5
11206  vertex 3.1 4.5 6.7
11207  endloop
11208  endfacet
11209  ...
11210  facet normal 0.2 0.2 0.4
11211  outerloop
11212  vertex 2.0 2.3 3.4
11213  vertex 3.1 3.2 6.5
11214  vertex 4.1 5.5 9.0
11215  endloop
11216  endfacet
11217  endsolid
11218 
11219  Discussion:
11220 
11221  The polygons in an STL file should only be triangular. This routine
11222  will try to automatically decompose higher-order polygonal faces into
11223  suitable triangles, without actually modifying the internal graphics
11224  data.
11225 
11226  Modified:
11227 
11228  01 September 1998
11229 
11230  Author:
11231 
11232  John Burkardt
11233 */
11234 {
11235  int icor3;
11236  int iface;
11237  int jvert;
11238  int face_num2;
11239  int text_num;
11240 /*
11241  Initialize.
11242 */
11243  text_num = 0;
11244  face_num2 = 0;
11245 
11246  fprintf ( fileout, "solid MYSOLID created by IVCON, original data in %s\n",
11247  filein_name );
11248 
11249  text_num = text_num + 1;
11250 
11251  for ( iface = 0; iface < face_num; iface++ ) {
11252 
11253  for ( jvert = 2; jvert < face_order[iface]; jvert++ ) {
11254 
11255  face_num2 = face_num2 + 1;
11256 
11257  fprintf ( fileout, " facet normal %f %f %f\n",
11258  face_normal[0][iface], face_normal[1][iface], face_normal[2][iface] );
11259 
11260  fprintf ( fileout, " outer loop\n" );
11261 
11262  icor3 = face[0][iface];
11263  fprintf ( fileout, " vertex %f %f %f\n",
11264  cor3[0][icor3], cor3[1][icor3], cor3[2][icor3] );
11265 
11266  icor3 = face[jvert-1][iface];
11267  fprintf ( fileout, " vertex %f %f %f\n",
11268  cor3[0][icor3], cor3[1][icor3], cor3[2][icor3] );
11269 
11270  icor3 = face[jvert][iface];
11271  fprintf ( fileout, " vertex %f %f %f\n",
11272  cor3[0][icor3], cor3[1][icor3], cor3[2][icor3] );
11273 
11274  fprintf ( fileout, " endloop\n" );
11275  fprintf ( fileout, " endfacet\n" );
11276  text_num = text_num + 7;
11277  }
11278  }
11279 
11280  fprintf ( fileout, "endsolid MYSOLID\n" );
11281  text_num = text_num + 1;
11282 /*
11283  Report.
11284 */
11285  printf ( "\n" );
11286  printf ( "STLA_WRITE - Wrote %d text lines.\n", text_num );
11287 
11288  if ( face_num != face_num2 ) {
11289  printf ( " Number of faces in original data was %d.\n", face_num );
11290  printf ( " Number of triangular faces in decomposed data is %d.\n",
11291  face_num2 );
11292  }
11293 
11294  return SUCCESS;
11295 }
11296 /******************************************************************************/
11297 
11298 int stlb_read ( FILE *filein )
11299 
11300 /******************************************************************************/
11301 
11302 /*
11303  Purpose:
11304 
11305  STLB_READ reads a binary STL (stereolithography) file.
11306 
11307  Example:
11308 
11309  80 byte string = header containing nothing in particular
11310 
11311  4 byte int = number of faces
11312 
11313  For each face:
11314 
11315  3 4-byte floats = components of normal vector to face;
11316  3 4-byte floats = coordinates of first node;
11317  3 4-byte floats = coordinates of second node;
11318  3 4-byte floats = coordinates of third and final node;
11319  2-byte int = attribute, whose value is 0.
11320 
11321  Modified:
11322 
11323  24 May 1999
11324 
11325  Author:
11326 
11327  John Burkardt
11328 */
11329 {
11330  short int attribute = 0;
11331  char c;
11332  float cvec[3];
11333  int icor3;
11334  int i;
11335  int iface;
11336  int ivert;
11337 /*
11338  80 byte Header.
11339 */
11340  for ( i = 0; i < 80; i++ ) {
11341  c = char_read ( filein );
11342  if ( debug ) {
11343  printf ( "%d\n", c );
11344  }
11345  bytes_num = bytes_num + 1;
11346  }
11347 /*
11348  Number of faces.
11349 */
11350  face_num = long_int_read ( filein );
11351  bytes_num = bytes_num + 4;
11352 /*
11353  For each (triangular) face,
11354  components of normal vector,
11355  coordinates of three vertices,
11356  2 byte "attribute".
11357 */
11358  for ( iface = 0; iface < face_num; iface++ ) {
11359 
11360  face_order[iface] = 3;
11361  face_material[iface] = 0;
11362 
11363  for ( i = 0; i < 3; i++ ) {
11364  face_normal[i][iface] = float_read ( filein );
11365  bytes_num = bytes_num + 4;
11366  }
11367 
11368  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
11369 
11370  for ( i = 0; i < 3; i++ ) {
11371  cvec[i] = float_read ( filein );
11372  bytes_num = bytes_num + 4;
11373  }
11374 
11375  if ( cor3_num < 1000 ) {
11376  icor3 = rcol_find ( cor3, 3, cor3_num, cvec );
11377  }
11378  else {
11379  icor3 = -1;
11380  }
11381 
11382  if ( icor3 == -1 ) {
11383  icor3 = cor3_num;
11384  if ( cor3_num < COR3_MAX ) {
11385  cor3[0][cor3_num] = cvec[0];
11386  cor3[1][cor3_num] = cvec[1];
11387  cor3[2][cor3_num] = cvec[2];
11388  }
11389  cor3_num = cor3_num + 1;
11390  }
11391  else {
11392  dup_num = dup_num + 1;
11393  }
11394 
11395  face[ivert][iface] = icor3;
11396 
11397  }
11398  attribute = short_int_read ( filein );
11399  if ( debug ) {
11400  printf ( "ATTRIBUTE = %d\n", attribute );
11401  }
11402  bytes_num = bytes_num + 2;
11403  }
11404 
11405  return SUCCESS;
11406 }
11407 /******************************************************************************/
11408 
11409 int stlb_write ( FILE *fileout )
11410 
11411 /******************************************************************************/
11412 
11413 /*
11414  Purpose:
11415 
11416  STLB_WRITE writes a binary STL (stereolithography) file.
11417 
11418  Example:
11419 
11420  80 byte string = header containing nothing in particular
11421 
11422  4 byte int = number of faces
11423 
11424  For each face:
11425 
11426  3 4-byte floats = components of normal vector to face;
11427  3 4-byte floats = coordinates of first node;
11428  3 4-byte floats = coordinates of second node;
11429  3 4-byte floats = coordinates of third and final node;
11430  2-byte int = attribute, whose value is 0.
11431 
11432  Discussion:
11433 
11434  The polygons in an STL file should only be triangular. This routine
11435  will try to automatically decompose higher-order polygonal faces into
11436  suitable triangles, without actually modifying the internal graphics
11437  data.
11438 
11439  Modified:
11440 
11441  24 May 1999
11442 
11443  Author:
11444 
11445  John Burkardt
11446 */
11447 {
11448  short int attribute = 0;
11449  char c;
11450  int i;
11451  int icor3;
11452  int iface;
11453  int jvert;
11454  int face_num2;
11455 /*
11456  80 byte Header.
11457 */
11458  for ( i = 0; i < 80; i++ ) {
11459  c = ' ';
11460  bytes_num = bytes_num + char_write ( fileout, c );
11461  }
11462 /*
11463  Number of faces.
11464 */
11465  face_num2 = 0;
11466  for ( iface = 0; iface < face_num; iface++ ) {
11467  face_num2 = face_num2 + face_order[iface] - 2;
11468  }
11469 
11470  bytes_num = bytes_num + long_int_write ( fileout, face_num2 );
11471 /*
11472  For each (triangular) face,
11473  components of normal vector,
11474  coordinates of three vertices,
11475  2 byte "attribute".
11476 */
11477  for ( iface = 0; iface < face_num; iface++ ) {
11478 
11479  for ( jvert = 2; jvert < face_order[iface]; jvert++ ) {
11480 
11481  for ( i = 0; i < 3; i++ ) {
11482  bytes_num = bytes_num + float_write ( fileout, face_normal[i][iface] );
11483  }
11484 
11485  icor3 = face[0][iface];
11486  for ( i = 0; i < 3; i++ ) {
11487  bytes_num = bytes_num + float_write ( fileout, cor3[i][icor3] );
11488  }
11489 
11490  icor3 = face[jvert-1][iface];
11491  for ( i = 0; i < 3; i++ ) {
11492  bytes_num = bytes_num + float_write ( fileout, cor3[i][icor3] );
11493  }
11494 
11495  icor3 = face[jvert][iface];
11496  for ( i = 0; i < 3; i++ ) {
11497  bytes_num = bytes_num + float_write ( fileout, cor3[i][icor3] );
11498  }
11499 
11500  bytes_num = bytes_num + short_int_write ( fileout, attribute );
11501 
11502  }
11503 
11504  }
11505 /*
11506  Report.
11507 */
11508  printf ( "\n" );
11509  printf ( "STLB_WRITE - Wrote %d bytes.\n", bytes_num );
11510 
11511  if ( face_num != face_num2 ) {
11512  printf ( " Number of faces in original data was %d.\n", face_num );
11513  printf ( " Number of triangular faces in decomposed data is %d.\n",
11514  face_num2 );
11515  }
11516 
11517  return SUCCESS;
11518 }
11519 /******************************************************************************/
11520 
11521 void tds_pre_process ( void )
11522 
11523 /******************************************************************************/
11524 
11525 /*
11526  Purpose:
11527 
11528  TDS_PRE_PROCESS divides the monolithic object into acceptably small pieces.
11529 
11530  Note:
11531 
11532  The 3DS binary format allows an unsigned short int for the number of
11533  points, and number of faces in an object. This limits such quantities
11534  to 65535. We have at least one interesting object with more faces
11535  than that. So we need to tag faces and nodes somehow.
11536 
11537  Modified:
11538 
11539  14 October 1998
11540 
11541  Author:
11542 
11543  John Burkardt
11544 */
11545 {
11546 /* static unsigned short int BIG = 60000; */
11547 
11548  return;
11549 }
11550 /******************************************************************************/
11551 
11552 int tds_read ( FILE *filein )
11553 
11554 /******************************************************************************/
11555 
11556 /*
11557  Purpose:
11558 
11559  TDS_READ reads a 3D Studio MAX binary 3DS file.
11560 
11561  Modified:
11562 
11563  20 October 1998
11564 
11565  Author:
11566 
11567  John Burkardt
11568 */
11569 {
11570  unsigned long int chunk_begin;
11571  unsigned long int chunk_end;
11572  unsigned long int chunk_length;
11573  unsigned long int chunk_length2;
11574  unsigned long int position;
11575  unsigned short int temp_int;
11576  int version;
11577  int views_read;
11578 /*
11579  Initialize.
11580 */
11581  views_read = 0;
11582 
11583  temp_int = tds_read_u_short_int ( filein );
11584 
11585  if ( temp_int == 0x4d4d ) {
11586 
11587  if ( debug ) {
11588  printf ( "TDS_READ: DEBUG: Read magic number %0X.\n", temp_int );
11589  }
11590 /*
11591  Move to 28 bytes from the beginning of the file.
11592 */
11593  position = 28;
11594  fseek ( filein, ( long ) position, SEEK_SET );
11595  version = fgetc ( filein );
11596 
11597  if ( version < 3 ) {
11598  printf ( "\n" );
11599  printf ( "TDS_READ - Fatal error!\n" );
11600  printf ( " This routine can only read 3DS version 3 or later.\n" );
11601  printf ( " The input file is version %d.\n" ,version );
11602  return ERROR;
11603  }
11604 
11605  if ( debug ) {
11606  printf ( "TDS_READ: DEBUG: Version number is %d.\n", version );
11607  }
11608 /*
11609  Move to 2 bytes from the beginning of the file.
11610  Set CURRENT_POINTER to the first byte of the chunk.
11611  Set CHUNK_LENGTH to the number of bytes in the chunk.
11612 */
11613  chunk_begin = 0;
11614  position = 2;
11615  fseek ( filein, ( long ) position, SEEK_SET );
11616 
11617  chunk_length = tds_read_u_long_int ( filein );
11618  position = 6;
11619 
11620  chunk_end = chunk_begin + chunk_length;
11621 
11622  if ( debug ) {
11623  printf ( "TDS_READ:\n" );
11624  printf ( " Chunk begin = %lu.\n", chunk_begin );
11625  printf ( " Chunk length = %lu.\n", chunk_length );
11626  printf ( " Chunk end = %lu.\n", chunk_end );
11627  }
11628 
11629  while ( position + 2 < chunk_end ) {
11630 
11631  temp_int = tds_read_u_short_int ( filein );
11632  position = position + 2;
11633 
11634  if ( debug ) {
11635  printf ( "TDS_READ: Short int = %0X, position = %lu.\n", temp_int, position );
11636  }
11637 
11638  if ( temp_int == 0x0002 ) {
11639  if ( debug ) {
11640  printf ( "TDS_READ: Read_Initial_Section:\n" );
11641  }
11642  chunk_length2 = tds_read_u_long_int ( filein );
11643  position = position + 4;
11644  position = position - 6 + chunk_length2;
11645  fseek ( filein, ( long ) position, SEEK_SET );
11646  }
11647  else if ( temp_int == 0x3d3d ) {
11648  if ( debug ) {
11649  printf ( "TDS_READ: Read_Edit_Section:\n" );
11650  }
11651  position = position - 2;
11652  position = position + tds_read_edit_section ( filein, &views_read );
11653  }
11654  else if ( temp_int == 0xb000 ) {
11655  if ( debug ) {
11656  printf ( "TDS_READ: Read_Keyframe_Section:\n" );
11657  }
11658 
11659  position = position - 2;
11660  position = position + tds_read_keyframe_section ( filein, &views_read );
11661  }
11662  else {
11663  printf ( "\n" );
11664  printf ( "TDS_READ - Fatal error!\n" );
11665  printf ( " Unexpected input, position = %lu.\n", position );
11666  printf ( " TEMP_INT = %hux\n", temp_int );
11667  return ERROR;
11668  }
11669  }
11670  position = chunk_begin + chunk_length;
11671  fseek ( filein, ( long ) position, SEEK_SET );
11672  }
11673  else {
11674  printf ( "\n" );
11675  printf ( "TDS_READ - Fatal error!\n" );
11676  printf ( " Could not find the main section tag.\n" );
11677  return ERROR;
11678  }
11679 
11680  return SUCCESS;
11681 }
11682 /******************************************************************************/
11683 
11684 unsigned long tds_read_ambient_section ( FILE *filein )
11685 
11686 /******************************************************************************/
11687 
11688 {
11689  unsigned long int current_pointer;
11690  unsigned char end_found = FALSE;
11691  int i;
11692  long int pointer;
11693  float rgb_val[3];
11694  unsigned short int temp_int;
11695  unsigned long int temp_pointer;
11696  unsigned long int teller;
11697  unsigned char true_c_val[3];
11698 
11699  current_pointer = ftell ( filein ) - 2;
11700  temp_pointer = tds_read_u_long_int ( filein );
11701  teller = 6;
11702 
11703  while ( end_found == FALSE ) {
11704 
11705  temp_int = tds_read_u_short_int ( filein );
11706  teller = teller + 2;
11707 
11708  switch ( temp_int ) {
11709  case 0x0010:
11710  if ( debug ) {
11711  printf ( " COLOR_F color definition section tag of %0X\n",
11712  temp_int );
11713  }
11714  for ( i = 0; i < 3; i++ ) {
11715  rgb_val[i] = float_read ( filein );
11716  }
11717  if ( debug ) {
11718  printf ( "RGB_VAL = %f %f %f\n", rgb_val[0], rgb_val[1], rgb_val[2] );
11719  }
11720  teller = teller + 3 * sizeof ( float );
11721  break;
11722  case 0x0011:
11723  if ( debug ) {
11724  printf ( " COLOR_24 24 bit color definition section tag of %0X\n",
11725  temp_int );
11726  }
11727 
11728  for ( i = 0; i < 3; i++ ) {
11729  true_c_val[i] = fgetc ( filein );
11730  }
11731  if ( debug ) {
11732  printf ( "TRUE_C_VAL = %d %d %d\n", true_c_val[0], true_c_val[1],
11733  true_c_val[2] );
11734  }
11735  teller = teller + 3;
11736  break;
11737  default:
11738  break;
11739  }
11740 
11741  if ( teller >= temp_pointer ) {
11742  end_found = TRUE;
11743  }
11744 
11745  }
11746 
11747  pointer = ( long ) ( current_pointer + temp_pointer );
11748  fseek ( filein, pointer, SEEK_SET );
11749 
11750  return ( temp_pointer );
11751 }
11752 /******************************************************************************/
11753 
11754 unsigned long tds_read_background_section ( FILE *filein )
11755 
11756 /******************************************************************************/
11757 
11758 {
11759  unsigned long int current_pointer;
11760  unsigned char end_found = FALSE;
11761  int i;
11762  long int pointer;
11763  float rgb_val[3];
11764  unsigned short int temp_int;
11765  unsigned long int temp_pointer;
11766  unsigned long int teller;
11767  unsigned char true_c_val[3];
11768 
11769  current_pointer = ftell ( filein ) - 2;
11770  temp_pointer = tds_read_u_long_int ( filein );
11771  teller = 6;
11772 
11773  while ( end_found == FALSE ) {
11774 
11775  temp_int = tds_read_u_short_int ( filein );
11776  teller = teller + 2;
11777 
11778  switch ( temp_int ) {
11779  case 0x0010:
11780  if ( debug ) {
11781  printf ( " COLOR_F RGB color definition section tag of %0X\n",
11782  temp_int );
11783  }
11784  for ( i = 0; i < 3; i++ ) {
11785  rgb_val[i] = float_read ( filein );
11786  }
11787  if ( debug ) {
11788  printf ( "RGB_VAL = %f %f %f\n", rgb_val[0], rgb_val[1], rgb_val[2] );
11789  }
11790  teller = teller + 3 * sizeof ( float );
11791  break;
11792  case 0x0011:
11793  if ( debug ) {
11794  printf ( " COLOR_24 24 bit color definition section tag of %0X\n",
11795  temp_int );
11796  }
11797 
11798  for ( i = 0; i < 3; i++ ) {
11799  true_c_val[i] = fgetc ( filein );
11800  }
11801  if ( debug ) {
11802  printf ( "TRUE_C_VAL = %d %d %d\n", true_c_val[0], true_c_val[1],
11803  true_c_val[2] );
11804  }
11805  teller = teller + 3;
11806  break;
11807  default:
11808  break;
11809  }
11810 
11811  if ( teller >= temp_pointer ) {
11812  end_found = TRUE;
11813  }
11814 
11815  }
11816 
11817  pointer = ( long ) ( current_pointer + temp_pointer );
11818  fseek ( filein, pointer, SEEK_SET );
11819 
11820  return ( temp_pointer );
11821 }
11822 /******************************************************************************/
11823 
11824 unsigned long tds_read_boolean ( unsigned char *boolean, FILE *filein )
11825 
11826 /******************************************************************************/
11827 
11828 {
11829  unsigned long current_pointer;
11830  long int pointer;
11831  unsigned long temp_pointer;
11832 
11833  current_pointer = ftell ( filein ) - 2;
11834  temp_pointer = tds_read_u_long_int ( filein );
11835 
11836  *boolean = fgetc ( filein );
11837 
11838  pointer = ( long ) ( current_pointer + temp_pointer );
11839  fseek ( filein, pointer, SEEK_SET );
11840 
11841  return ( temp_pointer );
11842 }
11843 /******************************************************************************/
11844 
11845 unsigned long tds_read_camera_section ( FILE *filein )
11846 
11847 /******************************************************************************/
11848 {
11849  float camera_eye[3];
11850  float camera_focus[3];
11851  unsigned long int current_pointer;
11852  float lens;
11853  long int pointer;
11854  float rotation;
11855  unsigned long int temp_pointer;
11856  unsigned short int u_short_int_val;
11857 
11858  current_pointer = ftell ( filein ) - 2;
11859  temp_pointer = tds_read_u_long_int ( filein );
11860 
11861  camera_eye[0] = float_read ( filein );
11862  camera_eye[1] = float_read ( filein );
11863  camera_eye[2] = float_read ( filein );
11864 
11865  camera_focus[0] = float_read ( filein );
11866  camera_focus[1] = float_read ( filein );
11867  camera_focus[2] = float_read ( filein );
11868 
11869  rotation = float_read ( filein );
11870  lens = float_read ( filein );
11871 
11872  if ( debug ) {
11873  printf ( " Found camera viewpoint at XYZ = %f %f %f.\n",
11874  camera_eye[0], camera_eye[1], camera_eye[2] );
11875  printf ( " Found camera focus coordinates at XYZ = %f %f %f.\n",
11876  camera_focus[0], camera_focus[1], camera_focus[2] );
11877  printf ( " Rotation of camera is: %f.\n", rotation );
11878  printf ( " Lens in used camera is: %f mm.\n", lens );
11879  }
11880 
11881  if ( ( temp_pointer-38 ) > 0 ) {
11882 
11883  if ( debug ) {
11884  printf ( " Found extra camera sections.\n" );
11885  }
11886 
11887  u_short_int_val = tds_read_u_short_int ( filein );
11888 
11889  if ( u_short_int_val == 0x4710 ) {
11890  if ( debug ) {
11891  printf ( " CAM_SEE_CONE.\n" );
11892  }
11893  tds_read_unknown_section ( filein );
11894  }
11895 
11896  u_short_int_val = tds_read_u_short_int ( filein );
11897 
11898  if ( u_short_int_val == 0x4720 ) {
11899  if ( debug ) {
11900  printf ( " CAM_RANGES.\n" );
11901  }
11902  tds_read_unknown_section ( filein );
11903  }
11904 
11905  }
11906 
11907  pointer = ( long ) ( current_pointer + temp_pointer );
11908  fseek ( filein, pointer, SEEK_SET );
11909 
11910  return ( temp_pointer );
11911 }
11912 /******************************************************************************/
11913 
11914 unsigned long tds_read_edit_section ( FILE *filein, int *views_read )
11915 
11916 /******************************************************************************/
11917 
11918 /*
11919  Modified:
11920 
11921  18 September 1998
11922 */
11923 {
11924  unsigned long int chunk_length;
11925  unsigned long int current_pointer;
11926  unsigned char end_found = FALSE;
11927  long int pointer;
11928  unsigned long int teller;
11929  unsigned short int temp_int;
11930 
11931  current_pointer = ftell ( filein ) - 2;
11932  chunk_length = tds_read_u_long_int ( filein );
11933  teller = 6;
11934 
11935  while ( end_found == FALSE ) {
11936 
11937  temp_int = tds_read_u_short_int ( filein );
11938  teller = teller + 2;
11939 
11940  if ( debug ) {
11941  printf ( " TDS_READ_EDIT_SECTION processing tag %0X\n", temp_int );
11942  }
11943 
11944  switch ( temp_int ) {
11945  case 0x1100:
11946  if ( debug ) {
11947  printf ( " BIT_MAP section tag of %0X\n", temp_int );
11948  }
11949  teller = teller + tds_read_unknown_section ( filein );
11950  break;
11951  case 0x1201:
11952  if ( debug ) {
11953  printf ( " USE_SOLID_BGND section tag of %0X\n", temp_int );
11954  }
11955  teller = teller + tds_read_unknown_section ( filein );
11956  break;
11957  case 0x1300:
11958  if ( debug ) {
11959  printf ( " V_GRADIENT section tag of %0X\n", temp_int );
11960  }
11961  teller = teller + tds_read_unknown_section ( filein );
11962  break;
11963  case 0x1400:
11964  teller = teller + tds_read_unknown_section ( filein );
11965  break;
11966  case 0x1420:
11967  teller = teller + tds_read_unknown_section ( filein );
11968  break;
11969  case 0x1450:
11970  teller = teller + tds_read_unknown_section ( filein );
11971  break;
11972  case 0x1500:
11973  teller = teller + tds_read_unknown_section ( filein );
11974  break;
11975  case 0x2200:
11976  teller = teller + tds_read_unknown_section ( filein );
11977  break;
11978  case 0x2201:
11979  teller = teller + tds_read_unknown_section ( filein );
11980  break;
11981  case 0x2210:
11982  teller = teller + tds_read_unknown_section ( filein );
11983  break;
11984  case 0x2300:
11985  teller = teller + tds_read_unknown_section ( filein );
11986  break;
11987  case 0x2302:
11988  teller = teller + tds_read_unknown_section ( filein );
11989  break;
11990  case 0x3000:
11991  teller = teller + tds_read_unknown_section ( filein );
11992  break;
11993  case 0x2100:
11994  if ( debug ) {
11995  printf ( " AMBIENT_LIGHT section tag of %0X\n", temp_int );
11996  }
11997  teller = teller + tds_read_ambient_section ( filein );
11998  break;
11999  case 0x1200:
12000  if ( debug ) {
12001  printf ( " SOLID_BGND section tag of %0X\n", temp_int );
12002  }
12003  teller = teller + tds_read_background_section ( filein );
12004  break;
12005  case 0x0100:
12006  if ( debug ) {
12007  printf ( " MASTER_SCALE section tag of %0X\n", temp_int );
12008  }
12009  teller = teller + tds_read_unknown_section ( filein );
12010  break;
12011  case 0x3d3e:
12012  if ( debug ) {
12013  printf ( " MESH_VERSION section tag of %0X\n", temp_int );
12014  }
12015  teller = teller + tds_read_unknown_section ( filein );
12016  break;
12017  case 0xafff:
12018  if ( debug ) {
12019  printf ( " MAT_ENTRY section tag of %0X\n", temp_int );
12020  }
12021  teller = teller + tds_read_material_section ( filein );
12022  break;
12023  case 0x4000:
12024  if ( debug ) {
12025  printf ( " NAMED_OBJECT section tag of %0X\n", temp_int );
12026  }
12027  teller = teller + tds_read_object_section ( filein );
12028  break;
12029  case 0x7001:
12030  if ( debug ) {
12031  printf ( " VIEWPORT_LAYOUT section tag of %0X\n",
12032  temp_int );
12033  }
12034  teller = teller + tds_read_view_section ( filein, views_read );
12035  break;
12036  case 0x7012:
12037  if ( debug ) {
12038  printf ( " VIEWPORT_DATA_3 section tag of %0X\n", temp_int );
12039  }
12040  teller = teller + tds_read_unknown_section ( filein );
12041  break;
12042  case 0x7011:
12043  if ( debug ) {
12044  printf ( " VIEWPORT_DATA section tag of %0X\n", temp_int );
12045  }
12046  teller = teller + tds_read_unknown_section ( filein );
12047  break;
12048  case 0x7020:
12049  if ( debug ) {
12050  printf ( " VIEWPORT_SIZE section tag of %0X\n", temp_int );
12051  }
12052  teller = teller + tds_read_unknown_section ( filein );
12053  break;
12054  default:
12055  if ( debug ) {
12056  printf ( " Junk.\n" );
12057  }
12058  break;
12059  }
12060 
12061  if ( teller >= chunk_length ) {
12062  end_found = TRUE;
12063  }
12064 
12065  }
12066 
12067  pointer = ( long ) ( current_pointer + chunk_length );
12068 
12069  fseek ( filein, pointer, SEEK_SET );
12070 
12071  return ( chunk_length );
12072 }
12073 /******************************************************************************/
12074 
12075 unsigned long tds_read_keyframe_section ( FILE *filein, int *views_read )
12076 
12077 /******************************************************************************/
12078 {
12079  unsigned long int current_pointer;
12080  unsigned char end_found = FALSE;
12081  long int pointer;
12082  unsigned short int temp_int;
12083  unsigned long int temp_pointer;
12084  unsigned long int teller;
12085 
12086  current_pointer = ftell ( filein ) - 2;
12087  temp_pointer = tds_read_u_long_int ( filein );
12088  teller = 6;
12089 
12090  while ( end_found == FALSE ) {
12091 
12092  temp_int = tds_read_u_short_int ( filein );
12093  teller = teller + 2;
12094 
12095  switch ( temp_int ) {
12096  case 0x7001:
12097  if ( debug ) {
12098  printf ( " VIEWPORT_LAYOUT main definition section tag of %0X\n",
12099  temp_int );
12100  }
12101  teller = teller + tds_read_view_section ( filein, views_read );
12102  break;
12103  case 0xb008:
12104  if ( debug ) {
12105  printf ( " KFSEG frames section tag of %0X\n", temp_int );
12106  }
12107  teller = teller + tds_read_unknown_section ( filein );
12108  break;
12109  case 0xb002:
12110  if ( debug ) {
12111  printf ( " OBJECT_NODE_TAG object description section tag of %0X\n",
12112  temp_int);
12113  }
12114  teller = teller + tds_read_keyframe_objdes_section ( filein );
12115  break;
12116  case 0xb009:
12117  if ( debug ) {
12118  printf ( " KFCURTIME section tag of %0X\n", temp_int );
12119  }
12120  teller = teller + tds_read_unknown_section ( filein );
12121  break;
12122  case 0xb00a:
12123  if ( debug ) {
12124  printf ( " KFHDR section tag of %0X\n", temp_int );
12125  }
12126  teller = teller + tds_read_unknown_section ( filein );
12127  break;
12128  default:
12129  break;
12130  }
12131 
12132  if ( teller >= temp_pointer ) {
12133  end_found = TRUE;
12134  }
12135 
12136  }
12137 
12138  pointer = ( long ) ( current_pointer + temp_pointer );
12139  fseek ( filein, pointer, SEEK_SET );
12140 
12141  return ( temp_pointer );
12142 }
12143 /******************************************************************************/
12144 
12145 unsigned long tds_read_keyframe_objdes_section ( FILE *filein )
12146 
12147 /******************************************************************************/
12148 
12149 /*
12150  Modified:
12151 
12152  21 September 1998
12153 */
12154 {
12155  unsigned long int chunk_size;
12156  unsigned long int current_pointer;
12157  unsigned char end_found = FALSE;
12158  long int pointer;
12159  unsigned short int temp_int;
12160  unsigned long int temp_pointer;
12161  unsigned long int teller;
12162  unsigned long int u_long_int_val;
12163  unsigned short int u_short_int_val;
12164 
12165  current_pointer = ftell ( filein ) - 2;
12166  temp_pointer = tds_read_u_long_int ( filein );
12167  teller = 6;
12168 
12169  while ( end_found == FALSE ) {
12170 
12171  temp_int = tds_read_u_short_int ( filein );
12172  teller = teller + 2;
12173 
12174  switch ( temp_int ) {
12175  case 0xb011:
12176  if ( debug ) {
12177  printf ( " INSTANCE_NAME section tag of %0X\n", temp_int );
12178  }
12179  teller = teller + tds_read_unknown_section ( filein );
12180  break;
12181  case 0xb010:
12182  if ( debug ) {
12183  printf ( " NODE_HDR section tag of %0X\n", temp_int );
12184  }
12185  teller = teller + tds_read_unknown_section ( filein );
12186  break;
12187  case 0xb020:
12188  if ( debug ) {
12189  printf ( " POS_TRACK_TAG section tag of %0X\n", temp_int );
12190  }
12191  chunk_size = tds_read_u_long_int ( filein );
12192  if ( debug ) {
12193  printf ( " chunk_size = %d\n", chunk_size );
12194  }
12195  u_short_int_val = tds_read_u_short_int ( filein );
12196  u_short_int_val = tds_read_u_short_int ( filein );
12197  u_short_int_val = tds_read_u_short_int ( filein );
12198  u_short_int_val = tds_read_u_short_int ( filein );
12199  u_short_int_val = tds_read_u_short_int ( filein );
12200  u_short_int_val = tds_read_u_short_int ( filein );
12201  u_short_int_val = tds_read_u_short_int ( filein );
12202  u_short_int_val = tds_read_u_short_int ( filein );
12203  u_long_int_val = tds_read_u_long_int ( filein );
12204  if ( debug ) {
12205  printf ( "u_short_int_val = %d\n", u_short_int_val );
12206  printf ( "u_long_int_val = %d\n", u_long_int_val );
12207  }
12208  origin[0] = float_read ( filein );
12209  origin[1] = float_read ( filein );
12210  origin[2] = float_read ( filein );
12211  teller = teller + 32;
12212  break;
12213  case 0xb013:
12214  if ( debug ) {
12215  printf ( " PIVOT section tag of %0X\n", temp_int );
12216  }
12217  chunk_size = tds_read_u_long_int ( filein );
12218  pivot[0] = float_read ( filein );
12219  pivot[1] = float_read ( filein );
12220  pivot[2] = float_read ( filein );
12221  teller = teller + 12;
12222  break;
12223  case 0xb014:
12224  if ( debug ) {
12225  printf ( " BOUNDBOX section tag of %0X\n", temp_int );
12226  }
12227  teller = teller + tds_read_unknown_section ( filein );
12228  break;
12229  case 0xb015:
12230  if ( debug ) {
12231  printf ( " MORPH_SMOOTH section tag of %0X\n", temp_int );
12232  }
12233  teller = teller + tds_read_unknown_section ( filein );
12234  break;
12235  case 0xb021:
12236  if ( debug ) {
12237  printf ( " ROT_TRACK_TAG section tag of %0X\n", temp_int );
12238  }
12239  teller = teller + tds_read_unknown_section ( filein );
12240  break;
12241  case 0xb022:
12242  if ( debug ) {
12243  printf ( " SCL_TRACK_TAG section tag of %0X\n", temp_int );
12244  }
12245  teller = teller + tds_read_unknown_section ( filein );
12246  break;
12247  case 0xb030:
12248  if ( debug ) {
12249  printf ( " NODE_ID section tag of %0X\n", temp_int );
12250  }
12251  teller = teller + tds_read_unknown_section ( filein );
12252  break;
12253  default:
12254  break;
12255  }
12256 
12257  if ( teller >= temp_pointer ) {
12258  end_found = TRUE;
12259  }
12260 
12261  }
12262 
12263  pointer = ( long ) ( current_pointer+temp_pointer );
12264  fseek ( filein, pointer, SEEK_SET );
12265 
12266  return ( temp_pointer );
12267 }
12268 /******************************************************************************/
12269 
12270 unsigned long tds_read_light_section ( FILE *filein )
12271 
12272 /******************************************************************************/
12273 {
12274  unsigned char boolean;
12275  unsigned long int current_pointer;
12276  unsigned char end_found = FALSE;
12277  int i;
12278  float light_coors[3];
12279  long int pointer;
12280  float rgb_val[3];
12281  unsigned long int teller;
12282  unsigned short int temp_int;
12283  unsigned long int temp_pointer;
12284  unsigned char true_c_val[3];
12285 
12286  current_pointer = ftell ( filein ) - 2;
12287  temp_pointer = tds_read_u_long_int ( filein );
12288  teller = 6;
12289 
12290  light_coors[0] = float_read ( filein );
12291  light_coors[1] = float_read ( filein );
12292  light_coors[2] = float_read ( filein );
12293 
12294  teller = teller + 3 * 4;
12295 
12296  if ( debug ) {
12297  printf ( " Found light at coordinates XYZ = %f %f %f.\n",
12298  light_coors[0], light_coors[1], light_coors[2] );
12299  }
12300 
12301  while ( end_found == FALSE ) {
12302 
12303  temp_int = tds_read_u_short_int ( filein );
12304  teller = teller + 2;
12305 
12306  switch ( temp_int ) {
12307  case 0x0010:
12308  if ( debug ) {
12309  printf ( " COLOR_F RGB color definition section tag of %0X\n",
12310  temp_int );
12311  }
12312  for ( i = 0; i < 3; i++ ) {
12313  rgb_val[i] = float_read ( filein );
12314  }
12315  if ( debug ) {
12316  printf ( " RGB_VAL value set to %f %f %f\n", rgb_val[0],
12317  rgb_val[1], rgb_val[2] );
12318  }
12319  teller = teller + 3 * sizeof ( float );
12320  break;
12321  case 0x0011:
12322  if ( debug ) {
12323  printf ( " COLOR_24 24 bit color definition section tag of %0X\n",
12324  temp_int );
12325  }
12326 
12327  for ( i = 0; i < 3; i++ ) {
12328  true_c_val[i] = fgetc ( filein );
12329  }
12330  if ( debug ) {
12331  printf ( " TRUE_C_VAL value set to %d %d %d\n", true_c_val[0],
12332  true_c_val[1], true_c_val[2] );
12333  }
12334  teller = teller + 3;
12335  break;
12336  case 0x4620:
12337  if ( debug ) {
12338  printf ( " DL_OFF section: %0X\n", temp_int );
12339  }
12340  teller = teller + tds_read_boolean ( &boolean, filein );
12341  if ( debug ) {
12342  if ( boolean == TRUE ) {
12343  printf ( " Light is on\n" );
12344  }
12345  else {
12346  printf ( " Light is off\n" );
12347  }
12348  }
12349  break;
12350  case 0x4610:
12351  if ( debug ) {
12352  printf ( " DL_SPOTLIGHT section tag of %0X\n", temp_int );
12353  }
12354  teller = teller + tds_read_spot_section ( filein );
12355  break;
12356  case 0x465a:
12357  if ( debug ) {
12358  printf ( " DL_OUTER_RANGE section tag of %0X\n", temp_int );
12359  }
12360  teller = teller + tds_read_unknown_section ( filein );
12361  break;
12362  default:
12363  break;
12364  }
12365 
12366  if ( teller >= temp_pointer ) {
12367  end_found = TRUE;
12368  }
12369 
12370  }
12371 
12372  pointer = ( long ) ( current_pointer + temp_pointer );
12373  fseek ( filein, pointer, SEEK_SET );
12374 
12375  return ( temp_pointer );
12376 }
12377 /******************************************************************************/
12378 
12379 unsigned long int tds_read_u_long_int ( FILE *filein )
12380 
12381 /******************************************************************************/
12382 
12383 /*
12384  Modified:
12385 
12386  01 October 1998
12387 
12388  Author:
12389 
12390  John Burkardt
12391 */
12392 {
12393  union {
12394  unsigned long int yint;
12395  char ychar[4];
12396  } y;
12397 
12398  if ( byte_swap == TRUE ) {
12399  y.ychar[3] = fgetc ( filein );
12400  y.ychar[2] = fgetc ( filein );
12401  y.ychar[1] = fgetc ( filein );
12402  y.ychar[0] = fgetc ( filein );
12403  }
12404  else {
12405  y.ychar[0] = fgetc ( filein );
12406  y.ychar[1] = fgetc ( filein );
12407  y.ychar[2] = fgetc ( filein );
12408  y.ychar[3] = fgetc ( filein );
12409  }
12410 
12411  return y.yint;
12412 }
12413 /******************************************************************************/
12414 
12415 int tds_read_long_name ( FILE *filein )
12416 
12417 /******************************************************************************/
12418 {
12419  unsigned char letter;
12420  unsigned int teller;
12421 
12422  teller = 0;
12423  letter = fgetc ( filein );
12424 /*
12425  Could be a dummy object.
12426 */
12427  if ( letter == 0 ) {
12428  strcpy ( temp_name, "Default_name" );
12429  return -1;
12430  }
12431 
12432  temp_name[teller] = letter;
12433  teller = teller + 1;
12434 
12435  do {
12436  letter = fgetc ( filein );
12437  temp_name[teller] = letter;
12438  teller = teller + 1;
12439  } while ( letter != 0 );
12440 
12441  temp_name[teller-1] = 0;
12442 
12443  if ( debug ) {
12444  printf ( " tds_read_long_name found name: %s.\n", temp_name );
12445  }
12446 
12447  return teller;
12448 }
12449 /******************************************************************************/
12450 
12451 unsigned long tds_read_matdef_section ( FILE *filein )
12452 
12453 /******************************************************************************/
12454 {
12455  unsigned long int current_pointer;
12456  long int pointer;
12457  int teller;
12458  unsigned long int temp_pointer;
12459 
12460  current_pointer = ftell ( filein ) - 2;
12461  temp_pointer = tds_read_u_long_int ( filein );
12462 
12463  teller = tds_read_long_name ( filein );
12464 
12465  if ( teller == -1 ) {
12466  if ( debug ) {
12467  printf ( " No material name found.\n" );
12468  }
12469  }
12470  else {
12471  strcpy ( mat_name, temp_name );
12472  if ( debug ) {
12473  printf ( " Material name %s.\n", mat_name );
12474  }
12475  }
12476 
12477  pointer = ( long ) ( current_pointer + temp_pointer );
12478  fseek ( filein, pointer, SEEK_SET );
12479 
12480  return ( temp_pointer );
12481 }
12482 /******************************************************************************/
12483 
12484 unsigned long tds_read_material_section ( FILE *filein )
12485 
12486 /******************************************************************************/
12487 {
12488  unsigned long int current_pointer;
12489  unsigned char end_found = FALSE;
12490  long int pointer;
12491  unsigned short int temp_int;
12492  unsigned long int temp_pointer;
12493  unsigned long int teller;
12494 
12495  current_pointer = ftell ( filein ) - 2;
12496 
12497  temp_pointer = tds_read_u_long_int ( filein );
12498  teller = 6;
12499 
12500  while ( end_found == FALSE ) {
12501 
12502  temp_int = tds_read_u_short_int ( filein );
12503  teller = teller + 2;
12504 
12505  switch ( temp_int ) {
12506 
12507  case 0xa000:
12508  if ( debug ) {
12509  printf ( " MAT_NAME definition section tag of %0X\n",
12510  temp_int );
12511  }
12512  teller = teller + tds_read_matdef_section ( filein );
12513  break;
12514  case 0xa010:
12515  if ( debug ) {
12516  printf ( " MAT_AMBIENT definition section tag of %0X\n",
12517  temp_int );
12518  }
12519  teller = teller + tds_read_unknown_section ( filein );
12520  break;
12521  case 0xa020:
12522  if ( debug ) {
12523  printf ( " MAT_DIFFUSE definition section tag of %0X\n",
12524  temp_int );
12525  }
12526  teller = teller + tds_read_unknown_section ( filein );
12527  break;
12528  case 0xa030:
12529  if ( debug ) {
12530  printf ( " MAT_SPECULAR definition section tag of %0X\n",
12531  temp_int );
12532  }
12533  teller = teller + tds_read_unknown_section ( filein );
12534  break;
12535  case 0xa040:
12536  if ( debug ) {
12537  printf ( " MAT_SHININESS definition section tag of %0X\n",
12538  temp_int );
12539  }
12540  teller = teller + tds_read_unknown_section ( filein );
12541  break;
12542  case 0xa041:
12543  if ( debug ) {
12544  printf ( " MAT_SHIN2PCT definition section tag of %0X\n",
12545  temp_int );
12546  }
12547  teller = teller + tds_read_unknown_section ( filein );
12548  break;
12549  case 0xa042:
12550  if ( debug ) {
12551  printf ( " MAT_SHIN3PCT definition section tag of %0X\n",
12552  temp_int );
12553  }
12554  teller = teller + tds_read_unknown_section ( filein );
12555  break;
12556  case 0xa050:
12557  if ( debug ) {
12558  printf ( " MAT_TRANSPARENCY definition section tag of %0X\n",
12559  temp_int );
12560  }
12561  teller = teller + tds_read_unknown_section ( filein );
12562  break;
12563  case 0xa052:
12564  if ( debug ) {
12565  printf ( " MAT_XPFALL definition section tag of %0X\n",
12566  temp_int );
12567  }
12568  teller = teller + tds_read_unknown_section ( filein );
12569  break;
12570  case 0xa053:
12571  if ( debug ) {
12572  printf ( " MAT_REFBLUR definition section tag of %0X\n",
12573  temp_int );
12574  }
12575  teller = teller + tds_read_unknown_section ( filein );
12576  break;
12577  case 0xa080:
12578  if ( debug ) {
12579  printf ( " MAT_SELF_ILLUM definition section tag of %0X\n",
12580  temp_int );
12581  }
12582  teller = teller + tds_read_unknown_section ( filein );
12583  break;
12584  case 0xa081:
12585  if ( debug ) {
12586  printf ( " MAT_TWO_SIDE definition section tag of %0X\n",
12587  temp_int );
12588  }
12589  teller = teller + tds_read_unknown_section ( filein );
12590  break;
12591  case 0xa082:
12592  if ( debug ) {
12593  printf ( " MAT_DECAL definition section tag of %0X\n",
12594  temp_int );
12595  }
12596  teller = teller + tds_read_unknown_section ( filein );
12597  break;
12598  case 0xa083:
12599  if ( debug ) {
12600  printf ( " MAT_ADDITIVE definition section tag of %0X\n",
12601  temp_int );
12602  }
12603  teller = teller + tds_read_unknown_section ( filein );
12604  break;
12605  case 0xa084:
12606  if ( debug ) {
12607  printf ( " MAT_SELF_ILPCT definition section tag of %0X\n",
12608  temp_int );
12609  }
12610  teller = teller + tds_read_unknown_section ( filein );
12611  break;
12612  case 0xa085:
12613  if ( debug ) {
12614  printf ( " MAT_WIRE definition section tag of %0X\n",
12615  temp_int );
12616  }
12617  teller = teller + tds_read_unknown_section ( filein );
12618  break;
12619  case 0xa086:
12620  if ( debug ) {
12621  printf ( " MAT_SUPERSMP definition section tag of %0X\n",
12622  temp_int );
12623  }
12624  teller = teller + tds_read_unknown_section ( filein );
12625  break;
12626  case 0xa087:
12627  if ( debug ) {
12628  printf ( " MAT_WIRESIZE definition section tag of %0X\n",
12629  temp_int );
12630  }
12631  teller = teller + tds_read_unknown_section ( filein );
12632  break;
12633  case 0xa088:
12634  if ( debug ) {
12635  printf ( " MAT_FACEMAP definition section tag of %0X\n",
12636  temp_int );
12637  }
12638  teller = teller + tds_read_unknown_section ( filein );
12639  break;
12640  case 0xa08a:
12641  if ( debug ) {
12642  printf ( " MAT_XPFALLIN definition section tag of %0X\n",
12643  temp_int );
12644  }
12645  teller = teller + tds_read_unknown_section ( filein );
12646  break;
12647  case 0xa08c:
12648  if ( debug ) {
12649  printf ( " MAT_PHONGSOFT definition section tag of %0X\n",
12650  temp_int );
12651  }
12652  teller = teller + tds_read_unknown_section ( filein );
12653  break;
12654  case 0xa08e:
12655  if ( debug ) {
12656  printf ( " MAT_WIREABS definition section tag of %0X\n",
12657  temp_int );
12658  }
12659  teller = teller + tds_read_unknown_section ( filein );
12660  break;
12661  case 0xa100:
12662  if ( debug ) {
12663  printf ( " MAT_SHADING definition section tag of %0X\n",
12664  temp_int );
12665  }
12666  teller = teller + tds_read_unknown_section ( filein );
12667  break;
12668  case 0xa200:
12669  if ( debug ) {
12670  printf ( " MAT_TEXMAP definition section tag of %0X\n",
12671  temp_int );
12672  }
12673  teller = teller + tds_read_texmap_section ( filein );
12674 /*
12675  teller = teller + tds_read_unknown_section ( filein );
12676 */
12677  break;
12678  case 0xa204:
12679  if ( debug ) {
12680  printf ( " MAT_SPECMAP definition section tag of %0X\n",
12681  temp_int );
12682  }
12683  teller = teller + tds_read_unknown_section ( filein );
12684  break;
12685  case 0xa210:
12686  if ( debug ) {
12687  printf ( " MAT_OPACMAP definition section tag of %0X\n",
12688  temp_int );
12689  }
12690  teller = teller + tds_read_unknown_section ( filein );
12691  break;
12692  case 0xa220:
12693  if ( debug ) {
12694  printf ( " MAT_REFLMAP definition section tag of %0X\n",
12695  temp_int );
12696  }
12697  teller = teller + tds_read_unknown_section ( filein );
12698  break;
12699  case 0xa230:
12700  if ( debug ) {
12701  printf ( " MAT_BUMPMAP definition section tag of %0X\n",
12702  temp_int );
12703  }
12704  teller = teller + tds_read_unknown_section ( filein );
12705  break;
12706  case 0xa353:
12707  if ( debug ) {
12708  printf ( " MAT_MAP_TEXBLUR definition section tag of %0X\n",
12709  temp_int );
12710  }
12711  teller = teller + tds_read_unknown_section ( filein );
12712  break;
12713  default:
12714  if ( debug ) {
12715  printf ( " Junk section tag of %0X\n", temp_int );
12716  }
12717  break;
12718  }
12719 
12720  if ( teller >= temp_pointer ) {
12721  end_found = TRUE;
12722  }
12723 
12724  }
12725  pointer = ( long ) ( current_pointer + temp_pointer );
12726 
12727  fseek ( filein, pointer, SEEK_SET );
12728 
12729  return ( temp_pointer );
12730 }
12731 /******************************************************************************/
12732 
12733 int tds_read_name ( FILE *filein )
12734 
12735 /******************************************************************************/
12736 {
12737  unsigned char letter;
12738  unsigned int teller;
12739 
12740  teller = 0;
12741  letter = fgetc ( filein );
12742 /*
12743  Could be a dummy object.
12744 */
12745 
12746  if ( letter == 0 ) {
12747  strcpy ( temp_name, "Default name" );
12748  return (-1);
12749  }
12750 
12751  temp_name[teller] = letter;
12752  teller = teller + 1;
12753 
12754  do {
12755  letter = fgetc ( filein );
12756  temp_name[teller] = letter;
12757  teller = teller + 1;
12758  } while ( ( letter != 0 ) && ( teller < 12 ) );
12759 
12760  temp_name[teller-1] = 0;
12761 
12762  if ( debug ) {
12763  printf ( " tds_read_name found name: %s.\n", temp_name );
12764  }
12765 
12766  return 0;
12767 }
12768 /******************************************************************************/
12769 
12770 unsigned long tds_read_obj_section ( FILE *filein )
12771 
12772 /******************************************************************************/
12773 
12774 /*
12775  Comments:
12776 
12777  Thanks to John F Flanagan for some suggested corrections.
12778 
12779  Modified:
12780 
12781  30 June 2001
12782 */
12783 {
12784  unsigned short int b;
12785  unsigned long int chunk_size;
12786  unsigned short int color_index;
12787  unsigned long int current_pointer;
12788  unsigned char end_found = FALSE;
12789  unsigned short int g;
12790  int i;
12791  int j;
12792  int cor3_num_base;
12793  int cor3_num_inc;
12794  int face_num_inc;
12795  long int pointer;
12796  unsigned short int r;
12797  unsigned short int temp_int;
12798  unsigned long int temp_pointer;
12799  unsigned long int temp_pointer2;
12800  unsigned long int teller;
12801 
12802  current_pointer = ftell ( filein ) - 2;
12803  temp_pointer = tds_read_u_long_int ( filein );
12804  teller = 6;
12805  cor3_num_base = cor3_num;
12806 
12807  while ( end_found == FALSE ) {
12808 
12809  temp_int = tds_read_u_short_int ( filein );
12810  teller = teller + 2;
12811 
12812  switch ( temp_int ) {
12813 
12814  case 0x4000:
12815  if ( debug ) {
12816  printf ( " NAMED_OBJECT section tag of %0X\n",
12817  temp_int );
12818  }
12819  teller = teller + tds_read_unknown_section ( filein );
12820  break;
12821 
12822  case 0x4100:
12823  if ( debug ) {
12824  printf ( " N_TRI_OBJECT section tag of %0X\n",
12825  temp_int );
12826  }
12827  teller = teller + tds_read_unknown_section ( filein );
12828  break;
12829 
12830  case 0x4110:
12831 
12832  if ( debug ) {
12833  printf ( " POINT_ARRAY section tag of %0X\n", temp_int );
12834  }
12835 
12836  current_pointer = ftell ( filein ) - 2;
12837  temp_pointer2 = tds_read_u_long_int ( filein );
12838  cor3_num_inc = ( int ) tds_read_u_short_int ( filein );
12839 
12840  for ( i = cor3_num; i < cor3_num + cor3_num_inc; i++ ) {
12841  cor3[0][i] = float_read ( filein );
12842  cor3[1][i] = float_read ( filein );
12843  cor3[2][i] = float_read ( filein );
12844  }
12845 
12846  cor3_num = cor3_num + cor3_num_inc;
12847  teller = teller + temp_pointer2;
12848  break;
12849 
12850  case 0x4111:
12851  if ( debug ) {
12852  printf ( " POINT_FLAG_ARRAY faces (2) section tag of %0X\n",
12853  temp_int );
12854  }
12855  teller = teller + tds_read_unknown_section ( filein );
12856  break;
12857 
12858  case 0x4120:
12859 
12860  if ( debug ) {
12861  printf ( " FACE_ARRAY section tag of %0X\n",
12862  temp_int );
12863  }
12864 
12865  temp_pointer2 = tds_read_u_long_int ( filein );
12866  face_num_inc = ( int ) tds_read_u_short_int ( filein );
12867 
12868  for ( i = face_num; i < face_num + face_num_inc; i++ ) {
12869  face[0][i] = tds_read_u_short_int ( filein ) + cor3_num_base;
12870  face[1][i] = tds_read_u_short_int ( filein ) + cor3_num_base;
12871  face[2][i] = tds_read_u_short_int ( filein ) + cor3_num_base;
12872  face_order[i] = 3;
12873  face_flags[i] = tds_read_u_short_int ( filein );
12874 /*
12875  Color is given per face, and as 24 bit RGB data packed in one word.
12876  Extract RGB from the word, and assign R / 255 to each vertex.
12877 
12878  Just a guess, JVB, 30 June 2001.
12879 */
12880  temp_int = face_flags[i] & 0x000F;
12881  r = ( temp_int & 0x0004 ) >> 2;
12882  g = ( temp_int & 0x0002 ) >> 1;
12883  b = ( temp_int & 0x0001 );
12884 
12885  for ( j = 0; j < 3; j++ ) {
12886  vertex_rgb[0][j][i] = ( float ) r / 255.0;
12887  vertex_rgb[1][j][i] = ( float ) g / 255.0;
12888  vertex_rgb[2][j][i] = ( float ) b / 255.0;
12889  }
12890 
12891  }
12892 
12893  temp_int = tds_read_u_short_int ( filein );
12894  if ( temp_int == 0x4150 ) {
12895  for ( i = face_num; i < face_num + face_num_inc; i++ ) {
12896  face_smooth[i] = ( int ) tds_read_u_long_int ( filein )
12897  + cor3_num_base;
12898  }
12899  }
12900  face_num = face_num + face_num_inc;
12901  teller = ftell ( filein );
12902  break;
12903 
12904  case 0x4130:
12905  if ( debug ) {
12906  printf ( " MSH_MAT_GROUP section tag of %0X\n",
12907  temp_int );
12908  }
12909  teller = teller + tds_read_unknown_section ( filein );
12910  break;
12911 
12912  case 0x4140:
12913  if ( debug ) {
12914  printf ( " TEX_VERTS section tag of %0X\n",
12915  temp_int );
12916  }
12917  teller = teller + tds_read_tex_verts_section ( filein );
12918  break;
12919 
12920  case 0x4150:
12921  if ( debug ) {
12922  printf ( " SMOOTH_GROUP section tag of %0X\n",
12923  temp_int );
12924  }
12925  teller = teller + tds_read_unknown_section ( filein );
12926  break;
12927 
12928  case 0x4160:
12929 
12930  if ( debug ) {
12931  printf ( " MESH_MATRIX section tag of %0X\n",
12932  temp_int );
12933  }
12934 
12935  tds_read_u_long_int ( filein );
12936 
12937  for ( j = 0; j < 4; j++ ) {
12938  for ( i = 0; i < 3; i++ ) {
12939  transform_matrix[j][i] = float_read ( filein );
12940  }
12941  }
12942  transform_matrix[0][3] = 0.0;
12943  transform_matrix[1][3] = 0.0;
12944  transform_matrix[2][3] = 0.0;
12945  transform_matrix[3][3] = 0.0;
12946 
12947  teller = teller + 12 * sizeof ( float );
12948  break;
12949 
12950  case 0x4165:
12951 
12952  if ( debug ) {
12953  printf ( " MESH_COLOR section tag of %0X\n", temp_int );
12954  }
12955 
12956  chunk_size = tds_read_u_long_int ( filein );
12957 
12958  if ( chunk_size == 7 ) {
12959  color_index = fgetc ( filein );
12960  teller = teller + 5;
12961  }
12962  else {
12963  color_index = tds_read_u_short_int ( filein );
12964  teller = teller + 6;
12965  }
12966  if ( debug ) {
12967  printf ( " Color index set to %d\n", color_index );
12968  }
12969  break;
12970 
12971  case 0x4170:
12972  if ( debug ) {
12973  printf ( " MESH_TEXTURE_INFO section tag of %0X\n",
12974  temp_int );
12975  }
12976  teller = teller + tds_read_unknown_section ( filein );
12977  break;
12978 
12979  default:
12980  if ( debug ) {
12981  printf ( " JUNK section tag of %0X\n", temp_int );
12982  }
12983  break;
12984  }
12985 
12986  if ( teller >= temp_pointer ) {
12987  end_found = TRUE;
12988  }
12989 
12990  }
12991 
12992  pointer = ( long int ) ( current_pointer + temp_pointer );
12993  fseek ( filein, pointer, SEEK_SET );
12994 
12995  return ( temp_pointer );
12996 }
12997 /******************************************************************************/
12998 
12999 unsigned long tds_read_object_section ( FILE *filein )
13000 
13001 /******************************************************************************/
13002 {
13003  unsigned char end_found = FALSE;
13004  unsigned long int current_pointer;
13005  int int_val;
13006  long int pointer;
13007  unsigned short int temp_int;
13008  unsigned long int temp_pointer;
13009  unsigned long int teller;
13010 
13011  current_pointer = ftell ( filein ) - 2;
13012  temp_pointer = tds_read_u_long_int ( filein );
13013  teller = 6;
13014 /*
13015  Why don't you read and save the name here?
13016 */
13017  int_val = tds_read_name ( filein );
13018 
13019  if ( int_val == -1 ) {
13020  if ( debug ) {
13021  printf ( " Dummy Object found\n" );
13022  }
13023  }
13024  else {
13025  strcpy ( object_name, temp_name );
13026  }
13027 
13028  while ( end_found == FALSE ) {
13029 
13030  temp_int = tds_read_u_short_int ( filein );
13031  teller = teller + 2;
13032 
13033  switch ( temp_int ) {
13034  case 0x4700:
13035  if ( debug ) {
13036  printf ( " N_CAMERA section tag of %0X\n", temp_int );
13037  }
13038  teller = teller + tds_read_camera_section ( filein );
13039  break;
13040  case 0x4600:
13041  if ( debug ) {
13042  printf ( " N_DIRECT_LIGHT section tag of %0X\n", temp_int );
13043  }
13044  teller = teller + tds_read_light_section ( filein );
13045  break;
13046  case 0x4100:
13047  if ( debug ) {
13048  printf ( " OBJ_TRIMESH section tag of %0X\n", temp_int );
13049  }
13050  teller = teller + tds_read_obj_section ( filein );
13051  break;
13052  case 0x4010:
13053  if ( debug ) {
13054  printf ( " OBJ_HIDDEN section tag of %0X\n", temp_int );
13055  }
13056  teller = teller + tds_read_unknown_section ( filein );
13057  break;
13058  case 0x4012:
13059  if ( debug ) {
13060  printf ( " OBJ_DOESNT_CAST section tag of %0X\n", temp_int );
13061  }
13062  teller = teller + tds_read_unknown_section ( filein );
13063  break;
13064  default:
13065  break;
13066  }
13067 
13068  if ( teller >= temp_pointer ) {
13069  end_found = TRUE;
13070  }
13071 
13072  }
13073 
13074  pointer = ( long ) ( current_pointer + temp_pointer );
13075 
13076  fseek ( filein, pointer, SEEK_SET );
13077 
13078  return ( temp_pointer );
13079 }
13080 /******************************************************************************/
13081 
13082 unsigned long int tds_read_tex_verts_section ( FILE *filein )
13083 
13084 /******************************************************************************/
13085 
13086 /*
13087  Purpose:
13088 
13089  TDS_READ_TEX_VERTS_SECTION reads the texture vertex data.
13090 
13091  Discussion:
13092 
13093  The texture vertex data seems to be associated with nodes. This routine
13094  distributes that data to vertices (nodes as they make up a particular
13095  face).
13096 
13097  Modified:
13098 
13099  02 July 1999
13100 
13101  Author:
13102 
13103  John Burkardt
13104 */
13105 {
13106  unsigned long int current_pointer;
13107  int icor3;
13108  long int pointer;
13109  unsigned long int temp_pointer;
13110  unsigned short int n2;
13111 
13112  current_pointer = ftell ( filein ) - 2;
13113  temp_pointer = tds_read_u_long_int ( filein );
13114 
13115  pointer = ( long int ) ( current_pointer + temp_pointer );
13116 
13117  n2 = tds_read_u_short_int ( filein );
13118 
13119  for ( icor3 = 0; icor3 < n2; icor3++ ) {
13120  cor3_tex_uv[0][icor3] = float_read ( filein );
13121  cor3_tex_uv[1][icor3] = float_read ( filein );
13122  }
13123 
13124  fseek ( filein, pointer, SEEK_SET );
13125 
13126  return ( temp_pointer );
13127 }
13128 /******************************************************************************/
13129 
13130 unsigned long tds_read_texmap_section ( FILE *filein )
13131 
13132 /******************************************************************************/
13133 
13134 /*
13135  Purpose:
13136 
13137  TDS_READ_TEXMAP_SECTION tries to get the TEXMAP name from the TEXMAP section.
13138 
13139  Warning:
13140 
13141  The code has room for lots of textures. In this routine, we behave as
13142  though there were only one, and we stick its name in the first name slot.
13143 
13144  Modified:
13145 
13146  30 June 1999
13147 
13148  Author:
13149 
13150  John Burkardt
13151 */
13152 {
13153  unsigned long int current_pointer;
13154  long int pointer;
13155  int teller;
13156  unsigned long int temp_pointer;
13157 
13158  texture_num = texture_num + 1;
13159 
13160  current_pointer = ftell ( filein ) - 2;
13161  temp_pointer = tds_read_u_long_int ( filein );
13162 
13163  tds_read_u_short_int ( filein );
13164  tds_read_u_short_int ( filein );
13165  tds_read_u_short_int ( filein );
13166  tds_read_u_short_int ( filein );
13167 
13168 /*
13169  This next short int should equal A300.
13170 */
13171  tds_read_u_short_int ( filein );
13172  tds_read_u_long_int ( filein );
13173 /*
13174  Now read the TEXMAP file name.
13175 */
13176  teller = tds_read_long_name ( filein );
13177 
13178  if ( teller == -1 ) {
13179  if ( debug ) {
13180  printf ( " No TEXMAP name found.\n" );
13181  }
13182  }
13183  else {
13184  strcpy ( texture_name[0], temp_name );
13185  if ( debug ) {
13186  printf ( " TEXMAP name %s.\n", texture_name[0] );
13187  }
13188  }
13189 
13190  pointer = ( long ) ( current_pointer + temp_pointer );
13191  fseek ( filein, pointer, SEEK_SET );
13192 
13193  return ( temp_pointer );
13194 }
13195 /******************************************************************************/
13196 
13197 unsigned short int tds_read_u_short_int ( FILE *filein )
13198 
13199 /******************************************************************************/
13200 {
13201  unsigned char c1;
13202  unsigned char c2;
13203  short int ival;
13204 
13205  c1 = fgetc ( filein );
13206  c2 = fgetc ( filein );
13207 
13208  ival = c1 | ( c2 << 8 );
13209 
13210  return ival;
13211 }
13212 /******************************************************************************/
13213 
13214 unsigned long tds_read_spot_section ( FILE *filein )
13215 
13216 /******************************************************************************/
13217 {
13218  unsigned long int current_pointer;
13219  float falloff;
13220  float hotspot;
13221  long int pointer;
13222  float target[4];
13223  unsigned long int temp_pointer;
13224 
13225  current_pointer = ftell ( filein ) - 2;
13226  temp_pointer = tds_read_u_long_int ( filein );
13227 
13228  target[0] = float_read ( filein );
13229  target[1] = float_read ( filein );
13230  target[2] = float_read ( filein );
13231  hotspot = float_read ( filein );
13232  falloff = float_read ( filein );
13233 
13234  if ( debug ) {
13235  printf ( " The target of the spot is XYZ = %f %f %f.\n",
13236  target[0], target[1], target[2] );
13237  printf ( " The hotspot of this light is %f.\n", hotspot );
13238  printf ( " The falloff of this light is %f.\n", falloff );
13239  }
13240 
13241  pointer = ( long ) ( current_pointer + temp_pointer );
13242 
13243  fseek ( filein, pointer, SEEK_SET );
13244 
13245  return ( temp_pointer );
13246 }
13247 /******************************************************************************/
13248 
13249 unsigned long int tds_read_unknown_section ( FILE *filein )
13250 
13251 /******************************************************************************/
13252 {
13253  unsigned long int current_pointer;
13254  long int pointer;
13255  unsigned long int temp_pointer;
13256 
13257  current_pointer = ftell ( filein ) - 2;
13258  temp_pointer = tds_read_u_long_int ( filein );
13259 
13260  pointer = ( long int ) ( current_pointer + temp_pointer );
13261 
13262  fseek ( filein, pointer, SEEK_SET );
13263 
13264  return ( temp_pointer );
13265 }
13266 /******************************************************************************/
13267 
13268 unsigned long tds_read_view_section ( FILE *filein, int *views_read )
13269 
13270 /******************************************************************************/
13271 {
13272  unsigned long int current_pointer;
13273  unsigned char end_found = FALSE;
13274  long int pointer;
13275  unsigned short int temp_int;
13276  unsigned long int temp_pointer;
13277  unsigned long int teller;
13278 
13279  current_pointer = ftell ( filein ) - 2;
13280  temp_pointer = tds_read_u_long_int ( filein );
13281  teller = 6;
13282 
13283  while ( end_found == FALSE ) {
13284 
13285  temp_int = tds_read_u_short_int ( filein );
13286  teller = teller + 2;
13287 
13288  switch ( temp_int ) {
13289  case 0x7012:
13290  if ( debug ) {
13291  printf ( " VIEWPORT_DATA_3 section tag of %0X\n", temp_int );
13292  }
13293  teller = teller + tds_read_vp_section ( filein, views_read );
13294  break;
13295  case 0x7011:
13296  if ( debug ) {
13297  printf ( " VIEWPORT_DATA section tag of %0X\n", temp_int );
13298  }
13299  teller = teller + tds_read_unknown_section ( filein );
13300  break;
13301  case 0x7020:
13302  if ( debug ) {
13303  printf ( " VIEWPORT_SIZE section tag of %0X\n", temp_int );
13304  }
13305  teller = teller + tds_read_vp_section ( filein, views_read );
13306  break;
13307  default:
13308  break;
13309  }
13310 
13311  if ( teller >= temp_pointer ) {
13312  end_found = TRUE;
13313  }
13314 
13315  if ( *views_read > 3 ) {
13316  end_found = TRUE;
13317  }
13318  }
13319 
13320  pointer = ( long int ) ( current_pointer + temp_pointer );
13321 
13322  fseek ( filein, pointer, SEEK_SET );
13323 
13324  return ( temp_pointer );
13325 }
13326 /******************************************************************************/
13327 
13328 unsigned long tds_read_vp_section ( FILE *filein, int *views_read )
13329 
13330 /******************************************************************************/
13331 {
13332  unsigned int attribs;
13333  unsigned long int current_pointer;
13334  int i;
13335  int int_val;
13336  long int pointer;
13337  unsigned int port;
13338  unsigned long int temp_pointer;
13339  char *viewports[11] = {
13340  "Bogus",
13341  "Top",
13342  "Bottom",
13343  "Left",
13344  "Right",
13345  "Front",
13346  "Back",
13347  "User",
13348  "Camera",
13349  "Light",
13350  "Disabled"
13351  };
13352 
13353  *views_read = *views_read + 1;
13354 
13355  current_pointer = ftell ( filein ) - 2;
13356  temp_pointer = tds_read_u_long_int ( filein );
13357 
13358  attribs = tds_read_u_short_int ( filein );
13359 
13360  if ( attribs == 3 ) {
13361  if ( debug ) {
13362  printf ( "<Snap> active in viewport.\n" );
13363  }
13364  }
13365 
13366  if ( attribs == 5 ) {
13367  if ( debug ) {
13368  printf ( "<Grid> active in viewport.\n" );
13369  }
13370  }
13371 /*
13372  Read 5 INTS to get to the viewport information.
13373 */
13374  for ( i = 1; i < 6; i++ ) {
13375  tds_read_u_short_int ( filein );
13376  }
13377 
13378  port = tds_read_u_short_int ( filein );
13379 /*
13380  Find camera section.
13381 */
13382  if ( ( port == 0xffff ) || ( port == 0 ) ) {
13383 
13384  for ( i = 0; i < 12; i++ ) {
13385  tds_read_u_short_int ( filein );
13386  }
13387 
13388  int_val = tds_read_name (filein );
13389 
13390  if ( int_val == -1 ) {
13391  if ( debug ) {
13392  printf ( " No Camera name found\n" );
13393  }
13394  }
13395 
13396  port = 0x0008;
13397  }
13398 
13399  if ( debug ) {
13400  printf ( "Reading [%s] information with tag:%d\n", viewports[port], port );
13401  }
13402 
13403  pointer = ( long int ) ( current_pointer + temp_pointer );
13404 
13405  fseek ( filein, pointer, SEEK_SET );
13406 
13407  return ( temp_pointer );
13408 }
13409 /******************************************************************************/
13410 
13411 int tds_write ( FILE *fileout )
13412 
13413 /******************************************************************************/
13414 
13415 /*
13416  Purpose:
13417 
13418  TDS_WRITE writes graphics information to a 3D Studio Max 3DS file.
13419 
13420  Modified:
13421 
13422  14 October 1998
13423 
13424  Author:
13425 
13426  John Burkardt
13427 
13428 */
13429 {
13430  float float_val;
13431  int i;
13432  int icor3;
13433  int iface;
13434  int j;
13435  long int l0002;
13436  long int l0100;
13437  long int l3d3d;
13438  long int l3d3e;
13439  long int l4000;
13440  long int l4100;
13441  long int l4110;
13442  long int l4120;
13443  long int l4150;
13444  long int l4160;
13445  long int l4d4d;
13446  long int lb000;
13447  long int lb002;
13448  long int lb00a;
13449  long int lb008;
13450  long int lb009;
13451  long int lb010;
13452  long int lb013;
13453  long int lb020;
13454  long int lb021;
13455  long int lb022;
13456  long int lb030;
13457  long int long_int_val;
13458  int name_length;
13459  short int short_int_val;
13460  unsigned short int u_short_int_val;
13461 
13462  bytes_num = 0;
13463  name_length = strlen ( object_name );
13464 
13465  l0002 = 10;
13466 
13467  l4150 = 2 + 4 + face_num * 4;
13468  l4120 = 2 + 4 + 2 + 4 * face_num * 2 + l4150;
13469  l4160 = 2 + 4 + 4 * 12;
13470  l4110 = 2 + 4 + 2 + cor3_num * 3 * 4;
13471  l4100 = 2 + 4 + l4110 + l4160 + l4120;
13472  l4000 = 2 + 4 + ( name_length + 1 ) + l4100;
13473  l0100 = 2 + 4 + 4;
13474  l3d3e = 2 + 4 + 4;
13475  l3d3d = 2 + 4 + l3d3e + l0100 + l4000;
13476 
13477  lb022 = 2 + 4 + 32;
13478  lb021 = 2 + 4 + 9 * 4;
13479  lb020 = 2 + 4 + 8 * 4;
13480  lb013 = 2 + 4 + 6 * 2;
13481  lb010 = 2 + 4 + ( name_length + 1 ) + 3 * 2;
13482  lb030 = 2 + 4 + 2;
13483  lb002 = 2 + 4 + lb030 + lb010 + lb013 + lb020 + lb021 + lb022;
13484  lb009 = 2 + 4 + 4;
13485  lb008 = 2 + 4 + 2 * 4;
13486  lb00a = 2 + 4 + 2 + 9 + 2 * 2;
13487  lb000 = 2 + 4 + lb00a + lb008 + lb009 + lb002;
13488 
13489  l4d4d = 2 + 4 + l0002 + l3d3d + lb000;
13490 /*
13491  M3DMAGIC begin.
13492  tag, size.
13493 */
13494  short_int_val = ( short ) 0x4d4d;
13495  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13496  bytes_num = bytes_num + long_int_write ( fileout, l4d4d );
13497 /*
13498  M3D_VERSION begin.
13499  tag, size, version.
13500 */
13501  short_int_val = ( short ) 0x0002;
13502  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13503  bytes_num = bytes_num + long_int_write ( fileout, l0002 );
13504  long_int_val = 3;
13505  bytes_num = bytes_num + long_int_write ( fileout, long_int_val );
13506 /*
13507  M3D_VERSION end.
13508  MDATA begin.
13509  tag, size.
13510 */
13511  short_int_val = ( short ) 0x3d3d;
13512  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13513  bytes_num = bytes_num + long_int_write ( fileout, l3d3d );
13514 /*
13515  MESH_VERSION begin.
13516  tag, size, version.
13517 */
13518  short_int_val = ( short ) 0x3d3e;
13519  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13520  bytes_num = bytes_num + long_int_write ( fileout, l3d3e );
13521  long_int_val = 3;
13522  bytes_num = bytes_num + long_int_write ( fileout, long_int_val );
13523 /*
13524  MESH_VERSION end.
13525  MASTER_SCALE begin.
13526  tag, size, scale.
13527 */
13528  short_int_val = ( short ) 0x0100;
13529  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13530  bytes_num = bytes_num + long_int_write ( fileout, l0100 );
13531  float_val = 1.0;
13532  bytes_num = bytes_num + float_write ( fileout, float_val );
13533 /*
13534  MASTER_SCALE end.
13535  NAMED_OBJECT begin.
13536  tag, size, name.
13537 */
13538  short_int_val = ( short ) 0x4000;
13539  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13540  bytes_num = bytes_num + long_int_write ( fileout, l4000 );
13542 /*
13543  N_TRI_OBJECT begin.
13544  tag, size.
13545 */
13546  short_int_val = ( short ) 0x4100;
13547  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13548  bytes_num = bytes_num + long_int_write ( fileout, l4100 );
13549 /*
13550  POINT_ARRAY begin.
13551  tag, size, number of points, coordinates of points.
13552  Warning! number of points could exceed a short!
13553 */
13554  short_int_val = ( short ) 0x4110;
13555  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13556  bytes_num = bytes_num + long_int_write ( fileout, l4110 );
13557 
13558  u_short_int_val = ( unsigned short ) cor3_num;
13559  bytes_num = bytes_num + tds_write_u_short_int ( fileout, u_short_int_val );
13560 
13561  for ( icor3 = 0; icor3 < cor3_num; icor3++ ) {
13562  for ( j = 0; j < 3; j++ ) {
13563  bytes_num = bytes_num + float_write ( fileout, cor3[j][icor3] );
13564  }
13565  }
13566 /*
13567  POINT_ARRAY end.
13568  MESH_MATRIX begin.
13569  tag, size, 4 by 3 matrix.
13570 */
13571  short_int_val = ( short ) 0x4160;
13572  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13573  bytes_num = bytes_num + long_int_write ( fileout, l4160 );
13574 
13575  for ( i = 0; i < 4; i++ ) {
13576  for ( j = 0; j < 3; j++ ) {
13577  float_val = transform_matrix[i][j];
13578  bytes_num = bytes_num + float_write ( fileout, float_val );
13579  }
13580  }
13581 /*
13582  MESH_MATRIX end.
13583  FACE_ARRAY begin.
13584  tag, size, number of faces, nodes per face.
13585  Warning: number of faces could exceed a short!
13586 */
13587  short_int_val = ( short ) 0x4120;
13588  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13589  bytes_num = bytes_num + long_int_write ( fileout, l4120 );
13590 
13591  u_short_int_val = ( unsigned short ) face_num;
13592  bytes_num = bytes_num + tds_write_u_short_int ( fileout, u_short_int_val );
13593 
13594  for ( iface = 0; iface < face_num; iface++ ) {
13595  for ( j = 0; j < 3; j++ ) {
13596  short_int_val = face[j][iface];
13597  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13598  }
13599  short_int_val = face_flags[iface];
13600  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13601  }
13602 /*
13603  SMOOTH_GROUP begin.
13604  tag, size, group for each face.
13605 */
13606  short_int_val = ( short ) 0x4150;
13607  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13608  bytes_num = bytes_num + long_int_write ( fileout, l4150 );
13609 
13610  for ( iface = 0; iface < face_num; iface++ ) {
13611  long_int_val = face_smooth[iface];
13612  bytes_num = bytes_num + long_int_write ( fileout, long_int_val );
13613  }
13614 /*
13615  SMOOTH_GROUP end.
13616  FACE_ARRAY end.
13617  N_TRI_OBJECT end.
13618  NAMED_OBJECT end.
13619  MDATA end.
13620  KFDATA begin.
13621 */
13622  short_int_val = ( short ) 0xb000;
13623  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13624  bytes_num = bytes_num + long_int_write ( fileout, lb000 );
13625 /*
13626  KFHDR begin.
13627  tag, size, revision, filename, animlen.
13628 */
13629  short_int_val = ( short ) 0xb00a;
13630  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13631  bytes_num = bytes_num + long_int_write ( fileout, lb00a );
13632  short_int_val = 5;
13633  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13634  bytes_num = bytes_num + tds_write_string ( fileout, "MAXSCENE" );
13635  short_int_val = 100;
13636  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13637  short_int_val = 0;
13638  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13639 /*
13640  KFHDR end.
13641  KFSEG begin.
13642  tag, size, start, end.
13643 */
13644  short_int_val = ( short ) 0xb008;
13645  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13646  bytes_num = bytes_num + long_int_write ( fileout, lb008 );
13647  long_int_val = 0;
13648  bytes_num = bytes_num + long_int_write ( fileout, long_int_val );
13649  long_int_val = 100;
13650  bytes_num = bytes_num + long_int_write ( fileout, long_int_val );
13651 /*
13652  KFSEG end.
13653  KFCURTIME begin.
13654  tag, size, current_frame.
13655 */
13656  short_int_val = ( short ) 0xb009;
13657  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13658  bytes_num = bytes_num + long_int_write ( fileout, lb009 );
13659  long_int_val = 0;
13660  bytes_num = bytes_num + long_int_write ( fileout, long_int_val );
13661 /*
13662  KFCURTIME end.
13663  OBJECT_NODE_TAG begin.
13664  tag, size.
13665 */
13666  short_int_val = ( short ) 0xb002;
13667  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13668  bytes_num = bytes_num + long_int_write ( fileout, lb002 );
13669 /*
13670  NODE_ID begin.
13671  tag, size, id.
13672 */
13673  short_int_val = ( short ) 0xb030;
13674  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13675  bytes_num = bytes_num + long_int_write ( fileout, lb030 );
13676  short_int_val = 0;
13677  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13678 /*
13679  NODE_ID end.
13680  NODE_HDR begin.
13681  tag, size, object_name, flag1, flag2, hierarchy.
13682 */
13683  short_int_val = ( short ) 0xb010;
13684  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13685  bytes_num = bytes_num + long_int_write ( fileout, lb010 );
13687  short_int_val = 16384;
13688  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13689  short_int_val = 0;
13690  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13691  short_int_val = -1;
13692  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13693 /*
13694  NODE_HDR end.
13695  PIVOT begin.
13696  tag, size, pivot_x, pivot_y, pivot_z.
13697 */
13698  short_int_val = ( short ) 0xb013;
13699  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13700  bytes_num = bytes_num + long_int_write ( fileout, lb013 );
13701  for ( i = 0; i < 3; i++ ) {
13702  float_val = pivot[i];
13703  bytes_num = bytes_num + float_write ( fileout, float_val );
13704  }
13705 /*
13706  PIVOT end.
13707  POS_TRACK_TAG begin.
13708  tag, size, flag, i1, i2, i3, i4, i5, i6, frame, l1, pos_x, pos_y, pos_z.
13709 */
13710  short_int_val = ( short ) 0xb020;
13711  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13712  bytes_num = bytes_num + long_int_write ( fileout, lb020 );
13713  short_int_val = 0;
13714  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13715  short_int_val = 0;
13716  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13717  short_int_val = 0;
13718  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13719  short_int_val = 0;
13720  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13721  short_int_val = 0;
13722  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13723  short_int_val = 1;
13724  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13725  short_int_val = 0;
13726  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13727  short_int_val = 0;
13728  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13729  long_int_val = 0;
13730  bytes_num = bytes_num + long_int_write ( fileout, long_int_val );
13731  for ( i = 0; i < 3; i++ ) {
13732  float_val = origin[i];
13733  bytes_num = bytes_num + float_write ( fileout, float_val );
13734  }
13735 /*
13736  POS_TRACK_TAG end.
13737  ROT_TRACK_TAG begin.
13738  tag, size, i1, i2, i3, i4, i5, i6, i7, i8, l1, rad, axis_x, axis_y, axis_z.
13739 */
13740  short_int_val = ( short ) 0xb021;
13741  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13742  bytes_num = bytes_num + long_int_write ( fileout, lb021 );
13743  short_int_val = 0;
13744  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13745  short_int_val = 0;
13746  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13747  short_int_val = 0;
13748  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13749  short_int_val = 0;
13750  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13751  short_int_val = 0;
13752  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13753  short_int_val = 1;
13754  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13755  short_int_val = 0;
13756  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13757  short_int_val = 0;
13758  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13759  long_int_val = 0;
13760  bytes_num = bytes_num + long_int_write ( fileout, long_int_val );
13761  float_val = 0.0;
13762  bytes_num = bytes_num + float_write ( fileout, float_val );
13763  bytes_num = bytes_num + float_write ( fileout, float_val );
13764  bytes_num = bytes_num + float_write ( fileout, float_val );
13765  bytes_num = bytes_num + float_write ( fileout, float_val );
13766 /*
13767  ROT_TRACK_TAG end.
13768  SCL_TRACK_TAG begin.
13769  tag, size, i1, i2, i3, i4, i5, i6, i7, i8, l1, scale_x, scale_y, scale_z.
13770 */
13771  short_int_val = ( short ) 0xb022;
13772  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13773  bytes_num = bytes_num + long_int_write ( fileout, lb022 );
13774  short_int_val = 0;
13775  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13776  short_int_val = 0;
13777  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13778  short_int_val = 0;
13779  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13780  short_int_val = 0;
13781  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13782  short_int_val = 0;
13783  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13784  short_int_val = 1;
13785  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13786  short_int_val = 0;
13787  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13788  short_int_val = 0;
13789  bytes_num = bytes_num + short_int_write ( fileout, short_int_val );
13790  long_int_val = 0;
13791  bytes_num = bytes_num + long_int_write ( fileout, long_int_val );
13792  float_val = 1.0;
13793  bytes_num = bytes_num + float_write ( fileout, float_val );
13794  bytes_num = bytes_num + float_write ( fileout, float_val );
13795  bytes_num = bytes_num + float_write ( fileout, float_val );
13796 /*
13797  SCL_TRACK_TAG end.
13798  OBJECT_NODE_TAG end.
13799  KFDATA end.
13800  M3DMAGIC end.
13801 */
13802 
13803 /*
13804  Report.
13805 */
13806  printf ( "TDS_WRITE wrote %d bytes.\n", bytes_num );
13807 
13808  return SUCCESS;
13809 }
13810 /******************************************************************************/
13811 
13812 int tds_write_string ( FILE *fileout, char *string )
13813 
13814 /******************************************************************************/
13815 
13816 /*
13817  Modified:
13818 
13819  23 September 1998
13820 
13821  Author:
13822 
13823  John Burkardt
13824 */
13825 {
13826  char *c;
13827  int nchar;
13828 
13829  nchar = 0;
13830 
13831  for ( c = string; nchar < 12; c++ ) {
13832 
13833  fputc ( *c, fileout );
13834  nchar = nchar + 1;
13835 
13836  if ( *c == 0 ) {
13837  return nchar;
13838  }
13839 
13840  }
13841 
13842  return nchar;
13843 }
13844 /******************************************************************************/
13845 
13846 int tds_write_u_short_int ( FILE *fileout, unsigned short int short_int_val )
13847 
13848 /******************************************************************************/
13849 
13850 /*
13851  Modified:
13852 
13853  14 October 1998
13854 
13855  Author:
13856 
13857  John Burkardt
13858 */
13859 {
13860  union {
13861  unsigned short int yint;
13862  char ychar[2];
13863  } y;
13864 
13865  y.yint = short_int_val;
13866 
13867  if ( byte_swap == TRUE ) {
13868  fputc ( y.ychar[1], fileout );
13869  fputc ( y.ychar[0], fileout );
13870  }
13871  else {
13872  fputc ( y.ychar[0], fileout );
13873  fputc ( y.ychar[1], fileout );
13874  }
13875 
13876  return 2;
13877 }
13878 /**********************************************************************/
13879 
13880 int tec_write ( FILE *fileout )
13881 
13882 /**********************************************************************/
13883 
13884 /*
13885  Purpose:
13886 
13887  TEC_WRITE writes graphics information to a TECPLOT file.
13888 
13889  Discussion:
13890 
13891  The file format used is appropriate for 3D finite element surface
13892  zone data. Polygons are decomposed into triangles where necessary.
13893 
13894  Example:
13895 
13896  TITLE = "cube.tec created by IVCON."
13897  VARIABLES = "X", "Y", "Z", "R", "G", "B"
13898  ZONE T="TRIANGLES", N=8, E=12, F=FEPOINT, ET=TRIANGLE
13899  0.0 0.0 0.0 0.0 0.0 0.0
13900  1.0 0.0 0.0 1.0 0.0 0.0
13901  1.0 1.0 0.0 1.0 1.0 0.0
13902  0.0 1.0 0.0 0.0 1.0 0.0
13903  0.0 0.0 1.0 0.0 0.0 1.0
13904  1.0 0.0 1.0 1.0 0.0 1.0
13905  1.0 1.0 1.0 1.0 1.0 1.0
13906  0.0 1.0 1.0 0.0 1.0 1.0
13907  1 4 2
13908  2 4 3
13909  1 5 8
13910  1 2 5
13911  2 6 5
13912  2 3 6
13913  3 7 6
13914  3 4 7
13915  4 8 7
13916  4 1 8
13917  5 6 8
13918  6 7 8
13919 
13920  Modified:
13921 
13922  09 June 1999
13923 
13924  Author:
13925 
13926  John Burkardt
13927 */
13928 {
13929  float b;
13930  int face2[3];
13931  float g;
13932  int icor3;
13933  int iface;
13934  int imat;
13935  int j;
13936  int face_num2;
13937  int text_num;
13938  float r;
13939 /*
13940  Determine the number of triangular faces.
13941 */
13942  face_num2 = 0;
13943  for ( iface = 0; iface < face_num; iface++ ) {
13944  for ( j = 0; j < face_order[iface] - 2; j++ ) {
13945  face_num2 = face_num2 + 1;
13946  }
13947  }
13948 
13949  text_num = 0;
13950 
13951  fprintf ( fileout, "\"%s created by IVCON.\"\n", fileout_name );
13952  fprintf ( fileout, "VARIABLES = \"X\", \"Y\", \"Z\", \"R\", \"G\", \"B\"\n" );
13953  fprintf ( fileout,
13954  "ZONE T=\"TRIANGLES\", N=%d, E=%d, F=FEPOINT, ET=TRIANGLE\n",
13955  cor3_num, face_num2 );
13956 
13957  text_num = text_num + 3;
13958 /*
13959  Write out X, Y, Z, R, G, B per node.
13960 */
13961  for ( icor3 = 0; icor3 < cor3_num; icor3++ ) {
13962  imat = cor3_material[icor3];
13963  r = material_rgba[0][imat];
13964  g = material_rgba[1][imat];
13965  b = material_rgba[2][imat];
13966  fprintf ( fileout, "%f %f %f %f %f %f\n", cor3[0][icor3], cor3[1][icor3],
13967  cor3[2][icor3], r, g, b );
13968  text_num = text_num + 1;
13969  }
13970 /*
13971  Do the next face.
13972 */
13973  for ( iface = 0; iface < face_num; iface++ ) {
13974 /*
13975  Break the face up into triangles, anchored at node 1.
13976 */
13977  for ( j = 0; j < face_order[iface] - 2; j++ ) {
13978 
13979  face2[0] = face[ 0][iface] + 1;
13980  face2[1] = face[j+1][iface] + 1;
13981  face2[2] = face[j+2][iface] + 1;
13982 
13983  fprintf ( fileout, "%d %d %d\n", face2[0], face2[1], face2[2] );
13984  text_num = text_num + 1;
13985 
13986  }
13987 
13988  }
13989 /*
13990  Report.
13991 */
13992  printf ( "\n" );
13993  printf ( "TEC_WRITE - Wrote %d text lines.\n", text_num );
13994 
13995  return SUCCESS;
13996 }
13997 
13998 /*********************************************************************/
13999 
14000 void tmat_init ( float a[4][4] )
14001 
14002 /*********************************************************************/
14003 
14004 /*
14005  Purpose:
14006 
14007  TMAT_INIT initializes the geometric transformation matrix.
14008 
14009  Definition:
14010 
14011  The geometric transformation matrix can be thought of as a 4 by 4
14012  matrix "A" having components:
14013 
14014  r11 r12 r13 t1
14015  r21 r22 r23 t2
14016  r31 r32 r33 t3
14017  0 0 0 1
14018 
14019  This matrix encodes the rotations, scalings and translations that
14020  are applied to graphical objects.
14021 
14022  A point P = (x,y,z) is rewritten in "homogeneous coordinates" as
14023  PH = (x,y,z,1). Then to apply the transformations encoded in A to
14024  the point P, we simply compute A * PH.
14025 
14026  Individual transformations, such as a scaling, can be represented
14027  by simple versions of the transformation matrix. If the matrix
14028  A represents the current set of transformations, and we wish to
14029  apply a new transformation B, { the original points are
14030  transformed twice: B * ( A * PH ). The new transformation B can
14031  be combined with the original one A, to give a single matrix C that
14032  encodes both transformations: C = B * A.
14033 
14034  Modified:
14035 
14036  19 October 1998
14037 
14038  Author:
14039 
14040  John Burkardt
14041 
14042  Reference:
14043 
14044  Foley, van Dam, Feiner, Hughes,
14045  Computer Graphics, Principles and Practice,
14046  Addison Wesley, Second Edition, 1990.
14047 
14048  Parameters:
14049 
14050  Input, float A[4][4], the geometric transformation matrix.
14051 */
14052 {
14053  int i;
14054  int j;
14055 
14056  for ( i = 0; i < 4; i++ ) {
14057  for ( j = 0; j < 4; j++ ) {
14058  if ( i == j ) {
14059  a[i][j] = 1.0;
14060  }
14061  else {
14062  a[i][j] = 0.0;
14063  }
14064  }
14065  }
14066  return;
14067 }
14068 /*********************************************************************/
14069 
14070 void tmat_mxm ( float a[4][4], float b[4][4], float c[4][4] )
14071 
14072 /*********************************************************************/
14073 
14074 /*
14075  Purpose:
14076 
14077  TMAT_MXM multiplies two geometric transformation matrices.
14078 
14079  Note:
14080 
14081  The product is accumulated in a temporary array, and { assigned
14082  to the result. Therefore, it is legal for any two, or all three,
14083  of the arguments to share memory.
14084 
14085  Modified:
14086 
14087  19 October 1998
14088 
14089  Author:
14090 
14091  John Burkardt
14092 
14093  Reference:
14094 
14095  Foley, van Dam, Feiner, Hughes,
14096  Computer Graphics, Principles and Practice,
14097  Addison Wesley, Second Edition, 1990.
14098 
14099  Parameters:
14100 
14101  Input, float A[4][4], the first geometric transformation matrix.
14102 
14103  Input, float B[4][4], the second geometric transformation matrix.
14104 
14105  Output, float C[4][4], the product A * B.
14106 */
14107 {
14108  float d[4][4];
14109  int i;
14110  int j;
14111  int k;
14112 
14113  for ( i = 0; i < 4; i++ ) {
14114  for ( k = 0; k < 4; k++ ) {
14115  d[i][k] = 0.0;
14116  for ( j = 0; j < 4; j++ ) {
14117  d[i][k] = d[i][k] + a[i][j] * b[j][k];
14118  }
14119  }
14120  }
14121 
14122  for ( i = 0; i < 4; i++ ) {
14123  for ( j = 0; j < 4; j++ ) {
14124  c[i][j] = d[i][j];
14125  }
14126  }
14127  return;
14128 }
14129 /*********************************************************************/
14130 
14131 void tmat_mxp ( float a[4][4], float x[4], float y[4] )
14132 
14133 /*********************************************************************/
14134 
14135 /*
14136  Purpose:
14137 
14138  TMAT_MXP multiplies a geometric transformation matrix times a point.
14139 
14140  Modified:
14141 
14142  19 October 1998
14143 
14144  Author:
14145 
14146  John Burkardt
14147 
14148  Reference:
14149 
14150  Foley, van Dam, Feiner, Hughes,
14151  Computer Graphics, Principles and Practice,
14152  Addison Wesley, Second Edition, 1990.
14153 
14154  Parameters:
14155 
14156  Input, float A[4][4], the geometric transformation matrix.
14157 
14158  Input, float X[4], the point to be multiplied. The fourth component
14159  of X is implicitly assigned the value of 1.
14160 
14161  Output, float Y[4], the result of A*X. The product is accumulated in
14162  a temporary vector, and { assigned to the result. Therefore, it
14163  is legal for X and Y to share memory.
14164 */
14165 {
14166  int i;
14167  int j;
14168  float z[4];
14169 
14170  for ( i = 0; i < 3; i++ ) {
14171  z[i] = a[i][3];
14172  for ( j = 0; j < 3; j++ ) {
14173  z[i] = z[i] + a[i][j] * x[j];
14174  }
14175  }
14176 
14177  for ( i = 0; i < 3; i++ ) {
14178  y[i] = z[i];
14179  }
14180  return;
14181 }
14182 /*********************************************************************/
14183 
14184 void tmat_mxp2 ( float a[4][4], float x[][3], float y[][3], int n )
14185 
14186 /*********************************************************************/
14187 
14188 /*
14189  Purpose:
14190 
14191  TMAT_MXP2 multiplies a geometric transformation matrix times N points.
14192 
14193  Modified:
14194 
14195  20 October 1998
14196 
14197  Author:
14198 
14199  John Burkardt
14200 
14201  Reference:
14202 
14203  Foley, van Dam, Feiner, Hughes,
14204  Computer Graphics, Principles and Practice,
14205  Addison Wesley, Second Edition, 1990.
14206 
14207  Parameters:
14208 
14209  Input, float A[4][4], the geometric transformation matrix.
14210 
14211  Input, float X[N][3], the points to be multiplied.
14212 
14213  Output, float Y[N][3], the transformed points. Each product is
14214  accumulated in a temporary vector, and { assigned to the
14215  result. Therefore, it is legal for X and Y to share memory.
14216 
14217 */
14218 {
14219  int i;
14220  int j;
14221  int k;
14222  float z[4];
14223 
14224  for ( k = 0; k < n; k++ ) {
14225 
14226  for ( i = 0; i < 3; i++ ) {
14227  z[i] = a[i][3];
14228  for ( j = 0; j < 3; j++ ) {
14229  z[i] = z[i] + a[i][j] * x[k][j];
14230  }
14231  }
14232 
14233  for ( i = 0; i < 3; i++ ) {
14234  y[k][i] = z[i];
14235  }
14236 
14237  }
14238  return;
14239 }
14240 /*********************************************************************/
14241 
14242 void tmat_mxv ( float a[4][4], float x[4], float y[4] )
14243 
14244 /*********************************************************************/
14245 
14246 /*
14247  Purpose:
14248 
14249  TMAT_MXV multiplies a geometric transformation matrix times a vector.
14250 
14251  Modified:
14252 
14253  12 August 1999
14254 
14255  Author:
14256 
14257  John Burkardt
14258 
14259  Reference:
14260 
14261  Foley, van Dam, Feiner, Hughes,
14262  Computer Graphics, Principles and Practice,
14263  Addison Wesley, Second Edition, 1990.
14264 
14265  Parameters:
14266 
14267  Input, float A[4][4], the geometric transformation matrix.
14268 
14269  Input, float X[3], the vector to be multiplied. The fourth component
14270  of X is implicitly assigned the value of 1.
14271 
14272  Output, float Y[3], the result of A*X. The product is accumulated in
14273  a temporary vector, and assigned to the result. Therefore, it
14274  is legal for X and Y to share memory.
14275 */
14276 {
14277  int i;
14278  int j;
14279  float z[4];
14280 
14281  for ( i = 0; i < 3; i++ ) {
14282  z[i] = 0.0;
14283  for ( j = 0; j < 3; j++ ) {
14284  z[i] = z[i] + a[i][j] * x[j];
14285  }
14286  z[i] = z[i] + a[i][3];
14287  }
14288 
14289  for ( i = 0; i < 3; i++ ) {
14290  y[i] = z[i];
14291  }
14292  return;
14293 }
14294 /*********************************************************************/
14295 
14296 void tmat_rot_axis ( float a[4][4], float b[4][4], float angle,
14297  char axis )
14298 
14299 /*********************************************************************/
14300 
14301 /*
14302  Purpose:
14303 
14304  TMAT_ROT_AXIS applies an axis rotation to the geometric transformation matrix.
14305 
14306  Modified:
14307 
14308  19 April 1999
14309 
14310  Author:
14311 
14312  John Burkardt
14313 
14314  Reference:
14315 
14316  Foley, van Dam, Feiner, Hughes,
14317  Computer Graphics, Principles and Practice,
14318  Addison Wesley, Second Edition, 1990.
14319 
14320  Parameters:
14321 
14322  Input, float A[4][4], the current geometric transformation matrix.
14323 
14324  Output, float B[4][4], the modified geometric transformation matrix.
14325  A and B may share the same memory.
14326 
14327  Input, float ANGLE, the angle, in degrees, of the rotation.
14328 
14329  Input, character AXIS, is 'X', 'Y' or 'Z', specifying the coordinate
14330  axis about which the rotation occurs.
14331 */
14332 {
14333  float c[4][4];
14334  float d[4][4];
14335  int i;
14336  int j;
14337  float theta;
14338 
14339  theta = angle * DEG_TO_RAD;
14340 
14341  tmat_init ( c );
14342 
14343  if ( axis == 'X' || axis == 'x' ) {
14344  c[1][1] = cos ( theta );
14345  c[1][2] = - sin ( theta );
14346  c[2][1] = sin ( theta );
14347  c[2][2] = cos ( theta );
14348  }
14349  else if ( axis == 'Y' || axis == 'y' ) {
14350  c[0][0] = cos ( theta );
14351  c[0][2] = sin ( theta );
14352  c[2][0] = - sin ( theta );
14353  c[2][2] = cos ( theta );
14354  }
14355  else if ( axis == 'Z' || axis == 'z' ) {
14356  c[0][0] = cos ( theta );
14357  c[0][1] = - sin ( theta );
14358  c[1][0] = sin ( theta );
14359  c[1][1] = cos ( theta );
14360  }
14361  else {
14362  printf ( "\n" );
14363  printf ( "TMAT_ROT_AXIS - Fatal error!\n" );
14364  printf ( " Illegal rotation axis: %c.\n", axis );
14365  printf ( " Legal choices are 'X', 'Y', or 'Z'.\n" );
14366  return;
14367  }
14368 
14369  tmat_mxm ( c, a, d );
14370 
14371  for ( i = 0; i < 4; i++ ) {
14372  for ( j = 0; j < 4; j++ ) {
14373  b[i][j] = d[i][j];
14374  }
14375  }
14376  return;
14377 }
14378 /*********************************************************************/
14379 
14380 void tmat_rot_vector ( float a[4][4], float b[4][4], float angle,
14381  float v1, float v2, float v3 )
14382 
14383 /*********************************************************************/
14384 
14385 /*
14386  Purpose:
14387 
14388  TMAT_ROT_VECTOR applies a rotation about a vector to the geometric transformation matrix.
14389 
14390  Modified:
14391 
14392  27 July 1999
14393 
14394  Author:
14395 
14396  John Burkardt
14397 
14398  Reference:
14399 
14400  Foley, van Dam, Feiner, Hughes,
14401  Computer Graphics, Principles and Practice,
14402  Addison Wesley, Second Edition, 1990.
14403 
14404  Parameters:
14405 
14406  Input, float A[4][4], the current geometric transformation matrix.
14407 
14408  Output, float B[4][4], the modified geometric transformation matrix.
14409  A and B may share the same memory.
14410 
14411  Input, float ANGLE, the angle, in degrees, of the rotation.
14412 
14413  Input, float V1, V2, V3, the X, Y and Z coordinates of a (nonzero)
14414  point defining a vector from the origin. The rotation will occur
14415  about this axis.
14416 */
14417 {
14418  float c[4][4];
14419  float ca;
14420  float d[4][4];
14421  int i;
14422  int j;
14423  float sa;
14424  float theta;
14425 
14426  if ( v1 * v1 + v2 * v2 + v3 * v3 == 0.0 ) {
14427  return;
14428  }
14429 
14430  theta = angle * DEG_TO_RAD;
14431 
14432  tmat_init ( c );
14433 
14434  ca = cos ( theta );
14435  sa = sin ( theta );
14436 
14437  c[0][0] = v1 * v1 + ca * ( 1.0 - v1 * v1 );
14438  c[0][1] = ( 1.0 - ca ) * v1 * v2 - sa * v3;
14439  c[0][2] = ( 1.0 - ca ) * v1 * v3 + sa * v2;
14440 
14441  c[1][0] = ( 1.0 - ca ) * v2 * v1 + sa * v3;
14442  c[1][1] = v2 * v2 + ca * ( 1.0 - v2 * v2 );
14443  c[1][2] = ( 1.0 - ca ) * v2 * v3 - sa * v1;
14444 
14445  c[2][0] = ( 1.0 - ca ) * v3 * v1 - sa * v2;
14446  c[2][1] = ( 1.0 - ca ) * v3 * v2 + sa * v1;
14447  c[2][2] = v3 * v3 + ca * ( 1.0 - v3 * v3 );
14448 
14449  tmat_mxm ( c, a, d );
14450 
14451  for ( i = 0; i < 4; i++ ) {
14452  for ( j = 0; j < 4; j++ ) {
14453  b[i][j] = d[i][j];
14454  }
14455  }
14456  return;
14457 }
14458 /*********************************************************************/
14459 
14460 void tmat_scale ( float a[4][4], float b[4][4], float sx, float sy,
14461  float sz )
14462 
14463 /*********************************************************************/
14464 
14465 /*
14466  Purpose:
14467 
14468  TMAT_SCALE applies a scaling to the geometric transformation matrix.
14469 
14470  Modified:
14471 
14472  19 October 1998
14473 
14474  Author:
14475 
14476  John Burkardt
14477 
14478  Reference:
14479 
14480  Foley, van Dam, Feiner, Hughes,
14481  Computer Graphics, Principles and Practice,
14482  Addison Wesley, Second Edition, 1990.
14483 
14484  Parameters:
14485 
14486  Input, float A[4][4], the current geometric transformation matrix.
14487 
14488  Output, float B[4][4], the modified geometric transformation matrix.
14489  A and B may share the same memory.
14490 
14491  Input, float SX, SY, SZ, the scalings to be applied to the X, Y and
14492  Z coordinates.
14493 */
14494 {
14495  float c[4][4];
14496  float d[4][4];
14497  int i;
14498  int j;
14499 
14500  tmat_init ( c );
14501 
14502  c[0][0] = sx;
14503  c[1][1] = sy;
14504  c[2][2] = sz;
14505 
14506  tmat_mxm ( c, a, d );
14507 
14508  for ( i = 0; i < 4; i++ ) {
14509  for ( j = 0; j < 4; j++ ) {
14510  b[i][j] = d[i][j];
14511  }
14512  }
14513  return;
14514 }
14515 /*********************************************************************/
14516 
14517 void tmat_shear ( float a[4][4], float b[4][4], char *axis, float s )
14518 
14519 /*********************************************************************/
14520 
14521 /*
14522  Purpose:
14523 
14524  TMAT_SHEAR applies a shear to the geometric transformation matrix.
14525 
14526  Modified:
14527 
14528  19 October 1998
14529 
14530  Author:
14531 
14532  John Burkardt
14533 
14534  Reference:
14535 
14536  Foley, van Dam, Feiner, Hughes,
14537  Computer Graphics, Principles and Practice,
14538  Addison Wesley, Second Edition, 1990.
14539 
14540  Parameters:
14541 
14542  Input, float A[4][4], the current geometric transformation matrix.
14543 
14544  Output, float B[4][4], the modified geometric transformation matrix.
14545  A and B may share the same memory.
14546 
14547  Input, character*3 AXIS, is 'XY', 'XZ', 'YX', 'YZ', 'ZX' or 'ZY',
14548  specifying the shear equation:
14549 
14550  XY: x' = x + s * y;
14551  XZ: x' = x + s * z;
14552  YX: y' = y + s * x;
14553  YZ: y' = y + s * z;
14554  ZX: z' = z + s * x;
14555  ZY: z' = z + s * y.
14556 
14557  Input, float S, the shear coefficient.
14558 */
14559 {
14560  float c[4][4];
14561  float d[4][4];
14562  int i;
14563  int j;
14564 
14565  tmat_init ( c );
14566 
14567  if ( strcmp ( axis, "XY" ) == 0 || strcmp ( axis, "xy" ) == 0 ) {
14568  c[0][1] = s;
14569  }
14570  else if ( strcmp ( axis, "XZ" ) == 0 || strcmp ( axis, "xz" ) == 0 ) {
14571  c[0][2] = s;
14572  }
14573  else if ( strcmp ( axis, "YX" ) == 0 || strcmp ( axis, "yx" ) == 0 ) {
14574  c[1][0] = s;
14575  }
14576  else if ( strcmp ( axis, "YZ" ) == 0 || strcmp ( axis, "yz" ) == 0 ) {
14577  c[1][2] = s;
14578  }
14579  else if ( strcmp ( axis, "ZX" ) == 0 || strcmp ( axis, "zx" ) == 0 ) {
14580  c[2][0] = s;
14581  }
14582  else if ( strcmp ( axis, "ZY" ) == 0 || strcmp ( axis, "zy" ) == 0 ) {
14583  c[2][1] = s;
14584  }
14585  else {
14586  printf ( "\n" );
14587  printf ( "TMAT_SHEAR - Fatal error!\n" );
14588  printf ( " Illegal shear axis: %s.\n", axis );
14589  printf ( " Legal choices are XY, XZ, YX, YZ, ZX, or ZY.\n" );
14590  return;
14591  }
14592 
14593  tmat_mxm ( c, a, d );
14594 
14595  for ( i = 0; i < 4; i++ ) {
14596  for ( j = 0; j < 4; j++ ) {
14597  b[i][j] = d[i][j];
14598  }
14599  }
14600  return;
14601 }
14602 /*********************************************************************/
14603 
14604 void tmat_trans ( float a[4][4], float b[4][4], float x, float y,
14605  float z )
14606 
14607 /*********************************************************************/
14608 
14609 /*
14610  Purpose:
14611 
14612  TMAT_TRANS applies a translation to the geometric transformation matrix.
14613 
14614  Modified:
14615 
14616  19 October 1998
14617 
14618  Author:
14619 
14620  John Burkardt
14621 
14622  Reference:
14623 
14624  Foley, van Dam, Feiner, Hughes,
14625  Computer Graphics, Principles and Practice,
14626  Addison Wesley, Second Edition, 1990.
14627 
14628  Parameters:
14629 
14630  Input, float A[4][4], the current geometric transformation matrix.
14631 
14632  Output, float B[4][4], the modified transformation matrix.
14633  A and B may share the same memory.
14634 
14635  Input, float X, Y, Z, the translation. This may be thought of as the
14636  point that the origin moves to under the translation.
14637 */
14638 {
14639  int i;
14640  int j;
14641 
14642  for ( i = 0; i < 4; i++ ) {
14643  for ( j = 0; j < 4; j++ ) {
14644  b[i][j] = a[i][j];
14645  }
14646  }
14647  b[0][3] = b[0][3] + x;
14648  b[1][3] = b[1][3] + y;
14649  b[2][3] = b[2][3] + z;
14650 
14651  return;
14652 }
14653 /******************************************************************************/
14654 
14655 int tria_read ( FILE *filein )
14656 
14657 /******************************************************************************/
14658 
14659 /*
14660  Purpose:
14661 
14662  TRIA_READ reads an ASCII triangle file.
14663 
14664  Example:
14665 
14666  12 <-- Number of triangles
14667 
14668  (x,y,z) and (nx,ny,nz) of normal vector at:
14669 
14670  0.0 0.0 0.0 0.3 0.3 0.3 node 1 of triangle 1.
14671  1.0 0.0 0.0 0.3 0.1 0.3 node 2 of triangle 1,
14672  0.0 1.0 0.0 0.3 0.1 0.3 node 3 of triangle 1,
14673  1.0 0.5 0.0 0.3 0.1 0.3 node 1 of triangle 2,
14674  ...
14675  0.0 0.5 0.5 0.3 0.1 0.3 node 3 of triangle 12.
14676 
14677  Modified:
14678 
14679  22 June 1999
14680 
14681  Author:
14682 
14683  John Burkardt
14684 */
14685 {
14686  float cvec[3];
14687  int icor3;
14688  int iface;
14689  int iface_hi;
14690  int iface_lo;
14691  int ivert;
14692  int face_num2;
14693  float r1;
14694  float r2;
14695  float r3;
14696  float r4;
14697  float r5;
14698  float r6;
14699 /*
14700  Get the number of triangles.
14701 */
14702  fgets ( input, LINE_MAX_LEN, filein );
14703  text_num = text_num + 1;
14704  sscanf ( input, "%d", &face_num2 );
14705 /*
14706  For each triangle:
14707 */
14708  iface_lo = face_num;
14709  iface_hi = face_num + face_num2;
14710 
14711  for ( iface = iface_lo; iface < iface_hi; iface++ ) {
14712 
14713  if ( iface < FACE_MAX ) {
14714  face_order[iface] = 3;
14715  face_material[iface] = 0;
14716  }
14717 /*
14718  For each face:
14719 */
14720  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
14721 
14722  fgets ( input, LINE_MAX_LEN, filein );
14723  text_num = text_num + 1;
14724  sscanf ( input, "%e %e %e %e %e %e", &r1, &r2, &r3, &r4, &r5, &r6 );
14725 
14726  cvec[0] = r1;
14727  cvec[1] = r2;
14728  cvec[2] = r3;
14729 
14730  if ( cor3_num < 1000 ) {
14731  icor3 = rcol_find ( cor3, 3, cor3_num, cvec );
14732  }
14733  else {
14734  icor3 = -1;
14735  }
14736 
14737  if ( icor3 == -1 ) {
14738  icor3 = cor3_num;
14739  if ( cor3_num < COR3_MAX ) {
14740  cor3[0][cor3_num] = cvec[0];
14741  cor3[1][cor3_num] = cvec[1];
14742  cor3[2][cor3_num] = cvec[2];
14743  }
14744  cor3_num = cor3_num + 1;
14745  }
14746  else {
14747  dup_num = dup_num + 1;
14748  }
14749 
14750  if ( iface < FACE_MAX ) {
14751 
14752  face[ivert][iface] = icor3;
14753  vertex_material[ivert][iface] = 0;
14754  vertex_normal[0][ivert][iface] = r4;
14755  vertex_normal[1][ivert][iface] = r5;
14756  vertex_normal[2][ivert][iface] = r6;
14757  }
14758 
14759  }
14760  }
14761  face_num = face_num + face_num2;
14762 
14763  return SUCCESS;
14764 }
14765 /**********************************************************************/
14766 
14767 int tria_write ( FILE *fileout )
14768 
14769 /**********************************************************************/
14770 
14771 /*
14772  Purpose:
14773 
14774  TRIA_WRITE writes the graphics data to an ASCII "triangle" file.
14775 
14776  Discussion:
14777 
14778  This is just a private format that Greg Hood requested from me.
14779 
14780  Example:
14781 
14782  12 <-- Number of triangles
14783 
14784  (x,y,z) and (nx,ny,nz) of normal vector at:
14785 
14786  0.0 0.0 0.0 0.3 0.3 0.3 node 1 of triangle 1.
14787  1.0 0.0 0.0 0.3 0.1 0.3 node 2 of triangle 1,
14788  0.0 1.0 0.0 0.3 0.1 0.3 node 3 of triangle 1,
14789  1.0 0.5 0.0 0.3 0.1 0.3 node 1 of triangle 2,
14790  ...
14791  0.0 0.5 0.5 0.3 0.1 0.3 node 3 of triangle 12.
14792 
14793  Modified:
14794 
14795  10 June 1999
14796 
14797  Author:
14798 
14799  John Burkardt
14800 */
14801 {
14802  int face2[3];
14803  int icor3;
14804  int iface;
14805  int jlo;
14806  int k;
14807  int face_num2;
14808  int text_num;
14809  float nx;
14810  float ny;
14811  float nz;
14812  float x;
14813  float y;
14814  float z;
14815 
14816  text_num = 0;
14817 /*
14818  Determine the number of triangular faces.
14819 */
14820  face_num2 = 0;
14821  for ( iface = 0; iface < face_num; iface++ ) {
14822  for ( jlo = 0; jlo < face_order[iface] - 2; jlo ++ ) {
14823  face_num2 = face_num2 + 1;
14824  }
14825  }
14826 
14827  fprintf ( fileout, "%d\n", face_num2 );
14828  text_num = text_num + 1;
14829 /*
14830  Do the next face.
14831 */
14832  for ( iface = 0; iface < face_num; iface++ ) {
14833 /*
14834  Break the face up into triangles, anchored at node 1.
14835 */
14836  for ( jlo = 0; jlo < face_order[iface] - 2; jlo ++ ) {
14837 
14838  face2[0] = face[ 0][iface];
14839  face2[1] = face[jlo+1][iface];
14840  face2[2] = face[jlo+2][iface];
14841 
14842  for ( k = 0; k < 3; k++ ) {
14843 
14844  icor3 = face2[k];
14845 
14846  x = cor3[0][icor3];
14847  y = cor3[1][icor3];
14848  z = cor3[2][icor3];
14849 
14850  nx = cor3_normal[0][icor3];
14851  ny = cor3_normal[1][icor3];
14852  nz = cor3_normal[2][icor3];
14853 
14854  fprintf ( fileout, "%f %f %f %f %f %f\n", x, y, z, nx, ny, nz );
14855 
14856  text_num = text_num + 1;
14857 
14858  }
14859 
14860  }
14861 
14862  }
14863 /*
14864  Report.
14865 */
14866  printf ( "\n" );
14867  printf ( "TRIA_WRITE - Wrote %d text lines.\n", text_num );
14868 
14869  return SUCCESS;
14870 }
14871 /******************************************************************************/
14872 
14873 int trib_read ( FILE *filein )
14874 
14875 /******************************************************************************/
14876 
14877 /*
14878  Purpose:
14879 
14880  TRIB_READ reads a binary triangle file.
14881 
14882  Example:
14883 
14884  4 byte int = number of triangles
14885 
14886  For each triangular face:
14887 
14888  3 4-byte floats = coordinates of first node;
14889  3 4-byte floats = components of normal vector at first node;
14890  3 4-byte floats = coordinates of second node;
14891  3 4-byte floats = components of normal vector at second node;
14892  3 4-byte floats = coordinates of third node;
14893  3 4-byte floats = components of normal vector at third node.
14894 
14895  Modified:
14896 
14897  22 June 1999
14898 
14899  Author:
14900 
14901  John Burkardt
14902 */
14903 {
14904  float cvec[3];
14905  int icor3;
14906  int i;
14907  int iface;
14908  int iface_hi;
14909  int iface_lo;
14910  int ivert;
14911  int face_num2;
14912 /*
14913  Read the number of triangles in the file.
14914 */
14915  face_num2 = long_int_read ( filein );
14916  bytes_num = bytes_num + 4;
14917 /*
14918  For each (triangular) face,
14919  read the coordinates and normal vectors of three vertices,
14920 */
14921  iface_lo = face_num;
14922  iface_hi = face_num + face_num2;
14923 
14924  for ( iface = iface_lo; iface < iface_hi; iface++ ) {
14925 
14926  if ( iface < FACE_MAX ) {
14927  face_order[iface] = 3;
14928  face_material[iface] = 0;
14929  }
14930 
14931  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
14932 
14933  for ( i = 0; i < 3; i++ ) {
14934  cvec[i] = float_read ( filein );
14935  bytes_num = bytes_num + 4;
14936  }
14937 
14938  if ( cor3_num < 1000 ) {
14939  icor3 = rcol_find ( cor3, 3, cor3_num, cvec );
14940  }
14941  else {
14942  icor3 = -1;
14943  }
14944 
14945  if ( icor3 == -1 ) {
14946  icor3 = cor3_num;
14947  if ( cor3_num < COR3_MAX ) {
14948  cor3[0][cor3_num] = cvec[0];
14949  cor3[1][cor3_num] = cvec[1];
14950  cor3[2][cor3_num] = cvec[2];
14951  }
14952  cor3_num = cor3_num + 1;
14953  }
14954  else {
14955  dup_num = dup_num + 1;
14956  }
14957 
14958  if ( iface < FACE_MAX ) {
14959 
14960  face[ivert][iface] = icor3;
14961  vertex_material[ivert][iface] = 0;
14962 
14963  for ( i = 0; i < 3; i++ ) {
14964  vertex_normal[i][ivert][iface] = float_read ( filein );
14965  bytes_num = bytes_num + 4;
14966  }
14967 
14968  }
14969 
14970  }
14971  }
14972 
14973  face_num = face_num + face_num2;
14974 
14975  return SUCCESS;
14976 }
14977 /**********************************************************************/
14978 
14979 int trib_write ( FILE *fileout )
14980 
14981 /**********************************************************************/
14982 
14983 /*
14984  Purpose:
14985 
14986  TRIB_WRITE writes the graphics data to a binary "triangle" file.
14987 
14988  Discussion:
14989 
14990  This is just a private format that Greg Hood requested from me.
14991 
14992  Example:
14993 
14994  12 Number of triangles
14995  0.0 x at node 1, triangle 1,
14996  0.0 y at node 1, triangle 1,
14997  0.0 z at node 1, triangle 1,
14998  0.3 nx at node 1, triangle 1,
14999  0.3 ny at node 1, triangle 1,
15000  0.3 nz at node 1, triangle 1.
15001  1.0 x at node 2, triangle 1,
15002  ...
15003  0.7 nz at node 3, triangle 1.
15004  1.2 x at node 1, triangle 2,
15005  ...
15006  0.3 nz at node 3, triangle 2.
15007  9.3 x at node 1, triangle 3,
15008  ...
15009  0.3 nz at node 3, triangle 12.
15010 
15011  Modified:
15012 
15013  16 June 1999
15014 
15015  Author:
15016 
15017  John Burkardt
15018 */
15019 {
15020  int face2[3];
15021  int icor3;
15022  int iface;
15023  int jlo;
15024  int k;
15025  int face_num2;
15026  float nx;
15027  float ny;
15028  float nz;
15029  float x;
15030  float y;
15031  float z;
15032 
15033  bytes_num = 0;
15034 /*
15035  Determine the number of triangular faces.
15036 */
15037  face_num2 = 0;
15038  for ( iface = 0; iface < face_num; iface++ ) {
15039  for ( jlo = 0; jlo < face_order[iface] - 2; jlo ++ ) {
15040  face_num2 = face_num2 + 1;
15041  }
15042  }
15043 
15044  bytes_num = bytes_num + long_int_write ( fileout, face_num2 );
15045 /*
15046  Do the next face.
15047 */
15048  for ( iface = 0; iface < face_num; iface++ ) {
15049 /*
15050  Break the face up into triangles, anchored at node 1.
15051 */
15052  for ( jlo = 0; jlo < face_order[iface] - 2; jlo ++ ) {
15053 
15054  face2[0] = face[ 0][iface];
15055  face2[1] = face[jlo+1][iface];
15056  face2[2] = face[jlo+2][iface];
15057 
15058  for ( k = 0; k < 3; k++ ) {
15059 
15060  icor3 = face2[k];
15061 
15062  x = cor3[0][icor3];
15063  y = cor3[1][icor3];
15064  z = cor3[2][icor3];
15065 
15066  nx = cor3_normal[0][icor3];
15067  ny = cor3_normal[1][icor3];
15068  nz = cor3_normal[2][icor3];
15069 
15070  bytes_num = bytes_num + float_write ( fileout, x );
15071  bytes_num = bytes_num + float_write ( fileout, y );
15072  bytes_num = bytes_num + float_write ( fileout, z );
15073  bytes_num = bytes_num + float_write ( fileout, nx );
15074  bytes_num = bytes_num + float_write ( fileout, ny );
15075  bytes_num = bytes_num + float_write ( fileout, nz );
15076 
15077  }
15078 
15079  }
15080 
15081  }
15082 /*
15083  Report.
15084 */
15085  printf ( "\n" );
15086  printf ( "TRIB_WRITE - Wrote %d bytes.\n", bytes_num );
15087 
15088  return SUCCESS;
15089 }
15090 /******************************************************************************/
15091 
15092 int txt_write ( FILE *fileout )
15093 
15094 /******************************************************************************/
15095 
15096 /*
15097  Purpose:
15098 
15099  TXT_WRITE writes the graphics data to a text file.
15100 
15101  Modified:
15102 
15103  25 June 1998
15104 
15105  Author:
15106 
15107  John Burkardt
15108 */
15109 {
15110  int i;
15111  int iface;
15112  int iline;
15113  int imat;
15114  int ivert;
15115  int nitem;
15116  int text_num;
15117 
15118  text_num = 0;
15119 
15120  fprintf ( fileout, "%s created by IVCON.\n", fileout_name );
15121  fprintf ( fileout, "Original data in %s.\n", filein_name );
15122  fprintf ( fileout, "Object name is %s.\n", object_name );
15123  fprintf ( fileout, "Object origin at %f %f %f.\n", origin[0], origin[1],
15124  origin[2] );
15125  fprintf ( fileout, "Object pivot at %f %f %f.\n", pivot[0], pivot[1],
15126  pivot[2] );
15127  text_num = text_num + 5;
15128 /*
15129  TRANSFORMATION MATRIX.
15130 */
15131  fprintf ( fileout, "\n" );
15132  fprintf ( fileout, "Transformation matrix:\n" );
15133  fprintf ( fileout, "\n" );
15134  text_num = text_num + 3;
15135 
15136  for ( i = 0; i < 4; i++ ) {
15137  fprintf ( fileout, " %f %f %f %f\n", transform_matrix[i][0],
15139  text_num = text_num + 1;
15140  }
15141 /*
15142  NODES.
15143 */
15144  fprintf ( fileout, "\n" );
15145  fprintf ( fileout, " %d nodes.\n", cor3_num );
15146  text_num = text_num + 2;
15147 
15148  if ( cor3_num > 0 ) {
15149 
15150  fprintf ( fileout, "\n" );
15151  fprintf ( fileout, " Node coordinate data:\n" );
15152  fprintf ( fileout, "\n" );
15153  text_num = text_num + 3;
15154 
15155  for ( i = 0; i < cor3_num; i++ ) {
15156  fprintf ( fileout, " %d %f %f %f\n ", i, cor3[0][i], cor3[1][i],
15157  cor3[2][i] );
15158  text_num = text_num + 1;
15159  }
15160 
15161  fprintf ( fileout, "\n" );
15162  fprintf ( fileout, " Node normal vectors:\n" );
15163  fprintf ( fileout, "\n" );
15164  text_num = text_num + 3;
15165 
15166  for ( i = 0; i < cor3_num; i++ ) {
15167  fprintf ( fileout, " %d %f %f %f\n ", i, cor3_normal[0][i],
15168  cor3_normal[1][i], cor3_normal[2][i] );
15169  text_num = text_num + 1;
15170  }
15171 
15172  fprintf ( fileout, "\n" );
15173  fprintf ( fileout, " Node materials:\n" );
15174  fprintf ( fileout, "\n" );
15175  text_num = text_num + 3;
15176 
15177  for ( i = 0; i < cor3_num; i++ ) {
15178  fprintf ( fileout, " %d %d\n ", i, cor3_material[i] );
15179  text_num = text_num + 1;
15180  }
15181 
15182  if ( texture_num > 0 ) {
15183  fprintf ( fileout, "\n" );
15184  fprintf ( fileout, " Node texture coordinates:\n" );
15185  fprintf ( fileout, "\n" );
15186  text_num = text_num + 3;
15187 
15188  for ( i = 0; i < cor3_num; i++ ) {
15189  fprintf ( fileout, " %d %f %f\n ", i, cor3_tex_uv[0][i],
15190  cor3_tex_uv[1][i] );
15191  text_num = text_num + 1;
15192  }
15193  }
15194  }
15195 /*
15196  LINES.
15197 */
15198  fprintf ( fileout, "\n" );
15199  fprintf ( fileout, " %d line data items.\n", line_num );
15200  text_num = text_num + 2;
15201 
15202  if ( line_num > 0 ) {
15203 
15204  fprintf ( fileout, "\n" );
15205  fprintf ( fileout, " Line index data:\n" );
15206  fprintf ( fileout, "\n" );
15207  text_num = text_num + 3;
15208 
15209  nitem = 0;
15210 
15211  for ( iline = 0; iline < line_num; iline++ ) {
15212 
15213  fprintf ( fileout, " %d", line_dex[iline] );
15214  nitem = nitem + 1;
15215 
15216  if ( iline == line_num - 1 || line_dex[iline] == -1 || nitem >= 10 ) {
15217  nitem = 0;
15218  fprintf ( fileout, "\n" );
15219  text_num = text_num + 1;
15220  }
15221 
15222  }
15223 
15224  fprintf ( fileout, "\n" );
15225  fprintf ( fileout, " Line materials:\n" );
15226  fprintf ( fileout, "\n" );
15227  text_num = text_num + 3;
15228 
15229  nitem = 0;
15230 
15231  for ( iline = 0; iline < line_num; iline++ ) {
15232 
15233  fprintf ( fileout, " %d", line_material[iline] );
15234  nitem = nitem + 1;
15235 
15236  if ( iline == line_num - 1 || line_material[iline] == -1 || nitem >= 10 ) {
15237  nitem = 0;
15238  fprintf ( fileout, "\n" );
15239  text_num = text_num + 1;
15240  }
15241  }
15242 
15243  }
15244 /*
15245  COLOR DATA
15246 */
15247  fprintf ( fileout, "\n" );
15248  fprintf ( fileout, " %d colors.\n", color_num );
15249  text_num = text_num + 2;
15250 /*
15251  FACES.
15252 */
15253  fprintf ( fileout, "\n" );
15254  fprintf ( fileout, " %d faces.\n", face_num );
15255  text_num = text_num + 2;
15256 
15257  if ( face_num > 0 ) {
15258 
15259  fprintf ( fileout, "\n" );
15260  fprintf ( fileout, " Face, Material, Number of vertices, Smoothing, Flags:\n" );
15261  fprintf ( fileout, "\n" );
15262  text_num = text_num + 3;
15263 
15264  for ( iface = 0; iface < face_num; iface++ ) {
15265  fprintf ( fileout, " %d %d %d %d %d\n", iface, face_material[iface],
15266  face_order[iface], face_smooth[iface], face_flags[iface] );
15267  text_num = text_num + 1;
15268  }
15269 
15270  fprintf ( fileout, "\n" );
15271  fprintf ( fileout, " Face, Vertices\n" );
15272  fprintf ( fileout, "\n" );
15273  text_num = text_num + 3;
15274 
15275  for ( iface = 0; iface < face_num; iface++ ) {
15276 
15277  fprintf ( fileout, "%d ", iface );
15278  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
15279  fprintf ( fileout, " %d", face[ivert][iface] );
15280  }
15281 
15282  fprintf ( fileout, "\n" );
15283  text_num = text_num + 1;
15284  }
15285 
15286  fprintf ( fileout, "\n" );
15287  fprintf ( fileout, " Face normal vectors:\n" );
15288  fprintf ( fileout, "\n" );
15289  text_num = text_num + 3;
15290 
15291  for ( iface = 0; iface < face_num; iface++ ) {
15292  fprintf ( fileout, " %d %f %f %f\n", iface, face_normal[0][iface],
15293  face_normal[1][iface], face_normal[2][iface] );
15294  text_num = text_num + 1;
15295  }
15296 
15297  if ( texture_num > 0 ) {
15298 
15299  fprintf ( fileout, "\n" );
15300  fprintf ( fileout, " Face texture coordinates:\n" );
15301  fprintf ( fileout, "\n" );
15302  text_num = text_num + 3;
15303 
15304  for ( iface = 0; iface < face_num; iface++ ) {
15305  fprintf ( fileout, " %d %f %f\n", iface, face_tex_uv[0][iface],
15306  face_tex_uv[1][iface] );
15307  text_num = text_num + 1;
15308  }
15309  }
15310  }
15311 /*
15312  VERTICES.
15313 */
15314  if ( face_num > 0 ) {
15315 
15316  fprintf ( fileout, "\n" );
15317  fprintf ( fileout, "Vertex normal vectors:\n" );
15318  text_num = text_num + 2;
15319 
15320  for ( iface = 0; iface < face_num; iface++ ) {
15321  fprintf ( fileout, "\n" );
15322  text_num = text_num + 1;
15323  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
15324  fprintf ( fileout, " %d %d %f %f %f\n", iface, ivert,
15325  vertex_normal[0][ivert][iface], vertex_normal[1][ivert][iface],
15326  vertex_normal[2][ivert][iface] );
15327  text_num = text_num + 1;
15328  }
15329  }
15330 
15331  fprintf ( fileout, "\n" );
15332  fprintf ( fileout, "Vertex materials:\n" );
15333  fprintf ( fileout, "\n" );
15334  text_num = text_num + 3;
15335 
15336  for ( iface = 0; iface < face_num; iface++ ) {
15337  fprintf ( fileout, "%d", iface );
15338  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
15339  fprintf ( fileout, " %d", vertex_material[ivert][iface] );
15340  }
15341  fprintf ( fileout, "\n" );
15342  text_num = text_num + 1;
15343  }
15344 
15345  if ( texture_num > 0 ) {
15346 
15347  fprintf ( fileout, "\n" );
15348  fprintf ( fileout, "Vertex UV texture coordinates:\n" );
15349  fprintf ( fileout, "\n" );
15350  text_num = text_num + 3;
15351 
15352  for ( iface = 0; iface < face_num; iface++ ) {
15353  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
15354  fprintf ( fileout, "%d %d %f %f\n", iface, ivert,
15355  vertex_tex_uv[0][ivert][iface], vertex_tex_uv[1][ivert][iface] );
15356  text_num = text_num + 1;
15357  }
15358  }
15359  }
15360  }
15361 /*
15362  MATERIALS.
15363 */
15364  fprintf ( fileout, "\n" );
15365  fprintf ( fileout, "%d materials.\n", material_num );
15366  fprintf ( fileout, "\n" );
15367  fprintf ( fileout, "Index Name R G B A\n" );
15368  fprintf ( fileout, "\n" );
15369 
15370  text_num = text_num + 5;
15371 
15372  for ( imat = 0; imat < material_num; imat++ ) {
15373  fprintf ( fileout, "%d %s %f %f %f %f\n", imat, material_name[imat],
15374  material_rgba[0][imat], material_rgba[1][imat], material_rgba[2][imat],
15375  material_rgba[3][imat] );
15376  text_num = text_num + 1;
15377  }
15378 /*
15379  TEXTURES.
15380 */
15381  fprintf ( fileout, "\n" );
15382  fprintf ( fileout, "%d textures.\n", texture_num );
15383  text_num = text_num + 2;
15384 
15385  if ( texture_num > 0 ) {
15386  fprintf ( fileout, "\n" );
15387  fprintf ( fileout, "Index Name\n" );
15388  fprintf ( fileout, "\n" );
15389  for ( i = 0; i < texture_num; i++ ) {
15390  fprintf ( fileout, "%d %s\n", i, texture_name[i] );
15391  }
15392  text_num = text_num + 3;
15393  }
15394 /*
15395  Report.
15396 */
15397  printf ( "\n" );
15398  printf ( "TXT_WRITE - Wrote %d text lines.\n", text_num );
15399 
15400  return SUCCESS;
15401 }
15402 /**********************************************************************/
15403 
15404 int ucd_write ( FILE *fileout )
15405 
15406 /**********************************************************************/
15407 
15408 /*
15409  Purpose:
15410 
15411  UCD_WRITE writes graphics data to an AVS UCD file.
15412 
15413  Examples:
15414 
15415  # cube.ucd created by IVREAD.
15416  #
15417  # Material RGB to hue map:
15418  #
15419  # material R G B Alpha Hue
15420  #
15421  # 0 0.94 0.70 0.15 1.000 0.116
15422  # 1 0.24 0.70 0.85 1.000 0.541
15423  # 2 0.24 0.00 0.85 1.000 0.666
15424  #
15425  # The node data is
15426  # node # / material # / RGBA / Hue
15427  #
15428  8 6 6 0 0
15429  0 0.0 0.0 0.0
15430  1 1.0 0.0 0.0
15431  2 1.0 1.0 0.0
15432  3 0.0 1.0 0.0
15433  4 0.0 0.0 1.0
15434  5 1.0 0.0 1.0
15435  6 1.0 1.0 1.0
15436  7 0.0 1.0 1.0
15437  0 0 quad 0 1 2 3
15438  1 0 quad 0 4 5 1
15439  2 0 quad 1 5 6 2
15440  3 0 quad 2 6 7 3
15441  4 0 quad 3 7 4 0
15442  5 0 quad 4 7 6 5
15443  3 1 4 1
15444  material, 0...2
15445  RGBA, 0-1/0-1/0-1/0-1
15446  Hue, 0-1
15447  0 0 0.94 0.70 0.15 1.0 0.116
15448  1 0 0.94 0.70 0.15 1.0 0.116
15449  2 0 0.94 0.70 0.15 1.0 0.116
15450  3 0 0.94 0.70 0.15 1.0 0.116
15451  4 1 0.24 0.70 0.85 1.0 0.541
15452  5 1 0.24 0.70 0.85 1.0 0.541
15453  6 2 0.24 0.24 0.85 0.0 0.666
15454  7 2 0.24 0.24 0.85 0.0 0.666
15455 
15456  Modified:
15457 
15458  22 May 1999
15459 
15460  Author:
15461 
15462  John Burkardt
15463 
15464 */
15465 {
15466  float a;
15467  float b;
15468  float g;
15469  float h;
15470  int i;
15471  int imat;
15472  int j;
15473  int text_num;
15474  float r;
15475 
15476  text_num = 0;
15477 
15478  fprintf ( fileout, "# %s created by IVREAD.\n", fileout_name );
15479  fprintf ( fileout, "#\n" );
15480  fprintf ( fileout, "# Material RGB to Hue map:\n" );
15481  fprintf ( fileout, "#\n" );
15482  fprintf ( fileout, "# material R G B Alpha Hue\n" );
15483  fprintf ( fileout, "#\n" );
15484 
15485  text_num = text_num + 6;
15486 
15487  for ( j = 0; j < material_num; j++ ) {
15488  r = material_rgba[0][j];
15489  g = material_rgba[1][j];
15490  b = material_rgba[2][j];
15491  a = material_rgba[3][j];
15492  h = rgb_to_hue ( r, g, b );
15493  fprintf ( fileout, "# %d %f %f %f %f %f\n", j, r, g, b, a, h );
15494  text_num = text_num + 1;
15495  }
15496 
15497  fprintf ( fileout, "#\n" );
15498  fprintf ( fileout, "# The node data is\n" );
15499  fprintf ( fileout, "# node # / material # / RGBA / Hue\n" );
15500  fprintf ( fileout, "#\n" );
15501  text_num = text_num + 4;
15502 
15503  fprintf ( fileout, "%d %d 6 0 0\n", cor3_num, face_num );
15504  text_num = text_num + 1;
15505 
15506  for ( j = 0; j < cor3_num; j++ ) {
15507  fprintf ( fileout, "%d %f %f %f\n", j, cor3[0][j], cor3[1][j],
15508  cor3[2][j] );
15509  text_num = text_num + 1;
15510  }
15511 /*
15512  NOTE:
15513  UCD only accepts triangles and quadrilaterals, not higher order
15514  polygons. We would need to break polygons up to proceed.
15515 */
15516  for ( j = 0; j < face_num; j++ ) {
15517 
15518  fprintf ( fileout, "%d %d", j, face_material[j] );
15519 
15520  if ( face_order[j] == 3 ) {
15521  fprintf ( fileout, " tri" );
15522  }
15523  else if ( face_order[j] == 4 ) {
15524  fprintf ( fileout, " quad" );
15525  }
15526  else {
15527  fprintf ( fileout, " ???" );
15528  }
15529 
15530  for ( i = 0; i < face_order[j]; i++ ) {
15531  fprintf ( fileout, "%d", face[i][j] );
15532  }
15533  fprintf ( fileout, "\n" );
15534  text_num = text_num + 1;
15535 
15536  }
15537 
15538  fprintf ( fileout, "3 1 4 1\n" );
15539  fprintf ( fileout, "material, 0...%d\n", material_num - 1 );
15540  fprintf ( fileout, "RGBA, 0-1/0-1/0-1/0-1\n" );
15541  fprintf ( fileout, "Hue, 0-1\n" );
15542  text_num = text_num + 4;
15543 
15544  for ( j = 0; j < cor3_num; j++ ) {
15545  imat = cor3_material[j];
15546  r = material_rgba[0][imat];
15547  g = material_rgba[1][imat];
15548  b = material_rgba[2][imat];
15549  a = material_rgba[3][imat];
15550  h = rgb_to_hue ( r, g, b );
15551 
15552  fprintf ( fileout, "%d %d %f %f %f %f %f\n", j, imat, r, g, b, a, h );
15553  text_num = text_num + 1;
15554  }
15555 /*
15556  Report.
15557 */
15558  printf ( "\n" );
15559  printf ( "UCD_WRITE - Wrote %d text lines.\n", text_num );
15560 
15561  return SUCCESS;
15562 }
15563 /******************************************************************************/
15564 
15565 void vertex_normal_set ( void )
15566 
15567 /******************************************************************************/
15568 
15569 /*
15570  Purpose:
15571 
15572  VERTEX_NORMAL_SET recomputes the face vertex normal vectors.
15573 
15574  Modified:
15575 
15576  12 October 1998
15577 
15578  Author:
15579 
15580  John Burkardt
15581 */
15582 {
15583  int i;
15584  int i0;
15585  int i1;
15586  int i2;
15587  int iface;
15588  int ivert;
15589  int jp1;
15590  int jp2;
15591  int nfix;
15592  float norm;
15593  float temp;
15594  float x0;
15595  float x1;
15596  float x2;
15597  float xc;
15598  float y0;
15599  float y1;
15600  float y2;
15601  float yc;
15602  float z0;
15603  float z1;
15604  float z2;
15605  float zc;
15606 
15607  if ( face_num <= 0 ) {
15608  return;
15609  }
15610 
15611  nfix = 0;
15612 /*
15613  Consider each face.
15614 */
15615  for ( iface = 0; iface < face_num; iface++ ) {
15616 
15617  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
15618 
15619  norm = 0.0;
15620  for ( i = 0; i < 3; i++ ) {
15621  temp = vertex_normal[i][ivert][iface];
15622  norm = norm + temp * temp;
15623  }
15624  norm = ( float ) sqrt ( norm );
15625 
15626  if ( norm == 0.0 ) {
15627 
15628  nfix = nfix + 1;
15629 
15630  i0 = face[ivert][iface];
15631  x0 = cor3[0][i0];
15632  y0 = cor3[1][i0];
15633  z0 = cor3[2][i0];
15634 
15635  jp1 = ivert + 1;
15636  if ( jp1 >= face_order[iface] ) {
15637  jp1 = jp1 - face_order[iface];
15638  }
15639  i1 = face[jp1][iface];
15640  x1 = cor3[0][i1];
15641  y1 = cor3[1][i1];
15642  z1 = cor3[2][i1];
15643 
15644  jp2 = ivert + 2;
15645  if ( jp2 >= face_order[iface] ) {
15646  jp2 = jp2 - face_order[iface];
15647  }
15648  i2 = face[jp2][iface];
15649  x2 = cor3[0][i2];
15650  y2 = cor3[1][i2];
15651  z2 = cor3[2][i2];
15652 
15653  xc = ( y1 - y0 ) * ( z2 - z0 ) - ( z1 - z0 ) * ( y2 - y0 );
15654  yc = ( z1 - z0 ) * ( x2 - x0 ) - ( x1 - x0 ) * ( z2 - z0 );
15655  zc = ( x1 - x0 ) * ( y2 - y0 ) - ( y1 - y0 ) * ( x2 - x0 );
15656 
15657  norm = ( float ) sqrt ( xc * xc + yc * yc + zc * zc );
15658 
15659  if ( norm == 0.0 ) {
15660  xc = ( float ) 1.0 / sqrt ( 3.0 );
15661  yc = ( float ) 1.0 / sqrt ( 3.0 );
15662  zc = ( float ) 1.0 / sqrt ( 3.0 );
15663  }
15664  else {
15665  xc = xc / norm;
15666  yc = yc / norm;
15667  zc = zc / norm;
15668  }
15669 
15670  vertex_normal[0][ivert][iface] = xc;
15671  vertex_normal[1][ivert][iface] = yc;
15672  vertex_normal[2][ivert][iface] = zc;
15673 
15674  }
15675  }
15676  }
15677 
15678  if ( nfix > 0 ) {
15679  printf ( "\n" );
15680  printf ( "VERTEX_NORMAL_SET: Recomputed %d face vertex normals.\n", nfix );
15681  }
15682 
15683  return;
15684 }
15685 /**********************************************************************/
15686 
15688 
15689 /**********************************************************************/
15690 
15691 /*
15692  Purpose:
15693 
15694  VERTEX_TO_FACE_MATERIAL extends vertex material definitions to faces.
15695 
15696  Discussion:
15697 
15698  Assuming material indices are defined for all the vertices, this
15699  routine assigns to each face the material associated with its
15700  first vertex.
15701 
15702  Modified:
15703 
15704  22 May 1999
15705 
15706  Author:
15707 
15708  John Burkardt
15709 */
15710 {
15711  int iface;
15712  int ivert;
15713 
15714  ivert = 0;
15715  for ( iface = 0; iface < face_num; iface++ ) {
15716  face_material[iface] = vertex_material[ivert][iface];
15717  }
15718 
15719  return;
15720 }
15721 /**********************************************************************/
15722 
15724 
15725 /**********************************************************************/
15726 
15727 /*
15728  Purpose:
15729 
15730  VERTEX_TO_NODE_MATERIAL extends vertex material definitions to nodes.
15731 
15732  Discussion:
15733 
15734  A NODE is a point in space.
15735  A VERTEX is a node as used in a particular face.
15736  One node may be used as a vertex in several faces, or none.
15737  This routine simply runs through all the vertices, and assigns
15738  the material of the vertex to the corresponding node. If a
15739  node appears as a vertex several times, then the node will
15740  end up having the material of the vertex that occurs "last".
15741 
15742  Modified:
15743 
15744  22 May 1999
15745 
15746  Author:
15747 
15748  John Burkardt
15749 */
15750 {
15751  int iface;
15752  int ivert;
15753  int node;
15754 
15755  for ( iface = 0; iface < face_num; iface++ ) {
15756  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
15757  node = face[ivert][iface];
15758  cor3_material[node] = vertex_material[ivert][iface];
15759  }
15760  }
15761 
15762  return;
15763 }
15764 
15765 /******************************************************************************/
15766 
15767 int vla_read ( FILE *filein )
15768 
15769 /******************************************************************************/
15770 
15771 /*
15772  Purpose:
15773 
15774  VLA_READ reads a VLA file.
15775 
15776  Examples:
15777 
15778  set comment cube.vla created by IVREAD
15779  set comment Original data in cube.iv.
15780  set comment
15781  set intensity EXPLICIT
15782  set parametric NON_PARAMETRIC
15783  set filecontent LINES
15784  set filetype NEW
15785  set depthcue 0
15786  set defaultdraw stellar
15787  set coordsys RIGHT
15788  set author IVREAD
15789  set site Buhl Planetarium
15790  set library_id UNKNOWN
15791  P 8.59816 5.55317 -3.05561 1.00000
15792  L 8.59816 2.49756 0.000000E+00 1.00000
15793  L 8.59816 2.49756 -3.05561 1.00000
15794  L 8.59816 5.55317 -3.05561 1.00000
15795  P 8.59816 5.55317 0.000000E+00 1.00000
15796  ...etc...
15797  L 2.48695 2.49756 -3.05561 1.00000
15798 
15799  Modified:
15800 
15801  23 May 1999
15802 
15803  Author:
15804 
15805  John Burkardt
15806 */
15807 {
15808  int i;
15809  int icor3;
15810  int dup_num;
15811  char *next;
15812  int text_num;
15813  float r1;
15814  float r2;
15815  float r3;
15816  float temp[3];
15817  char token[LINE_MAX_LEN];
15818  int width;
15819 /*
15820  Initialize.
15821 */
15822  dup_num = 0;
15823  text_num = 0;
15824 /*
15825  Read the next line of the file into INPUT.
15826 */
15827  while ( fgets ( input, LINE_MAX_LEN, filein ) != NULL ) {
15828 
15829  text_num = text_num + 1;
15830 /*
15831  Advance to the first nonspace character in INPUT.
15832 */
15833  for ( next = input; *next != '\0' && isspace(*next); next++ ) {
15834  }
15835 /*
15836  Skip blank lines and comments.
15837 */
15838  if ( *next == '\0' || *next == ';' ) {
15839  continue;
15840  }
15841 /*
15842  Extract the first word in this line.
15843 */
15844  sscanf ( next, "%s%n", token, &width );
15845 /*
15846  Set NEXT to point to just after this token.
15847 */
15848  next = next + width;
15849 /*
15850  SET (ignore)
15851 */
15852  if ( leqi ( token, "set" ) == TRUE ) {
15853  }
15854 /*
15855  P (begin a line)
15856  L (continue a line)
15857 */
15858  else if ( leqi ( token, "P" ) == TRUE || leqi ( token, "L") == TRUE ) {
15859 
15860  if ( leqi ( token, "P" ) == TRUE ) {
15861  if ( line_num > 0 ) {
15862  if ( line_num < LINES_MAX ) {
15863  line_dex[line_num] = -1;
15864  line_material[line_num] = -1;
15865  line_num = line_num + 1;
15866  }
15867  }
15868  }
15869 
15870  sscanf ( next, "%e %e %e", &r1, &r2, &r3 );
15871 
15872  temp[0] = r1;
15873  temp[1] = r2;
15874  temp[2] = r3;
15875 
15876  if ( cor3_num < 1000 ) {
15877  icor3 = rcol_find ( cor3, 3, cor3_num, temp );
15878  }
15879  else {
15880  icor3 = -1;
15881  }
15882 
15883  if ( icor3 == -1 ) {
15884 
15885  icor3 = cor3_num;
15886 
15887  if ( cor3_num < COR3_MAX ) {
15888  for ( i = 0; i < 3; i++ ) {
15889  cor3[i][cor3_num] = temp[i];
15890  }
15891  }
15892  cor3_num = cor3_num + 1;
15893  }
15894  else {
15895  dup_num = dup_num + 1;
15896  }
15897 
15898  if ( line_num < LINES_MAX ) {
15899  line_dex[line_num] = icor3;
15900  line_material[line_num] = 0;
15901  line_num = line_num + 1;
15902  }
15903  }
15904 /*
15905  Unexpected or unrecognized.
15906 */
15907  else {
15908  printf ( "\n" );
15909  printf ( "VLA_READ - Fatal error!\n" );
15910  printf ( " Unrecognized first word on line.\n" );
15911  return ERROR;
15912  }
15913 
15914  }
15915 
15916  if ( line_num > 0 ) {
15917  if ( line_num < LINES_MAX ) {
15918  line_dex[line_num] = -1;
15919  line_material[line_num] = -1;
15920  line_num = line_num + 1;
15921  }
15922  }
15923 
15924  return SUCCESS;
15925 }
15926 /******************************************************************************/
15927 
15928 int vla_write ( FILE *fileout )
15929 
15930 /******************************************************************************/
15931 
15932 /*
15933  Purpose:
15934 
15935  VLA_WRITE writes internal graphics information to a VLA file.
15936 
15937  Discussion:
15938 
15939  Comments begin with a semicolon in column 1.
15940  The X, Y, Z coordinates of points begin with a "P" to
15941  denote the beginning of a line, and "L" to denote the
15942  continuation of a line. The fourth entry is intensity, which
15943  should be between 0.0 and 1.0.
15944 
15945  Examples:
15946 
15947  set comment cube.vla created by IVREAD
15948  set comment Original data in cube.iv.
15949  set comment
15950  set intensity EXPLICIT
15951  set parametric NON_PARAMETRIC
15952  set filecontent LINES
15953  set filetype NEW
15954  set depthcue 0
15955  set defaultdraw stellar
15956  set coordsys RIGHT
15957  set author IVREAD
15958  set site Buhl Planetarium
15959  set library_id UNKNOWN
15960  P 8.59816 5.55317 -3.05561 1.00000
15961  L 8.59816 2.49756 0.000000E+00 1.00000
15962  L 8.59816 2.49756 -3.05561 1.00000
15963  L 8.59816 5.55317 -3.05561 1.00000
15964  P 8.59816 5.55317 0.000000E+00 1.00000
15965  ...etc...
15966  L 2.48695 2.49756 -3.05561 1.00000
15967 
15968  Modified:
15969 
15970  22 May 1999
15971 
15972  Author:
15973 
15974  John Burkardt
15975 */
15976 {
15977  char c;
15978  int iline;
15979  float intense = 1.0;
15980  int k;
15981  int text_num;
15982 /*
15983  Initialize.
15984 */
15985  text_num = 0;
15986 
15987  fprintf ( fileout, "set comment %s created by IVCON.\n", fileout_name );
15988  fprintf ( fileout, "set comment Original data in %s.\n", filein_name );
15989  fprintf ( fileout, "set comment\n" );
15990  fprintf ( fileout, "set intensity EXPLICIT\n" );
15991  fprintf ( fileout, "set parametric NON_PARAMETRIC\n" );
15992  fprintf ( fileout, "set filecontent LINES\n" );
15993  fprintf ( fileout, "set filetype NEW\n" );
15994  fprintf ( fileout, "set depthcue 0\n" );
15995  fprintf ( fileout, "set defaultdraw stellar\n" );
15996  fprintf ( fileout, "set coordsys RIGHT\n" );
15997  fprintf ( fileout, "set author IVCON\n" );
15998  fprintf ( fileout, "set site Buhl Planetarium\n" );
15999  fprintf ( fileout, "set library_id UNKNOWN\n" );
16000 
16001  text_num = text_num + 13;
16002 
16003  c = 'P';
16004 
16005  for ( iline = 0; iline < line_num; iline++ ) {
16006 
16007  k = line_dex[iline];
16008 
16009  if ( k == -1 ) {
16010 
16011  c = 'P';
16012  }
16013  else {
16014 
16015  fprintf ( fileout, "%c %f %f %f %f\n",
16016  c, cor3[0][k], cor3[1][k], cor3[2][k], intense );
16017 
16018  text_num = text_num + 1;
16019 
16020  c = 'L';
16021  }
16022  }
16023 /*
16024  Report.
16025 */
16026  printf ( "\n" );
16027  printf ( "VLA_WRITE - Wrote %d text lines.\n", text_num );
16028 
16029 
16030  return SUCCESS;
16031 }
16032 
16033 /**********************************************************************/
16034 
16035 int wrl_write ( FILE *fileout )
16036 
16037 /**********************************************************************/
16038 
16039 /*
16040  Purpose:
16041 
16042  WRL_WRITE writes graphics data to a WRL file.
16043 
16044  Example:
16045 
16046  #VRML V2.0 utf8
16047 
16048  WorldInfo {
16049  title "cube.iv."
16050  string "WRL file generated by IVREAD.
16051  }
16052 
16053  Group {
16054  children [
16055 
16056  Shape {
16057 
16058  appearance Appearance {
16059  material Material {
16060  diffuseColor 0.0 0.0 0.0
16061  emissiveColor 0.0 0.0 0.0
16062  shininess 1.0
16063  }
16064  } #end of appearance
16065 
16066  geometry IndexedLineSet {
16067 
16068  coord Coordinate {
16069  point [
16070  8.59816 5.55317 -3.05561
16071  8.59816 2.49756 0.000000E+00
16072  ...etc...
16073  2.48695 2.49756 -3.05561
16074  ]
16075  }
16076 
16077  coordIndex [
16078  0 1 2 -1 3 4 5 6 7 8 -
16079  9 10 -1 11 12 -1 13 14 15 -1 1
16080  ...etc...
16081  191 -1
16082  ]
16083 
16084  colorPerVertex TRUE
16085 
16086  colorIndex [
16087  0 0 0 -1 2 3 1 1 4 7 -
16088  10 9 -1 7 7 -1 3 2 2 -1 1
16089  ...etc...
16090  180 -1
16091  ]
16092 
16093  } #end of geometry
16094 
16095  } #end of Shape
16096 
16097  ] #end of children
16098 
16099  } #end of Group
16100 
16101  Modified:
16102 
16103  23 May 1999
16104 
16105  Author:
16106 
16107  John Burkardt
16108 */
16109 {
16110  int icor3;
16111  int iface;
16112  int itemp;
16113  int ivert;
16114  int j;
16115  int length;
16116  int ndx;
16117 
16118  text_num = 0;
16119 
16120  fprintf ( fileout, "#VRML V2.0 utf8\n" );
16121  fprintf ( fileout, "\n" );
16122  fprintf ( fileout, " WorldInfo {\n" );
16123  fprintf ( fileout, " title \"%s\"\n", fileout_name );
16124  fprintf ( fileout, " info \"WRL file generated by IVREAD.\"\n" );
16125  fprintf ( fileout, " info \"Original data in %s\"\n", filein_name );
16126  fprintf ( fileout, " }\n" );
16127  fprintf ( fileout, "\n" );
16128  fprintf ( fileout, " Group {\n" );
16129  fprintf ( fileout, " children [\n" );
16130  fprintf ( fileout, " Shape {\n" );
16131  fprintf ( fileout, " appearance Appearance {\n" );
16132  fprintf ( fileout, " material Material {\n" );
16133  fprintf ( fileout, " diffuseColor 0.0 0.0 0.0\n" );
16134  fprintf ( fileout, " emissiveColor 0.0 0.0 0.0\n" );
16135  fprintf ( fileout, " shininess 1.0\n" );
16136  fprintf ( fileout, " }\n" );
16137  fprintf ( fileout, " }\n" );
16138 
16139  text_num = text_num + 18;
16140 /*
16141  IndexedLineSet
16142 */
16143  if ( line_num > 0 ) {
16144 
16145  fprintf ( fileout, " geometry IndexedLineSet {\n" );
16146 /*
16147  IndexedLineSet coord
16148 */
16149  fprintf ( fileout, " coord Coordinate {\n" );
16150  fprintf ( fileout, " point [\n" );
16151 
16152  text_num = text_num + 3;
16153 
16154  for ( icor3 = 0; icor3 < cor3_num; icor3++ ) {
16155  fprintf ( fileout, " %f %f %f\n", cor3[0][icor3],
16156  cor3[1][icor3], cor3[2][icor3] );
16157  text_num = text_num + 1;
16158  }
16159 
16160  fprintf ( fileout, " ]\n" );
16161  fprintf ( fileout, " }\n" );
16162  text_num = text_num + 2;
16163 /*
16164  IndexedLineSet coordIndex.
16165 */
16166  fprintf ( fileout, " coordIndex [\n" );
16167 
16168  text_num = text_num + 1;
16169 
16170  length = 0;
16171  for ( j = 0; j < line_num; j++ ) {
16172  fprintf ( fileout, "%d ", line_dex[j] );
16173  length = length + 1;
16174  if ( line_dex[j] == -1 || length >= 10 || j == line_num - 1 ) {
16175  fprintf ( fileout, "\n" );
16176  text_num = text_num + 1;
16177  length = 0;
16178  }
16179  }
16180 
16181  fprintf ( fileout, " ]\n" );
16182  text_num = text_num + 1;
16183 /*
16184  Colors. (materials)
16185 */
16186  fprintf ( fileout, " color Color {\n" );
16187  fprintf ( fileout, " color [\n" );
16188  text_num = text_num + 2;
16189 
16190  for ( j = 0; j < material_num; j++ ) {
16191  fprintf ( fileout, " %f %f %f\n", material_rgba[0][j],
16192  material_rgba[1][j], material_rgba[2][j] );
16193  text_num = text_num + 1;
16194  }
16195 
16196  fprintf ( fileout, " ]\n" );
16197  fprintf ( fileout, " }\n" );
16198  fprintf ( fileout, " colorPerVertex TRUE\n" );
16199 /*
16200  IndexedLineset colorIndex
16201 */
16202  fprintf ( fileout, " colorIndex [\n" );
16203 
16204  text_num = text_num + 4;
16205 
16206  length = 0;
16207  for ( j = 0; j < line_num; j++ ) {
16208  fprintf ( fileout, "%d ", line_material[j] );
16209  length = length + 1;
16210  if ( line_dex[j] == -1 || length >= 10 || j == line_num - 1 ) {
16211  fprintf ( fileout, "\n" );
16212  text_num = text_num + 1;
16213  length = 0;
16214  }
16215  }
16216 
16217  fprintf ( fileout, " ]\n" );
16218  fprintf ( fileout, " }\n" );
16219  text_num = text_num + 2;
16220 
16221  }
16222 /*
16223  End of IndexedLineSet
16224 
16225  IndexedFaceSet
16226 */
16227  if ( face_num > 0 ) {
16228 
16229  fprintf ( fileout, " geometry IndexedFaceSet {\n" );
16230 /*
16231  IndexedFaceSet coord
16232 */
16233  fprintf ( fileout, " coord Coordinate {\n" );
16234  fprintf ( fileout, " point [\n" );
16235 
16236  text_num = text_num + 3;
16237 
16238  for ( icor3 = 0; icor3 < cor3_num; icor3++ ) {
16239  fprintf ( fileout, " %f %f %f\n", cor3[0][icor3],
16240  cor3[1][icor3], cor3[2][icor3] );
16241 
16242  text_num = text_num + 1;
16243  }
16244 
16245  fprintf ( fileout, " ]\n" );
16246  fprintf ( fileout, " }\n" );
16247 /*
16248  IndexedFaceSet coordIndex.
16249 */
16250  fprintf ( fileout, " coordIndex [\n" );
16251 
16252  text_num = text_num + 3;
16253 
16254  length = 0;
16255 
16256  for ( iface = 0; iface < face_num; iface++ ) {
16257 
16258  for ( ivert = 0; ivert <= face_order[iface]; ivert++ ) {
16259 
16260  if ( ivert <= face_order[iface] ) {
16261  itemp = face[ivert][iface];
16262  }
16263  else {
16264  itemp = 0;
16265  }
16266 
16267  fprintf ( fileout, "%d ", itemp );
16268  length = length + 1;
16269 
16270  if ( itemp == -1 || length >= 10 ||
16271  ( iface == face_num - 1 && ivert == face_order[iface] ) ) {
16272  fprintf ( fileout, "\n" );
16273  text_num = text_num + 1;
16274  length = 0;
16275  }
16276 
16277  }
16278 
16279  }
16280 
16281  fprintf ( fileout, " ]\n" );
16282  text_num = text_num + 1;
16283 /*
16284  IndexedFaceset colorIndex
16285 */
16286  fprintf ( fileout, " colorIndex [\n" );
16287  text_num = text_num + 1;
16288 
16289  length = 0;
16290  ndx = 0;
16291 
16292  for ( iface = 0; iface < face_num; iface++ ) {
16293 
16294  for ( ivert = 0; ivert <= face_order[iface]; ivert++ ) {
16295 
16296  if ( ivert <= face_order[iface] ) {
16297  itemp = vertex_material[ivert][iface];
16298  ndx = ndx + 1;
16299  }
16300  else {
16301  itemp = 0;
16302  }
16303 
16304  fprintf ( fileout, "%d ", itemp );
16305  length = length + 1;
16306 
16307  if ( itemp == -1 || length >= 10 ||
16308  ( iface == face_num - 1 && ivert == face_order[iface] ) ) {
16309 
16310  fprintf ( fileout, "\n" );
16311  text_num = text_num + 1;
16312  length = 0;
16313 
16314  }
16315 
16316  }
16317 
16318  }
16319 
16320  fprintf ( fileout, " ]\n" );
16321  fprintf ( fileout, " }\n" );
16322  text_num = text_num + 2;
16323 
16324  }
16325 /*
16326  End of IndexedFaceSet
16327 
16328  End of:
16329  Shape
16330  children
16331  Group
16332 */
16333  fprintf ( fileout, " }\n" );
16334  fprintf ( fileout, " ]\n" );
16335  fprintf ( fileout, " }\n" );
16336 
16337  text_num = text_num + 3;
16338 /*
16339  Report.
16340 */
16341  printf ( "\n" );
16342  printf ( "WRL_WRITE - Wrote %d text lines.\n", text_num );
16343 
16344  return SUCCESS;
16345 }
16346 /******************************************************************************/
16347 
16348 int xgl_write ( FILE *fileout )
16349 
16350 /******************************************************************************/
16351 
16352 /*
16353  Purpose:
16354 
16355  XGL_WRITE writes an XGL file.
16356 
16357  Discussion:
16358 
16359  Two corrections to the routine were pointed out by
16360  Mike Phillips, msphil@widowmaker.com, on 17 September 2001,
16361  and are gratefully acknowledged.
16362 
16363  Example:
16364 
16365  <WORLD>
16366 
16367  <BACKGROUND>
16368  <BACKCOLOR> 0.1, 0.1, 0.1 </BACKCOLOR>
16369  </BACKGROUND>
16370 
16371  <LIGHTING>
16372  <AMBIENT> 0.2, 0.1, 0.1 </AMBIENT>
16373  <DIRECTIONALLIGHT>
16374  <DIFFUSE> 0.1, 0.2, 0.1 </DIFFUSE>
16375  <DIRECTION> 0, 0, 100 </DIRECTION>
16376  <SPECULAR> 0.1, 0.1, 0.2 </SPECULAR>
16377  </DIRECTIONALLIGHT>
16378  </LIGHTING>
16379 
16380  <MESH ID = "0">
16381 
16382  <P ID="0"> -0.5, -0.5, 1 </P>
16383  <P ID="1"> 0.5, -0.5, 1 </P>
16384  <P ID="2"> 0.5, 0.5, 1 </P>
16385  <P ID="3"> -0.5, 0.5, 1 </P>
16386  <P ID="4"> 0.5, -0.5, 0 </P>
16387  <P ID="5"> -0.5, -0.5, 0 </P>
16388  <P ID="6"> -0.5, 0.5, 0 </P>
16389  <P ID="7"> 0.5, 0.5, 0 </P>
16390 
16391  <N ID="0"> -0.408248, -0.408248, 0.816497 </N>
16392  <N ID="1"> 0.666667, -0.666667, 0.333333 </N>
16393  <N ID="2"> 0.408248, 0.408248, 0.816497 </N>
16394  <N ID="3"> -0.666667, 0.666667, 0.333333 </N>
16395  <N ID="4"> 0.408248, -0.408248, -0.816497 </N>
16396  <N ID="5"> -0.666667, -0.666667, -0.333333 </N>
16397  <N ID="6"> -0.408248, 0.408248, -0.816497 </N>
16398  <N ID="7"> 0.666667, 0.666667, -0.333333 </N>
16399 
16400  <MAT ID="0">
16401  <ALPHA> 0.9 </ALPHA>
16402  <AMB> 0.1, 0.1, 0.1 </AMB>
16403  <DIFF> 0.2, 0.1, 0.1 </DIFF>
16404  <EMISS> 0.1, 0.2, 0.1 </EMISS>
16405  <SHINE> 0.8 </SHINE>
16406  <SPEC> 0.1, 0.1, 0.2 </SPEC>
16407  </MAT>
16408 
16409  <F>
16410  <MATREF> 0 </MATREF>
16411  <FV1><PREF> 0 </PREF><NREF> 0 </NREF></FV1>
16412  <FV2><PREF> 1 </PREF><NREF> 1 </NREF></FV2>
16413  <FV3><PREF> 2 </PREF><NREF> 2 </NREF></FV3>
16414  </F>
16415  <F>
16416  <MATREF> 0 </MATREF>
16417  <FV1><PREF> 0 </PREF><NREF> 0 </NREF></FV1>
16418  <FV2><PREF> 2 </PREF><NREF> 2 </NREF></FV2>
16419  <FV3><PREF> 3 </PREF><NREF> 3 </NREF></FV3>
16420  </F>
16421  <F>
16422  <MATREF> 0 </MATREF>
16423  <FV1><PREF> 4 </PREF><NREF> 4 </NREF></FV1>
16424  <FV2><PREF> 5 </PREF><NREF> 5 </NREF></FV2>
16425  <FV3><PREF> 6 </PREF><NREF> 6 </NREF></FV3>
16426  </F>
16427  <F>
16428  <MATREF> 0 </MATREF>
16429  <FV1><PREF> 4 </PREF><NREF> 4 </NREF></FV1>
16430  <FV2><PREF> 6 </PREF><NREF> 6 </NREF></FV2>
16431  <FV3><PREF> 7 </PREF><NREF> 7 </NREF></FV3>
16432  </F>
16433  <F>
16434  <MATREF> 0 </MATREF>
16435  <FV1><PREF> 5 </PREF><NREF> 5 </NREF></FV1>
16436  <FV2><PREF> 0 </PREF><NREF> 0 </NREF></FV2>
16437  <FV3><PREF> 3 </PREF><NREF> 3 </NREF></FV3>
16438  </F>
16439  <F>
16440  <MATREF> 0 </MATREF>
16441  <FV1><PREF> 5 </PREF><NREF> 5 </NREF></FV1>
16442  <FV2><PREF> 3 </PREF><NREF> 3 </NREF></FV2>
16443  <FV3><PREF> 6 </PREF><NREF> 6 </NREF></FV3>
16444  </F>
16445  <F>
16446  <MATREF> 0 </MATREF>
16447  <FV1><PREF> 1 </PREF><NREF> 1 </NREF></FV1>
16448  <FV2><PREF> 4 </PREF><NREF> 4 </NREF></FV2>
16449  <FV3><PREF> 7 </PREF><NREF> 7 </NREF></FV3>
16450  </F>
16451  <F>
16452  <MATREF> 0 </MATREF>
16453  <FV1><PREF> 1 </PREF><NREF> 1 </NREF></FV1>
16454  <FV2><PREF> 7 </PREF><NREF> 7 </NREF></FV2>
16455  <FV3><PREF> 2 </PREF><NREF> 2 </NREF></FV3>
16456  </F>
16457  <F>
16458  <MATREF> 0 </MATREF>
16459  <FV1><PREF> 5 </PREF><NREF> 5 </NREF></FV1>
16460  <FV2><PREF> 4 </PREF><NREF> 4 </NREF></FV2>
16461  <FV3><PREF> 1 </PREF><NREF> 1 </NREF></FV3>
16462  </F>
16463  <F>
16464  <MATREF> 0 </MATREF>
16465  <FV1><PREF> 5 </PREF><NREF> 5 </NREF></FV1>
16466  <FV2><PREF> 1 </PREF><NREF> 1 </NREF></FV2>
16467  <FV3><PREF> 0 </PREF><NREF> 0 </NREF></FV3>
16468  </F>
16469  <F>
16470  <MATREF> 0 </MATREF>
16471  <FV1><PREF> 3 </PREF><NREF> 3 </NREF></FV1>
16472  <FV2><PREF> 2 </PREF><NREF> 2 </NREF></FV2>
16473  <FV3><PREF> 7 </PREF><NREF> 7 </NREF></FV3>
16474  </F>
16475  <F>
16476  <MATREF> 0 </MATREF>
16477  <FV1><PREF> 3 </PREF><NREF> 3 </NREF></FV1>
16478  <FV2><PREF> 7 </PREF><NREF> 7 </NREF></FV2>
16479  <FV3><PREF> 6 </PREF><NREF> 6 </NREF></FV3>
16480  </F>
16481  </MESH>
16482 
16483  <OBJECT>
16484  <TRANSFORM>
16485  <FORWARD> 0, 0, 0 </FORWARD>
16486  <POSITION> 0, 0, 0 </POSITION>
16487  <SCALE> 1, 1, 1 </SCALE>
16488  <UP> 1, 1, 1 </UP>
16489  </TRANSFORM>
16490  <MESHREF> 0 </MESHREF>
16491  </OBJECT>
16492 
16493  </WORLD>
16494 
16495  Reference:
16496 
16497  XGL specification at http://www.xglspec.org/
16498 
16499  Modified:
16500 
16501  17 September 2001
16502 
16503  Author:
16504 
16505  John Burkardt
16506 */
16507 {
16508  int iface;
16509  int ivert;
16510  int j;
16511  float light_ambient_rgb[3];
16512  float light_diffuse_rgb[3];
16513  float light_direction[3];
16514  float light_specular_rgb[3];
16515  int material;
16516  float material_alpha;
16517  float material_amb_rgb[3];
16518  float material_diff_rgb[3];
16519  float material_emiss_rgb[3];
16520  float material_shine;
16521  float material_spec_rgb[3];
16522  int mesh;
16523  int mesh_num = 1;
16524  int object;
16525  float transform_forward[3];
16526  float transform_position[3];
16527  float transform_scale[3];
16528  float transform_up[3];
16529 /*
16530  Make up some placeholder values for now.
16531 */
16532  light_ambient_rgb[0] = 0.2;
16533  light_ambient_rgb[1] = 0.1;
16534  light_ambient_rgb[2] = 0.1;
16535 
16536  light_diffuse_rgb[0] = 0.1;
16537  light_diffuse_rgb[1] = 0.2;
16538  light_diffuse_rgb[2] = 0.1;
16539 
16540  light_direction[0] = 0.0;
16541  light_direction[1] = 0.0;
16542  light_direction[2] = 100.0;
16543 
16544  light_specular_rgb[0] = 0.1;
16545  light_specular_rgb[1] = 0.1;
16546  light_specular_rgb[2] = 0.2;
16547 
16548  material_alpha = 0.9;
16549 
16550  material_amb_rgb[0] = 0.1;
16551  material_amb_rgb[1] = 0.1;
16552  material_amb_rgb[2] = 0.1;
16553 
16554  material_diff_rgb[0] = 0.2;
16555  material_diff_rgb[1] = 0.1;
16556  material_diff_rgb[2] = 0.1;
16557 
16558  material_emiss_rgb[0] = 0.1;
16559  material_emiss_rgb[1] = 0.2;
16560  material_emiss_rgb[2] = 0.1;
16561 
16562  material_shine = 0.8;
16563 
16564  material_spec_rgb[0] = 0.1;
16565  material_spec_rgb[1] = 0.1;
16566  material_spec_rgb[2] = 0.2;
16567 
16568  transform_forward[0] = 0.0;
16569  transform_forward[1] = 0.0;
16570  transform_forward[2] = 0.0;
16571 
16572  transform_position[0] = 0.0;
16573  transform_position[1] = 0.0;
16574  transform_position[2] = 0.0;
16575 
16576  transform_scale[0] = 1.0;
16577  transform_scale[1] = 1.0;
16578  transform_scale[2] = 1.0;
16579 
16580  transform_up[0] = 1.0;
16581  transform_up[1] = 1.0;
16582  transform_up[2] = 1.0;
16583 
16584  object_num = 1;
16585 
16586  text_num = 0;
16587 
16588  fprintf ( fileout, "<WORLD>\n" );
16589  fprintf ( fileout, "\n" );
16590 
16591  text_num = text_num + 2;
16592 
16593  fprintf ( fileout, " <BACKGROUND>\n" );
16594  fprintf ( fileout, " <BACKCOLOR> %f, %f, %f </BACKCOLOR>\n",
16596  fprintf ( fileout, " </BACKGROUND>\n" );
16597  fprintf ( fileout, "\n" );
16598  fprintf ( fileout, " <LIGHTING>\n" );
16599  fprintf ( fileout, " <AMBIENT> %f, %f, %f </AMBIENT>\n",
16600  light_ambient_rgb[0], light_ambient_rgb[1], light_ambient_rgb[2] );
16601  fprintf ( fileout, " <DIRECTIONALLIGHT>\n" );
16602  fprintf ( fileout, " <DIFFUSE> %f, %f, %f </DIFFUSE>\n",
16603  light_diffuse_rgb[0], light_diffuse_rgb[1], light_diffuse_rgb[2] );
16604  fprintf ( fileout, " <DIRECTION> %f, %f, %f </DIRECTION>\n",
16605  light_direction[0], light_direction[1], light_direction[2] );
16606  fprintf ( fileout, " <SPECULAR> %f, %f, %f </SPECULAR>\n",
16607  light_specular_rgb[0], light_specular_rgb[1], light_specular_rgb[2] );
16608  fprintf ( fileout, " </DIRECTIONALLIGHT>\n" );
16609  fprintf ( fileout, " </LIGHTING>\n" );
16610 
16611  text_num = text_num + 12;
16612 
16613  for ( mesh = 0; mesh < mesh_num; mesh++ ) {
16614 
16615  fprintf ( fileout, "\n" );
16616  fprintf ( fileout, " <MESH ID = \"%d\">\n", mesh );
16617  fprintf ( fileout, "\n" );
16618  text_num = text_num + 3;
16619 
16620  for ( j = 0; j < cor3_num; j++ ) {
16621  fprintf ( fileout, " <P ID=\"%d\"> %f, %f, %f </P>\n", j,
16622  cor3[0][j], cor3[1][j], cor3[2][j] );
16623  text_num = text_num + 1;
16624  }
16625 
16626  fprintf ( fileout, "\n" );
16627  text_num = text_num + 1;
16628  for ( j = 0; j < cor3_num; j++ ) {
16629  fprintf ( fileout, " <N ID=\"%d\"> %f, %f, %f </N>\n", j,
16630  cor3_normal[0][j], cor3_normal[1][j], cor3_normal[2][j] );
16631  text_num = text_num + 1;
16632  }
16633 
16634  for ( material = 0; material < material_num; material++ ) {
16635  fprintf ( fileout, "\n" );
16636  fprintf ( fileout, " <MAT ID=\"%d\">\n", material );
16637  fprintf ( fileout, " <ALPHA> %f </ALPHA>\n", material_alpha );
16638  fprintf ( fileout, " <AMB> %f, %f, %f </AMB>\n",
16639  material_amb_rgb[0], material_amb_rgb[1], material_amb_rgb[2] );
16640  fprintf ( fileout, " <DIFF> %f, %f, %f </DIFF>\n",
16641  material_diff_rgb[0], material_diff_rgb[1], material_diff_rgb[2] );
16642  fprintf ( fileout, " <EMISS> %f, %f, %f </EMISS>\n",
16643  material_emiss_rgb[0], material_emiss_rgb[1], material_emiss_rgb[2] );
16644  fprintf ( fileout, " <SHINE> %f </SHINE>\n", material_shine );
16645  fprintf ( fileout, " <SPEC> %f, %f, %f </SPEC>\n",
16646  material_spec_rgb[0], material_spec_rgb[1], material_spec_rgb[2] );
16647  fprintf ( fileout, " </MAT>\n" );
16648  text_num = text_num + 9;
16649  }
16650 
16651  fprintf ( fileout, "\n" );
16652  text_num = text_num + 1;
16653 
16654  for ( iface = 0; iface < face_num; iface++ ) {
16655  fprintf ( fileout, " <F>\n" );
16656  fprintf ( fileout, " <MATREF> %d </MATREF>\n", face_material[iface] );
16657  text_num = text_num + 2;
16658  for ( ivert = 0; ivert < face_order[iface]; ivert++ ) {
16659  fprintf ( fileout,
16660  " <FV%d><PREF> %d </PREF><NREF> %d </NREF></FV%d>\n",
16661  ivert+1, face[ivert][iface], face[ivert][iface], ivert+1 );
16662  text_num = text_num + 1;
16663  }
16664  fprintf ( fileout, " </F>\n" );
16665  text_num = text_num + 1;
16666  }
16667 
16668  fprintf ( fileout, " </MESH>\n" );
16669  text_num = text_num + 1;
16670 
16671  }
16672 
16673  fprintf ( fileout, "\n" );
16674  text_num = text_num + 1;
16675 
16676  for ( object = 0; object < object_num; object++ ) {
16677 
16678  fprintf ( fileout, " <OBJECT>\n" );
16679  fprintf ( fileout, " <TRANSFORM>\n" );
16680  fprintf ( fileout, " <FORWARD> %f, %f, %f </FORWARD>\n",
16681  transform_forward[0], transform_forward[1], transform_forward[2] );
16682  fprintf ( fileout, " <POSITION> %f, %f, %f </POSITION>\n",
16683  transform_position[0], transform_position[1], transform_position[2] );
16684  fprintf ( fileout, "' <SCALE> %f, %f, %f </SCALE>\n",
16685  transform_scale[0], transform_scale[1], transform_scale[2] );
16686  fprintf ( fileout, " <UP> %f, %f, %f </UP>\n",
16687  transform_up[0], transform_up[1], transform_up[2] );
16688  fprintf ( fileout, " </TRANSFORM>\n" );
16689  mesh = 0;
16690  fprintf ( fileout, " <MESHREF> %d </MESHREF>\n", mesh );
16691  fprintf ( fileout, " </OBJECT>\n" );
16692  text_num = text_num + 9;
16693 
16694  }
16695 
16696  fprintf ( fileout, "\n" );
16697  fprintf ( fileout, "</WORLD>\n" );
16698  text_num = text_num + 2;
16699 
16700 /*
16701  Report.
16702 */
16703  printf ( "\n" );
16704  printf ( "XGL_WRITE - Wrote %d text lines.\n", text_num );
16705 
16706  return SUCCESS;
16707 }
filein_name
char filein_name[1024]
Definition: ivcon.c:164
line_material
int line_material[LINES_MAX]
Definition: ivcon.c:175
GMOD_MAX_SECTIONS
#define GMOD_MAX_SECTIONS
Definition: ivcon.c:43
char_pad
int char_pad(int *char_index, int *null_index, char *string, int STRING_MAX)
Definition: ivcon.c:1604
material_name
char material_name[MATERIAL_MAX][LINE_MAX_LEN]
Definition: ivcon.c:182
temp_name
char temp_name[81]
Definition: ivcon.c:198
TEXTURE_MAX
#define TEXTURE_MAX
Definition: ivcon.c:133
mat_name
char mat_name[81]
Definition: ivcon.c:186
gmod_write_float
void gmod_write_float(float Val, FILE *fileout)
Definition: ivcon.c:5015
help
void help(void)
Definition: ivcon.c:5168
normal_binding
char normal_binding[80]
Definition: ivcon.c:189
obj_write
int obj_write(FILE *fileout)
Definition: ivcon.c:9600
cor3_normal_set
void cor3_normal_set(void)
Definition: ivcon.c:1858
MATERIAL_MAX
#define MATERIAL_MAX
Definition: ivcon.c:131
texture_binding
char texture_binding[80]
Definition: ivcon.c:202
material_binding
char material_binding[80]
Definition: ivcon.c:181
vla_read
int vla_read(FILE *filein)
Definition: ivcon.c:15767
gmod_write_w16
void gmod_write_w16(unsigned short Val, FILE *fileout)
Definition: ivcon.c:5051
tds_read_tex_verts_section
unsigned long int tds_read_tex_verts_section(FILE *filein)
Definition: ivcon.c:13082
gmod_read_w32
unsigned long gmod_read_w32(FILE *filein)
Definition: ivcon.c:4697
tmat_mxp
void tmat_mxp(float a[4][4], float x[4], float y[4])
Definition: ivcon.c:14131
G1_SECTION_MODEL_VERT_ANIMATION
#define G1_SECTION_MODEL_VERT_ANIMATION
Definition: ivcon.c:42
line_dex
int line_dex[LINES_MAX]
Definition: ivcon.c:174
face_to_line
void face_to_line(void)
Definition: ivcon.c:3990
i
int i
Definition: ivcon.c:169
tria_write
int tria_write(FILE *fileout)
Definition: ivcon.c:14767
G1_SECTION_MODEL_QUADS
#define G1_SECTION_MODEL_QUADS
Definition: ivcon.c:40
tds_read_spot_section
unsigned long int tds_read_spot_section(FILE *filein)
Definition: ivcon.c:13214
xgl_write
int xgl_write(FILE *fileout)
Definition: ivcon.c:16348
LINE_MAX_LEN
#define LINE_MAX_LEN
Definition: ivcon.c:128
tds_read_texmap_section
unsigned long int tds_read_texmap_section(FILE *filein)
Definition: ivcon.c:13130
LEVEL_MAX
#define LEVEL_MAX
Definition: ivcon.c:129
smf_read
int smf_read(FILE *filein)
Definition: ivcon.c:10180
tmat_shear
void tmat_shear(float a[4][4], float b[4][4], char *axis, float s)
Definition: ivcon.c:14517
byte_swap
int byte_swap
Definition: ivcon.c:138
cor3_normal
float cor3_normal[3][COR3_MAX]
Definition: ivcon.c:145
face_print
int face_print(int iface)
Definition: ivcon.c:3704
file_ext
char * file_ext(char *file_name)
Definition: ivcon.c:4140
iv_read
int iv_read(FILE *filein)
Definition: ivcon.c:6895
GMOD_UNUSED_VERTEX
#define GMOD_UNUSED_VERTEX
Definition: ivcon.c:44
char_write
int char_write(FILE *fileout, char c)
Definition: ivcon.c:1690
DEG_TO_RAD
#define DEG_TO_RAD
Definition: ivcon.c:48
cor3
float cor3[3][COR3_MAX]
Definition: ivcon.c:143
transform_matrix
float transform_matrix[4][4]
Definition: ivcon.c:207
char_index_last
int char_index_last(char *string, char c)
Definition: ivcon.c:1571
tds_read_u_long_int
unsigned long int tds_read_u_long_int(FILE *filein)
Definition: ivcon.c:12379
tds_write_string
int tds_write_string(FILE *fileout, char *string)
Definition: ivcon.c:13812
vertex_rgb
float vertex_rgb[3][ORDER_MAX][FACE_MAX]
Definition: ivcon.c:211
tmat_rot_vector
void tmat_rot_vector(float a[4][4], float b[4][4], float angle, float v1, float v2, float v3)
Definition: ivcon.c:14380
list
int list[COR3_MAX]
Definition: ivcon.c:179
tmat_scale
void tmat_scale(float a[4][4], float b[4][4], float sx, float sy, float sz)
Definition: ivcon.c:14460
G1_SECTION_MODEL_TEXTURE_NAMES
#define G1_SECTION_MODEL_TEXTURE_NAMES
Definition: ivcon.c:41
tec_write
int tec_write(FILE *fileout)
Definition: ivcon.c:13880
tds_read_long_name
int tds_read_long_name(FILE *filein)
Definition: ivcon.c:12415
tds_read_keyframe_section
unsigned long int tds_read_keyframe_section(FILE *filein, int *views_read)
Definition: ivcon.c:12075
rcol_find
int rcol_find(float a[][COR3_MAX], int m, int n, float r[])
Definition: ivcon.c:9931
tds_read_background_section
unsigned long int tds_read_background_section(FILE *filein)
Definition: ivcon.c:11754
FALSE
#define FALSE
Definition: ivcon.c:36
COR3_MAX
#define COR3_MAX
Definition: ivcon.c:126
max_order2
int max_order2
Definition: ivcon.c:187
trib_read
int trib_read(FILE *filein)
Definition: ivcon.c:14873
smf_write
int smf_write(FILE *fileout)
Definition: ivcon.c:10799
ORDER_MAX
#define ORDER_MAX
Definition: ivcon.c:132
data_check
void data_check(void)
Definition: ivcon.c:2016
tria_read
int tria_read(FILE *filein)
Definition: ivcon.c:14655
ucd_write
int ucd_write(FILE *fileout)
Definition: ivcon.c:15404
stla_write
int stla_write(FILE *fileout)
Definition: ivcon.c:11190
ivec_max
int ivec_max(int n, int *a)
Definition: ivcon.c:8766
long_int_write
int long_int_write(FILE *fileout, long int int_val)
Definition: ivcon.c:8908
iv_write
int iv_write(FILE *fileout)
Definition: ivcon.c:8396
byu_write
int byu_write(FILE *fileout)
Definition: ivcon.c:1447
gmod_read
int gmod_read(FILE *filein)
Definition: ivcon.c:4317
tds_read_light_section
unsigned long int tds_read_light_section(FILE *filein)
Definition: ivcon.c:12270
face_flags
int face_flags[FACE_MAX]
Definition: ivcon.c:155
input
char input[LINE_MAX_LEN]
Definition: ivcon.c:170
FACE_MAX
#define FACE_MAX
Definition: ivcon.c:127
leqi
int leqi(char *string1, char *string2)
Definition: ivcon.c:8805
face
int face[ORDER_MAX][FACE_MAX]
Definition: ivcon.c:153
char_read
char char_read(FILE *filein)
Definition: ivcon.c:1664
float_reverse_bytes
float float_reverse_bytes(float x)
Definition: ivcon.c:4201
tmat_mxm
void tmat_mxm(float a[4][4], float b[4][4], float c[4][4])
Definition: ivcon.c:14070
face_area
float face_area[FACE_MAX]
Definition: ivcon.c:154
vla_write
int vla_write(FILE *fileout)
Definition: ivcon.c:15928
tmat_mxp2
void tmat_mxp2(float a[4][4], float x[][3], float y[][3], int n)
Definition: ivcon.c:14184
tds_read_u_short_int
unsigned short int tds_read_u_short_int(FILE *filein)
Definition: ivcon.c:13197
float_read
float float_read(FILE *filein)
Definition: ivcon.c:4171
wrl_write
int wrl_write(FILE *filout)
Definition: ivcon.c:16035
material_num
int material_num
Definition: ivcon.c:183
tds_read_edit_section
unsigned long int tds_read_edit_section(FILE *filein, int *views_read)
Definition: ivcon.c:11914
tmat_rot_axis
void tmat_rot_axis(float a[4][4], float b[4][4], float angle, char axis)
Definition: ivcon.c:14296
tds_pre_process
void tds_pre_process(void)
Definition: ivcon.c:11521
tds_read_unknown_section
unsigned long int tds_read_unknown_section(FILE *filein)
Definition: ivcon.c:13249
interact
int interact(void)
Definition: ivcon.c:6507
vertex_normal
float vertex_normal[3][ORDER_MAX][FACE_MAX]
Definition: ivcon.c:210
face_object
int face_object[FACE_MAX]
Definition: ivcon.c:159
short_int_write
int short_int_write(FILE *fileout, short int int_val)
Definition: ivcon.c:10142
stla_read
int stla_read(FILE *filein)
Definition: ivcon.c:11004
tds_read_name
int tds_read_name(FILE *filein)
Definition: ivcon.c:12733
gmod_write_w32
void gmod_write_w32(unsigned long Val, FILE *fileout)
Definition: ivcon.c:5078
tds_read_camera_section
unsigned long int tds_read_camera_section(FILE *filein)
Definition: ivcon.c:11845
line_prune
int line_prune
Definition: ivcon.c:177
k
int k
Definition: ivcon.c:171
hrc_read
int hrc_read(FILE *filein)
Definition: ivcon.c:5210
gmod_read_w16
unsigned short gmod_read_w16(FILE *filein)
Definition: ivcon.c:4669
face_num
int face_num
Definition: ivcon.c:158
tds_read_keyframe_objdes_section
unsigned long int tds_read_keyframe_objdes_section(FILE *filein)
Definition: ivcon.c:12145
bytes_num
int bytes_num
Definition: ivcon.c:139
object_name
char object_name[81]
Definition: ivcon.c:192
COLOR_MAX
#define COLOR_MAX
Definition: ivcon.c:125
hrc_write
int hrc_write(FILE *fileout)
Definition: ivcon.c:6081
hello
void hello(void)
Definition: ivcon.c:5108
news
void news(void)
Definition: ivcon.c:8950
main
int main(int argc, char **argv)
Definition: ivcon.c:349
tds_write_u_short_int
int tds_write_u_short_int(FILE *fileout, unsigned short int int_val)
Definition: ivcon.c:13846
data_init
void data_init(void)
Definition: ivcon.c:2106
dxf_read
int dxf_read(FILE *filein)
Definition: ivcon.c:2841
vertex_normal_set
void vertex_normal_set(void)
Definition: ivcon.c:15565
edge_null_delete
void edge_null_delete(void)
Definition: ivcon.c:3289
LINES_MAX
#define LINES_MAX
Definition: ivcon.c:130
init_program_data
void init_program_data(void)
Definition: ivcon.c:6471
face_reverse_order
void face_reverse_order(void)
Definition: ivcon.c:3769
face_material
int face_material[FACE_MAX]
Definition: ivcon.c:156
group_num
int group_num
Definition: ivcon.c:167
fileout_name
char fileout_name[1024]
Definition: ivcon.c:165
vertex_to_node_material
void vertex_to_node_material(void)
Definition: ivcon.c:15723
tds_write
int tds_write(FILE *fileout)
Definition: ivcon.c:13411
texture_name
char texture_name[TEXTURE_MAX][LINE_MAX_LEN]
Definition: ivcon.c:203
rgbcolor
float rgbcolor[3][COLOR_MAX]
Definition: ivcon.c:197
ase_read
int ase_read(FILE *filein)
Definition: ivcon.c:387
face_area_set
void face_area_set(void)
Definition: ivcon.c:3385
tds_read_view_section
unsigned long int tds_read_view_section(FILE *filein, int *views_read)
Definition: ivcon.c:13268
short_int_read
short int short_int_read(FILE *filein)
Definition: ivcon.c:10112
pov_write
int pov_write(FILE *fileout)
Definition: ivcon.c:9745
node_to_vertex_material
void node_to_vertex_material(void)
Definition: ivcon.c:9099
tds_read_vp_section
unsigned long int tds_read_vp_section(FILE *filein, int *views_read)
Definition: ivcon.c:13328
TRUE
#define TRUE
Definition: ivcon.c:37
tds_read_ambient_section
unsigned long int tds_read_ambient_section(FILE *filein)
Definition: ivcon.c:11684
cor3_range
void cor3_range(void)
Definition: ivcon.c:1932
tds_read_material_section
unsigned long int tds_read_material_section(FILE *filein)
Definition: ivcon.c:12484
tmat_init
void tmat_init(float a[4][4])
Definition: ivcon.c:14000
tds_read_matdef_section
unsigned long int tds_read_matdef_section(FILE *filein)
Definition: ivcon.c:12451
tds_read_boolean
unsigned long int tds_read_boolean(unsigned char *boolean, FILE *filein)
Definition: ivcon.c:11824
comment_num
int comment_num
Definition: ivcon.c:141
tds_read_object_section
unsigned long int tds_read_object_section(FILE *filein)
Definition: ivcon.c:12999
data_write
int data_write(void)
Definition: ivcon.c:2634
normal_temp
float normal_temp[3][ORDER_MAX *FACE_MAX]
Definition: ivcon.c:190
anim_name
char anim_name[LINE_MAX_LEN]
Definition: ivcon.c:135
data_report
void data_report(void)
Definition: ivcon.c:2596
face_order
int face_order[FACE_MAX]
Definition: ivcon.c:160
level_name
char level_name[LEVEL_MAX][LINE_MAX_LEN]
Definition: ivcon.c:172
cor3_material
int cor3_material[COR3_MAX]
Definition: ivcon.c:144
cor3_num
int cor3_num
Definition: ivcon.c:146
tds_read
int tds_read(FILE *filein)
Definition: ivcon.c:11552
color_num
int color_num
Definition: ivcon.c:140
text_num
int text_num
Definition: ivcon.c:200
gmod_read_float
float gmod_read_float(FILE *filein)
Definition: ivcon.c:4630
vertex_tex_uv
float vertex_tex_uv[2][ORDER_MAX][FACE_MAX]
Definition: ivcon.c:212
material_rgba
float material_rgba[4][MATERIAL_MAX]
Definition: ivcon.c:184
debug
int debug
Definition: ivcon.c:149
face_to_vertex_material
void face_to_vertex_material(void)
Definition: ivcon.c:4104
cor3_tex_uv
float cor3_tex_uv[3][COR3_MAX]
Definition: ivcon.c:147
txt_write
int txt_write(FILE *fileout)
Definition: ivcon.c:15092
background_rgb
float background_rgb[3]
Definition: ivcon.c:136
tds_read_obj_section
unsigned long int tds_read_obj_section(FILE *filein)
Definition: ivcon.c:12770
texture_temp
float texture_temp[2][ORDER_MAX *FACE_MAX]
Definition: ivcon.c:205
tmat_mxv
void tmat_mxv(float a[4][4], float x[4], float y[4])
Definition: ivcon.c:14242
face_null_delete
void face_null_delete(void)
Definition: ivcon.c:3624
ERROR
#define ERROR
Definition: ivcon.c:39
dup_num
int dup_num
Definition: ivcon.c:151
object_num
int object_num
Definition: ivcon.c:193
SUCCESS
#define SUCCESS
Definition: ivcon.c:46
face_normal_ave
void face_normal_ave(void)
Definition: ivcon.c:3539
byu_read
int byu_read(FILE *filein)
Definition: ivcon.c:1275
face_subset
int face_subset(void)
Definition: ivcon.c:3854
rgb_to_hue
float rgb_to_hue(float r, float g, float b)
Definition: ivcon.c:9979
ase_write
int ase_write(FILE *fileout)
Definition: ivcon.c:1085
stlb_write
int stlb_write(FILE *fileout)
Definition: ivcon.c:11409
trib_write
int trib_write(FILE *fileout)
Definition: ivcon.c:14979
vertex_material
int vertex_material[ORDER_MAX][FACE_MAX]
Definition: ivcon.c:209
face_normal
float face_normal[3][FACE_MAX]
Definition: ivcon.c:157
line_num
int line_num
Definition: ivcon.c:176
origin
float origin[3]
Definition: ivcon.c:195
float_write
int float_write(FILE *fileout, float float_val)
Definition: ivcon.c:4245
stlb_read
int stlb_read(FILE *filein)
Definition: ivcon.c:11298
vertex_to_face_material
void vertex_to_face_material(void)
Definition: ivcon.c:15687
gmod_write
int gmod_write(FILE *fileout)
Definition: ivcon.c:4730
gmod_arch_check
int gmod_arch_check(void)
Definition: ivcon.c:4275
long_int_read
long int long_int_read(FILE *filein)
Definition: ivcon.c:8868
texture_num
int texture_num
Definition: ivcon.c:204
pivot
float pivot[3]
Definition: ivcon.c:196
obj_read
int obj_read(FILE *filein)
Definition: ivcon.c:9138
data_read
int data_read(void)
Definition: ivcon.c:2289
dxf_write
int dxf_write(FILE *fileout)
Definition: ivcon.c:3068
bad_num
int bad_num
Definition: ivcon.c:137
tmat_trans
void tmat_trans(float a[4][4], float b[4][4], float x, float y, float z)
Definition: ivcon.c:14604
face_smooth
int face_smooth[FACE_MAX]
Definition: ivcon.c:161
face_tex_uv
float face_tex_uv[2][FACE_MAX]
Definition: ivcon.c:162
command_line
int command_line(char **argv)
Definition: ivcon.c:1714


ivcon
Author(s): John Burkardt
autogenerated on Wed Mar 2 2022 00:23:40