$search
00001 /* ivcon.c 24 May 2001 */ 00002 00003 /* 00004 Purpose: 00005 00006 IVCON converts various 3D graphics files. 00007 00008 Acknowledgements: 00009 00010 Coding, comments, and advice were supplied by a number of collaborators. 00011 00012 John F Flanagan made some corrections to the 3D Studio Max routines. 00013 00014 Zik Saleeba (zik@zikzak.net) enhanced the DXF routines, and added the 00015 Golgotha GMOD routines. 00016 00017 Thanks to Susan M. Fisher, University of North Carolina, 00018 Department of Computer Science, for pointing out a coding error 00019 in FACE_NULL_DELETE that was overwriting all the data! 00020 00021 Modified: 00022 00023 04 July 2000 00024 00025 Author: 00026 00027 John Burkardt 00028 */ 00029 00030 #include <ctype.h> 00031 #include <math.h> 00032 #include <stdio.h> 00033 #include <stdlib.h> 00034 #include <string.h> 00035 00036 #define FALSE 0 00037 #define TRUE 1 00038 00039 #define ERROR 1 00040 #define G1_SECTION_MODEL_QUADS 18 00041 #define G1_SECTION_MODEL_TEXTURE_NAMES 19 00042 #define G1_SECTION_MODEL_VERT_ANIMATION 20 00043 #define GMOD_MAX_SECTIONS 32 00044 #define GMOD_UNUSED_VERTEX 65535 00045 #define PI 3.141592653589793238462643 00046 #define SUCCESS 0 00047 00048 #define DEG_TO_RAD ( PI / 180.0 ) 00049 #define RAD_TO_DEG ( 180.0 / PI ) 00050 00051 /******************************************************************************/ 00052 00053 /* GLOBAL DATA */ 00054 00055 /******************************************************************************/ 00056 00057 /* 00058 BACKGROUND_RGB[3], the background color. 00059 00060 BYTE_SWAP, byte swapping option. 00061 00062 COR3[3][COR3_MAX], the coordinates of nodes. 00063 00064 COR3_MATERIAL[COR3_MAX], the index of the material of each node. 00065 00066 COR3_MAX, the maximum number of points. 00067 00068 COR3_NORMAL[3][COR3_MAX], normal vectors associated with nodes. 00069 00070 COR3_NUM, the number of points. 00071 00072 COR3_RGB[3][COR3_MAX], RGB colors associated with nodes. 00073 00074 COR3_TEX_UV[2][COR3_MAX], texture coordinates associated with nodes. 00075 00076 FACE[ORDER_MAX][FACE_MAX] contains the index of the I-th node making up face J. 00077 00078 FACE_AREA(FACE_MAX), the area of each face. 00079 00080 FACE_MATERIAL[FACE_MAX]; the material of each face. 00081 00082 FACE_MAX, the maximum number of faces. 00083 00084 FACE_NORMAL[3][FACE_MAX], the face normal vectors. 00085 00086 FACE_NUM, the number of faces. 00087 00088 FACE_ORDER[FACE_MAX], the number of vertices per face. 00089 00090 FACE_TEX_UV[2][FACE_MAX], texture coordinates associated with faces. 00091 00092 LINE_DEX[LINES_MAX], node indices, denoting polylines, each terminated by -1. 00093 00094 LINE_MATERIAL[LINES_MAX], index into RGBCOLOR for line color. 00095 00096 LINES_MAX, the maximum number of line definition items. 00097 00098 LINE_NUM, the number of line definition items. 00099 00100 LINE_PRUNE, pruning option ( 0 = no pruning, nonzero = pruning). 00101 00102 MATERIAL_MAX, the maximum number of materials. 00103 00104 MATERIAL_NUM, the number of materials. 00105 00106 ORDER_MAX, the maximum number of vertices per face. 00107 00108 TEXTURE_MAX, the maximum number of textures. 00109 00110 TEXTURE_NAME[TEXTURE_MAX][LINE_MAX_LEN], ... 00111 00112 TEXTURE_NUM, the number of textures. 00113 00114 TRANSFORM_MATRIX[4][4], the current transformation matrix. 00115 00116 VERTEX_MATERIAL[ORDER_MAX][FACE_MAX]; the material of vertices of faces. 00117 00118 VERTEX_NORMAL[3][ORDER_MAX][FACE_MAX], normals at vertices of faces. 00119 00120 VERTEX_RGB[3][ORDER_MAX][FACE_MAX], colors of vertices of faces. 00121 00122 VERTEX_TEX_UV[2][ORDER_MAX][FACE_MAX], texture coordinates of vertices of faces. 00123 */ 00124 00125 #define COLOR_MAX 1000 00126 #define COR3_MAX 200000 00127 #define FACE_MAX 200000 00128 #define LINE_MAX_LEN 256 00129 #define LEVEL_MAX 10 00130 #define LINES_MAX 100000 00131 #define MATERIAL_MAX 100 00132 #define ORDER_MAX 10 00133 #define TEXTURE_MAX 100 00134 00135 char anim_name[LINE_MAX_LEN]; 00136 float background_rgb[3]; 00137 int bad_num; 00138 int byte_swap; 00139 int bytes_num; 00140 int color_num; 00141 int comment_num; 00142 00143 float cor3[3][COR3_MAX]; 00144 int cor3_material[COR3_MAX]; 00145 float cor3_normal[3][COR3_MAX]; 00146 int cor3_num; 00147 float cor3_tex_uv[3][COR3_MAX]; 00148 00149 int debug; 00150 00151 int dup_num; 00152 00153 int face[ORDER_MAX][FACE_MAX]; 00154 float face_area[FACE_MAX]; 00155 int face_flags[FACE_MAX]; 00156 int face_material[FACE_MAX]; 00157 float face_normal[3][FACE_MAX]; 00158 int face_num; 00159 int face_object[FACE_MAX]; 00160 int face_order[FACE_MAX]; 00161 int face_smooth[FACE_MAX]; 00162 float face_tex_uv[2][FACE_MAX]; 00163 00164 char filein_name[1024]; 00165 char fileout_name[1024]; 00166 00167 int group_num; 00168 00169 int i; 00170 char input[LINE_MAX_LEN]; 00171 int k; 00172 char level_name[LEVEL_MAX][LINE_MAX_LEN]; 00173 00174 int line_dex[LINES_MAX]; 00175 int line_material[LINES_MAX]; 00176 int line_num; 00177 int line_prune; 00178 00179 int list[COR3_MAX]; 00180 00181 char material_binding[80]; 00182 char material_name[MATERIAL_MAX][LINE_MAX_LEN]; 00183 int material_num; 00184 float material_rgba[4][MATERIAL_MAX]; 00185 00186 char mat_name[81]; 00187 int max_order2; 00188 00189 char normal_binding[80]; 00190 float normal_temp[3][ORDER_MAX*FACE_MAX]; 00191 00192 char object_name[81]; 00193 int object_num; 00194 00195 float origin[3]; 00196 float pivot[3]; 00197 float rgbcolor[3][COLOR_MAX]; 00198 char temp_name[81]; 00199 00200 int text_num; 00201 00202 char texture_binding[80]; 00203 char texture_name[TEXTURE_MAX][LINE_MAX_LEN]; 00204 int texture_num; 00205 float texture_temp[2][ORDER_MAX*FACE_MAX]; 00206 00207 float transform_matrix[4][4]; 00208 00209 int vertex_material[ORDER_MAX][FACE_MAX]; 00210 float vertex_normal[3][ORDER_MAX][FACE_MAX]; 00211 float vertex_rgb[3][ORDER_MAX][FACE_MAX]; 00212 float vertex_tex_uv[2][ORDER_MAX][FACE_MAX]; 00213 00214 /******************************************************************************/ 00215 00216 /* FUNCTION PROTOTYPES */ 00217 00218 /******************************************************************************/ 00219 00220 int main ( int argc, char **argv ); 00221 int ase_read ( FILE *filein ); 00222 int ase_write ( FILE *fileout ); 00223 int byu_read ( FILE *filein ); 00224 int byu_write ( FILE *fileout ); 00225 int char_index_last ( char* string, char c ); 00226 int char_pad ( int *char_index, int *null_index, char *string, 00227 int STRING_MAX ); 00228 char char_read ( FILE *filein ); 00229 int char_write ( FILE *fileout, char c ); 00230 int command_line ( char **argv ); 00231 void cor3_normal_set ( void ); 00232 void cor3_range ( void ); 00233 void data_check ( void ); 00234 void data_init ( void ); 00235 int data_read ( void ); 00236 void data_report ( void ); 00237 int data_write ( void ); 00238 int dxf_read ( FILE *filein ); 00239 int dxf_write ( FILE *fileout ); 00240 void edge_null_delete ( void ); 00241 void face_area_set ( void ); 00242 void face_normal_ave ( void ); 00243 void face_null_delete ( void ); 00244 int face_print ( int iface ); 00245 void face_reverse_order ( void ); 00246 int face_subset ( void ); 00247 void face_to_line ( void ); 00248 void face_to_vertex_material ( void ); 00249 char *file_ext ( char *file_name ); 00250 float float_read ( FILE *filein ); 00251 float float_reverse_bytes ( float x ); 00252 int float_write ( FILE *fileout, float float_val ); 00253 int gmod_arch_check ( void ); 00254 int gmod_read ( FILE *filein ); 00255 float gmod_read_float ( FILE *filein ); 00256 unsigned short gmod_read_w16 ( FILE *filein ); 00257 unsigned long gmod_read_w32 ( FILE *filein ); 00258 int gmod_write ( FILE *fileout ); 00259 void gmod_write_float ( float Val, FILE *fileout ); 00260 void gmod_write_w16 ( unsigned short Val, FILE *fileout ); 00261 void gmod_write_w32 ( unsigned long Val, FILE *fileout ); 00262 void hello ( void ); 00263 void help ( void ); 00264 int hrc_read ( FILE *filein ); 00265 int hrc_write ( FILE *fileout ); 00266 void init_program_data ( void ); 00267 int interact ( void ); 00268 int iv_read ( FILE *filein ); 00269 int iv_write ( FILE *fileout ); 00270 int ivec_max ( int n, int *a ); 00271 int leqi ( char* string1, char* string2 ); 00272 long int long_int_read ( FILE *filein ); 00273 int long_int_write ( FILE *fileout, long int int_val ); 00274 void news ( void ); 00275 void node_to_vertex_material ( void ); 00276 int obj_read ( FILE *filein ); 00277 int obj_write ( FILE *fileout ); 00278 int pov_write ( FILE *fileout ); 00279 int rcol_find ( float a[][COR3_MAX], int m, int n, float r[] ); 00280 float rgb_to_hue ( float r, float g, float b ); 00281 short int short_int_read ( FILE *filein ); 00282 int short_int_write ( FILE *fileout, short int int_val ); 00283 int smf_read ( FILE *filein ); 00284 int smf_write ( FILE *fileout ); 00285 int stla_read ( FILE *filein ); 00286 int stla_write ( FILE *fileout ); 00287 int stlb_read ( FILE *filein ); 00288 int stlb_write ( FILE *fileout ); 00289 void tds_pre_process ( void ); 00290 int tds_read ( FILE *filein ); 00291 unsigned long int tds_read_ambient_section ( FILE *filein ); 00292 unsigned long int tds_read_background_section ( FILE *filein ); 00293 unsigned long int tds_read_boolean ( unsigned char *boolean, FILE *filein ); 00294 unsigned long int tds_read_camera_section ( FILE *filein ); 00295 unsigned long int tds_read_edit_section ( FILE *filein, int *views_read ); 00296 unsigned long int tds_read_keyframe_section ( FILE *filein, int *views_read ); 00297 unsigned long int tds_read_keyframe_objdes_section ( FILE *filein ); 00298 unsigned long int tds_read_light_section ( FILE *filein ); 00299 unsigned long int tds_read_u_long_int ( FILE *filein ); 00300 int tds_read_long_name ( FILE *filein ); 00301 unsigned long int tds_read_matdef_section ( FILE *filein ); 00302 unsigned long int tds_read_material_section ( FILE *filein ); 00303 int tds_read_name ( FILE *filein ); 00304 unsigned long int tds_read_obj_section ( FILE *filein ); 00305 unsigned long int tds_read_object_section ( FILE *filein ); 00306 unsigned long int tds_read_tex_verts_section ( FILE *filein ); 00307 unsigned long int tds_read_texmap_section ( FILE *filein ); 00308 unsigned short int tds_read_u_short_int ( FILE *filein ); 00309 unsigned long int tds_read_spot_section ( FILE *filein ); 00310 unsigned long int tds_read_unknown_section ( FILE *filein ); 00311 unsigned long int tds_read_view_section ( FILE *filein, int *views_read ); 00312 unsigned long int tds_read_vp_section ( FILE *filein, int *views_read ); 00313 int tds_write ( FILE *fileout ); 00314 int tds_write_string ( FILE *fileout, char *string ); 00315 int tds_write_u_short_int ( FILE *fileout, 00316 unsigned short int int_val ); 00317 int tec_write ( FILE *fileout ); 00318 void tmat_init ( float a[4][4] ); 00319 void tmat_mxm ( float a[4][4], float b[4][4], float c[4][4] ); 00320 void tmat_mxp ( float a[4][4], float x[4], float y[4] ); 00321 void tmat_mxp2 ( float a[4][4], float x[][3], float y[][3], int n ); 00322 void tmat_mxv ( float a[4][4], float x[4], float y[4] ); 00323 void tmat_rot_axis ( float a[4][4], float b[4][4], float angle, 00324 char axis ); 00325 void tmat_rot_vector ( float a[4][4], float b[4][4], float angle, 00326 float v1, float v2, float v3 ); 00327 void tmat_scale ( float a[4][4], float b[4][4], float sx, float sy, 00328 float sz ); 00329 void tmat_shear ( float a[4][4], float b[4][4], char *axis, 00330 float s ); 00331 void tmat_trans ( float a[4][4], float b[4][4], float x, float y, 00332 float z ); 00333 int tria_read ( FILE *filein ); 00334 int tria_write ( FILE *fileout ); 00335 int trib_read ( FILE *filein ); 00336 int trib_write ( FILE *fileout ); 00337 int txt_write ( FILE *fileout ); 00338 int ucd_write ( FILE *fileout ); 00339 void vertex_normal_set ( void ); 00340 void vertex_to_face_material ( void ); 00341 void vertex_to_node_material ( void ); 00342 int vla_read ( FILE *filein ); 00343 int vla_write ( FILE *fileout ); 00344 int wrl_write ( FILE *filout ); 00345 int xgl_write ( FILE *fileout ); 00346 00347 /******************************************************************************/ 00348 00349 int main ( int argc, char **argv ) 00350 00351 /******************************************************************************/ 00352 00353 /* 00354 Purpose: 00355 00356 MAIN is the main program for converting graphics files. 00357 00358 Modified: 00359 00360 26 May 1999 00361 00362 Author: 00363 00364 John Burkardt 00365 */ 00366 { 00367 int result; 00368 /* 00369 Initialize the program data. 00370 */ 00371 init_program_data ( ); 00372 /* 00373 If there are at least two command line arguments, call COMMAND_LINE. 00374 Otherwise call INTERACT and get information from the user. 00375 */ 00376 if ( argc >= 2 ) { 00377 result = command_line ( argv ); 00378 } 00379 else { 00380 result = interact ( ); 00381 } 00382 00383 return result; 00384 } 00385 /******************************************************************************/ 00386 00387 int ase_read ( FILE *filein ) 00388 00389 /******************************************************************************/ 00390 00391 /* 00392 Purpose: 00393 00394 ASE_READ reads an AutoCAD ASE file. 00395 00396 Modified: 00397 00398 22 May 1999 00399 00400 Author: 00401 00402 John Burkardt 00403 */ 00404 { 00405 float bval; 00406 int count; 00407 float gval; 00408 int i; 00409 int iface; 00410 int ivert; 00411 int iword; 00412 int level; 00413 char *next; 00414 int nlbrack; 00415 int nrbrack; 00416 int cor3_num_old; 00417 int face_num_old; 00418 float rval; 00419 float temp; 00420 int width; 00421 char word[LINE_MAX_LEN]; 00422 char word1[LINE_MAX_LEN]; 00423 char word2[LINE_MAX_LEN]; 00424 char wordm1[LINE_MAX_LEN]; 00425 float x; 00426 float y; 00427 float z; 00428 00429 level = 0; 00430 strcpy ( level_name[0], "Top" ); 00431 cor3_num_old = cor3_num; 00432 face_num_old = face_num; 00433 nlbrack = 0; 00434 nrbrack = 0; 00435 00436 strcpy ( word, " " ); 00437 strcpy ( wordm1, " " ); 00438 /* 00439 Read a line of text from the file. 00440 */ 00441 00442 for ( ;; ) { 00443 00444 if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) { 00445 break; 00446 } 00447 00448 text_num = text_num + 1; 00449 next = input; 00450 iword = 0; 00451 /* 00452 Read the next word from the line. 00453 */ 00454 for ( ;; ) { 00455 00456 strcpy ( wordm1, word ); 00457 strcpy ( word, " " ); 00458 00459 count = sscanf ( next, "%s%n", word, &width ); 00460 next = next + width; 00461 00462 if ( count <= 0 ) { 00463 break; 00464 } 00465 00466 iword = iword + 1; 00467 00468 if ( iword == 1 ) { 00469 strcpy ( word1, word ); 00470 } 00471 /* 00472 In case the new word is a bracket, update the bracket count. 00473 */ 00474 if ( strcmp ( word, "{" ) == 0 ) { 00475 00476 nlbrack = nlbrack + 1; 00477 level = nlbrack - nrbrack; 00478 strcpy ( level_name[level], wordm1 ); 00479 } 00480 else if ( strcmp ( word, "}" ) == 0 ) { 00481 00482 nrbrack = nrbrack + 1; 00483 00484 if ( nlbrack < nrbrack ) { 00485 00486 printf ( "\n" ); 00487 printf ( "ASE_READ - Fatal error!\n" ); 00488 printf ( " Extraneous right bracket on line %d\n", text_num ); 00489 printf ( " Currently processing field:\n" ); 00490 printf ( "%s\n", level_name[level] ); 00491 return ERROR; 00492 } 00493 00494 } 00495 /* 00496 *3DSMAX_ASCIIEXPORT 200 00497 */ 00498 if ( strcmp ( word1, "*3DSMAX_ASCIIEXPORT" ) == 0 ) { 00499 break; 00500 } 00501 /* 00502 *COMMENT 00503 */ 00504 else if ( strcmp ( word1, "*COMMENT" ) == 0 ) { 00505 break; 00506 } 00507 /* 00508 *GEOMOBJECT 00509 */ 00510 else if ( strcmp ( level_name[level], "*GEOMOBJECT" ) == 0 ) { 00511 00512 if ( strcmp ( word, "{" ) == 0 ) { 00513 continue; 00514 } 00515 else if ( strcmp ( word, "}" ) == 0 ) { 00516 level = nlbrack - nrbrack; 00517 continue; 00518 } 00519 /* 00520 Why don't you read and save this name? 00521 */ 00522 else if ( strcmp ( word, "*NODE_NAME" ) == 0 ) { 00523 break; 00524 } 00525 else if ( strcmp ( word, "*NODE_TM" ) == 0 ) { 00526 continue; 00527 } 00528 else if ( strcmp ( word, "*MESH" ) == 0 ) { 00529 continue; 00530 } 00531 else if ( strcmp ( word, "*PROP_CASTSHADOW" ) == 0 ) { 00532 break; 00533 } 00534 else if ( strcmp ( word, "*PROP_MOTIONBLUR" ) == 0 ) { 00535 break; 00536 } 00537 else if ( strcmp ( word, "*PROP_RECVSHADOW" ) == 0 ) { 00538 break; 00539 } 00540 else { 00541 bad_num = bad_num + 1; 00542 printf ( "Bad data in GEOMOBJECT, line %d\n", text_num ); 00543 break; 00544 } 00545 } 00546 /* 00547 *MESH 00548 */ 00549 else if ( strcmp ( level_name[level], "*MESH" ) == 0 ) { 00550 00551 if ( strcmp ( word, "{" ) == 0 ) { 00552 continue; 00553 } 00554 else if ( strcmp ( word, "}" ) == 0 ) { 00555 level = nlbrack - nrbrack; 00556 continue; 00557 } 00558 else if ( strcmp ( word, "*MESH_CFACELIST" ) == 0 ) { 00559 continue; 00560 } 00561 else if ( strcmp ( word, "*MESH_CVERTLIST" ) == 0 ) { 00562 continue; 00563 } 00564 else if ( strcmp ( word, "*MESH_FACE_LIST" ) == 0 ) { 00565 continue; 00566 } 00567 else if ( strcmp ( word, "*MESH_NORMALS" ) == 0 ) { 00568 continue; 00569 } 00570 else if ( strcmp ( word, "*MESH_NUMCVERTEX" ) == 0 ) { 00571 break; 00572 } 00573 else if ( strcmp ( word, "*MESH_NUMCVFACES" ) == 0 ) { 00574 break; 00575 } 00576 else if ( strcmp ( word, "*MESH_NUMFACES" ) == 0 ) { 00577 break; 00578 } 00579 else if ( strcmp ( word, "*MESH_NUMTVERTEX" ) == 0 ) { 00580 break; 00581 } 00582 else if ( strcmp ( word, "*MESH_NUMTVFACES" ) == 0 ) { 00583 break; 00584 } 00585 else if ( strcmp ( word, "*MESH_NUMVERTEX" ) == 0 ) { 00586 break; 00587 } 00588 else if ( strcmp ( word, "*MESH_TFACELIST" ) == 0 ) { 00589 continue; 00590 } 00591 else if ( strcmp ( word, "*MESH_TVERTLIST" ) == 0 ) { 00592 continue; 00593 } 00594 else if ( strcmp ( word, "*MESH_VERTEX_LIST" ) == 0 ) { 00595 continue; 00596 } 00597 else if ( strcmp ( word, "*TIMEVALUE" ) == 0 ) { 00598 break; 00599 } 00600 else { 00601 bad_num = bad_num + 1; 00602 printf ( "Bad data in MESH, line %d\n", text_num ); 00603 break; 00604 } 00605 } 00606 /* 00607 *MESH_CFACELIST 00608 */ 00609 else if ( strcmp ( level_name[level], "*MESH_CFACELIST" ) == 0 ) { 00610 00611 if ( strcmp ( word, "{" ) == 0 ) { 00612 continue; 00613 } 00614 else if ( strcmp ( word, "}" ) == 0 ) { 00615 level = nlbrack - nrbrack; 00616 continue; 00617 } 00618 else if ( strcmp ( word, "*MESH_CFACE" ) == 0 ) { 00619 break; 00620 } 00621 else { 00622 bad_num = bad_num + 1; 00623 printf ( "Bad data in MESH_CFACE, line %d\n", text_num ); 00624 break; 00625 } 00626 } 00627 /* 00628 *MESH_CVERTLIST 00629 00630 Mesh vertex indices must be incremented by COR3_NUM_OLD before being stored 00631 in the internal array. 00632 */ 00633 else if ( strcmp ( level_name[level], "*MESH_CVERTLIST" ) == 0 ) { 00634 00635 if ( strcmp ( word, "{" ) == 0 ) { 00636 continue; 00637 } 00638 else if ( strcmp ( word, "}" ) == 0 ) { 00639 level = nlbrack - nrbrack; 00640 continue; 00641 } 00642 else if ( strcmp ( word, "*MESH_VERTCOL" ) == 0 ) { 00643 00644 count = sscanf ( next, "%d%n", &i, &width ); 00645 next = next + width; 00646 00647 i = i + cor3_num_old; 00648 00649 count = sscanf ( next, "%f%n", &rval, &width ); 00650 next = next + width; 00651 00652 count = sscanf ( next, "%f%n", &gval, &width ); 00653 next = next + width; 00654 00655 count = sscanf ( next, "%f%n", &bval, &width ); 00656 next = next + width; 00657 00658 if ( material_num < MATERIAL_MAX ) { 00659 material_rgba[0][material_num] = rval; 00660 material_rgba[1][material_num] = gval; 00661 material_rgba[2][material_num] = bval; 00662 material_rgba[3][material_num] = 1.0; 00663 } 00664 00665 material_num = material_num + 1; 00666 cor3_material[i] = material_num; 00667 } 00668 else { 00669 bad_num = bad_num + 1; 00670 printf ( "\n" ); 00671 printf ( "ASE_READ - Warning!\n" ); 00672 printf ( " Bad data in MESH_CVERTLIST, line %d\n", text_num ); 00673 break; 00674 } 00675 00676 } 00677 /* 00678 *MESH_FACE_LIST 00679 This coding assumes a face is always triangular or quadrilateral. 00680 */ 00681 else if ( strcmp ( level_name[level], "*MESH_FACE_LIST" ) == 0 ) { 00682 00683 if ( strcmp ( word, "{" ) == 0 ) { 00684 continue; 00685 } 00686 else if ( strcmp ( word, "}" ) == 0 ) { 00687 level = nlbrack - nrbrack; 00688 continue; 00689 } 00690 else if ( strcmp ( word, "*MESH_FACE" ) == 0 ) { 00691 00692 if ( face_num < FACE_MAX ) { 00693 00694 face_material[face_num] = 0; 00695 face_order[face_num] = 0; 00696 00697 count = sscanf ( next, "%d%n", &i, &width ); 00698 next = next + width; 00699 00700 count = sscanf ( next, "%s%n", word2, &width ); 00701 next = next + width; 00702 count = sscanf ( next, "%s%n", word2, &width ); 00703 next = next + width; 00704 00705 count = sscanf ( next, "%d%n", &i, &width ); 00706 next = next + width; 00707 face[0][face_num] = i + cor3_num_old; 00708 face_order[face_num] = face_order[face_num] + 1; 00709 00710 count = sscanf ( next, "%s%n", word2, &width ); 00711 next = next + width; 00712 00713 count = sscanf ( next, "%d%n", &i, &width ); 00714 next = next + width; 00715 face[1][face_num] = i + cor3_num_old; 00716 face_order[face_num] = face_order[face_num] + 1; 00717 00718 count = sscanf ( next, "%s%n", word2, &width ); 00719 next = next + width; 00720 00721 count = sscanf ( next, "%d%n", &i, &width ); 00722 next = next + width; 00723 face[2][face_num] = i + cor3_num_old; 00724 face_order[face_num] = face_order[face_num] + 1; 00725 00726 count = sscanf ( next, "%s%n", word2, &width ); 00727 next = next + width; 00728 00729 if ( strcmp ( word2, "D:" ) == 0 ) { 00730 count = sscanf ( next, "%d%n", &i, &width ); 00731 next = next + width; 00732 face[3][face_num] = i + cor3_num_old; 00733 face_order[face_num] = face_order[face_num] + 1; 00734 } 00735 } 00736 00737 face_num = face_num + 1; 00738 00739 break; 00740 00741 } 00742 else { 00743 bad_num = bad_num + 1; 00744 printf ( "Bad data in MESH_FACE_LIST, line %d\n", text_num ); 00745 break; 00746 } 00747 } 00748 /* 00749 *MESH_NORMALS 00750 */ 00751 else if ( strcmp ( level_name[level], "*MESH_NORMALS" ) == 0 ) { 00752 00753 if ( strcmp ( word, "{" ) == 0 ) { 00754 continue; 00755 } 00756 else if ( strcmp ( word, "}" ) == 0 ) { 00757 level = nlbrack - nrbrack; 00758 continue; 00759 } 00760 else if ( strcmp ( word, "*MESH_FACENORMAL" ) == 0 ) { 00761 00762 count = sscanf ( next, "%d%n", &iface, &width ); 00763 next = next + width; 00764 00765 count = sscanf ( next, "%f%n", &x, &width ); 00766 next = next + width; 00767 00768 count = sscanf ( next, "%f%n", &y, &width ); 00769 next = next + width; 00770 00771 count = sscanf ( next, "%f%n", &z, &width ); 00772 next = next + width; 00773 00774 iface = iface + face_num_old; 00775 ivert = 0; 00776 00777 face_normal[0][iface] = x; 00778 face_normal[1][iface] = y; 00779 face_normal[2][iface] = z; 00780 00781 break; 00782 00783 } 00784 else if ( strcmp ( word, "*MESH_VERTEXNORMAL" ) == 0 ) { 00785 00786 count = sscanf ( next, "%d%n", &i, &width ); 00787 next = next + width; 00788 00789 count = sscanf ( next, "%f%n", &x, &width ); 00790 next = next + width; 00791 00792 count = sscanf ( next, "%f%n", &y, &width ); 00793 next = next + width; 00794 00795 count = sscanf ( next, "%f%n", &z, &width ); 00796 next = next + width; 00797 00798 vertex_normal[0][ivert][iface] = x; 00799 vertex_normal[1][ivert][iface] = y; 00800 vertex_normal[2][ivert][iface] = z; 00801 ivert = ivert + 1; 00802 00803 break; 00804 } 00805 else { 00806 bad_num = bad_num + 1; 00807 printf ( "Bad data in MESH_NORMALS, line %d\n", text_num ); 00808 break; 00809 } 00810 } 00811 /* 00812 *MESH_TFACELIST 00813 */ 00814 else if ( strcmp ( level_name[level], "*MESH_TFACELIST" ) == 0 ) { 00815 00816 if ( strcmp ( word, "{" ) == 0 ) { 00817 continue; 00818 } 00819 else if ( strcmp ( word, "}" ) == 0 ) { 00820 level = nlbrack - nrbrack; 00821 continue; 00822 } 00823 else if ( strcmp ( word1, "*MESH_TFACE" ) == 0 ) { 00824 break; 00825 } 00826 else { 00827 bad_num = bad_num + 1; 00828 printf ( "Bad data in MESH_TFACE_LIST, line %d\n", text_num ); 00829 break; 00830 } 00831 } 00832 /* 00833 *MESH_TVERTLIST 00834 */ 00835 else if ( strcmp ( level_name[level], "*MESH_TVERTLIST" ) == 0 ) { 00836 00837 if ( strcmp ( word, "{" ) == 0 ) { 00838 continue; 00839 } 00840 else if ( strcmp ( word, "}" ) == 0 ) { 00841 level = nlbrack - nrbrack; 00842 continue; 00843 } 00844 else if ( strcmp ( word1, "*MESH_TVERT" ) == 0 ) { 00845 break; 00846 } 00847 else { 00848 bad_num = bad_num + 1; 00849 printf ( "Bad data in MESH_TVERTLIST, line %d\n", text_num ); 00850 break; 00851 } 00852 } 00853 /* 00854 *MESH_VERTEX_LIST 00855 */ 00856 else if ( strcmp ( level_name[level], "*MESH_VERTEX_LIST" ) == 0 ) { 00857 00858 if ( strcmp ( word, "{" ) == 0 ) { 00859 cor3_num_old = cor3_num; 00860 continue; 00861 } 00862 else if ( strcmp ( word, "}" ) == 0 ) { 00863 level = nlbrack - nrbrack; 00864 continue; 00865 } 00866 else if ( strcmp ( word1, "*MESH_VERTEX" ) == 0 ) { 00867 00868 count = sscanf ( next, "%d%n", &i, &width ); 00869 next = next + width; 00870 00871 count = sscanf ( next, "%f%n", &x, &width ); 00872 next = next + width; 00873 00874 count = sscanf ( next, "%f%n", &y, &width ); 00875 next = next + width; 00876 00877 count = sscanf ( next, "%f%n", &z, &width ); 00878 next = next + width; 00879 00880 i = i + cor3_num_old; 00881 if ( cor3_num < i + 1 ) { 00882 cor3_num = i + 1; 00883 } 00884 00885 if ( i < COR3_MAX ) { 00886 00887 cor3[0][i] = 00888 transform_matrix[0][0] * x 00889 + transform_matrix[0][1] * y 00890 + transform_matrix[0][2] * z 00891 + transform_matrix[0][3]; 00892 00893 cor3[1][i] = 00894 transform_matrix[1][0] * x 00895 + transform_matrix[1][1] * y 00896 + transform_matrix[1][2] * z 00897 + transform_matrix[1][3]; 00898 00899 cor3[2][i] = 00900 transform_matrix[2][0] * x 00901 + transform_matrix[2][1] * y 00902 + transform_matrix[2][2] * z 00903 + transform_matrix[2][3]; 00904 } 00905 00906 break; 00907 } 00908 else { 00909 bad_num = bad_num + 1; 00910 printf ( "Bad data in MESH_VERTEX_LIST, line %d\n", text_num ); 00911 break; 00912 } 00913 } 00914 /* 00915 *NODE_TM 00916 00917 Each node should start out with a default transformation matrix. 00918 */ 00919 else if ( strcmp ( level_name[level], "*NODE_TM" ) == 0 ) { 00920 00921 if ( strcmp ( word, "{" ) == 0 ) { 00922 00923 tmat_init ( transform_matrix ); 00924 00925 continue; 00926 } 00927 else if ( strcmp ( word, "}" ) == 0 ) { 00928 level = nlbrack - nrbrack; 00929 continue; 00930 } 00931 else if ( strcmp ( word, "*INHERIT_POS" ) == 0 ) { 00932 break; 00933 } 00934 else if ( strcmp ( word, "*INHERIT_ROT" ) == 0 ) { 00935 break; 00936 } 00937 else if ( strcmp ( word, "*INHERIT_SCL" ) == 0 ) { 00938 break; 00939 } 00940 else if ( strcmp ( word, "*NODE_NAME" ) == 0 ) { 00941 break; 00942 } 00943 else if ( strcmp ( word, "*TM_POS" ) == 0 ) { 00944 break; 00945 } 00946 else if ( strcmp ( word, "*TM_ROTANGLE" ) == 0 ) { 00947 break; 00948 } 00949 else if ( strcmp ( word, "*TM_ROTAXIS" ) == 0 ) { 00950 break; 00951 } 00952 else if ( strcmp ( word, "*TM_ROW0" ) == 0 ) { 00953 00954 count = sscanf ( next, "%f%n", &temp, &width ); 00955 next = next + width; 00956 transform_matrix[0][0] = temp; 00957 00958 count = sscanf ( next, "%f%n", &temp, &width ); 00959 next = next + width; 00960 transform_matrix[1][0] = temp; 00961 00962 count = sscanf ( next, "%f%n", &temp, &width ); 00963 next = next + width; 00964 transform_matrix[2][0] = temp; 00965 00966 break; 00967 } 00968 else if ( strcmp ( word, "*TM_ROW1" ) == 0 ) { 00969 00970 count = sscanf ( next, "%f%n", &temp, &width ); 00971 next = next + width; 00972 transform_matrix[0][1] = temp; 00973 00974 count = sscanf ( next, "%f%n", &temp, &width ); 00975 next = next + width; 00976 transform_matrix[1][1] = temp; 00977 00978 count = sscanf ( next, "%f%n", &temp, &width ); 00979 next = next + width; 00980 transform_matrix[2][1] = temp; 00981 00982 break; 00983 } 00984 else if ( strcmp ( word, "*TM_ROW2" ) == 0 ) { 00985 00986 count = sscanf ( next, "%f%n", &temp, &width ); 00987 next = next + width; 00988 transform_matrix[0][2] = temp; 00989 00990 count = sscanf ( next, "%f%n", &temp, &width ); 00991 next = next + width; 00992 transform_matrix[1][2] = temp; 00993 00994 count = sscanf ( next, "%f%n", &temp, &width ); 00995 next = next + width; 00996 transform_matrix[2][2] = temp; 00997 00998 break; 00999 } 01000 else if ( strcmp ( word, "*TM_ROW3" ) == 0 ) { 01001 01002 count = sscanf ( next, "%f%n", &temp, &width ); 01003 next = next + width; 01004 transform_matrix[0][3] = temp; 01005 01006 count = sscanf ( next, "%f%n", &temp, &width ); 01007 next = next + width; 01008 transform_matrix[1][3] = temp; 01009 01010 count = sscanf ( next, "%f%n", &temp, &width ); 01011 next = next + width; 01012 transform_matrix[2][3] = temp; 01013 01014 break; 01015 } 01016 else if ( strcmp ( word, "*TM_SCALE" ) == 0 ) { 01017 break; 01018 } 01019 else if ( strcmp ( word, "*TM_SCALEAXIS" ) == 0 ) { 01020 break; 01021 } 01022 else if ( strcmp ( word, "*TM_SCALEAXISANG" ) == 0 ) { 01023 break; 01024 } 01025 else { 01026 bad_num = bad_num + 1; 01027 printf ( "Bad data in NODE_TM, line %d\n", text_num ); 01028 break; 01029 } 01030 } 01031 /* 01032 *SCENE 01033 */ 01034 else if ( strcmp ( level_name[level], "*SCENE" ) == 0 ) { 01035 01036 if ( strcmp ( word, "{" ) == 0 ) { 01037 continue; 01038 } 01039 else if ( strcmp ( word, "}" ) == 0 ) { 01040 level = nlbrack - nrbrack; 01041 continue; 01042 } 01043 else if ( strcmp ( word, "*SCENE_AMBIENT_STATIC" ) == 0 ) { 01044 break; 01045 } 01046 else if ( strcmp ( word, "*SCENE_BACKGROUND_STATIC" ) == 0 ) { 01047 break; 01048 } 01049 else if ( strcmp ( word, "*SCENE_FILENAME" ) == 0 ) { 01050 break; 01051 } 01052 else if ( strcmp ( word, "*SCENE_FIRSTFRAME" ) == 0 ) { 01053 break; 01054 } 01055 else if ( strcmp ( word, "*SCENE_FRAMESPEED" ) == 0 ) { 01056 break; 01057 } 01058 else if ( strcmp ( word, "*SCENE_LASTFRAME" ) == 0 ) { 01059 break; 01060 } 01061 else if ( strcmp ( word, "*SCENE_TICKSPERFRAME" ) == 0 ) { 01062 break; 01063 } 01064 else { 01065 bad_num = bad_num + 1; 01066 printf ( "Bad data in SCENE, line %d\n", text_num ); 01067 break; 01068 } 01069 01070 } 01071 01072 } 01073 /* 01074 End of loop reading words from the line. 01075 */ 01076 } 01077 /* 01078 End of loop reading lines from input file. 01079 */ 01080 01081 return SUCCESS; 01082 } 01083 /******************************************************************************/ 01084 01085 int ase_write ( FILE *fileout ) 01086 01087 /******************************************************************************/ 01088 01089 /* 01090 Purpose: 01091 01092 ASE_WRITE writes graphics information to an AutoCAD ASE file. 01093 01094 Modified: 01095 01096 30 September 1998 01097 01098 Author: 01099 01100 John Burkardt 01101 01102 */ 01103 { 01104 int i1; 01105 int i2; 01106 int i3; 01107 int i4; 01108 int iface; 01109 int ivert; 01110 int j; 01111 int text_num; 01112 01113 text_num = 0; 01114 /* 01115 Write the header. 01116 */ 01117 fprintf ( fileout, "*3DSMAX_ASCIIEXPORT 200\n" ); 01118 fprintf ( fileout, "*COMMENT \"%s, created by IVCON.\"\n", fileout_name ); 01119 fprintf ( fileout, "*COMMENT \"Original data in %s\"\n", filein_name ); 01120 01121 text_num = text_num + 3; 01122 /* 01123 Write the scene block. 01124 */ 01125 fprintf ( fileout, "*SCENE {\n" ); 01126 fprintf ( fileout, " *SCENE_FILENAME \"\"\n" ); 01127 fprintf ( fileout, " *SCENE_FIRSTFRAME 0\n" ); 01128 fprintf ( fileout, " *SCENE_LASTFRAME 100\n" ); 01129 fprintf ( fileout, " *SCENE_FRAMESPEED 30\n" ); 01130 fprintf ( fileout, " *SCENE_TICKSPERFRAME 160\n" ); 01131 fprintf ( fileout, " *SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000\n" ); 01132 fprintf ( fileout, " *SCENE_AMBIENT_STATIC 0.0431 0.0431 0.0431\n" ); 01133 fprintf ( fileout, "}\n" ); 01134 01135 text_num = text_num + 9; 01136 /* 01137 Begin the big geometry block. 01138 */ 01139 fprintf ( fileout, "*GEOMOBJECT {\n" ); 01140 fprintf ( fileout, " *NODE_NAME \"%s\"\n", object_name ); 01141 01142 text_num = text_num + 2; 01143 /* 01144 Sub block NODE_TM: 01145 */ 01146 fprintf ( fileout, " *NODE_TM {\n" ); 01147 fprintf ( fileout, " *NODE_NAME \"Object01\"\n" ); 01148 fprintf ( fileout, " *INHERIT_POS 0 0 0\n" ); 01149 fprintf ( fileout, " *INHERIT_ROT 0 0 0\n" ); 01150 fprintf ( fileout, " *INHERIT_SCL 0 0 0\n" ); 01151 fprintf ( fileout, " *TM_ROW0 1.0000 0.0000 0.0000\n" ); 01152 fprintf ( fileout, " *TM_ROW1 0.0000 1.0000 0.0000\n" ); 01153 fprintf ( fileout, " *TM_ROW2 0.0000 0.0000 1.0000\n" ); 01154 fprintf ( fileout, " *TM_ROW3 0.0000 0.0000 0.0000\n" ); 01155 fprintf ( fileout, " *TM_POS 0.0000 0.0000 0.0000\n" ); 01156 fprintf ( fileout, " *TM_ROTAXIS 0.0000 0.0000 0.0000\n" ); 01157 fprintf ( fileout, " *TM_ROTANGLE 0.0000\n" ); 01158 fprintf ( fileout, " *TM_SCALE 1.0000 1.0000 1.0000\n" ); 01159 fprintf ( fileout, " *TM_SCALEAXIS 0.0000 0.0000 0.0000\n" ); 01160 fprintf ( fileout, " *TM_SCALEAXISANG 0.0000\n" ); 01161 fprintf ( fileout, " }\n" ); 01162 01163 text_num = text_num + 16; 01164 /* 01165 Sub block MESH: 01166 Items 01167 */ 01168 fprintf ( fileout, " *MESH {\n" ); 01169 fprintf ( fileout, " *TIMEVALUE 0\n" ); 01170 fprintf ( fileout, " *MESH_NUMVERTEX %d\n", cor3_num ); 01171 fprintf ( fileout, " *MESH_NUMFACES %d\n", face_num ); 01172 01173 text_num = text_num + 4; 01174 /* 01175 Sub sub block MESH_VERTEX_LIST 01176 */ 01177 fprintf ( fileout, " *MESH_VERTEX_LIST {\n" ); 01178 text_num = text_num + 1; 01179 01180 for ( j = 0; j < cor3_num; j++ ) { 01181 fprintf ( fileout, " *MESH_VERTEX %d %f %f %f\n", j, cor3[0][j], 01182 cor3[1][j], cor3[2][j] ); 01183 text_num = text_num + 1; 01184 } 01185 01186 fprintf ( fileout, " }\n" ); 01187 text_num = text_num + 1; 01188 /* 01189 Sub sub block MESH_FACE_LIST 01190 Items MESH_FACE 01191 */ 01192 fprintf ( fileout, " *MESH_FACE_LIST {\n" ); 01193 text_num = text_num + 1; 01194 01195 for ( iface = 0; iface < face_num; iface++ ) { 01196 01197 i1 = face[0][iface]; 01198 i2 = face[1][iface]; 01199 i3 = face[2][iface]; 01200 01201 if ( face_order[iface] == 3 ) { 01202 fprintf ( fileout, " *MESH_FACE %d: A: %d B: %d C: %d", iface, i1, i2, i3 ); 01203 fprintf ( fileout, " AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING *MESH_MTLID 1\n" ); 01204 text_num = text_num + 1; 01205 } 01206 else if ( face_order[iface] == 4 ) { 01207 i4 = face[3][iface]; 01208 fprintf ( fileout, " *MESH_FACE %d: A: %d B: %d C: %d D: %d", iface, i1, i2, i3, i4 ); 01209 fprintf ( fileout, " AB: 1 BC: 1 CD: 1 DA: 1 *MESH_SMOOTHING *MESH_MTLID 1\n" ); 01210 text_num = text_num + 1; 01211 } 01212 } 01213 01214 fprintf ( fileout, " }\n" ); 01215 text_num = text_num + 1; 01216 /* 01217 Item MESH_NUMTVERTEX. 01218 */ 01219 fprintf ( fileout, " *MESH_NUMTVERTEX 0\n" ); 01220 text_num = text_num + 1; 01221 /* 01222 Item NUMCVERTEX. 01223 */ 01224 fprintf ( fileout, " *MESH_NUMCVERTEX 0\n" ); 01225 text_num = text_num + 1; 01226 /* 01227 Sub block MESH_NORMALS 01228 Items MESH_FACENORMAL, MESH_VERTEXNORMAL (repeated) 01229 */ 01230 fprintf ( fileout, " *MESH_NORMALS {\n" ); 01231 text_num = text_num + 1; 01232 01233 for ( iface = 0; iface < face_num; iface++ ) { 01234 01235 fprintf ( fileout, " *MESH_FACENORMAL %d %f %f %f\n", 01236 iface, face_normal[0][iface], face_normal[1][iface], face_normal[2][iface] ); 01237 text_num = text_num + 1; 01238 01239 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 01240 fprintf ( fileout, " *MESH_VERTEXNORMAL %d %f %f %f\n", 01241 face[ivert][iface], vertex_normal[0][ivert][iface], 01242 vertex_normal[1][ivert][iface], vertex_normal[2][ivert][iface] ); 01243 text_num = text_num + 1; 01244 } 01245 } 01246 01247 fprintf ( fileout, " }\n" ); 01248 text_num = text_num + 1; 01249 /* 01250 Close the MESH object. 01251 */ 01252 fprintf ( fileout, " }\n" ); 01253 /* 01254 A few closing parameters. 01255 */ 01256 fprintf ( fileout, " *PROP_MOTIONBLUR 0\n" ); 01257 fprintf ( fileout, " *PROP_CASTSHADOW 1\n" ); 01258 fprintf ( fileout, " *PROP_RECVSHADOW 1\n" ); 01259 /* 01260 Close the GEOM object. 01261 */ 01262 fprintf ( fileout, "}\n" ); 01263 01264 text_num = text_num + 5; 01265 /* 01266 Report. 01267 */ 01268 printf ( "\n" ); 01269 printf ( "ASE_WRITE - Wrote %d text lines;\n", text_num ); 01270 01271 return SUCCESS; 01272 } 01273 /**********************************************************************/ 01274 01275 int byu_read ( FILE *filein ) 01276 01277 /**********************************************************************/ 01278 01279 /* 01280 Purpose: 01281 01282 BYU_READ reads graphics data from a Movie.BYU surface geometry file. 01283 01284 Discussion: 01285 01286 A Movie.BYU surface geometry file contains 4 groups of data. 01287 01288 The first group of data is a single line, containing 4 integers, 01289 each one left justified in 8 columns. The integers are: 01290 01291 PART_NUM, VERTEX_NUM, POLY_NUM, EDGE_NUM, 01292 01293 that is, the number of parts or objects, the number of vertices or nodes, 01294 the number of polygons or faces, and the number of edges. 01295 01296 The second group of data is a single line, containing 2 integers, 01297 each one left justified in 8 columnes. The integers are: 01298 01299 POLY1, POLY2, 01300 01301 the starting and ending polygon numbers. Presumably, this means 01302 that the polygons are labeled POLY1, POLY1+1, ..., POLY2, comprising 01303 a total of POLY_NUM polygons. 01304 01305 The third group is the X, Y and Z coordinates of all the vertices. 01306 These may be written using a FORTRAN format of 6E12.5, which 01307 crams two sets of (X,Y,Z) data onto each line, with each real value 01308 written in an exponential format with 5 places after the decimal. 01309 However, it is generally possible to write the XYZ coordinate data 01310 for each vertex on a separate line. 01311 01312 The fourth group defines the polygons in terms of the vertex indices. 01313 For each polygon, the vertices that make up the polygon are listed in 01314 counterclockwise order. The last vertex listed is given with a negative 01315 sign to indicate the end of the list. All the vertices for all the 01316 polygons are listed one after the other, using a format that puts 01317 up to 10 left-justified integers on a line, with each integer occupying 01318 8 spaces. 01319 01320 This code will certainly read a BYU file created by BYU_WRITE, but 01321 it will not handle more general files. In particular, an object 01322 can have several parts, the coordinate data can be grouped so 01323 that there are 2 sets of (x,y,z) data per line, and so on. 01324 01325 Example: 01326 01327 1 8 6 24 01328 1 6 01329 0.00000E+00 0.00000E+00 0.00000E+00 01330 1.00000E+00 0.00000E+00 0.00000E+00 01331 1.00000E+00 2.00000E+00 0.00000E+00 01332 0.00000E+00 2.00000E+00 0.00000E+00 01333 0.00000E+00 0.00000E+00 1.00000E+00 01334 1.00000E+00 0.00000E+00 1.00000E+00 01335 1.00000E+00 2.00000E+00 1.00000E+00 01336 0.00000E+00 2.00000E+00 1.00000E+00 01337 4 3 2 -1 01338 5 6 7 -8 01339 1 5 8 -4 01340 4 8 7 -3 01341 3 7 6 -2 01342 2 6 5 -1 01343 01344 Modified: 01345 01346 24 May 2001 01347 01348 Author: 01349 01350 John Burkardt 01351 01352 */ 01353 { 01354 int cor3_num_new; 01355 int count; 01356 int edge_num; 01357 int face_num_new; 01358 int iface; 01359 int ival; 01360 int ivert; 01361 int j; 01362 char *next; 01363 int part_num; 01364 int poly1; 01365 int poly2; 01366 int text_num; 01367 int width; 01368 float x; 01369 float y; 01370 float z; 01371 01372 text_num = 0; 01373 01374 if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) { 01375 return ERROR; 01376 } 01377 text_num = text_num + 1; 01378 01379 sscanf ( input, "%d %d %d %d", &part_num, &cor3_num_new, &face_num_new, 01380 &edge_num ); 01381 01382 if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) { 01383 return ERROR; 01384 } 01385 text_num = text_num + 1; 01386 01387 sscanf ( input, "%d %d", &poly1, &poly2 ); 01388 01389 for ( j = cor3_num; j < cor3_num + cor3_num_new; j++ ) { 01390 01391 if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) { 01392 return ERROR; 01393 } 01394 text_num = text_num + 1; 01395 01396 sscanf ( input, "%f %f %f", &x, &y, &z ); 01397 cor3[0][j] = x; 01398 cor3[1][j] = y; 01399 cor3[2][j] = z; 01400 } 01401 01402 for ( iface = face_num; iface < face_num + face_num_new; iface++ ) { 01403 01404 if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) { 01405 return ERROR; 01406 } 01407 text_num = text_num + 1; 01408 01409 next = input; 01410 ivert = 0; 01411 01412 for (;;) { 01413 01414 count = sscanf ( next, "%d%n", &ival, &width ); 01415 next = next + width; 01416 01417 if ( count <= 0 ) { 01418 return ERROR; 01419 } 01420 01421 if ( ival > 0 ) { 01422 face[ivert][iface] = ival - 1 + cor3_num; 01423 } 01424 else { 01425 face[ivert][iface] = - ival - 1 - cor3_num; 01426 break; 01427 } 01428 01429 ivert = ivert + 1; 01430 01431 } 01432 face_order[iface] = ivert + 1; 01433 } 01434 01435 cor3_num = cor3_num + cor3_num_new; 01436 face_num = face_num + face_num_new; 01437 /* 01438 Report. 01439 */ 01440 printf ( "\n" ); 01441 printf ( "BYU_READ - Read %d text lines.\n", text_num ); 01442 01443 return SUCCESS; 01444 } 01445 /**********************************************************************/ 01446 01447 int byu_write ( FILE *fileout ) 01448 01449 /**********************************************************************/ 01450 01451 /* 01452 Purpose: 01453 01454 BYU_WRITE writes out the graphics data as a Movie.BYU surface geometry file. 01455 01456 Discussion: 01457 01458 A Movie.BYU surface geometry file contains 4 groups of data. 01459 01460 The first group of data is a single line, containing 4 integers, 01461 each one left justified in 8 columns. The integers are: 01462 01463 PART_NUM, VERTEX_NUM, POLY_NUM, EDGE_NUM, 01464 01465 that is, the number of parts or objects, the number of vertices or nodes, 01466 the number of polygons or faces, and the number of edges. 01467 01468 The second group of data is a single line, containing 2 integers, 01469 each one left justified in 8 columnes. The integers are: 01470 01471 POLY1, POLY2, 01472 01473 the starting and ending polygon numbers. Presumably, this means 01474 that the polygons are labeled POLY1, POLY1+1, ..., POLY2, comprising 01475 a total of POLY_NUM polygons. 01476 01477 The third group is the X, Y and Z coordinates of all the vertices. 01478 These may be written using a FORTRAN format of 6E12.5, which 01479 crams two sets of (X,Y,Z) data onto each line, with each real value 01480 written in an exponential format with 5 places after the decimal. 01481 However, it is generally possible to write the XYZ coordinate data 01482 for each vertex on a separate line. 01483 01484 The fourth group defines the polygons in terms of the vertex indices. 01485 For each polygon, the vertices that make up the polygon are listed in 01486 counterclockwise order. The last vertex listed is given with a negative 01487 sign to indicate the end of the list. All the vertices for all the 01488 polygons are listed one after the other, using a format that puts 01489 up to 10 left-justified integers on a line, with each integer occupying 01490 8 spaces. 01491 01492 Example: 01493 01494 1 8 6 24 01495 1 6 01496 0.00000E+00 0.00000E+00 0.00000E+00 01497 1.00000E+00 0.00000E+00 0.00000E+00 01498 1.00000E+00 2.00000E+00 0.00000E+00 01499 0.00000E+00 2.00000E+00 0.00000E+00 01500 0.00000E+00 0.00000E+00 1.00000E+00 01501 1.00000E+00 0.00000E+00 1.00000E+00 01502 1.00000E+00 2.00000E+00 1.00000E+00 01503 0.00000E+00 2.00000E+00 1.00000E+00 01504 4 3 2 -1 01505 5 6 7 -8 01506 1 5 8 -4 01507 4 8 7 -3 01508 3 7 6 -2 01509 2 6 5 -1 01510 01511 Modified: 01512 01513 24 May 2001 01514 01515 Author: 01516 01517 John Burkardt 01518 */ 01519 { 01520 int edge_num; 01521 int iface; 01522 int ivert; 01523 int j; 01524 int jp; 01525 int part_num; 01526 int text_num; 01527 01528 text_num = 0; 01529 01530 edge_num = 0; 01531 for ( iface = 0; iface < face_num; iface++ ) { 01532 edge_num = edge_num + face_order[iface]; 01533 } 01534 01535 part_num = 1; 01536 01537 fprintf ( fileout, "%d %d %d %d\n", part_num, cor3_num, face_num, edge_num ); 01538 text_num = text_num + 1; 01539 01540 fprintf ( fileout, "1 %d\n", face_num ); 01541 text_num = text_num + 1; 01542 01543 for ( j = 0; j < cor3_num; j++ ) { 01544 fprintf ( fileout, "%f %f %f\n", cor3[0][j], cor3[1][j], cor3[2][j] ); 01545 text_num = text_num + 1; 01546 } 01547 01548 for ( iface = 0; iface < face_num; iface++ ) { 01549 01550 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 01551 01552 jp = face[ivert][iface] + 1; 01553 if ( ivert == face_order[iface] - 1 ) { 01554 jp = - jp; 01555 } 01556 fprintf ( fileout, "%d ", jp ); 01557 } 01558 fprintf ( fileout, "\n" ); 01559 text_num = text_num + 1; 01560 } 01561 /* 01562 Report. 01563 */ 01564 printf ( "\n" ); 01565 printf ( "BYU_WRITE - Wrote %d text lines.\n", text_num ); 01566 01567 return SUCCESS; 01568 } 01569 /******************************************************************************/ 01570 01571 int char_index_last ( char* string, char c ) 01572 01573 /******************************************************************************/ 01574 01575 /* 01576 Purpose: 01577 01578 CHAR_INDEX_LAST reports the last occurrence of a character in a string. 01579 01580 Author: 01581 01582 John Burkardt 01583 */ 01584 { 01585 int i; 01586 int j; 01587 int nchar; 01588 01589 j = -1; 01590 01591 nchar = strlen ( string ); 01592 01593 for ( i = 0; i < nchar; i++ ) { 01594 if ( string[i] == c ) { 01595 j = i; 01596 } 01597 } 01598 01599 return j; 01600 01601 } 01602 /******************************************************************************/ 01603 01604 int char_pad ( int *char_index, int *null_index, char *string, 01605 int STRING_MAX ) 01606 01607 /******************************************************************************/ 01608 01609 /* 01610 Purpose: 01611 01612 CHAR_PAD "pads" a character in a string with a blank on either side. 01613 01614 Modified: 01615 01616 16 October 1998 01617 01618 Author: 01619 01620 John Burkardt 01621 01622 Parameters: 01623 01624 Input/output, int *CHAR_INDEX, the position of the character to be padded. 01625 On output, this is increased by 1. 01626 01627 Input/output, int *NULL_INDEX, the position of the terminating NULL in 01628 the string. On output, this is increased by 2. 01629 01630 Input/output, char STRING[STRING_MAX], the string to be manipulated. 01631 01632 Input, int STRING_MAX, the maximum number of characters that can be stored 01633 in the string. 01634 01635 Output, int CHAR_PAD, is SUCCESS if the operation worked, and ERROR otherwise. 01636 */ 01637 { 01638 int i; 01639 01640 if ( *char_index < 0 || 01641 *char_index >= *null_index || 01642 *char_index > STRING_MAX-1 ) { 01643 return ERROR; 01644 } 01645 01646 if ( (*null_index) + 2 > STRING_MAX-1 ) { 01647 return ERROR; 01648 } 01649 01650 for ( i = *null_index + 2; i > *char_index + 2; i-- ) { 01651 string[i] = string[i-2]; 01652 } 01653 string[*char_index+2] = ' '; 01654 string[*char_index+1] = string[*char_index]; 01655 string[*char_index] = ' '; 01656 01657 *char_index = *char_index + 1; 01658 *null_index = *null_index + 2; 01659 01660 return SUCCESS; 01661 } 01662 /******************************************************************************/ 01663 01664 char char_read ( FILE *filein ) 01665 01666 /******************************************************************************/ 01667 01668 /* 01669 Purpose: 01670 01671 CHAR_READ reads one character from a binary file. 01672 01673 Modified: 01674 01675 24 May 1999 01676 01677 Author: 01678 01679 John Burkardt 01680 */ 01681 { 01682 char c; 01683 01684 c = ( char ) fgetc ( filein ); 01685 01686 return c; 01687 } 01688 /******************************************************************************/ 01689 01690 int char_write ( FILE *fileout, char c ) 01691 01692 /******************************************************************************/ 01693 01694 /* 01695 Purpose: 01696 01697 CHAR_WRITE writes one character to a binary file. 01698 01699 Modified: 01700 01701 24 May 1999 01702 01703 Author: 01704 01705 John Burkardt 01706 */ 01707 { 01708 fputc ( c, fileout ); 01709 01710 return 1; 01711 } 01712 /******************************************************************************/ 01713 01714 int command_line ( char **argv ) 01715 01716 /******************************************************************************/ 01717 01718 /* 01719 01720 Purpose: 01721 01722 COMMAND_LINE carries out a command-line session of file conversion. 01723 01724 Discussion: 01725 01726 This routine is invoked when the user command is something like 01727 01728 ivcon filein_name fileout_name 01729 01730 or 01731 01732 ivcon -rn filein_name fileout_name 01733 01734 where "-rn" signals the "reverse normals" option, or 01735 01736 ivcon -rf filein_name fileout_name 01737 01738 where "-rf" signals the "reverse faces" option. 01739 01740 Modified: 01741 01742 28 June 1999 01743 01744 Author: 01745 01746 John Burkardt 01747 */ 01748 { 01749 int i; 01750 int iarg; 01751 int icor3; 01752 int ierror; 01753 int iface; 01754 int ivert; 01755 int reverse_faces; 01756 int reverse_normals; 01757 /* 01758 Initialize local data. 01759 */ 01760 iarg = 0; 01761 ierror = 0; 01762 reverse_faces = FALSE; 01763 reverse_normals = FALSE; 01764 /* 01765 Initialize the graphics data. 01766 */ 01767 data_init ( ); 01768 /* 01769 Get the -RN option, -RF option, and the input file name. 01770 */ 01771 iarg = iarg + 1; 01772 strcpy ( filein_name, argv[iarg] ); 01773 01774 if ( leqi ( filein_name, "-RN" ) == TRUE ) { 01775 reverse_normals = TRUE; 01776 printf ( "\n" ); 01777 printf ( "COMMAND_LINE: Reverse_Normals option requested.\n" ); 01778 iarg = iarg + 1; 01779 strcpy ( filein_name, argv[iarg] ); 01780 } 01781 01782 if ( leqi ( filein_name, "-RF" ) == TRUE ) { 01783 reverse_faces = TRUE; 01784 printf ( "\n" ); 01785 printf ( "COMMAND_LINE: Reverse_Faces option requested.\n" ); 01786 iarg = iarg + 1; 01787 strcpy ( filein_name, argv[iarg] ); 01788 } 01789 /* 01790 Read the input. 01791 */ 01792 ierror = data_read ( ); 01793 01794 if ( ierror == ERROR ) { 01795 printf ( "\n" ); 01796 printf ( "COMMAND_LINE - Fatal error!\n" ); 01797 printf ( " Failure while reading input data.\n" ); 01798 return ERROR; 01799 } 01800 /* 01801 Reverse the normal vectors if requested. 01802 */ 01803 if ( reverse_normals == TRUE ) { 01804 01805 for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { 01806 for ( i = 0; i < 3; i++ ) { 01807 cor3_normal[i][icor3] = - cor3_normal[i][icor3]; 01808 } 01809 } 01810 01811 for ( iface = 0; iface < face_num; iface++ ) { 01812 for ( i = 0; i < 3; i++ ) { 01813 face_normal[i][iface] = - face_normal[i][iface]; 01814 } 01815 } 01816 01817 for ( iface = 0; iface < face_num; iface++ ) { 01818 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 01819 for ( i = 0; i < 3; i++ ) { 01820 vertex_normal[i][ivert][iface] = 01821 - vertex_normal[i][ivert][iface]; 01822 } 01823 } 01824 } 01825 printf ( "\n" ); 01826 printf ( "COMMAND_LINE - Note:\n" ); 01827 printf ( " Reversed node, face, and vertex normals.\n" ); 01828 } 01829 /* 01830 Reverse the faces if requested. 01831 */ 01832 if ( reverse_faces == TRUE ) { 01833 01834 face_reverse_order ( ); 01835 01836 printf ( "\n" ); 01837 printf ( "COMMAND_LINE - Note:\n" ); 01838 printf ( " Reversed the face definitions.\n" ); 01839 } 01840 /* 01841 Write the output file. 01842 */ 01843 iarg = iarg + 1; 01844 strcpy ( fileout_name, argv[iarg] ); 01845 01846 ierror = data_write ( ); 01847 01848 if ( ierror == ERROR ) { 01849 printf ( "\n" ); 01850 printf ( "COMMAND_LINE - Fatal error!\n" ); 01851 printf ( " Failure while writing output data.\n" ); 01852 return ERROR; 01853 } 01854 return SUCCESS; 01855 } 01856 /******************************************************************************/ 01857 01858 void cor3_normal_set ( void ) 01859 01860 /******************************************************************************/ 01861 01862 /* 01863 Purpose: 01864 01865 COR3_NORMAL_SET computes node normal vectors. 01866 01867 Modified: 01868 01869 18 November 1998 01870 01871 Author: 01872 01873 John Burkardt 01874 */ 01875 { 01876 int icor3; 01877 int iface; 01878 int ivert; 01879 int j; 01880 float norm; 01881 float temp; 01882 01883 for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { 01884 for ( j = 0; j < 3; j++ ) { 01885 cor3_normal[j][icor3] = 0.0; 01886 } 01887 } 01888 /* 01889 Add up the normals at all the faces to which the node belongs. 01890 */ 01891 for ( iface = 0; iface < face_num; iface++ ) { 01892 01893 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 01894 01895 icor3 = face[ivert][iface]; 01896 01897 for ( j = 0; j < 3; j++ ) { 01898 cor3_normal[j][icor3] = cor3_normal[j][icor3] 01899 + vertex_normal[j][ivert][iface]; 01900 } 01901 } 01902 } 01903 /* 01904 Renormalize. 01905 */ 01906 for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { 01907 01908 norm = 0.0; 01909 for ( j = 0; j < 3; j++ ) { 01910 temp = cor3_normal[j][icor3]; 01911 norm = norm + temp * temp; 01912 } 01913 01914 if ( norm == 0.0 ) { 01915 norm = 3.0; 01916 for ( j = 0; j < 3; j++ ) { 01917 cor3_normal[j][icor3] = 1.0; 01918 } 01919 } 01920 01921 norm = ( float ) sqrt ( norm ); 01922 01923 for ( j = 0; j < 3; j++ ) { 01924 cor3_normal[j][icor3] = cor3_normal[j][icor3] / norm; 01925 } 01926 } 01927 01928 return; 01929 } 01930 /******************************************************************************/ 01931 01932 void cor3_range ( void ) 01933 01934 /******************************************************************************/ 01935 01936 /* 01937 Purpose: 01938 01939 COR3_RANGE computes the coordinate minima and maxima. 01940 01941 Modified: 01942 01943 31 August 1998 01944 01945 Author: 01946 01947 John Burkardt 01948 */ 01949 { 01950 int i; 01951 float xave; 01952 float xmax; 01953 float xmin; 01954 float yave; 01955 float ymax; 01956 float ymin; 01957 float zave; 01958 float zmax; 01959 float zmin; 01960 01961 xave = cor3[0][0]; 01962 xmax = cor3[0][0]; 01963 xmin = cor3[0][0]; 01964 01965 yave = cor3[1][0]; 01966 ymax = cor3[1][0]; 01967 ymin = cor3[1][0]; 01968 01969 zave = cor3[2][0]; 01970 zmax = cor3[2][0]; 01971 zmin = cor3[2][0]; 01972 01973 for ( i = 1; i < cor3_num; i++ ) { 01974 01975 xave = xave + cor3[0][i]; 01976 if ( cor3[0][i] < xmin ) { 01977 xmin = cor3[0][i]; 01978 } 01979 if ( cor3[0][i] > xmax ) { 01980 xmax = cor3[0][i]; 01981 } 01982 01983 yave = yave + cor3[1][i]; 01984 if ( cor3[1][i] < ymin ) { 01985 ymin = cor3[1][i]; 01986 } 01987 if ( cor3[1][i] > ymax ) { 01988 ymax = cor3[1][i]; 01989 } 01990 01991 zave = zave + cor3[2][i]; 01992 if ( cor3[2][i] < zmin ) { 01993 zmin = cor3[2][i]; 01994 } 01995 if ( cor3[2][i] > zmax ) { 01996 zmax = cor3[2][i]; 01997 } 01998 } 01999 02000 xave = xave / cor3_num; 02001 yave = yave / cor3_num; 02002 zave = zave / cor3_num; 02003 02004 printf ( "\n" ); 02005 printf ( "COR3_RANGE - Data range:\n" ); 02006 printf ( "\n" ); 02007 printf ( " Minimum Average Maximum Range\n" ); 02008 printf ( "\n" ); 02009 printf ( "X %f %f %f %f\n", xmin, xave, xmax, xmax-xmin ); 02010 printf ( "Y %f %f %f %f\n", ymin, yave, ymax, ymax-ymin ); 02011 printf ( "Z %f %f %f %f\n", zmin, zave, zmax, zmax-zmin ); 02012 02013 } 02014 /******************************************************************************/ 02015 02016 void data_check ( void ) 02017 02018 /******************************************************************************/ 02019 02020 /* 02021 Purpose: 02022 02023 DATA_CHECK checks the input data. 02024 02025 Modified: 02026 02027 18 May 1999 02028 02029 Author: 02030 02031 John Burkardt 02032 */ 02033 { 02034 int iface; 02035 int nfix; 02036 02037 if ( color_num > COLOR_MAX ) { 02038 printf ( "\n" ); 02039 printf ( "DATA_CHECK - Warning!\n" ); 02040 printf ( " The input data requires %d colors.\n", color_num ); 02041 printf ( " There was only room for %d\n", COLOR_MAX ); 02042 color_num = COLOR_MAX; 02043 } 02044 02045 if ( cor3_num > COR3_MAX ) { 02046 printf ( "\n" ); 02047 printf ( "DATA_CHECK - Warning!\n" ); 02048 printf ( " The input data requires %d points.\n", cor3_num ); 02049 printf ( " There was only room for %d\n", COR3_MAX ); 02050 cor3_num = COR3_MAX; 02051 } 02052 02053 if ( face_num > FACE_MAX ) { 02054 printf ( "\n" ); 02055 printf ( "DATA_CHECK - Warning!\n" ); 02056 printf ( " The input data requires %d faces.\n", face_num ); 02057 printf ( " There was only room for %d\n", FACE_MAX ); 02058 face_num = FACE_MAX; 02059 } 02060 02061 if ( line_num > LINES_MAX ) { 02062 printf ( "\n" ); 02063 printf ( "DATA_CHECK - Warning!\n" ); 02064 printf ( " The input data requires %d line items.\n", line_num ); 02065 printf ( " There was only room for %d.\n", LINES_MAX ); 02066 line_num = LINES_MAX; 02067 } 02068 02069 nfix = 0; 02070 02071 for ( iface = 0; iface < face_num; iface++ ) { 02072 02073 if ( face_order[iface] > ORDER_MAX ) { 02074 face_order[iface] = ORDER_MAX; 02075 nfix = nfix + 1; 02076 } 02077 02078 } 02079 02080 if ( nfix > 0 ) { 02081 printf ( "\n" ); 02082 printf ( "DATA_CHECK - Warning!\n" ); 02083 printf ( " Corrected %d faces using more than %d vertices per face.\n", 02084 nfix, ORDER_MAX ); 02085 } 02086 02087 for ( i = 0; i < material_num; i++ ) { 02088 if ( strcmp ( material_name[i], "" ) == 0 ) { 02089 strcpy ( material_name[i], "Material_0000" ); 02090 } 02091 } 02092 02093 for ( i = 0; i < texture_num; i++ ) { 02094 if ( strcmp ( texture_name[i], "" ) == 0 ) { 02095 strcpy ( texture_name[i], "Texture_0000" ); 02096 } 02097 } 02098 02099 printf ( "\n" ); 02100 printf ( "DATA_CHECK - Data checked.\n" ); 02101 02102 return; 02103 } 02104 /******************************************************************************/ 02105 02106 void data_init ( void ) 02107 02108 /******************************************************************************/ 02109 02110 /* 02111 Purpose: 02112 02113 DATA_INIT initializes the internal graphics data. 02114 02115 Modified: 02116 02117 04 July 2000 02118 02119 Author: 02120 02121 John Burkardt 02122 */ 02123 { 02124 int i; 02125 int iface; 02126 int ivert; 02127 int j; 02128 int k; 02129 02130 strcpy( anim_name, "" ); 02131 02132 for ( i = 0; i < 3; i++ ) { 02133 background_rgb[i] = 0.0; 02134 } 02135 02136 for ( i = 0; i < 3; i++ ) { 02137 for ( j = 0; j < COR3_MAX; j++ ) { 02138 cor3[i][j] = 0.0; 02139 } 02140 } 02141 02142 for ( i = 0; i < COR3_MAX; i++ ) { 02143 cor3_material[i] = 0; 02144 } 02145 02146 for ( i = 0; i < 3; i++ ) { 02147 for ( j = 0; j < COR3_MAX; j++ ) { 02148 cor3_normal[i][j] = 0.0; 02149 } 02150 } 02151 02152 for ( j = 0; j < COR3_MAX; j++ ) { 02153 cor3_tex_uv[0][j] = 0.0; 02154 cor3_tex_uv[1][j] = 0.0; 02155 } 02156 02157 for ( iface = 0; iface < FACE_MAX; iface++ ) { 02158 for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) { 02159 face[ivert][iface] = 0; 02160 } 02161 } 02162 02163 for ( iface = 0; iface < FACE_MAX; iface++ ) { 02164 face_flags[iface] = 6; 02165 } 02166 02167 for ( iface = 0; iface < FACE_MAX; iface++ ) { 02168 face_material[iface] = 0; 02169 } 02170 02171 for ( iface = 0; iface < FACE_MAX; iface++ ) { 02172 for ( i = 0; i < 3; i++ ) { 02173 face_normal[i][iface] = 0; 02174 } 02175 } 02176 02177 for ( iface = 0; iface < FACE_MAX; iface++ ) { 02178 face_object[iface] = -1; 02179 } 02180 02181 for ( iface = 0; iface < FACE_MAX; iface++ ) { 02182 face_order[iface] = 0; 02183 } 02184 02185 for ( iface = 0; iface < FACE_MAX; iface++ ) { 02186 face_smooth[iface] = 1; 02187 } 02188 02189 for ( i = 0; i < LINES_MAX; i++ ) { 02190 line_dex[i] = -1; 02191 } 02192 02193 for ( i = 0; i < LINES_MAX; i++ ) { 02194 line_material[i] = 0; 02195 } 02196 02197 strcpy ( material_binding, "DEFAULT" ); 02198 02199 for ( j = 0; j < MATERIAL_MAX; j++ ) { 02200 strcpy ( material_name[j], "Material_0000" ); 02201 } 02202 02203 for ( i = 0; i < 4; i++ ) { 02204 for ( j = 0; j < MATERIAL_MAX; j++ ) { 02205 material_rgba[i][j] = 0.0; 02206 } 02207 } 02208 02209 strcpy ( normal_binding, "DEFAULT" ); 02210 02211 for ( j = 0; j < ORDER_MAX*FACE_MAX; j++ ) { 02212 for ( i = 0; i < 3; i++ ) { 02213 normal_temp[i][j] = 0; 02214 } 02215 } 02216 02217 color_num = 0; 02218 cor3_num = 0; 02219 face_num = 0; 02220 group_num = 0; 02221 line_num = 0; 02222 material_num = 0; 02223 object_num = 0; 02224 texture_num = 0; 02225 02226 strcpy ( object_name, "IVCON" ); 02227 02228 for ( i = 0; i < 3; i++ ) { 02229 origin[i] = 0.0; 02230 } 02231 02232 for ( i = 0; i < 3; i++ ) { 02233 pivot[i] = 0.0; 02234 } 02235 02236 for ( j = 0; j < COLOR_MAX; j++ ) { 02237 rgbcolor[0][j] = 0.299; 02238 rgbcolor[1][j] = 0.587; 02239 rgbcolor[2][j] = 0.114; 02240 } 02241 02242 strcpy ( texture_binding, "DEFAULT" ); 02243 02244 for ( j = 0; j < TEXTURE_MAX; j++ ) { 02245 strcpy ( texture_name[j], "Texture_0000" ); 02246 } 02247 02248 tmat_init ( transform_matrix ); 02249 02250 for ( iface = 0; iface < FACE_MAX; iface++ ) { 02251 for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) { 02252 vertex_material[ivert][iface] = 0; 02253 } 02254 } 02255 02256 for ( iface = 0; iface < FACE_MAX; iface++ ) { 02257 for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) { 02258 for ( i = 0; i < 3; i++ ) { 02259 vertex_normal[i][ivert][iface] = 0.0; 02260 } 02261 } 02262 } 02263 02264 for ( j = 0; j < 3; j++ ) { 02265 for ( k = 0; k < FACE_MAX; k++ ) { 02266 vertex_rgb[0][j][k] = 0.299; 02267 vertex_rgb[1][j][k] = 0.587; 02268 vertex_rgb[2][j][k] = 0.114; 02269 } 02270 } 02271 02272 for ( iface = 0; iface < FACE_MAX; iface++ ) { 02273 for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) { 02274 for ( i = 0; i < 2; i++ ) { 02275 vertex_tex_uv[i][ivert][iface] = 0.0; 02276 } 02277 } 02278 } 02279 02280 if ( debug ) { 02281 printf ( "\n" ); 02282 printf ( "DATA_INIT: Graphics data initialized.\n" ); 02283 } 02284 02285 return; 02286 } 02287 /******************************************************************************/ 02288 02289 int data_read ( void ) 02290 02291 /******************************************************************************/ 02292 02293 /* 02294 Purpose: 02295 02296 DATA_READ reads a file into internal graphics data. 02297 02298 Modified: 02299 02300 26 September 1999 02301 02302 Author: 02303 02304 John Burkardt 02305 */ 02306 { 02307 FILE *filein; 02308 char *filein_type; 02309 int icor3; 02310 int ierror; 02311 int iface; 02312 int iline; 02313 int ivert; 02314 int ntemp; 02315 /* 02316 Retrieve the input file type. 02317 */ 02318 filein_type = file_ext ( filein_name ); 02319 02320 if ( filein_type == NULL ) { 02321 printf ( "\n" ); 02322 printf ( "DATA_READ - Fatal error!\n" ); 02323 printf ( " Could not determine the type of '%s'.\n", filein_name ); 02324 return ERROR; 02325 } 02326 else if ( debug ) { 02327 printf ( "\n" ); 02328 printf ( "DATA_READ: Input file has type %s.\n", filein_type ); 02329 } 02330 /* 02331 Initialize some data. 02332 */ 02333 max_order2 = 0; 02334 bad_num = 0; 02335 bytes_num = 0; 02336 comment_num = 0; 02337 dup_num = 0; 02338 text_num = 0; 02339 /* 02340 Open the file. 02341 */ 02342 if ( leqi ( filein_type, "3DS" ) == TRUE || 02343 leqi ( filein_type, "STLB" ) == TRUE || 02344 leqi ( filein_type, "TRIB" ) == TRUE ) { 02345 filein = fopen ( filein_name, "rb" ); 02346 } 02347 else { 02348 filein = fopen ( filein_name, "r" ); 02349 } 02350 02351 if ( filein == NULL ) { 02352 printf ( "\n" ); 02353 printf ( "DATA_READ - Fatal error!\n" ); 02354 printf ( " Could not open the input file '%s'!\n", filein_name ); 02355 return ERROR; 02356 } 02357 /* 02358 Read the information in the file. 02359 */ 02360 if ( leqi ( filein_type, "3DS" ) == TRUE ) { 02361 02362 ierror = tds_read ( filein ); 02363 /* 02364 Cleanup: distribute the node textures to the vertices. 02365 */ 02366 if ( ierror == SUCCESS ) { 02367 02368 for ( iface = 0; iface < face_num; iface++ ) { 02369 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 02370 icor3 = face[ivert][iface]; 02371 vertex_tex_uv[0][ivert][iface] = cor3_tex_uv[0][icor3]; 02372 vertex_tex_uv[1][ivert][iface] = cor3_tex_uv[1][icor3]; 02373 } 02374 } 02375 02376 } 02377 02378 } 02379 else if ( leqi ( filein_type, "ASE" ) == TRUE ) { 02380 02381 ierror = ase_read ( filein ); 02382 02383 if ( ierror == SUCCESS ) { 02384 02385 node_to_vertex_material ( ); 02386 02387 vertex_to_face_material ( ); 02388 02389 } 02390 02391 } 02392 else if ( leqi ( filein_type, "BYU" ) == TRUE ) { 02393 02394 ierror = byu_read ( filein ); 02395 02396 } 02397 else if ( leqi ( filein_type, "DXF" ) == TRUE ) { 02398 02399 ierror = dxf_read ( filein ); 02400 02401 } 02402 else if ( leqi ( filein_type, "GMOD" ) == TRUE ) { 02403 02404 ierror = gmod_read ( filein ); 02405 02406 } 02407 else if ( leqi ( filein_type, "HRC" ) == TRUE ) { 02408 02409 ierror = hrc_read ( filein ); 02410 02411 } 02412 else if ( leqi ( filein_type, "IV" ) == TRUE ) { 02413 02414 ierror = iv_read ( filein ); 02415 02416 } 02417 else if ( leqi ( filein_type, "OBJ" ) == TRUE ) { 02418 02419 ierror = obj_read ( filein ); 02420 02421 } 02422 else if ( leqi ( filein_type, "SMF" ) == TRUE ) { 02423 02424 ierror = smf_read ( filein ); 02425 02426 } 02427 else if ( 02428 leqi ( filein_type, "STL" ) == TRUE || 02429 leqi ( filein_type, "STLA") == TRUE ) { 02430 02431 ierror = stla_read ( filein ); 02432 02433 if( ierror ) { 02434 // might be binary 02435 fclose(filein); 02436 filein = fopen ( filein_name, "rb" ); 02437 ierror = stlb_read ( filein ); 02438 } 02439 } 02440 else if ( leqi ( filein_type, "STLB") == TRUE ) { 02441 02442 ierror = stlb_read ( filein ); 02443 02444 } 02445 else if ( 02446 leqi ( filein_type, "TRI" ) == TRUE || 02447 leqi ( filein_type, "TRIA") == TRUE ) { 02448 02449 ierror = tria_read ( filein ); 02450 02451 } 02452 else if ( leqi ( filein_type, "TRIB") == TRUE ) { 02453 02454 ierror = trib_read ( filein ); 02455 02456 } 02457 else if ( leqi ( filein_type, "VLA" ) == TRUE ) { 02458 02459 ierror = vla_read ( filein ); 02460 02461 } 02462 else { 02463 printf ( "\n" ); 02464 printf ( "DATA_READ - Fatal error!\n" ); 02465 printf ( " Unacceptable input file type.\n" ); 02466 return ERROR; 02467 } 02468 02469 fclose ( filein ); 02470 02471 if ( debug ) { 02472 printf ( "DATA_READ: Finished reading the data file.\n" ); 02473 } 02474 /* 02475 Catch errors reported by the various reading routines. 02476 */ 02477 if ( ierror == ERROR ) { 02478 return ierror; 02479 } 02480 /* 02481 Restore the transformation matrix. 02482 */ 02483 tmat_init ( transform_matrix ); 02484 /* 02485 Report on what we read. 02486 */ 02487 if ( face_num < FACE_MAX ) { 02488 ntemp = face_num; 02489 } 02490 else { 02491 ntemp = FACE_MAX; 02492 } 02493 02494 max_order2 = ivec_max ( ntemp, face_order ); 02495 02496 data_report ( ); 02497 /* 02498 Warn about any errors that occurred during reading. 02499 */ 02500 if ( ierror == ERROR ) { 02501 printf ( "\n" ); 02502 printf ( "DATA_READ - Fatal error!\n" ); 02503 printf ( " An error occurred while reading the input file.\n" ); 02504 return ERROR; 02505 } 02506 /* 02507 Check the data. 02508 You MUST wait until after this check before doing other computations, 02509 since COR3_NUM and other variables could be much larger than the legal 02510 maximums, until corrected by DATA_CHECK. 02511 */ 02512 data_check ( ); 02513 /* 02514 MATERIALS FIXUPS: 02515 02516 If there are no materials at all, define one. 02517 */ 02518 if ( material_num < 1 ) { 02519 material_num = 1; 02520 strcpy ( material_name[0], "Material_0000" ); 02521 material_rgba[0][0] = 0.7; 02522 material_rgba[1][0] = 0.7; 02523 material_rgba[2][0] = 0.7; 02524 material_rgba[3][0] = 1.0; 02525 } 02526 /* 02527 If a node has not been assigned a material, set it to material 0. 02528 */ 02529 for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { 02530 if ( cor3_material[icor3] < 0 || cor3_material[icor3] > material_num - 1 ) { 02531 cor3_material[icor3] = 0; 02532 } 02533 } 02534 /* 02535 If a vertex has not been assigned a material, set it to material 0. 02536 */ 02537 for ( iface = 0; iface < face_num; iface++ ) { 02538 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 02539 if ( vertex_material[ivert][iface] < 0 || vertex_material[ivert][iface] > material_num - 1 ) { 02540 vertex_material[ivert][iface] = 0; 02541 } 02542 } 02543 } 02544 /* 02545 If a face has not been assigned a material, set it to material 0. 02546 */ 02547 for ( iface = 0; iface < face_num; iface++ ) { 02548 if ( face_material[iface] < 0 || face_material[iface] > material_num - 1 ) { 02549 face_material[iface] = 0; 02550 } 02551 } 02552 /* 02553 If a line item has not been assigned a material, set it to material 0. 02554 */ 02555 for ( iline = 0; iline < line_num; iline++ ) { 02556 if ( line_dex[iline] == -1 ) { 02557 line_material[iline] = -1; 02558 } 02559 else if ( line_material[iline] < 0 || line_material[iline] > material_num - 1 ) { 02560 line_material[iline] = 0; 02561 } 02562 } 02563 /* 02564 Delete edges of zero length. 02565 */ 02566 edge_null_delete ( ); 02567 /* 02568 Compute the area of each face. 02569 */ 02570 face_area_set ( ); 02571 /* 02572 Delete faces with zero area. 02573 */ 02574 face_null_delete ( ); 02575 /* 02576 Recompute zero face-vertex normals from vertex positions. 02577 */ 02578 vertex_normal_set ( ); 02579 /* 02580 Compute the node normals from the vertex normals. 02581 */ 02582 cor3_normal_set ( ); 02583 /* 02584 Recompute zero face normals by averaging face-vertex normals. 02585 */ 02586 face_normal_ave ( ); 02587 /* 02588 Report on the nodal coordinate range. 02589 */ 02590 cor3_range ( ); 02591 02592 return SUCCESS; 02593 } 02594 /**********************************************************************/ 02595 02596 void data_report ( void ) 02597 02598 /**********************************************************************/ 02599 02600 /* 02601 Purpose: 02602 02603 DATA_REPORT gives a summary of the contents of the data file. 02604 02605 Modified: 02606 02607 24 May 1999 02608 02609 Author: 02610 02611 John Burkardt 02612 */ 02613 { 02614 printf ( "\n" ); 02615 printf ( "DATA_REPORT - The input file contains:\n" ); 02616 printf ( "\n" ); 02617 printf ( " Bad data items %d\n", bad_num ); 02618 printf ( " Text lines %d\n", text_num ); 02619 printf ( " Text bytes (binary data) %d\n", bytes_num ); 02620 printf ( " Colors %d\n", color_num ); 02621 printf ( " Comments %d\n", comment_num ); 02622 printf ( " Duplicate points %d\n", dup_num ); 02623 printf ( " Faces %d\n", face_num ); 02624 printf ( " Groups %d\n", group_num ); 02625 printf ( " Vertices per face, maximum %d\n", max_order2 ); 02626 printf ( " Line items %d\n", line_num ); 02627 printf ( " Points %d\n", cor3_num ); 02628 printf ( " Objects %d\n", object_num ); 02629 02630 return; 02631 } 02632 /******************************************************************************/ 02633 02634 int data_write ( void ) 02635 02636 /******************************************************************************/ 02637 02638 /* 02639 Purpose: 02640 02641 DATA_WRITE writes the internal graphics data to a file. 02642 02643 Modified: 02644 02645 22 May 1999 02646 02647 Author: 02648 02649 John Burkardt 02650 */ 02651 { 02652 FILE *fileout; 02653 char *fileout_type; 02654 int line_num_save; 02655 int result; 02656 02657 result = SUCCESS; 02658 /* 02659 Retrieve the output file type. 02660 */ 02661 fileout_type = file_ext ( fileout_name ); 02662 02663 if ( fileout_type == NULL ) { 02664 printf ( "\n" ); 02665 printf ( "DATA_WRITE - Fatal error!\n" ); 02666 printf ( " Could not determine the output file type.\n" ); 02667 return ERROR; 02668 } 02669 /* 02670 Open the output file. 02671 */ 02672 if ( leqi ( fileout_type, "3DS" ) == TRUE || 02673 leqi ( fileout_type, "STLB" ) == TRUE || 02674 leqi ( fileout_type, "TRIB" ) ) { 02675 fileout = fopen ( fileout_name, "wb" ); 02676 } 02677 else { 02678 fileout = fopen ( fileout_name, "w" ); 02679 } 02680 02681 if ( fileout == NULL ) { 02682 printf ( "\n" ); 02683 printf ( "DATA_WRITE - Fatal error!\n" ); 02684 printf ( " Could not open the output file!\n" ); 02685 return ERROR; 02686 } 02687 /* 02688 Write the output file. 02689 */ 02690 if ( leqi ( fileout_type, "3DS" ) == TRUE ) { 02691 02692 tds_pre_process(); 02693 result = tds_write ( fileout ); 02694 02695 } 02696 else if ( leqi ( fileout_type, "ASE" ) == TRUE ) { 02697 02698 result = ase_write ( fileout ); 02699 02700 } 02701 else if ( leqi ( fileout_type, "BYU" ) == TRUE ) { 02702 02703 result = byu_write ( fileout ); 02704 02705 } 02706 else if ( leqi ( fileout_type, "DXF" ) == TRUE ) { 02707 02708 result = dxf_write ( fileout ); 02709 02710 } 02711 else if ( leqi ( fileout_type, "GMOD" ) == TRUE ) { 02712 02713 result = gmod_write ( fileout ); 02714 02715 } 02716 else if ( leqi ( fileout_type, "HRC" ) == TRUE ) { 02717 02718 result = hrc_write ( fileout ); 02719 02720 } 02721 else if ( leqi ( fileout_type, "IV" ) == TRUE ) { 02722 02723 result = iv_write ( fileout ); 02724 02725 } 02726 else if ( leqi ( fileout_type, "OBJ" ) == TRUE ) { 02727 02728 result = obj_write ( fileout ); 02729 02730 } 02731 else if ( leqi ( fileout_type, "POV" ) == TRUE ) { 02732 02733 result = pov_write ( fileout ); 02734 02735 } 02736 else if ( leqi ( fileout_type, "SMF" ) == TRUE ) { 02737 02738 result = smf_write ( fileout ); 02739 02740 } 02741 else if ( 02742 leqi ( fileout_type, "STL" ) == TRUE || 02743 leqi ( fileout_type, "STLA" ) == TRUE ) { 02744 02745 result = stla_write ( fileout ); 02746 02747 } 02748 else if ( leqi ( fileout_type, "STLB" ) == TRUE ) { 02749 02750 result = stlb_write ( fileout ); 02751 02752 } 02753 else if ( leqi ( fileout_type, "TEC" ) == TRUE ) { 02754 02755 result = tec_write ( fileout ); 02756 02757 } 02758 else if ( 02759 leqi ( fileout_type, "TRI" ) == TRUE || 02760 leqi ( fileout_type, "TRIA" ) == TRUE ) { 02761 02762 result = tria_write ( fileout ); 02763 02764 } 02765 else if ( leqi ( fileout_type, "TRIB" ) == TRUE ) { 02766 02767 result = trib_write ( fileout ); 02768 02769 } 02770 else if ( leqi ( fileout_type, "TXT" ) == TRUE ) { 02771 02772 result = txt_write ( fileout ); 02773 02774 } 02775 else if ( leqi ( fileout_type, "UCD" ) == TRUE ) { 02776 02777 result = ucd_write ( fileout ); 02778 02779 } 02780 else if ( leqi ( fileout_type, "VLA" ) == TRUE ) { 02781 02782 line_num_save = line_num; 02783 02784 if ( face_num > 0 ) { 02785 02786 printf ( "\n" ); 02787 printf ( "DATA_WRITE - Note:\n" ); 02788 printf ( " Face information will temporarily be converted to\n" ); 02789 printf ( " line information for output to a VLA file.\n" ); 02790 02791 face_to_line ( ); 02792 02793 if ( line_num > LINES_MAX ) { 02794 printf ( "\n" ); 02795 printf ( "DATA_WRITE - Warning:\n" ); 02796 printf ( " Some face information was lost.\n" ); 02797 printf ( " The maximum number of lines is %d.\n", LINES_MAX ); 02798 printf ( " The number of lines needed is %d.\n", line_num ); 02799 line_num = LINES_MAX; 02800 } 02801 02802 } 02803 02804 result = vla_write ( fileout ); 02805 02806 line_num = line_num_save; 02807 02808 } 02809 else if ( leqi ( fileout_type, "WRL" ) == TRUE ) { 02810 02811 result = wrl_write ( fileout ); 02812 02813 } 02814 else if ( leqi ( fileout_type, "XGL" ) == TRUE ) { 02815 02816 result = xgl_write ( fileout ); 02817 02818 } 02819 else { 02820 02821 result = ERROR; 02822 printf ( "\n" ); 02823 printf ( "DATA_WRITE - Fatal error!\n" ); 02824 printf ( " Unacceptable output file type \"%s\".\n", fileout_type ); 02825 02826 } 02827 /* 02828 Close the output file. 02829 */ 02830 fclose ( fileout ); 02831 02832 if ( result == ERROR ) { 02833 return ERROR; 02834 } 02835 else { 02836 return SUCCESS; 02837 } 02838 } 02839 /******************************************************************************/ 02840 02841 int dxf_read ( FILE *filein ) 02842 02843 /******************************************************************************/ 02844 02845 /* 02846 Purpose: 02847 02848 DXF_READ reads an AutoCAD DXF file. 02849 02850 Examples: 02851 02852 0 02853 SECTION 02854 2 02855 HEADER 02856 999 02857 diamond.dxf created by IVREAD. 02858 999 02859 Original data in diamond.obj. 02860 0 02861 ENDSEC 02862 0 02863 SECTION 02864 2 02865 TABLES 02866 0 02867 ENDSEC 02868 0 02869 SECTION 02870 2 02871 BLOCKS 02872 0 02873 ENDSEC 02874 0 02875 SECTION 02876 2 02877 ENTITIES 02878 0 02879 LINE 02880 8 02881 0 02882 10 02883 0.00 (X coordinate of beginning of line.) 02884 20 02885 0.00 (Y coordinate of beginning of line.) 02886 30 02887 0.00 (Z coordinate of beginning of line.) 02888 11 02889 1.32 (X coordinate of end of line.) 02890 21 02891 1.73 (Y coordinate of end of line.) 02892 31 02893 2.25 (Z coordinate of end of line.) 02894 0 02895 3DFACE 02896 8 02897 Cube 02898 10 02899 -0.50 (X coordinate of vertex 1) 02900 20 02901 0.50 (Y coordinate of vertex 1) 02902 30 02903 1.0 (Z coordinate of vertex 1) 02904 11 02905 0.50 (X coordinate of vertex 2) 02906 21 02907 0.50 (Y coordinate of vertex 2) 02908 31 02909 1.0 (Z coordinate of vertex 2) 02910 12 02911 0.50 (X coordinate of vertex 3) 02912 22 02913 0.50 (Y coordinate of vertex 3) 02914 32 02915 0.00 (Z coordinate of vertex 3) 02916 0 02917 ENDSEC 02918 0 02919 EOF 02920 02921 Modified: 02922 02923 23 May 1999 02924 02925 Author: 02926 02927 John Burkardt 02928 */ 02929 { 02930 int code; 02931 int count; 02932 float cvec[3]; 02933 int icor3; 02934 char input1[LINE_MAX_LEN]; 02935 char input2[LINE_MAX_LEN]; 02936 int ivert; 02937 float rval; 02938 int width; 02939 int linemode; 02940 int cpos; 02941 02942 linemode = 0; 02943 ivert = 0; 02944 /* 02945 Read the next two lines of the file into INPUT1 and INPUT2. 02946 */ 02947 02948 for ( ;; ) { 02949 02950 /* 02951 INPUT1 should contain a single integer, which tells what INPUT2 02952 will contain. 02953 */ 02954 if ( fgets ( input1, LINE_MAX_LEN, filein ) == NULL ) { 02955 break; 02956 } 02957 02958 text_num = text_num + 1; 02959 02960 count = sscanf ( input1, "%d%n", &code, &width ); 02961 if ( count <= 0 ) { 02962 break; 02963 } 02964 /* 02965 Read the second line, and interpret it according to the code. 02966 */ 02967 if ( fgets ( input2, LINE_MAX_LEN, filein ) == NULL ) { 02968 break; 02969 } 02970 02971 text_num = text_num + 1; 02972 02973 if ( code == 0 ) { 02974 02975 if ( ivert > 0 ) { 02976 /* finish off the face */ 02977 face_order[face_num] = ivert; 02978 face_num = face_num + 1; 02979 ivert = 0; 02980 } 02981 02982 if ( strncmp( input2, "LINE", 4 ) == 0 ) { 02983 linemode = 1; 02984 } 02985 else if ( strncmp( input2, "3DFACE", 6 ) == 0 ) { 02986 linemode = 0; 02987 ivert = 0; 02988 } 02989 } 02990 else { 02991 02992 for (cpos = 0; input1[cpos] == ' '; cpos++) 02993 {}; 02994 02995 if ( input1[cpos] == '1' || input1[cpos] == '2' || input1[cpos] == '3' ) { 02996 02997 count = sscanf ( input2, "%e%n", &rval, &width ); 02998 02999 switch ( input1[cpos] ) 03000 { 03001 case '1': 03002 if ( line_num > 0 ) { 03003 if ( linemode ) { 03004 line_dex[line_num] = - 1; 03005 line_material[line_num] = - 1; 03006 line_num = line_num + 1; 03007 } 03008 } 03009 cvec[0] = rval; 03010 break; 03011 03012 case '2': 03013 cvec[1] = rval; 03014 break; 03015 03016 case '3': 03017 cvec[2] = rval; 03018 03019 if ( cor3_num < 1000 ) { 03020 icor3 = rcol_find ( cor3, 3, cor3_num, cvec ); 03021 } 03022 else { 03023 icor3 = -1; 03024 } 03025 03026 if ( icor3 == -1 ) { 03027 icor3 = cor3_num; 03028 if ( cor3_num < COR3_MAX ) { 03029 cor3[0][cor3_num] = cvec[0]; 03030 cor3[1][cor3_num] = cvec[1]; 03031 cor3[2][cor3_num] = cvec[2]; 03032 } 03033 cor3_num = cor3_num + 1; 03034 } 03035 else { 03036 dup_num = dup_num + 1; 03037 } 03038 03039 if ( linemode ) { 03040 line_dex[line_num] = icor3; 03041 line_material[line_num] = 0; 03042 line_num = line_num + 1; 03043 } 03044 else { 03045 face[ivert][face_num] = icor3; 03046 ivert = ivert + 1; 03047 } 03048 break; 03049 03050 default: 03051 break; 03052 } 03053 } 03054 } 03055 } 03056 03057 if ( line_num > 0 ) { 03058 if ( linemode ) { 03059 line_dex[line_num] = - 1; 03060 line_material[line_num] = - 1; 03061 line_num = line_num + 1; 03062 } 03063 } 03064 return SUCCESS; 03065 } 03066 /******************************************************************************/ 03067 03068 int dxf_write ( FILE *fileout ) 03069 03070 /******************************************************************************/ 03071 03072 /* 03073 Purpose: 03074 03075 DXF_WRITE writes graphics information to an AutoCAD DXF file. 03076 03077 Examples: 03078 03079 0 03080 SECTION 03081 2 03082 HEADER 03083 999 03084 diamond.dxf created by IVREAD. 03085 999 03086 Original data in diamond.obj. 03087 0 03088 ENDSEC 03089 0 03090 SECTION 03091 2 03092 TABLES 03093 0 03094 ENDSEC 03095 0 03096 SECTION 03097 2 03098 BLOCKS 03099 0 03100 ENDSEC 03101 0 03102 SECTION 03103 2 03104 ENTITIES 03105 0 03106 LINE 03107 8 03108 0 03109 10 03110 0.00 (X coordinate of beginning of line.) 03111 20 03112 0.00 (Y coordinate of beginning of line.) 03113 30 03114 0.00 (Z coordinate of beginning of line.) 03115 11 03116 1.32 (X coordinate of end of line.) 03117 21 03118 1.73 (Y coordinate of end of line.) 03119 31 03120 2.25 (Z coordinate of end of line.) 03121 0 03122 3DFACE 03123 8 03124 Cube 03125 10 03126 -0.50 (X coordinate of vertex 1) 03127 20 03128 0.50 (Y coordinate of vertex 1) 03129 30 03130 1.0 (Z coordinate of vertex 1) 03131 11 03132 0.50 (X coordinate of vertex 2) 03133 21 03134 0.50 (Y coordinate of vertex 2) 03135 31 03136 1.0 (Z coordinate of vertex 2) 03137 12 03138 0.50 (X coordinate of vertex 3) 03139 22 03140 0.50 (Y coordinate of vertex 3) 03141 32 03142 0.00 (Z coordinate of vertex 3) 03143 0 03144 ENDSEC 03145 0 03146 EOF 03147 03148 Modified: 03149 03150 16 May 1999 03151 03152 Author: 03153 03154 John Burkardt 03155 */ 03156 { 03157 int icor3; 03158 int iline; 03159 int iface; 03160 int ivert; 03161 int jcor3; 03162 int newline; 03163 int text_num; 03164 03165 /* 03166 Initialize. 03167 */ 03168 text_num = 0; 03169 03170 fprintf ( fileout, " 0\n" ); 03171 fprintf ( fileout, "SECTION\n" ); 03172 fprintf ( fileout, " 2\n" ); 03173 fprintf ( fileout, "HEADER\n" ); 03174 fprintf ( fileout, "999\n" ); 03175 fprintf ( fileout, "%s created by IVCON.\n", fileout_name ); 03176 fprintf ( fileout, "999\n" ); 03177 fprintf ( fileout, "Original data in %s.\n", filein_name ); 03178 fprintf ( fileout, " 0\n" ); 03179 fprintf ( fileout, "ENDSEC\n" ); 03180 text_num = text_num + 10; 03181 03182 fprintf ( fileout, " 0\n" ); 03183 fprintf ( fileout, "SECTION\n" ); 03184 fprintf ( fileout, " 2\n" ); 03185 fprintf ( fileout, "TABLES\n" ); 03186 fprintf ( fileout, " 0\n" ); 03187 fprintf ( fileout, "ENDSEC\n" ); 03188 text_num = text_num + 6; 03189 03190 fprintf ( fileout, " 0\n" ); 03191 fprintf ( fileout, "SECTION\n" ); 03192 fprintf ( fileout, " 2\n" ); 03193 fprintf ( fileout, "BLOCKS\n" ); 03194 fprintf ( fileout, " 0\n" ); 03195 fprintf ( fileout, "ENDSEC\n" ); 03196 text_num = text_num + 6; 03197 03198 fprintf ( fileout, " 0\n" ); 03199 fprintf ( fileout, "SECTION\n" ); 03200 fprintf ( fileout, " 2\n" ); 03201 fprintf ( fileout, "ENTITIES\n" ); 03202 text_num = text_num + 4; 03203 /* 03204 Handle lines. 03205 */ 03206 jcor3 = 0; 03207 newline = TRUE; 03208 03209 for ( iline = 0; iline < line_num; iline++ ) { 03210 03211 icor3 = line_dex[iline]; 03212 03213 if ( icor3 == -1 ) { 03214 03215 newline = TRUE; 03216 } 03217 else { 03218 03219 if ( newline == FALSE ) { 03220 03221 fprintf ( fileout, " 0\n" ); 03222 fprintf ( fileout, "LINE\n" ); 03223 fprintf ( fileout, " 8\n" ); 03224 fprintf ( fileout, " 0\n" ); 03225 fprintf ( fileout, " 10\n" ); 03226 fprintf ( fileout, "%f\n", cor3[0][jcor3] ); 03227 fprintf ( fileout, " 20\n" ); 03228 fprintf ( fileout, "%f\n", cor3[1][jcor3] ); 03229 fprintf ( fileout, " 30\n" ); 03230 fprintf ( fileout, "%f\n", cor3[2][jcor3] ); 03231 fprintf ( fileout, " 11\n" ); 03232 fprintf ( fileout, "%f\n", cor3[0][icor3] ); 03233 fprintf ( fileout, " 21\n" ); 03234 fprintf ( fileout, "%f\n", cor3[1][icor3] ); 03235 fprintf ( fileout, " 31\n" ); 03236 fprintf ( fileout, "%f\n", cor3[2][icor3] ); 03237 03238 text_num = text_num + 16; 03239 03240 } 03241 03242 jcor3 = icor3; 03243 newline = FALSE; 03244 03245 } 03246 } 03247 /* 03248 Handle faces. 03249 (If FACE_ORDER is greater than 10, you're sure to have problems here) 03250 */ 03251 for ( iface = 0; iface < face_num; iface++ ) { 03252 03253 fprintf ( fileout, " 0\n" ); 03254 fprintf ( fileout, "3DFACE\n" ); 03255 fprintf ( fileout, " 8\n" ); 03256 fprintf ( fileout, " Cube\n" ); 03257 text_num = text_num + 4; 03258 03259 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 03260 03261 icor3 = face[ivert][iface]; 03262 03263 fprintf ( fileout, "1%d\n", ivert ); 03264 fprintf ( fileout, "%f\n", cor3[0][icor3] ); 03265 fprintf ( fileout, "2%d\n", ivert ); 03266 fprintf ( fileout, "%f\n", cor3[1][icor3] ); 03267 fprintf ( fileout, "3%d\n", ivert ); 03268 fprintf ( fileout, "%f\n", cor3[2][icor3] ); 03269 03270 text_num = text_num + 6; 03271 } 03272 } 03273 03274 fprintf ( fileout, " 0\n" ); 03275 fprintf ( fileout, "ENDSEC\n" ); 03276 fprintf ( fileout, " 0\n" ); 03277 fprintf ( fileout, "EOF\n" ); 03278 text_num = text_num + 4; 03279 /* 03280 Report. 03281 */ 03282 printf ( "\n" ); 03283 printf ( "DXF_WRITE - Wrote %d text lines.\n", text_num ); 03284 03285 return SUCCESS; 03286 } 03287 /**********************************************************************/ 03288 03289 void edge_null_delete ( void ) 03290 03291 /**********************************************************************/ 03292 03293 /* 03294 Purpose: 03295 03296 EDGE_NULL_DELETE deletes face edges with zero length. 03297 03298 Modified: 03299 03300 16 July 1999 03301 03302 Author: 03303 03304 John Burkardt 03305 */ 03306 { 03307 float distsq; 03308 int face2[ORDER_MAX]; 03309 int face_order2; 03310 int iface; 03311 int inode; 03312 int ivert; 03313 int j; 03314 int jnode; 03315 int jvert; 03316 int edge_num; 03317 int edge_num_del; 03318 float vertex_normal2[3][ORDER_MAX]; 03319 float x; 03320 float y; 03321 float z; 03322 03323 edge_num = 0; 03324 edge_num_del = 0; 03325 /* 03326 Consider each face. 03327 */ 03328 for ( iface = 0; iface < face_num; iface++ ) { 03329 /* 03330 Consider each pair of consecutive vertices. 03331 */ 03332 face_order2 = 0; 03333 03334 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 03335 03336 edge_num = edge_num + 1; 03337 03338 jvert = ivert + 1; 03339 if ( jvert >= face_order[iface] ) { 03340 jvert = 0; 03341 } 03342 03343 inode = face[ivert][iface]; 03344 jnode = face[jvert][iface]; 03345 03346 03347 x = cor3[0][inode] - cor3[0][jnode]; 03348 y = cor3[1][inode] - cor3[1][jnode]; 03349 z = cor3[2][inode] - cor3[2][jnode]; 03350 03351 distsq = x * x + y * y + z * z; 03352 03353 if ( distsq != 0.0 ) { 03354 face2[face_order2] = face[ivert][iface]; 03355 vertex_normal2[0][face_order2] = vertex_normal[0][ivert][iface]; 03356 vertex_normal2[1][face_order2] = vertex_normal[1][ivert][iface]; 03357 vertex_normal2[2][face_order2] = vertex_normal[2][ivert][iface]; 03358 face_order2 = face_order2 + 1; 03359 } 03360 else { 03361 edge_num_del = edge_num_del + 1; 03362 } 03363 03364 } 03365 03366 face_order[iface] = face_order2; 03367 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 03368 face[ivert][iface] = face2[ivert]; 03369 for ( j = 0; j < 3; j++ ) { 03370 vertex_normal[j][ivert][iface] = vertex_normal2[j][ivert]; 03371 } 03372 } 03373 03374 } 03375 03376 printf ( "\n" ); 03377 printf ( "EDGE_NULL_DELETE:\n" ); 03378 printf ( " There are a total of %d edges.\n", edge_num ); 03379 printf ( " Of these, %d were of zero length, and deleted.\n", edge_num_del ); 03380 03381 return; 03382 } 03383 /**********************************************************************/ 03384 03385 void face_area_set ( void ) 03386 03387 /**********************************************************************/ 03388 03389 /* 03390 Purpose: 03391 03392 FACE_AREA_SET computes the area of the faces. 03393 03394 Formula: 03395 03396 The area is the sum of the areas of the triangles formed by 03397 node N with consecutive pairs of nodes. 03398 03399 Reference: 03400 03401 Adrian Bowyer and John Woodwark, 03402 A Programmer's Geometry, 03403 Butterworths, 1983. 03404 03405 Modified: 03406 03407 17 July 1999 03408 03409 Author: 03410 03411 John Burkardt 03412 */ 03413 { 03414 float alpha; 03415 float area_max; 03416 float area_min; 03417 float area_tri; 03418 float base; 03419 float dot; 03420 float height; 03421 int i; 03422 int i1; 03423 int i2; 03424 int i3; 03425 int iface; 03426 int face_num_del; 03427 float tol; 03428 float x; 03429 float x1; 03430 float x2; 03431 float x3; 03432 float y; 03433 float y1; 03434 float y2; 03435 float y3; 03436 float z; 03437 float z1; 03438 float z2; 03439 float z3; 03440 03441 for ( iface = 0; iface < face_num; iface++ ) { 03442 03443 face_area[iface] = 0.0; 03444 03445 for ( i = 0; i < face_order[iface]-2; i++ ) { 03446 03447 i1 = face[i][iface]; 03448 i2 = face[i+1][iface]; 03449 i3 = face[i+2][iface]; 03450 03451 x1 = cor3[0][i1]; 03452 y1 = cor3[1][i1]; 03453 z1 = cor3[2][i1]; 03454 03455 x2 = cor3[0][i2]; 03456 y2 = cor3[1][i2]; 03457 z2 = cor3[2][i2]; 03458 03459 x3 = cor3[0][i3]; 03460 y3 = cor3[1][i3]; 03461 z3 = cor3[2][i3]; 03462 /* 03463 Find the projection of (P3-P1) onto (P2-P1). 03464 */ 03465 dot = 03466 ( x2 - x1 ) * ( x3 - x1 ) + 03467 ( y2 - y1 ) * ( y3 - y1 ) + 03468 ( z2 - z1 ) * ( z3 - z1 ); 03469 03470 base = sqrt ( 03471 ( x2 - x1 ) * ( x2 - x1 ) 03472 + ( y2 - y1 ) * ( y2 - y1 ) 03473 + ( z2 - z1 ) * ( z2 - z1 ) ); 03474 /* 03475 The height of the triangle is the length of (P3-P1) after its 03476 projection onto (P2-P1) has been subtracted. 03477 */ 03478 if ( base == 0.0 ) { 03479 height = 0.0; 03480 } 03481 else { 03482 03483 alpha = dot / ( base * base ); 03484 03485 x = x3 - x1 - alpha * ( x2 - x1 ); 03486 y = y3 - y1 - alpha * ( y2 - y1 ); 03487 z = z3 - z1 - alpha * ( z2 - z1 ); 03488 03489 height = sqrt ( x * x + y * y + z * z ); 03490 03491 } 03492 03493 area_tri = 0.5 * base * height; 03494 03495 face_area[iface] = face_area[iface] + area_tri; 03496 03497 } 03498 03499 } 03500 03501 area_min = face_area[0]; 03502 area_max = face_area[0]; 03503 03504 for ( iface = 1; iface < face_num; iface++ ) { 03505 if ( area_min > face_area[iface] ) { 03506 area_min = face_area[iface]; 03507 } 03508 if ( area_max < face_area[iface] ) { 03509 area_max = face_area[iface]; 03510 } 03511 } 03512 03513 printf ( "\n" ); 03514 printf ( "FACE_AREA_SET:\n" ); 03515 printf ( " Minimum face area is %f\n", area_min ); 03516 printf ( " Maximum face area is %f\n", area_max ); 03517 03518 tol = area_max / 10000.0; 03519 03520 if ( area_min < tol ) { 03521 03522 face_num_del = 0; 03523 03524 for ( iface = 0; iface < face_num; iface++ ) { 03525 if ( face_area[iface] < tol ) { 03526 face_order[iface] = 0; 03527 face_num_del = face_num_del + 1; 03528 } 03529 } 03530 03531 printf ( " Marked %d tiny faces for deletion.\n", face_num_del ); 03532 03533 } 03534 03535 return; 03536 } 03537 /******************************************************************************/ 03538 03539 void face_normal_ave ( void ) 03540 03541 /******************************************************************************/ 03542 03543 /* 03544 Purpose: 03545 03546 FACE_NORMAL_AVE sets face normals as average of face vertex normals. 03547 03548 Modified: 03549 03550 09 October 1998 03551 03552 Author: 03553 03554 John Burkardt 03555 */ 03556 { 03557 int i; 03558 int iface; 03559 int ivert; 03560 int nfix; 03561 float norm; 03562 float x; 03563 float y; 03564 float z; 03565 03566 if ( face_num <= 0 ) { 03567 return; 03568 } 03569 03570 nfix = 0; 03571 03572 for ( iface = 0; iface < face_num; iface++ ) { 03573 03574 /* 03575 Check the norm of the current normal vector. 03576 */ 03577 x = face_normal[0][iface]; 03578 y = face_normal[1][iface]; 03579 z = face_normal[2][iface]; 03580 norm = ( float ) sqrt ( x * x + y * y + z * z ); 03581 03582 if ( norm == 0.0 ) { 03583 03584 nfix = nfix + 1; 03585 03586 for ( i = 0; i < 3; i++ ) { 03587 face_normal[i][iface] = 0.0; 03588 } 03589 03590 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 03591 for ( i = 0; i < 3; i++ ) { 03592 face_normal[i][iface] = face_normal[i][iface] + 03593 vertex_normal[i][ivert][iface]; 03594 } 03595 } 03596 03597 x = face_normal[0][iface]; 03598 y = face_normal[1][iface]; 03599 z = face_normal[2][iface]; 03600 norm = ( float ) sqrt ( x * x + y * y + z * z ); 03601 03602 if ( norm == 0.0 ) { 03603 for ( i = 0; i < 3; i++ ) { 03604 face_normal[i][iface] = ( float ) ( 1.0 / sqrt ( 3.0 ) ); 03605 } 03606 } 03607 else { 03608 for ( i = 0; i < 3; i++ ) { 03609 face_normal[i][iface] = face_normal[i][iface] / norm; 03610 } 03611 } 03612 } 03613 } 03614 03615 if ( nfix > 0 ) { 03616 printf ( "\n" ); 03617 printf ( "FACE_NORMAL_AVE: Recomputed %d face normals\n", nfix ); 03618 printf ( " by averaging face vertex normals.\n" ); 03619 } 03620 return; 03621 } 03622 /**********************************************************************/ 03623 03624 void face_null_delete ( void ) 03625 03626 /**********************************************************************/ 03627 03628 /* 03629 Purpose: 03630 03631 FACE_NULL_DELETE deletes faces of order less than 3. 03632 03633 Comments: 03634 03635 Thanks to Susan M. Fisher, University of North Carolina, 03636 Department of Computer Science, for pointing out a coding error 03637 in FACE_NULL_DELETE that was overwriting all the data! 03638 03639 Modified: 03640 03641 30 November 1999 03642 03643 Author: 03644 03645 John Burkardt 03646 */ 03647 { 03648 int iface; 03649 int ivert; 03650 int j; 03651 int face_num2; 03652 /* 03653 FACE_NUM2 is the number of faces we'll keep. 03654 */ 03655 face_num2 = 0; 03656 /* 03657 Check every face. 03658 */ 03659 for ( iface = 0; iface < face_num; iface++ ) { 03660 /* 03661 Keep it only if it has order 3 or more. 03662 */ 03663 if ( face_order[iface] >= 3 ) { 03664 /* 03665 We don't have to slide data down in the array until 03666 NUMFACE2 and IFACE get out of synch, that is, after 03667 we've discarded at least one face. 03668 */ 03669 if ( face_num2 != iface ) { 03670 03671 face_area[face_num2] = face_area[iface]; 03672 face_material[face_num2] = face_material[iface]; 03673 face_order[face_num2] = face_order[iface]; 03674 for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) { 03675 face[ivert][face_num2] = face[ivert][iface]; 03676 vertex_material[ivert][face_num2] = vertex_material[ivert][iface]; 03677 for ( j = 0; j < 3; j++ ) { 03678 vertex_normal[j][ivert][face_num2] = vertex_normal[j][ivert][iface]; 03679 } 03680 } 03681 03682 } 03683 /* 03684 Update the count only after we've used the un-incremented value 03685 as a pointer. 03686 */ 03687 face_num2 = face_num2 + 1; 03688 03689 } 03690 03691 } 03692 03693 printf ( "\n" ); 03694 printf ( "FACE_NULL_DELETE\n" ); 03695 printf ( " There are a total of %d faces.\n", face_num ); 03696 printf ( " Of these, %d passed the order test.\n", face_num2 ); 03697 03698 face_num = face_num2; 03699 03700 return; 03701 } 03702 /******************************************************************************/ 03703 03704 int face_print ( int iface ) 03705 03706 /******************************************************************************/ 03707 03708 /* 03709 Purpose: 03710 03711 FACE_PRINT prints out information about a face. 03712 03713 Modified: 03714 03715 31 August 1998 03716 03717 Author: 03718 03719 John Burkardt 03720 */ 03721 { 03722 int ivert; 03723 int j; 03724 int k; 03725 03726 if ( iface < 0 || iface > face_num-1 ) { 03727 printf ( "\n" ); 03728 printf ( "FACE_PRINT - Fatal error!\n" ); 03729 printf ( " Face indices must be between 1 and %d\n", face_num ); 03730 printf ( " But your requested value was %d\n", iface ); 03731 return ERROR; 03732 } 03733 03734 printf ( "\n" ); 03735 printf ( "FACE_PRINT\n" ); 03736 printf ( " Information about face %d\n", iface ); 03737 printf ( "\n" ); 03738 printf ( " Number of vertices is %d\n", face_order[iface] ); 03739 printf ( "\n" ); 03740 printf ( " Vertex list:\n" ); 03741 printf ( " Vertex #, Node #, Material #, X, Y, Z:\n" ); 03742 printf ( "\n" ); 03743 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 03744 j = face[ivert][iface]; 03745 k = vertex_material[ivert][iface]; 03746 printf ( " %d %d %d %f %f %f\n", ivert, j, k, cor3[0][j], cor3[1][j], 03747 cor3[2][j] ); 03748 } 03749 03750 printf ( "\n" ); 03751 printf ( " Face normal vector:\n" ); 03752 printf ( "\n" ); 03753 printf ( " %f %f %f\n", face_normal[0][iface], face_normal[1][iface], 03754 face_normal[2][iface] ); 03755 03756 printf ( "\n" ); 03757 printf ( " Vertex face normals:\n" ); 03758 printf ( "\n" ); 03759 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 03760 printf ( " %d %f %f %f\n", ivert, vertex_normal[0][ivert][iface], 03761 vertex_normal[1][ivert][iface], vertex_normal[2][ivert][iface] ); 03762 } 03763 03764 return SUCCESS; 03765 03766 } 03767 /**********************************************************************/ 03768 03769 void face_reverse_order ( void ) 03770 03771 /**********************************************************************/ 03772 03773 /* 03774 Purpose: 03775 03776 FACE_REVERSE_ORDER reverses the order of the nodes in each face. 03777 03778 Discussion: 03779 03780 Reversing the order of the nodes requires that the normal vectors 03781 be reversed as well, so this routine will automatically reverse 03782 the normals associated with nodes, vertices and faces. 03783 03784 Modified: 03785 03786 28 June 1999 03787 03788 Author: 03789 03790 John Burkardt 03791 */ 03792 { 03793 int i; 03794 int iface; 03795 int itemp; 03796 int ivert; 03797 int j; 03798 int m; 03799 float temp; 03800 03801 for ( iface = 0; iface < face_num; iface++ ) { 03802 03803 m = face_order[iface]; 03804 03805 for ( ivert = 0; ivert < ( m / 2 ); ivert++ ) { 03806 03807 itemp = face[ivert][iface]; 03808 face[ivert][iface] = face[m-1-ivert][iface]; 03809 face[m-1-ivert][iface] = itemp; 03810 03811 itemp = vertex_material[ivert][iface]; 03812 vertex_material[ivert][iface] = vertex_material[m-1-ivert][iface]; 03813 vertex_material[m-1-ivert][iface] = itemp; 03814 03815 for ( j = 0; j < 3; j++ ) { 03816 temp = vertex_normal[j][ivert][iface]; 03817 vertex_normal[j][ivert][iface] = vertex_normal[j][m-1-ivert][iface]; 03818 vertex_normal[j][m-1-ivert][iface] = temp; 03819 } 03820 03821 for ( j = 0; j < 2; j++ ) { 03822 temp = vertex_tex_uv[j][ivert][iface]; 03823 vertex_tex_uv[j][ivert][iface] = vertex_tex_uv[j][m-1-ivert][iface]; 03824 vertex_tex_uv[j][m-1-ivert][iface] = temp; 03825 } 03826 03827 } 03828 03829 } 03830 03831 for ( i = 0; i < cor3_num; i++ ) { 03832 for ( j = 0; j < 3; j++ ) { 03833 cor3_normal[j][i] = - cor3_normal[j][i]; 03834 } 03835 } 03836 03837 for ( i = 0; i < face_num; i++ ) { 03838 for ( j = 0; j < 3; j++ ) { 03839 face_normal[j][i] = - face_normal[j][i]; 03840 } 03841 } 03842 03843 printf ( "\n" ); 03844 printf ( "FACE_REVERSE_ORDER\n" ); 03845 printf ( " Each list of nodes defining a face\n" ); 03846 printf ( " has been reversed; related information,\n" ); 03847 printf ( " including normal vectors, was also updated.\n" ); 03848 03849 return; 03850 } 03851 03852 /******************************************************************************/ 03853 03854 int face_subset ( void ) 03855 03856 /******************************************************************************/ 03857 03858 /* 03859 Purpose: 03860 03861 FACE_SUBSET selects a subset of the current faces as the new object. 03862 03863 Warning: 03864 03865 The original graphic object is overwritten by the new one. 03866 03867 Modified: 03868 03869 12 October 1998 03870 03871 Author: 03872 03873 John Burkardt 03874 03875 */ 03876 { 03877 int i; 03878 int iface; 03879 int iface1; 03880 int iface2; 03881 int inc; 03882 int ivert; 03883 int j; 03884 int k; 03885 int cor3_num2; 03886 03887 line_num = 0; 03888 /* 03889 Get the first and last faces to save, IFACE1 and IFACE2. 03890 */ 03891 printf ( "\n" ); 03892 printf ( "Enter lowest face number to save between 0 and %d:\n", face_num-1 ); 03893 scanf ( "%d", &iface1 ); 03894 if ( iface1 < 0 || iface1 > face_num - 1 ) { 03895 printf ( "Illegal choice!\n" ); 03896 return ERROR; 03897 } 03898 03899 printf ( "\n" ); 03900 printf ( "Enter highest face number to save between %d and %d:\n", 03901 iface1, face_num-1 ); 03902 scanf ( "%d", &iface2 ); 03903 if ( iface2 < iface1 || iface2 > face_num - 1 ) { 03904 printf ( "Illegal choice!\n" ); 03905 return ERROR; 03906 } 03907 03908 inc = iface1; 03909 /* 03910 "Slide" the data for the saved faces down the face arrays. 03911 */ 03912 for ( iface = 0; iface < iface2 + 1 - iface1; iface++ ) { 03913 face_order[iface] = face_order[iface+inc]; 03914 for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) { 03915 face[ivert][iface] = face[ivert][iface+inc]; 03916 vertex_material[ivert][iface] = vertex_material[ivert][iface+inc]; 03917 for ( i = 0; i < 3; i++ ) { 03918 vertex_normal[i][ivert][iface] = 03919 vertex_normal[i][ivert][iface+inc]; 03920 vertex_rgb[i][ivert][iface] = vertex_rgb[i][ivert][iface+inc]; 03921 } 03922 } 03923 for ( i = 0; i < 3; i++ ) { 03924 face_normal[i][iface] = face_normal[i][iface+inc]; 03925 } 03926 } 03927 /* 03928 Now reset the number of faces. 03929 */ 03930 face_num = iface2 + 1 - iface1; 03931 /* 03932 Now, for each point I, set LIST(I) = J if point I is the J-th 03933 point we are going to save, and 0 otherwise. Then J will be 03934 the new label of point I. 03935 */ 03936 for ( i = 0; i < cor3_num; i++ ) { 03937 list[i] = -1; 03938 } 03939 03940 cor3_num2 = 0; 03941 03942 for ( iface = 0; iface < face_num; iface++ ){ 03943 for ( ivert = 0; ivert < face_order[iface]; ivert++ ){ 03944 j = face[ivert][iface]; 03945 if ( list[j] == -1 ) { 03946 cor3_num2 = cor3_num2 + 1; 03947 list[j] = cor3_num2; 03948 } 03949 } 03950 } 03951 /* 03952 Now make the nonzero list entries rise in order, so that 03953 we can compress the COR3 data in a minute. 03954 */ 03955 cor3_num2 = 0; 03956 03957 for ( i = 0; i < cor3_num; i++ ) { 03958 if ( list[i] != -1 ) { 03959 list[i] = cor3_num2; 03960 cor3_num2 = cor3_num2 + 1; 03961 } 03962 } 03963 /* 03964 Relabel the FACE array with the new node indices. 03965 */ 03966 for ( iface = 0; iface < face_num; iface++ ){ 03967 for ( ivert = 0; ivert < face_order[iface]; ivert++ ){ 03968 j = face[ivert][iface]; 03969 face[ivert][iface] = list[j]; 03970 } 03971 } 03972 /* 03973 Rebuild the COR3 array by sliding data down. 03974 */ 03975 for ( i = 0; i < cor3_num; i++ ){ 03976 k = list[i]; 03977 if ( k != -1 ) { 03978 for ( j = 0; j < 3; j++ ) { 03979 cor3[j][k] = cor3[j][i]; 03980 } 03981 } 03982 } 03983 03984 cor3_num = cor3_num2; 03985 03986 return SUCCESS; 03987 } 03988 /**********************************************************************/ 03989 03990 void face_to_line ( void ) 03991 03992 /**********************************************************************/ 03993 03994 /* 03995 Purpose: 03996 03997 FACE_TO_LINE converts face information to line information. 03998 03999 Discussion: 04000 04001 In some cases, the graphic information represented by polygonal faces 04002 must be converted to a representation based solely on line segments. 04003 This is particularly true if a VLA file is being written. 04004 04005 Modified: 04006 04007 26 May 1999 04008 04009 Author: 04010 04011 John Burkardt 04012 */ 04013 { 04014 int icor3; 04015 int iface; 04016 int ivert; 04017 int jcor3; 04018 int jvert; 04019 /* 04020 Case 0: 04021 No line pruning. 04022 */ 04023 if ( line_prune == 0 ) { 04024 04025 for ( iface = 0; iface < face_num; iface++ ) { 04026 04027 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 04028 04029 icor3 = face[ivert][iface]; 04030 04031 line_num = line_num + 1; 04032 if ( line_num <= LINES_MAX ) { 04033 line_dex[line_num] = icor3; 04034 line_material[line_num] = vertex_material[ivert][iface]; 04035 } 04036 } 04037 04038 ivert = 0; 04039 icor3 = face[ivert][iface]; 04040 04041 line_num = line_num + 1; 04042 if ( line_num <= LINES_MAX ) { 04043 line_dex[line_num] = icor3; 04044 line_material[line_num] = vertex_material[ivert][iface]; 04045 } 04046 04047 line_num = line_num + 1; 04048 if ( line_num <= LINES_MAX ) { 04049 line_dex[line_num] = -1; 04050 line_material[line_num] = -1; 04051 } 04052 } 04053 04054 } 04055 /* 04056 Case 2: 04057 Simple-minded line pruning. 04058 Only draw line (I,J) if I < J. 04059 */ 04060 else { 04061 04062 for ( iface = 0; iface < face_num; iface++ ) { 04063 04064 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 04065 04066 icor3 = face[ivert][iface]; 04067 04068 if ( ivert + 1 < face_order[iface] ) { 04069 jvert = ivert + 1; 04070 } 04071 else { 04072 jvert = 0; 04073 } 04074 04075 jcor3 = face[jvert][iface]; 04076 04077 if ( icor3 < jcor3 ) { 04078 04079 if ( line_num + 3 < LINES_MAX ) { 04080 04081 line_num = line_num + 1; 04082 line_dex[line_num] = icor3; 04083 line_material[line_num] = vertex_material[ivert][iface]; 04084 04085 line_num = line_num + 1; 04086 line_dex[line_num] = jcor3; 04087 line_material[line_num] = vertex_material[jvert][iface]; 04088 04089 line_num = line_num + 1; 04090 line_dex[line_num] = -1; 04091 line_material[line_num] = -1; 04092 04093 } 04094 } 04095 } 04096 } 04097 04098 } 04099 04100 return; 04101 } 04102 /**********************************************************************/ 04103 04104 void face_to_vertex_material ( void ) 04105 04106 /**********************************************************************/ 04107 04108 /* 04109 Purpose: 04110 04111 FACE_TO_VERTEX_MAT extends face material definitions to vertices. 04112 04113 Discussion: 04114 04115 Assuming material indices are defined for all the faces, this 04116 routine assigns to each vertex of a face the material of that face. 04117 04118 Modified: 04119 04120 22 May 1999 04121 04122 Author: 04123 04124 John Burkardt 04125 */ 04126 { 04127 int iface; 04128 int ivert; 04129 04130 for ( iface = 0; iface < face_num; iface++ ) { 04131 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 04132 vertex_material[ivert][iface] = face_material[iface]; 04133 } 04134 } 04135 04136 return; 04137 } 04138 /******************************************************************************/ 04139 04140 char *file_ext ( char *file_name ) 04141 04142 /******************************************************************************/ 04143 04144 /* 04145 Purpose: 04146 04147 FILE_EXT picks out the extension in a file name. 04148 04149 Modified: 04150 04151 21 July 1998 04152 04153 Author: 04154 04155 John Burkardt 04156 */ 04157 { 04158 int i; 04159 04160 i = char_index_last ( file_name, '.' ); 04161 04162 if ( i == -1 ) { 04163 return NULL; 04164 } 04165 else { 04166 return file_name + i + 1; 04167 } 04168 } 04169 /******************************************************************************/ 04170 04171 float float_read ( FILE *filein ) 04172 04173 /******************************************************************************/ 04174 04175 /* 04176 Purpose: 04177 04178 FLOAT_READ reads 1 float from a binary file. 04179 04180 Modified: 04181 04182 24 May 1999 04183 */ 04184 { 04185 float rval; 04186 float temp; 04187 04188 fread ( &temp, sizeof ( float ), 1, filein ); 04189 04190 if ( byte_swap == TRUE ) { 04191 rval = float_reverse_bytes ( temp ); 04192 } 04193 else { 04194 rval = temp; 04195 } 04196 04197 return rval; 04198 } 04199 /******************************************************************************/ 04200 04201 float float_reverse_bytes ( float x ) 04202 04203 /******************************************************************************/ 04204 04205 /* 04206 Purpose: 04207 04208 FLOAT_REVERSE_BYTES reverses the four bytes in a float. 04209 04210 Modified: 04211 04212 24 May 1999 04213 04214 Author: 04215 04216 John Burkardt 04217 04218 Parameters: 04219 04220 X, a float whose bytes are to be reversed. 04221 04222 FLOAT_REVERSE_BYTES, a float with bytes in reverse order from those in X. 04223 */ 04224 { 04225 char c; 04226 union { 04227 float yfloat; 04228 char ychar[4]; 04229 } y; 04230 04231 y.yfloat = x; 04232 04233 c = y.ychar[0]; 04234 y.ychar[0] = y.ychar[3]; 04235 y.ychar[3] = c; 04236 04237 c = y.ychar[1]; 04238 y.ychar[1] = y.ychar[2]; 04239 y.ychar[2] = c; 04240 04241 return ( y.yfloat ); 04242 } 04243 /******************************************************************************/ 04244 04245 int float_write ( FILE *fileout, float float_val ) 04246 04247 /******************************************************************************/ 04248 04249 /* 04250 Purpose: 04251 04252 FLOAT_WRITE writes 1 float to a binary file. 04253 04254 Modified: 04255 04256 23 September 1998 04257 */ 04258 { 04259 int nbyte = sizeof ( float ); 04260 float temp; 04261 04262 if ( byte_swap == TRUE ) { 04263 temp = float_reverse_bytes ( float_val ); 04264 } 04265 else { 04266 temp = float_val; 04267 } 04268 04269 fwrite ( &temp, nbyte, 1, fileout ); 04270 04271 return nbyte; 04272 } 04273 /******************************************************************************/ 04274 04275 int gmod_arch_check ( void ) 04276 04277 /******************************************************************************/ 04278 04279 /* 04280 Purpose: 04281 04282 GMOD_ARCH_CHECK inquires into some features of the computer architecture. 04283 04284 Modified: 04285 04286 19 May 1999 04287 04288 Author: 04289 04290 Zik Saleeba (zik@zikzak.net) 04291 */ 04292 { 04293 static unsigned char one[4]; 04294 int temp; 04295 04296 temp = sizeof ( float ); 04297 if ( temp != 4 ) { 04298 return FALSE; 04299 } 04300 04301 *(float *)one = 1.0; 04302 04303 if (one[0] == 0 && one[1] == 0 && one[2] == 128 && one[3] == 63) { 04304 /* little endian IEEE floats */ 04305 return TRUE; 04306 } 04307 04308 if (one[0] == 63 && one[1] == 128 && one[2] == 0 && one[3] == 0) { 04309 /* big endian IEEE floats */ 04310 return TRUE; 04311 } 04312 04313 return FALSE; 04314 } 04315 /******************************************************************************/ 04316 04317 int gmod_read ( FILE *filein ) 04318 04319 /******************************************************************************/ 04320 04321 /* 04322 Purpose: 04323 04324 GMOD_READ reads a golgotha GMOD file. 04325 04326 Modified: 04327 04328 19 May 1999 04329 04330 Author: 04331 04332 Zik Saleeba (zik@zikzak.net) 04333 */ 04334 04335 /* 04336 golgotha GMOD file format: 04337 04338 04339 FILE HEADER 04340 04341 w32 magic number f9 fa 63 1e 04342 w32 number of sections 04343 [ number of sections 04344 w32 section id 04345 w32 section offset 04346 ] 04347 04348 04349 TEXTURE NAME SECTION - section id = 0x13 (19) 04350 04351 w16 number of faces 04352 [ number of faces 04353 w16 texture name length 04354 [ texture name length 04355 w8 texture name character 04356 ] 04357 ] 04358 04359 04360 04361 MODEL QUADS SECTION - section id = 0x12 (18) 04362 04363 w16 number of faces 04364 [ number of faces 04365 [ four vertices 04366 w16 vertex index 04367 float xpos (0.0-1.0) 04368 float ypos (0.0-1.0) 04369 ] 04370 float scale 04371 w16 flags 04372 float xnormal (normal should be normalised) 04373 float ynormal 04374 float znormal 04375 ] 04376 04377 04378 VERTEX ARRAY SECTION - section id = 0x14 (20) 04379 04380 w16 number of vertices 04381 w16 number of animations 04382 w16 length of animation name 04383 [ length of animation name 04384 w8 animation name character 04385 ] 04386 w16 number of frames in animation 04387 [ number of frames in animation 04388 [ number of vertices 04389 float xpos 04390 float ypos 04391 float zpos 04392 float xnormal 04393 float ynormal 04394 float znormal 04395 ] 04396 ] 04397 */ 04398 { 04399 unsigned char MagicNumber[4]; 04400 unsigned long int NumSections; 04401 int SectionCount; 04402 unsigned long int SectionID[GMOD_MAX_SECTIONS]; 04403 unsigned long int SectionOffset[GMOD_MAX_SECTIONS]; 04404 04405 unsigned short NumAnimations; 04406 unsigned short NumFrames; 04407 unsigned short FaceCount; 04408 unsigned short TextureCount; 04409 int VertexCount; 04410 04411 float Scale; 04412 unsigned short Flags; 04413 unsigned short TextureNameLen; 04414 unsigned short AnimationNameLen; 04415 int Order; 04416 int MaxCor = 0; 04417 04418 /* 04419 * check if we can handle this architecture 04420 */ 04421 04422 if (!gmod_arch_check()) { 04423 printf("GMOD_READ - This architecture not supported.\n"); 04424 return ERROR; 04425 } 04426 04427 /* 04428 * read the file header 04429 */ 04430 04431 /* read the magic number */ 04432 fread(MagicNumber, 1, 4, filein); 04433 if (MagicNumber[0] != 0xf9 || 04434 MagicNumber[1] != 0xfa || 04435 MagicNumber[2] != 0x63 || 04436 MagicNumber[3] != 0x1e) { 04437 printf("GMOD_READ - Bad magic number on GMOD file.\n"); 04438 return ERROR; 04439 } 04440 04441 NumSections = gmod_read_w32(filein); 04442 if (NumSections >= GMOD_MAX_SECTIONS) { 04443 printf("GMOD_READ - Too many sections (%ld) in GMOD file - please increase static limit GMOD_MAX_SECTIONS\n", NumSections); 04444 return ERROR; 04445 } 04446 04447 /* 04448 Read the sections. 04449 */ 04450 04451 for ( SectionCount = 0; SectionCount < ( int ) NumSections; SectionCount++ ) { 04452 SectionID[SectionCount] = gmod_read_w32(filein); 04453 SectionOffset[SectionCount] = gmod_read_w32(filein); 04454 } 04455 /* 04456 Read each successive section. 04457 */ 04458 for ( SectionCount = 0; SectionCount < ( int ) NumSections; SectionCount++ ) { 04459 /* 04460 Go to the start of the section. 04461 */ 04462 fseek ( filein, ( long int ) SectionOffset[SectionCount], SEEK_SET ); 04463 /* 04464 What type of section is it? 04465 */ 04466 switch (SectionID[SectionCount]) { 04467 04468 /* 04469 Model section. 04470 */ 04471 case G1_SECTION_MODEL_QUADS: 04472 /* 04473 Get the number of faces. 04474 */ 04475 face_num = gmod_read_w16 ( filein ); 04476 04477 if (face_num > FACE_MAX) { 04478 printf("GMOD_READ - Too many faces (%d) in GMOD file - please increase static limit FACE_MAX.\n", face_num); 04479 return ERROR; 04480 } 04481 /* 04482 Get the information on each face. 04483 */ 04484 for ( FaceCount = 0; FaceCount < ( unsigned short ) face_num; FaceCount++ ) { 04485 04486 Order = 0; 04487 for ( VertexCount = 0; VertexCount < 4; VertexCount++ ) { 04488 04489 /* read the vertex index */ 04490 04491 face[VertexCount][FaceCount] = gmod_read_w16(filein); 04492 04493 if (face[VertexCount][FaceCount] != GMOD_UNUSED_VERTEX) { 04494 Order = VertexCount+1; 04495 if (MaxCor < face[VertexCount][FaceCount]) 04496 MaxCor = face[VertexCount][FaceCount]; 04497 } 04498 04499 /* read the texture position */ 04500 04501 vertex_tex_uv[0][VertexCount][FaceCount] = gmod_read_float(filein); 04502 vertex_tex_uv[1][VertexCount][FaceCount] = gmod_read_float(filein); 04503 } 04504 04505 /* scale and flags */ 04506 04507 fread(&Scale, sizeof(Scale), 1, filein); 04508 Flags = gmod_read_w16(filein); 04509 04510 if ( debug ) { 04511 printf ( "Flags = %d\n", Flags ); 04512 } 04513 04514 /* normal vector */ 04515 04516 face_normal[0][FaceCount] = gmod_read_float(filein); 04517 face_normal[1][FaceCount] = gmod_read_float(filein); 04518 face_normal[2][FaceCount] = gmod_read_float(filein); 04519 04520 /* the order is the number of used vertices */ 04521 04522 face_order[FaceCount] = Order; 04523 } 04524 break; 04525 04526 04527 /* 04528 Texture name section. 04529 */ 04530 04531 case G1_SECTION_MODEL_TEXTURE_NAMES: 04532 04533 /* get the number of textures */ 04534 04535 texture_num = gmod_read_w16(filein); 04536 if (texture_num > TEXTURE_MAX) { 04537 printf ( "GMOD_READ - Too many texture maps (%d) in GMOD file.\n", texture_num ); 04538 printf ( " Increase static limit TEXTURE_MAX.\n" ); 04539 return ERROR; 04540 } 04541 face_num = texture_num; 04542 04543 for (TextureCount = 0; TextureCount < ( unsigned short ) texture_num; 04544 TextureCount++) { 04545 04546 /* read the texture name */ 04547 04548 TextureNameLen = gmod_read_w16(filein); 04549 fread ( texture_name[TextureCount], sizeof(char), TextureNameLen, filein); 04550 texture_name[TextureCount][TextureNameLen] = '\0'; 04551 } 04552 break; 04553 04554 04555 /* 04556 * vertex section 04557 */ 04558 04559 case G1_SECTION_MODEL_VERT_ANIMATION: 04560 04561 /* get the number of vertices */ 04562 04563 cor3_num = gmod_read_w16(filein); 04564 if (cor3_num > COR3_MAX) { 04565 printf("GMOD_READ - Too many vertices (%d) in GMOD file - please increase static limit COR3_MAX.\n", cor3_num); 04566 return ERROR; 04567 } 04568 04569 /* 04570 Get the number of animations. 04571 */ 04572 04573 NumAnimations = gmod_read_w16(filein); 04574 04575 if (NumAnimations > 1) { 04576 printf ( "GMOD_READ - Fatal error!\n" ); 04577 printf ( " GMOD files can only handle one animation.\n" ); 04578 printf ( " This file contains %d.\n", NumAnimations ); 04579 return ERROR; 04580 } 04581 04582 /* read the animation name */ 04583 AnimationNameLen = gmod_read_w16(filein); 04584 fread ( anim_name, sizeof(char), AnimationNameLen, filein); 04585 anim_name[AnimationNameLen] = '\0'; 04586 04587 /* get the number of frames of animation */ 04588 NumFrames = gmod_read_w16(filein); 04589 if (NumFrames > 1) 04590 printf("GMOD_READ - Too many frames of animation (%d) in GMOD file - will only use 1.\n", NumFrames); 04591 04592 /* go through all the vertices, reading each one */ 04593 for (VertexCount = 0; VertexCount < cor3_num; VertexCount++) { 04594 04595 /* read the vertex */ 04596 cor3[0][VertexCount] = gmod_read_float(filein); 04597 cor3[1][VertexCount] = gmod_read_float(filein); 04598 cor3[2][VertexCount] = gmod_read_float(filein); 04599 04600 /* read the normal */ 04601 cor3_normal[0][VertexCount] = gmod_read_float(filein); 04602 cor3_normal[1][VertexCount] = gmod_read_float(filein); 04603 cor3_normal[2][VertexCount] = gmod_read_float(filein); 04604 } 04605 break; 04606 04607 default: 04608 continue; 04609 } 04610 } 04611 04612 /* 04613 Set some other stray info. 04614 */ 04615 line_num = 0; 04616 04617 /* 04618 Check for sanity. 04619 */ 04620 if ( MaxCor >= cor3_num ) { 04621 printf ( "GMOD_READ - Maximum coordinate index (%d)\n", MaxCor ); 04622 printf ( " exceeded number of coordinates (%d) in GMOD file.\n", cor3_num ); 04623 return ERROR; 04624 } 04625 04626 return SUCCESS; 04627 } 04628 /******************************************************************************/ 04629 04630 float gmod_read_float ( FILE *filein ) 04631 04632 /******************************************************************************/ 04633 04634 /* 04635 Purpose: 04636 04637 GMOD_READ_FLOAT reads a float from a Golgotha GMOD file. 04638 04639 Modified: 04640 04641 19 May 1999 04642 04643 Author: 04644 04645 Zik Saleeba (zik@zikzak.net) 04646 */ 04647 { 04648 int endian = 1; 04649 unsigned char *out_pos; 04650 int i; 04651 float Val; 04652 04653 if (*(char *)&endian == 1) { 04654 /* we're little-endian, which is native for GMOD floats */ 04655 fread(&Val, sizeof(Val), 1, filein); 04656 } 04657 else { 04658 /* we're big-endian, flip `em */ 04659 out_pos = (unsigned char *)&Val; 04660 for ( i = sizeof(Val)-1; i >= 0; i-- ) { 04661 *(out_pos+i) = fgetc(filein); 04662 } 04663 } 04664 04665 return Val; 04666 } 04667 /******************************************************************************/ 04668 04669 unsigned short gmod_read_w16 ( FILE *filein ) 04670 04671 /******************************************************************************/ 04672 04673 /* 04674 Purpose: 04675 04676 GMOD_READ_W16 reads a 16 bit word from a Golgotha GMOD file. 04677 04678 Modified: 04679 04680 19 May 1999 04681 04682 Author: 04683 04684 Zik Saleeba (zik@zikzak.net) 04685 */ 04686 { 04687 unsigned char Byte1; 04688 unsigned char Byte2; 04689 04690 Byte1 = fgetc ( filein ); 04691 Byte2 = fgetc ( filein ); 04692 04693 return Byte1 | (((unsigned short)Byte2) << 8); 04694 } 04695 /******************************************************************************/ 04696 04697 unsigned long gmod_read_w32 ( FILE *filein ) 04698 04699 /******************************************************************************/ 04700 04701 /* 04702 Purpose: 04703 04704 GMOD_READ_W32 reads a 32 bit word from a Golgotha GMOD file. 04705 04706 Modified: 04707 04708 19 May 1999 04709 04710 Author: 04711 04712 Zik Saleeba (zik@zikzak.net) 04713 */ 04714 { 04715 unsigned char Byte1, Byte2, Byte3, Byte4; 04716 04717 Byte1 = fgetc(filein); 04718 Byte2 = fgetc(filein); 04719 Byte3 = fgetc(filein); 04720 Byte4 = fgetc(filein); 04721 04722 return Byte1 | 04723 (((unsigned long)Byte2) << 8) | 04724 (((unsigned long)Byte3) << 16) | 04725 (((unsigned long)Byte4) << 24); 04726 } 04727 04728 /******************************************************************************/ 04729 04730 int gmod_write ( FILE *fileout ) { 04731 04732 /******************************************************************************/ 04733 04734 /* 04735 Purpose: 04736 04737 GMOD_WRITE writes a Golgotha GMOD file. 04738 04739 Modified: 04740 04741 19 May 1999 04742 04743 Author: 04744 04745 Zik Saleeba (zik@zikzak.net) 04746 */ 04747 static unsigned char MagicNumber[4] = { 0xf9, 0xfa, 0x63, 0x1e }; 04748 unsigned long NumSections; 04749 unsigned long SectionHeaderPos; 04750 unsigned long TextureNameSectionPos; 04751 unsigned long ModelSectionPos; 04752 unsigned long VertexSectionPos; 04753 04754 int VertexCount; 04755 int FaceCount; 04756 int TextureCount; 04757 unsigned long SectionCount; 04758 float Scale; 04759 float Min[3]; 04760 float Max[3]; 04761 int CorNumber; 04762 int DimensionCount; 04763 float MaxWidth; 04764 /* 04765 Check if we can handle this architecture. 04766 */ 04767 04768 if ( !gmod_arch_check() ) { 04769 printf("GMOD_WRITE - This architecture not supported.\n"); 04770 return ERROR; 04771 } 04772 04773 /* 04774 Write the file header. 04775 */ 04776 04777 /* 04778 Write the magic number. 04779 */ 04780 fwrite ( MagicNumber, sizeof(char), 4, fileout ); 04781 04782 /* 04783 Write the number of sections. 04784 */ 04785 NumSections = 3; 04786 gmod_write_w32 ( NumSections, fileout ); 04787 04788 /* 04789 Write a dummy section header which we'll overwrite later. 04790 */ 04791 SectionHeaderPos = ftell ( fileout ); 04792 for (SectionCount = 0; SectionCount < NumSections; SectionCount++) { 04793 gmod_write_w32 ( 0, fileout ); 04794 gmod_write_w32 ( 0, fileout ); 04795 } 04796 /* 04797 Texture name section. 04798 */ 04799 04800 /* 04801 Take note of where we are in the file. 04802 */ 04803 TextureNameSectionPos = ftell ( fileout ); 04804 04805 /* 04806 Write the number of textures. 04807 */ 04808 04809 gmod_write_w16 ( ( unsigned short ) face_num, fileout ); 04810 /* 04811 Write the texture names. 04812 */ 04813 for ( TextureCount = 0; TextureCount < face_num; TextureCount++ ) { 04814 04815 gmod_write_w16 ( ( unsigned short ) strlen ( texture_name[TextureCount] ), 04816 fileout ); 04817 04818 fwrite ( texture_name[TextureCount], strlen ( texture_name[TextureCount] ), 04819 1, fileout ); 04820 } 04821 04822 /* 04823 Model section. 04824 */ 04825 04826 /* 04827 Take note of where we are in the file. 04828 */ 04829 04830 ModelSectionPos = ftell(fileout); 04831 04832 /* 04833 Write the number of faces. 04834 */ 04835 04836 gmod_write_w16 ( ( unsigned short ) face_num, fileout ); 04837 04838 /* 04839 Write the information on each face. 04840 */ 04841 04842 for ( FaceCount = 0; FaceCount < face_num; FaceCount++ ) { 04843 04844 for (VertexCount = 0; VertexCount < ((face_order[FaceCount] < 4) ? face_order[FaceCount] : 4); VertexCount++) { 04845 04846 /* 04847 Write the vertex index. 04848 */ 04849 gmod_write_w16 ( ( unsigned short ) face[VertexCount][FaceCount], fileout ); 04850 04851 /* 04852 Write the texture position. 04853 */ 04854 04855 gmod_write_float ( vertex_tex_uv[0][VertexCount][FaceCount], fileout ); 04856 gmod_write_float ( vertex_tex_uv[1][VertexCount][FaceCount], fileout ); 04857 } 04858 04859 /* 04860 Write any extra vertices which are unused. 04861 */ 04862 04863 for ( ; VertexCount < 4; VertexCount++ ) { 04864 04865 /* 04866 Write the vertex index. 04867 */ 04868 gmod_write_w16 ( GMOD_UNUSED_VERTEX, fileout ); 04869 /* 04870 Write the texture position. 04871 */ 04872 gmod_write_float ( vertex_tex_uv[0][VertexCount][FaceCount], fileout ); 04873 04874 gmod_write_float ( vertex_tex_uv[1][VertexCount][FaceCount], fileout ); 04875 } 04876 04877 /* 04878 Scale and flags. 04879 */ 04880 04881 /* 04882 Find the bounding box. 04883 */ 04884 04885 for ( DimensionCount = 0; DimensionCount < 3; DimensionCount++ ) { 04886 04887 CorNumber = face[0][FaceCount]; 04888 Min[DimensionCount] = cor3[DimensionCount][CorNumber]; 04889 Max[DimensionCount] = cor3[DimensionCount][CorNumber]; 04890 04891 for (VertexCount = 1; VertexCount < ((face_order[FaceCount] < 4) ? face_order[FaceCount] : 4); VertexCount++) { 04892 04893 CorNumber = face[VertexCount][FaceCount]; 04894 04895 if (Min[DimensionCount] > cor3[DimensionCount][CorNumber]) 04896 Min[DimensionCount] = cor3[DimensionCount][CorNumber]; 04897 04898 if (Max[DimensionCount] < cor3[DimensionCount][CorNumber]) 04899 Max[DimensionCount] = cor3[DimensionCount][CorNumber]; 04900 } 04901 } 04902 04903 /* 04904 The scale is the "width" of the face for mipmapping - 04905 I just take the maximum bounding box dimension. 04906 */ 04907 MaxWidth = Max[0] - Min[0]; 04908 for ( DimensionCount = 1; DimensionCount < 3; DimensionCount++ ) { 04909 04910 if ( MaxWidth < Max[DimensionCount] - Min[DimensionCount] ) 04911 MaxWidth = Max[DimensionCount] - Min[DimensionCount]; 04912 } 04913 04914 Scale = MaxWidth; 04915 fwrite ( &Scale, sizeof(Scale), 1, fileout ); 04916 04917 /* 04918 Flags are just nothing. 04919 */ 04920 gmod_write_w16 ( 0, fileout ); 04921 /* 04922 Normal vector. 04923 */ 04924 gmod_write_float ( face_normal[0][FaceCount], fileout ); 04925 gmod_write_float ( face_normal[1][FaceCount], fileout ); 04926 gmod_write_float ( face_normal[2][FaceCount], fileout ); 04927 } 04928 04929 /* 04930 Vertex section. 04931 */ 04932 04933 /* 04934 Take note of where we are in the file. 04935 */ 04936 04937 VertexSectionPos = ftell ( fileout ); 04938 04939 /* 04940 Write the number of vertices. 04941 */ 04942 04943 gmod_write_w16 ( ( unsigned short ) cor3_num, fileout ); 04944 04945 /* 04946 Write the number of animations. 04947 */ 04948 04949 gmod_write_w16 ( 1, fileout ); 04950 04951 /* 04952 Write the animation name. 04953 */ 04954 04955 gmod_write_w16 ( 0, fileout ); 04956 04957 /* 04958 Write the number of frames of animation. 04959 */ 04960 04961 gmod_write_w16 ( 1, fileout ); 04962 04963 /* 04964 Go through all the vertices, writing each one. 04965 */ 04966 04967 for ( VertexCount = 0; VertexCount < cor3_num; VertexCount++ ) { 04968 04969 /* 04970 Write the vertex. 04971 */ 04972 gmod_write_float ( cor3[0][VertexCount], fileout ); 04973 gmod_write_float ( cor3[1][VertexCount], fileout ); 04974 gmod_write_float ( cor3[2][VertexCount], fileout ); 04975 04976 /* 04977 Write the normal. 04978 */ 04979 gmod_write_float ( cor3_normal[0][VertexCount], fileout ); 04980 gmod_write_float ( cor3_normal[1][VertexCount], fileout ); 04981 gmod_write_float ( cor3_normal[2][VertexCount], fileout ); 04982 } 04983 /* 04984 Now rewrite the section header. 04985 */ 04986 04987 /* 04988 Go back to the section header. 04989 */ 04990 fseek ( fileout, ( long int ) SectionHeaderPos, SEEK_SET ); 04991 04992 /* 04993 Write the texture name section header. 04994 */ 04995 gmod_write_w32 ( G1_SECTION_MODEL_TEXTURE_NAMES, fileout ); 04996 gmod_write_w32 ( TextureNameSectionPos, fileout ); 04997 04998 /* 04999 Write the model section header. 05000 */ 05001 gmod_write_w32 ( G1_SECTION_MODEL_QUADS, fileout ); 05002 gmod_write_w32 ( ModelSectionPos, fileout ); 05003 05004 /* 05005 Write the vertex section header. 05006 */ 05007 gmod_write_w32 ( G1_SECTION_MODEL_VERT_ANIMATION, fileout ); 05008 gmod_write_w32 ( VertexSectionPos, fileout ); 05009 05010 return SUCCESS; 05011 } 05012 05013 /******************************************************************************/ 05014 05015 void gmod_write_float ( float Val, FILE *fileout ) 05016 05017 /******************************************************************************/ 05018 05019 /* 05020 Purpose: 05021 05022 GMOD_WRITE_FLOAT writes a float to a Golgotha GMOD file. 05023 05024 Modified: 05025 05026 19 May 1999 05027 05028 Author: 05029 05030 Zik Saleeba (zik@zikzak.net) 05031 */ 05032 { 05033 int endian = 1; 05034 unsigned char *out_pos; 05035 int i; 05036 05037 if (*(char *)&endian == 1) { 05038 /* we're little-endian, which is native for GMOD floats */ 05039 fwrite ( &Val, sizeof(Val), 1, fileout ); 05040 } 05041 else { 05042 /* we're big-endian, flip `em */ 05043 out_pos = (unsigned char *)&Val; 05044 for ( i = sizeof(Val)-1; i >= 0; i-- ) { 05045 fputc(*(out_pos+i), fileout); 05046 } 05047 } 05048 } 05049 /******************************************************************************/ 05050 05051 void gmod_write_w16 ( unsigned short Val, FILE *fileout ) 05052 05053 /******************************************************************************/ 05054 05055 /* 05056 Purpose: 05057 05058 GMOD_WRITE_W16 writes a 16 bit word to a Golgotha GMOD file. 05059 05060 Modified: 05061 05062 13 September 2000 05063 05064 Author: 05065 05066 Zik Saleeba (zik@zikzak.net) 05067 */ 05068 { 05069 unsigned char OutByte[2]; 05070 05071 OutByte[0] = (unsigned char)(Val & 0xff); 05072 OutByte[1] = (unsigned char)(Val >> 8); 05073 05074 fwrite ( OutByte, sizeof(unsigned char), 2, fileout ); 05075 } 05076 /******************************************************************************/ 05077 05078 void gmod_write_w32 ( unsigned long Val, FILE *fileout ) 05079 05080 /******************************************************************************/ 05081 05082 /* 05083 Purpose: 05084 05085 GMOD_WRITE writes a 32 bit word to a Golgotha GMOD file. 05086 05087 Modified: 05088 05089 19 May 1999 05090 05091 Author: 05092 05093 Zik Saleeba (zik@zikzak.net) 05094 */ 05095 { 05096 unsigned char OutByte[4]; 05097 05098 OutByte[0] = (unsigned char)(Val & 0xff); 05099 OutByte[1] = (unsigned char)((Val >> 8) & 0xff); 05100 OutByte[2] = (unsigned char)((Val >> 16) & 0xff); 05101 OutByte[3] = (unsigned char)((Val >> 24) & 0xff); 05102 05103 fwrite ( OutByte, sizeof(unsigned char), 4, fileout ); 05104 } 05105 05106 /******************************************************************************/ 05107 05108 void hello ( void ) 05109 05110 /******************************************************************************/ 05111 /* 05112 Purpose: 05113 05114 HELLO prints an explanatory header message. 05115 05116 Modified: 05117 05118 04 July 2000 05119 05120 Author: 05121 05122 John Burkardt 05123 */ 05124 { 05125 printf ( "\n" ); 05126 printf ( "Hello: This is IVCON,\n" ); 05127 printf ( " for 3D graphics file conversion.\n" ); 05128 printf ( "\n" ); 05129 printf ( " \".3ds\" 3D Studio Max binary;\n" ); 05130 printf ( " \".ase\" 3D Studio Max ASCII export;\n" ); 05131 printf ( " \".byu\" Movie.BYU surface geometry;\n" ); 05132 printf ( " \".dxf\" DXF;\n" ); 05133 printf ( " \".gmod\" Golgotha model;\n" ); 05134 printf ( " \".hrc\" SoftImage hierarchy;\n" ); 05135 printf ( " \".iv\" SGI Open Inventor;\n" ); 05136 printf ( " \".obj\" WaveFront Advanced Visualizer;\n" ); 05137 printf ( " \".pov\" Persistence of Vision (output only);\n" ); 05138 printf ( " \".smf\" Michael Garland's format;\n" ); 05139 printf ( " \".stl\" ASCII StereoLithography;\n" ); 05140 printf ( " \".stla\" ASCII StereoLithography;\n" ); 05141 printf ( " \".stlb\" Binary StereoLithography;\n" ); 05142 printf ( " \".tec\" TECPLOT (output only);\n" ); 05143 printf ( " \".tri\" [Greg Hood ASCII triangle format];\n" ); 05144 printf ( " \".tria\" [Greg Hood ASCII triangle format];\n" ); 05145 printf ( " \".trib\" [Greg Hood binary triangle format];\n" ); 05146 printf ( " \".txt\" Text (output only);\n" ); 05147 printf ( " \".ucd\" AVS UCD file(output only);\n" ); 05148 printf ( " \".vla\" VLA;\n" ); 05149 printf ( " \".wrl\" VRML (Virtual Reality Modeling Language) (output only).\n" ); 05150 printf ( " \".xgl\" XML/OpenGL format (output only);\n" ); 05151 printf ( "\n" ); 05152 printf ( " Current limits include:\n" ); 05153 printf ( " %d faces;\n", FACE_MAX ); 05154 printf ( " %d line items;\n", LINES_MAX ); 05155 printf ( " %d points;\n", COR3_MAX ); 05156 printf ( " %d face order;\n", ORDER_MAX ); 05157 printf ( " %d materials;\n", MATERIAL_MAX); 05158 printf ( " %d textures.\n", TEXTURE_MAX ); 05159 printf ( "\n" ); 05160 printf ( " Last modification: 04 July 2000.\n" ); 05161 printf ( "\n" ); 05162 printf ( " Send problem reports to burkardt@psc.edu.\n" ); 05163 05164 return; 05165 } 05166 /******************************************************************************/ 05167 05168 void help ( void ) 05169 05170 /******************************************************************************/ 05171 05172 /* 05173 Purpose: 05174 05175 HELP prints a list of the interactive commands. 05176 05177 Modified: 05178 05179 26 May 1999 05180 05181 Author: 05182 05183 John Burkardt 05184 */ 05185 { 05186 printf ( "\n" ); 05187 printf ( "Commands:\n" ); 05188 printf ( "\n" ); 05189 printf ( "< file Read data from input file;\n" ); 05190 printf ( "<< file Append data in input file to current data;\n" ); 05191 printf ( "> file Write output file;\n" ); 05192 printf ( "B Switch the binary file byte-swapping mode;\n" ); 05193 printf ( "D Switch the debugging mode;\n" ); 05194 printf ( "F Print information about one face;\n" ); 05195 printf ( "H Print this help list;\n" ); 05196 printf ( "I Info, print out recent changes;\n" ); 05197 printf ( "LINES Convert face information to lines;\n" ); 05198 printf ( "N Recompute normal vectors;\n" ); 05199 printf ( "P Set LINE_PRUNE option.\n" ); 05200 printf ( "Q Quit;\n" ); 05201 printf ( "R Reverse the normal vectors.\n" ); 05202 printf ( "S Select face subset (NOT WORKING).\n" ); 05203 printf ( "T Transform the data.\n" ); 05204 printf ( "W Reverse the face node ordering.\n" ); 05205 05206 return; 05207 } 05208 /******************************************************************************/ 05209 05210 int hrc_read ( FILE *filein ) 05211 05212 /******************************************************************************/ 05213 05214 /* 05215 Purpose: 05216 05217 HRC_READ reads graphics information from a SoftImage HRC file. 05218 05219 Examples: 05220 05221 HRCH: Softimage 4D Creative Environment v3.00 05222 05223 05224 model 05225 { 05226 name "cube_10x10" 05227 scaling 1.000 1.000 1.000 05228 rotation 0.000 0.000 0.000 05229 translation 0.000 0.000 0.000 05230 05231 mesh 05232 { 05233 flag ( PROCESS ) 05234 discontinuity 60.000 05235 05236 vertices 8 05237 { 05238 [0] position -5.000 -5.000 -5.000 05239 [1] position -5.000 -5.000 5.000 05240 [2] position -5.000 5.000 -5.000 05241 [3] position -5.000 5.000 5.000 05242 [4] position 5.000 -5.000 -5.000 05243 [5] position 5.000 -5.000 5.000 05244 [6] position 5.000 5.000 -5.000 05245 [7] position 5.000 5.000 5.000 05246 } 05247 05248 polygons 6 05249 { 05250 [0] nodes 4 05251 { 05252 [0] vertex 0 05253 normal -1.000 0.000 0.000 05254 uvTexture 0.000 0.000 05255 vertexColor 255 178 178 178 05256 [1] vertex 1 05257 normal -1.000 0.000 0.000 05258 uvTexture 0.000 0.000 05259 vertexColor 255 178 178 178 05260 [2] vertex 3 05261 normal -1.000 0.000 0.000 05262 uvTexture 0.000 0.000 05263 vertexColor 255 178 178 178 05264 [3] vertex 2 05265 normal -1.000 0.000 0.000 05266 uvTexture 0.000 0.000 05267 vertexColor 255 178 178 178 05268 } 05269 material 0 05270 [1] nodes 4 05271 { 05272 [0] vertex 1 05273 normal 0.000 0.000 1.000 05274 uvTexture 0.000 0.000 05275 vertexColor 255 178 178 178 05276 [1] vertex 5 05277 05278 ...etc..... 05279 05280 [5] nodes 4 05281 { 05282 [0] vertex 2 05283 normal 0.000 1.000 0.000 05284 uvTexture 0.000 0.000 05285 vertexColor 255 178 178 178 05286 [1] vertex 3 05287 normal 0.000 1.000 0.000 05288 uvTexture 0.000 0.000 05289 vertexColor 255 178 178 178 05290 [2] vertex 7 05291 normal 0.000 1.000 0.000 05292 uvTexture 0.000 0.000 05293 vertexColor 255 178 178 178 05294 [3] vertex 6 05295 normal 0.000 1.000 0.000 05296 uvTexture 0.000 0.000 05297 vertexColor 255 178 178 178 05298 } 05299 material 0 05300 } 05301 05302 edges 12 05303 { 05304 [1] vertices 3 2 05305 [2] vertices 2 0 05306 [3] vertices 0 1 05307 [4] vertices 1 3 05308 [5] vertices 7 3 05309 [6] vertices 1 5 05310 [7] vertices 5 7 05311 [8] vertices 6 7 05312 [9] vertices 5 4 05313 [10] vertices 4 6 05314 [11] vertices 2 6 05315 [12] vertices 4 0 05316 } 05317 } 05318 05319 material [0] 05320 { 05321 name "kazoo" 05322 type PHONG 05323 ambient 0.0 1.0 0.0 05324 diffuse 1.0 0.0 0.0 05325 specular 0.0 0.0 1.0 05326 exponent 50.0 05327 reflectivity 0.0 05328 transparency 0.0 05329 refracIndex 1.0 05330 glow 0 05331 coc 0.0 05332 } 05333 05334 texture [0] 05335 { 05336 name "/usr/users/foss/HOUSE/PICTURES/mellon" 05337 glbname "t2d1" 05338 anim STATIC 05339 method XY 05340 repeat 1 1 05341 scaling 1.000 1.000 05342 offset 0.000 0.000 05343 pixelInterp 05344 effect INTENSITY 05345 blending 1.000 05346 ambient 0.977 05347 diffuse 1.000 05348 specular 0.966 05349 reflect 0.000 05350 transp 0.000 05351 roughness 0.000 05352 reflMap 1.000 05353 rotation 0.000 05354 txtsup_rot 0.000 0.000 0.000 05355 txtsup_trans 0.000 0.000 0.000 05356 txtsup_scal 1.000 1.000 1.000 05357 } 05358 } 05359 05360 Modified: 05361 05362 25 June 1999 05363 05364 Author: 05365 05366 John Burkardt 05367 */ 05368 { 05369 float b; 05370 int count; 05371 float g; 05372 int i; 05373 int icor3; 05374 int ivert; 05375 int iword; 05376 int jval; 05377 int level; 05378 char *next; 05379 int nlbrack; 05380 int nrbrack; 05381 int cor3_num_old; 05382 float r; 05383 float t; 05384 float temp[3]; 05385 int width; 05386 char word[LINE_MAX_LEN]; 05387 char word1[LINE_MAX_LEN]; 05388 char word2[LINE_MAX_LEN]; 05389 char wordm1[LINE_MAX_LEN]; 05390 float x; 05391 float y; 05392 float z; 05393 05394 level = 0; 05395 strcpy ( level_name[0], "Top" ); 05396 nlbrack = 0; 05397 nrbrack = 0; 05398 cor3_num_old = cor3_num; 05399 strcpy ( word, " " ); 05400 strcpy ( wordm1, " " ); 05401 /* 05402 Read a line of text from the file. 05403 */ 05404 for ( ;; ) { 05405 05406 if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) { 05407 break; 05408 } 05409 05410 text_num = text_num + 1; 05411 next = input; 05412 iword = 0; 05413 /* 05414 Read a word from the line. 05415 */ 05416 for ( ;; ) { 05417 05418 strcpy ( wordm1, word ); 05419 05420 count = sscanf ( next, "%s%n", word2, &width ); 05421 next = next + width; 05422 05423 if ( count <= 0 ) { 05424 break; 05425 } 05426 05427 strcpy ( word, word2 ); 05428 05429 iword = iword + 1; 05430 05431 if ( iword == 1 ) { 05432 strcpy ( word1, word ); 05433 } 05434 /* 05435 The first line of the file must be the header. 05436 */ 05437 if ( text_num == 1 ) { 05438 05439 if ( strcmp ( word1, "HRCH:" ) != 0 ) { 05440 printf ( "\n" ); 05441 printf ( "HRC_READ - Fatal error!\n" ); 05442 printf ( " The input file has a bad header.\n" ); 05443 return ERROR; 05444 } 05445 else { 05446 comment_num = comment_num + 1; 05447 } 05448 break; 05449 } 05450 /* 05451 If the word is a curly bracket, count it. 05452 */ 05453 if ( strcmp ( word, "{" ) == 0 ) { 05454 nlbrack = nlbrack + 1; 05455 level = nlbrack - nrbrack; 05456 strcpy ( level_name[level], wordm1 ); 05457 if ( debug ) { 05458 printf ( "New level: %s\n", level_name[level] ); 05459 } 05460 } 05461 else if ( strcmp ( word, "}" ) == 0 ) { 05462 nrbrack = nrbrack + 1; 05463 05464 if ( nlbrack < nrbrack ) { 05465 printf ( "\n" ); 05466 printf ( "HRC_READ - Fatal error!\n" ); 05467 printf ( " Extraneous right bracket on line %d.\n", text_num ); 05468 printf ( " Currently processing field %s\n.", level_name[level] ); 05469 return ERROR; 05470 } 05471 } 05472 /* 05473 CONTROLPOINTS 05474 */ 05475 if ( strcmp ( level_name[level], "controlpoints" ) == 0 ) { 05476 05477 if ( strcmp ( word, "{" ) == 0 ) { 05478 } 05479 else if ( strcmp ( word, "}" ) == 0 ) { 05480 05481 if ( line_num < LINES_MAX ) { 05482 line_dex[line_num] = -1; 05483 line_material[line_num] = 0; 05484 } 05485 line_num = line_num + 1; 05486 level = nlbrack - nrbrack; 05487 } 05488 else if ( word[0] == '[' ) { 05489 } 05490 else if ( strcmp ( word, "position" ) == 0 ) { 05491 05492 count = sscanf ( next, "%f%n", &x, &width ); 05493 next = next + width; 05494 05495 count = sscanf ( next, "%f%n", &y, &width ); 05496 next = next + width; 05497 05498 count = sscanf ( next, "%f%n", &z, &width ); 05499 next = next + width; 05500 05501 temp[0] = x; 05502 temp[1] = y; 05503 temp[2] = z; 05504 05505 if ( cor3_num < 1000 ) { 05506 icor3 = rcol_find ( cor3, 3, cor3_num, temp ); 05507 } 05508 else { 05509 icor3 = -1; 05510 } 05511 05512 if ( icor3 == -1 ) { 05513 05514 icor3 = cor3_num; 05515 if ( cor3_num < COR3_MAX ) { 05516 cor3[0][cor3_num] = x; 05517 cor3[1][cor3_num] = y; 05518 cor3[2][cor3_num] = z; 05519 } 05520 cor3_num = cor3_num + 1; 05521 05522 } 05523 else { 05524 dup_num = dup_num + 1; 05525 } 05526 05527 if ( line_num < LINES_MAX ) { 05528 line_dex[line_num] = icor3; 05529 line_material[line_num] = 0; 05530 } 05531 line_num = line_num + 1; 05532 } 05533 else { 05534 bad_num = bad_num + 1; 05535 printf ( "CONTROLPOINTS: Bad data %s\n", word ); 05536 return ERROR; 05537 } 05538 05539 } 05540 /* 05541 EDGES 05542 */ 05543 else if ( strcmp ( level_name[level], "edges" ) == 0 ) { 05544 05545 if ( strcmp( word, "{" ) == 0 ) { 05546 } 05547 else if ( strcmp ( word, "}" ) == 0 ) { 05548 level = nlbrack - nrbrack; 05549 } 05550 else if ( word[0] == '[' ) { 05551 } 05552 else if ( strcmp ( word, "vertices" ) == 0 ) { 05553 05554 count = sscanf ( next, "%d%n", &jval, &width ); 05555 next = next + width; 05556 05557 if ( line_num < LINES_MAX ) { 05558 line_dex[line_num] = jval + cor3_num_old; 05559 line_material[line_num] = 0; 05560 } 05561 line_num = line_num + 1; 05562 05563 count = sscanf ( next, "%d%n", &jval, &width ); 05564 next = next + width; 05565 05566 if ( line_num < LINES_MAX ) { 05567 line_dex[line_num] = jval + cor3_num_old; 05568 line_material[line_num] = 0; 05569 } 05570 line_num = line_num + 1; 05571 05572 if ( line_num < LINES_MAX ) { 05573 line_dex[line_num] = -1; 05574 line_material[line_num] = -1; 05575 } 05576 line_num = line_num + 1; 05577 05578 } 05579 else { 05580 bad_num = bad_num + 1; 05581 printf ( "EDGES: Bad data %s\n", word ); 05582 return ERROR; 05583 } 05584 05585 } 05586 /* 05587 MATERIAL 05588 */ 05589 else if ( strcmp ( level_name[level], "material" ) == 0 ) { 05590 05591 if ( strcmp ( word, "{" ) == 0 ) { 05592 material_num = material_num + 1; 05593 } 05594 else if ( strcmp ( word, "}" ) == 0 ) { 05595 level = nlbrack - nrbrack; 05596 } 05597 else if ( word[0] == '[' ) { 05598 } 05599 else if ( strcmp ( word, "ambient" ) == 0 ) { 05600 } 05601 else if ( strcmp ( word, "coc" ) == 0 ) { 05602 } 05603 else if ( strcmp ( word, "diffuse" ) == 0 ) { 05604 05605 count = sscanf ( next, "%f%n", &r, &width ); 05606 next = next + width; 05607 material_rgba[0][material_num-1] = r; 05608 05609 count = sscanf ( next, "%f%n", &g, &width ); 05610 next = next + width; 05611 material_rgba[0][material_num-1] = g; 05612 05613 count = sscanf ( next, "%f%n", &b, &width ); 05614 next = next + width; 05615 material_rgba[0][material_num-1] = b; 05616 05617 } 05618 else if ( strcmp ( word, "exponent" ) == 0 ) { 05619 } 05620 else if ( strcmp ( word, "glow" ) == 0 ) { 05621 } 05622 else if ( strcmp ( word, "name" ) == 0 ) { 05623 count = sscanf ( next, "%s%n", word, &width ); 05624 next = next + width; 05625 strcpy ( material_name[material_num-1], word ); 05626 } 05627 else if ( strcmp ( word, "reflectivity" ) == 0 ) { 05628 } 05629 else if ( strcmp ( word, "refracindex" ) == 0 ) { 05630 } 05631 else if ( strcmp ( word, "specular" ) == 0 ) { 05632 } 05633 else if ( strcmp ( word, "transparency" ) == 0 ) { 05634 count = sscanf ( next, "%f%n", &t, &width ); 05635 next = next + width; 05636 material_rgba[3][material_num-1] = 1.0 - t; 05637 } 05638 else if ( strcmp ( word, "type" ) == 0 ) { 05639 } 05640 else { 05641 bad_num = bad_num + 1; 05642 printf ( "MATERIAL: Bad data %s\n", word ); 05643 return ERROR; 05644 } 05645 } 05646 /* 05647 MESH 05648 */ 05649 else if ( strcmp ( level_name[level], "mesh" ) == 0 ) { 05650 05651 if ( strcmp ( word, "{" ) == 0 ) { 05652 } 05653 else if ( strcmp ( word, "}" ) == 0 ) { 05654 level = nlbrack - nrbrack; 05655 } 05656 else if ( strcmp ( word, "discontinuity" ) == 0 ) { 05657 break; 05658 } 05659 else if ( strcmp ( word, "edges" ) == 0 ) { 05660 break; 05661 } 05662 else if ( strcmp ( word, "flag" ) == 0 ) { 05663 break; 05664 } 05665 else if ( strcmp ( word, "polygons" ) == 0 ) { 05666 break; 05667 } 05668 else if ( strcmp ( word, "vertices" ) == 0 ) { 05669 break; 05670 } 05671 else { 05672 bad_num = bad_num + 1; 05673 printf ( "MESH: Bad data %s\n", word ); 05674 return ERROR; 05675 } 05676 05677 } 05678 /* 05679 MODEL 05680 */ 05681 else if ( strcmp ( level_name[level], "model" ) == 0 ) { 05682 05683 if ( strcmp ( word, "{" ) == 0 ) { 05684 } 05685 else if ( strcmp ( word, "}" ) == 0 ) { 05686 level = nlbrack - nrbrack; 05687 } 05688 else if ( strcmp ( word, "material" ) == 0 ) { 05689 break; 05690 } 05691 else if ( strcmp ( word, "mesh" ) == 0 ) { 05692 break; 05693 } 05694 else if ( strcmp ( word, "name" ) == 0 ) { 05695 break; 05696 } 05697 else if ( strcmp ( word, "patch" ) == 0 ) { 05698 break; 05699 } 05700 else if ( strcmp ( word, "rotation" ) == 0 ) { 05701 break; 05702 } 05703 else if ( strcmp ( word, "scaling" ) == 0 ) { 05704 break; 05705 } 05706 else if ( strcmp ( word, "spline" ) == 0 ) { 05707 break; 05708 } 05709 else if ( strcmp ( word, "translation" ) == 0 ) { 05710 break; 05711 } 05712 else { 05713 bad_num = bad_num + 1; 05714 printf ( "MODEL: Bad data %s\n", word ); 05715 return ERROR; 05716 } 05717 05718 } 05719 /* 05720 NODES 05721 */ 05722 else if ( strcmp ( level_name[level], "nodes" ) == 0 ) { 05723 05724 if ( strcmp ( word, "{" ) == 0 ) { 05725 ivert = 0; 05726 face_order[face_num] = 0; 05727 face_num = face_num + 1; 05728 } 05729 else if ( strcmp ( word, "}" ) == 0 ) { 05730 level = nlbrack - nrbrack; 05731 } 05732 else if ( word[0] == '[' ) { 05733 } 05734 else if ( strcmp ( word, "normal" ) == 0 ) { 05735 05736 count = sscanf ( next, "%f%n", &x, &width ); 05737 next = next + width; 05738 05739 count = sscanf ( next, "%f%n", &y, &width ); 05740 next = next + width; 05741 05742 count = sscanf ( next, "%f%n", &z, &width ); 05743 next = next + width; 05744 05745 if ( ivert < ORDER_MAX && face_num < FACE_MAX ) { 05746 vertex_normal[0][ivert-1][face_num-1] = x; 05747 vertex_normal[1][ivert-1][face_num-1] = y; 05748 vertex_normal[2][ivert-1][face_num-1] = z; 05749 } 05750 05751 } 05752 else if ( strcmp ( word, "uvTexture" ) == 0 ) { 05753 05754 count = sscanf ( next, "%f%n", &x, &width ); 05755 next = next + width; 05756 05757 count = sscanf ( next, "%f%n", &y, &width ); 05758 next = next + width; 05759 05760 if ( ivert < ORDER_MAX && face_num < FACE_MAX ) { 05761 vertex_tex_uv[0][ivert-1][face_num-1] = x; 05762 vertex_tex_uv[1][ivert-1][face_num-1] = y; 05763 } 05764 } 05765 else if ( strcmp ( word, "vertex" ) == 0 ) { 05766 05767 count = sscanf ( next, "%d%n", &jval, &width ); 05768 next = next + width; 05769 05770 if ( ivert < ORDER_MAX && face_num < FACE_MAX ) { 05771 face_order[face_num-1] = face_order[face_num-1] + 1; 05772 face[ivert][face_num-1] = jval; 05773 } 05774 ivert = ivert + 1; 05775 05776 } 05777 /* 05778 Right now, we don't do anything with the vertexColor information. 05779 */ 05780 else if ( strcmp ( word, "vertexColor" ) == 0 ) { 05781 05782 count = sscanf ( next, "%d%n", &jval, &width ); 05783 next = next + width; 05784 05785 count = sscanf ( next, "%d%n", &jval, &width ); 05786 next = next + width; 05787 05788 count = sscanf ( next, "%d%n", &jval, &width ); 05789 next = next + width; 05790 05791 count = sscanf ( next, "%d%n", &jval, &width ); 05792 next = next + width; 05793 } 05794 else { 05795 bad_num = bad_num + 1; 05796 printf ( "NODES: Bad data %s\n", word ); 05797 return ERROR; 05798 } 05799 05800 } 05801 /* 05802 PATCH 05803 I don't know what to do with this yet. 05804 */ 05805 else if ( strcmp ( level_name[level], "patch" ) == 0 ) { 05806 05807 if ( strcmp ( word, "{" ) == 0 ) { 05808 } 05809 else if ( strcmp ( word, "}" ) == 0 ) { 05810 level = nlbrack - nrbrack; 05811 } 05812 else if ( strcmp ( word, "approx_type" ) == 0 ) { 05813 } 05814 else if ( strcmp ( word, "controlpoints" ) == 0 ) { 05815 } 05816 else if ( strcmp ( word, "curv_u" ) == 0 ) { 05817 } 05818 else if ( strcmp ( word, "curv_v" ) == 0 ) { 05819 } 05820 else if ( strcmp ( word, "recmin" ) == 0 ) { 05821 } 05822 else if ( strcmp ( word, "recmax" ) == 0 ) { 05823 } 05824 else if ( strcmp ( word, "recursion" ) == 0 ) { 05825 } 05826 else if ( strcmp ( word, "spacial" ) == 0 ) { 05827 } 05828 else if ( strcmp ( word, "taggedpoints" ) == 0 ) { 05829 } 05830 else if ( strcmp ( word, "ucurve" ) == 0 ) { 05831 } 05832 else if ( strcmp ( word, "ustep" ) == 0 ) { 05833 } 05834 else if ( strcmp ( word, "utension" ) == 0 ) { 05835 } 05836 else if ( strcmp ( word, "utype" ) == 0 ) { 05837 } 05838 else if ( strcmp ( word, "vclose" ) == 0 ) { 05839 } 05840 else if ( strcmp ( word, "vcurve" ) == 0 ) { 05841 } 05842 else if ( strcmp ( word, "viewdep" ) == 0 ) { 05843 } 05844 else if ( strcmp ( word, "vpoint" ) == 0 ) { 05845 } 05846 else if ( strcmp ( word, "vstep" ) == 0 ) { 05847 } 05848 else if ( strcmp ( word, "vtension" ) == 0 ) { 05849 } 05850 else if ( strcmp ( word, "vtype" ) == 0 ) { 05851 } 05852 else { 05853 bad_num = bad_num + 1; 05854 printf ( "PATCH: Bad data %s\n", word ); 05855 return ERROR; 05856 } 05857 } 05858 /* 05859 POLYGONS 05860 */ 05861 else if ( strcmp ( level_name[level], "polygons" ) == 0 ) { 05862 05863 if ( strcmp ( word, "{" ) == 0 ) { 05864 } 05865 else if ( strcmp ( word, "}" ) == 0 ) { 05866 level = nlbrack - nrbrack; 05867 } 05868 else if ( word[0] == '[' ) { 05869 } 05870 else if ( strcmp ( word, "material" ) == 0 ) { 05871 05872 count = sscanf ( next, "%d%n", &jval, &width ); 05873 next = next + width; 05874 05875 for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) { 05876 vertex_material[ivert][face_num-1] = jval; 05877 } 05878 05879 } 05880 else if ( strcmp ( word, "nodes" ) == 0 ) { 05881 count = sscanf ( next, "%s%n", word2, &width ); 05882 next = next + width; 05883 } 05884 else { 05885 bad_num = bad_num + 1; 05886 printf ( "POLYGONS: Bad data %s\n", word ); 05887 return ERROR; 05888 } 05889 05890 } 05891 /* 05892 SPLINE 05893 */ 05894 else if ( strcmp ( level_name[level], "spline" ) == 0 ) { 05895 05896 if ( strcmp ( word, "{" ) == 0 ) { 05897 } 05898 else if ( strcmp ( word, "}" ) == 0 ) { 05899 level = nlbrack - nrbrack; 05900 } 05901 else if ( strcmp ( word, "controlpoints" ) == 0 ) { 05902 break; 05903 } 05904 /* 05905 WHY DON'T YOU READ IN THE OBJECT NAME HERE? 05906 */ 05907 else if ( strcmp ( word, "name" ) == 0 ) { 05908 break; 05909 } 05910 else if ( strcmp ( word, "nbKeys" ) == 0 ) { 05911 break; 05912 } 05913 else if ( strcmp ( word, "step" ) == 0 ) { 05914 break; 05915 } 05916 else if ( strcmp ( word, "tension" ) == 0 ) { 05917 break; 05918 } 05919 else if ( strcmp ( word, "type" ) == 0 ) { 05920 break; 05921 } 05922 else { 05923 bad_num = bad_num + 1; 05924 printf ( "SPLINE: Bad data %s\n", word ); 05925 return ERROR; 05926 } 05927 05928 } 05929 /* 05930 TAGGEDPOINTS 05931 */ 05932 else if ( strcmp ( level_name[level], "taggedpoints" ) == 0 ) { 05933 05934 if ( strcmp ( word, "{" ) == 0 ) { 05935 } 05936 else if ( strcmp ( word, "}" ) == 0 ) { 05937 level = nlbrack - nrbrack; 05938 } 05939 else if ( word[0] == '[' ) { 05940 } 05941 else if ( strcmp ( word, "tagged" ) == 0 ) { 05942 } 05943 else { 05944 bad_num = bad_num + 1; 05945 printf ( "TAGGEDPOINTS: Bad data %s\n", word ); 05946 return ERROR; 05947 } 05948 05949 } 05950 /* 05951 TEXTURE 05952 */ 05953 else if ( strcmp ( level_name[level], "texture" ) == 0 ) { 05954 05955 if ( strcmp ( word, "{" ) == 0 ) { 05956 texture_num = texture_num + 1; 05957 } 05958 else if ( strcmp ( word, "}" ) == 0 ) { 05959 level = nlbrack - nrbrack; 05960 } 05961 else if ( word[0] == '[' ) { 05962 } 05963 else if ( strcmp ( word, "ambient" ) == 0 ) { 05964 } 05965 else if ( strcmp ( word, "anim" ) == 0 ) { 05966 } 05967 else if ( strcmp ( word, "blending" ) == 0 ) { 05968 } 05969 else if ( strcmp ( word, "diffuse" ) == 0 ) { 05970 } 05971 else if ( strcmp ( word, "effect" ) == 0 ) { 05972 } 05973 else if ( strcmp ( word, "glbname" ) == 0 ) { 05974 } 05975 else if ( strcmp ( word, "method" ) == 0 ) { 05976 } 05977 else if ( strcmp ( word, "name" ) == 0 ) { 05978 count = sscanf ( next, "%s%n", word, &width ); 05979 next = next + width; 05980 strcpy ( texture_name[texture_num-1], word ); 05981 } 05982 else if ( strcmp ( word, "offset" ) == 0 ) { 05983 } 05984 else if ( strcmp ( word, "pixelinterp" ) == 0 ) { 05985 } 05986 else if ( strcmp ( word, "reflect" ) == 0 ) { 05987 } 05988 else if ( strcmp ( word, "reflmap" ) == 0 ) { 05989 } 05990 else if ( strcmp ( word, "repeat" ) == 0 ) { 05991 } 05992 else if ( strcmp ( word, "rotation" ) == 0 ) { 05993 } 05994 else if ( strcmp ( word, "roughness" ) == 0 ) { 05995 } 05996 else if ( strcmp ( word, "scaling" ) == 0 ) { 05997 } 05998 else if ( strcmp ( word, "specular" ) == 0 ) { 05999 } 06000 else if ( strcmp ( word, "transp" ) == 0 ) { 06001 } 06002 else if ( strcmp ( word, "txtsup_rot" ) == 0 ) { 06003 } 06004 else if ( strcmp ( word, "txtsup_scal" ) == 0 ) { 06005 } 06006 else if ( strcmp ( word, "txtsup_trans" ) == 0 ) { 06007 } 06008 else { 06009 bad_num = bad_num + 1; 06010 printf ( "TEXTURE: Bad data %s\n", word ); 06011 return ERROR; 06012 } 06013 } 06014 /* 06015 VERTICES 06016 */ 06017 else if ( strcmp ( level_name[level], "vertices" ) == 0 ) { 06018 06019 if ( strcmp ( word, "{" ) == 0 ) { 06020 } 06021 else if ( strcmp ( word, "}" ) == 0 ) { 06022 level = nlbrack - nrbrack; 06023 } 06024 else if ( word[0] == '[' ) { 06025 } 06026 else if ( strcmp ( word, "position" ) == 0 ) { 06027 06028 count = sscanf ( next, "%f%n", &x, &width ); 06029 next = next + width; 06030 06031 count = sscanf ( next, "%f%n", &y, &width ); 06032 next = next + width; 06033 06034 count = sscanf ( next, "%f%n", &z, &width ); 06035 next = next + width; 06036 06037 if ( cor3_num < COR3_MAX ) { 06038 cor3[0][cor3_num] = x; 06039 cor3[1][cor3_num] = y; 06040 cor3[2][cor3_num] = z; 06041 } 06042 cor3_num = cor3_num + 1; 06043 } 06044 else { 06045 bad_num = bad_num + 1; 06046 printf ( "VERTICES: Bad data %s\n", word ); 06047 return ERROR; 06048 } 06049 } 06050 /* 06051 Any other word: 06052 */ 06053 else { 06054 06055 } 06056 } 06057 } 06058 06059 /* 06060 End of information in file. 06061 06062 Check the "materials" defining a line. 06063 06064 If COORDINDEX is -1, so should be the MATERIALINDEX. 06065 If COORDINDEX is not -1, then the MATERIALINDEX shouldn"t be either. 06066 */ 06067 for ( i = 0; i < line_num; i++ ) { 06068 06069 if ( line_dex[i] == -1 ) { 06070 line_material[i] = -1; 06071 } 06072 else if ( line_material[i] == -1 ) { 06073 line_material[i] = 0; 06074 } 06075 06076 } 06077 return SUCCESS; 06078 } 06079 /******************************************************************************/ 06080 06081 int hrc_write ( FILE* fileout ) 06082 06083 /******************************************************************************/ 06084 06085 /* 06086 Purpose: 06087 06088 HRC_WRITE writes graphics data to an HRC SoftImage file. 06089 06090 Examples: 06091 06092 HRCH: Softimage 4D Creative Environment v3.00 06093 06094 06095 model 06096 { 06097 name "cube_10x10" 06098 scaling 1.000 1.000 1.000 06099 rotation 0.000 0.000 0.000 06100 translation 0.000 0.000 0.000 06101 06102 mesh 06103 { 06104 flag ( PROCESS ) 06105 discontinuity 60.000 06106 06107 vertices 8 06108 { 06109 [0] position -5.000 -5.000 -5.000 06110 [1] position -5.000 -5.000 5.000 06111 [2] position -5.000 5.000 -5.000 06112 [3] position -5.000 5.000 5.000 06113 [4] position 5.000 -5.000 -5.000 06114 [5] position 5.000 -5.000 5.000 06115 [6] position 5.000 5.000 -5.000 06116 [7] position 5.000 5.000 5.000 06117 } 06118 06119 polygons 6 06120 { 06121 [0] nodes 4 06122 { 06123 [0] vertex 0 06124 normal -1.000 0.000 0.000 06125 uvTexture 0.000 0.000 06126 vertexColor 255 178 178 178 06127 [1] vertex 1 06128 normal -1.000 0.000 0.000 06129 uvTexture 0.000 0.000 06130 vertexColor 255 178 178 178 06131 [2] vertex 3 06132 normal -1.000 0.000 0.000 06133 uvTexture 0.000 0.000 06134 vertexColor 255 178 178 178 06135 [3] vertex 2 06136 normal -1.000 0.000 0.000 06137 uvTexture 0.000 0.000 06138 vertexColor 255 178 178 178 06139 } 06140 material 0 06141 [1] nodes 4 06142 { 06143 [0] vertex 1 06144 normal 0.000 0.000 1.000 06145 uvTexture 0.000 0.000 06146 vertexColor 255 178 178 178 06147 [1] vertex 5 06148 06149 ...etc..... 06150 06151 [5] nodes 4 06152 { 06153 [0] vertex 2 06154 normal 0.000 1.000 0.000 06155 uvTexture 0.000 0.000 06156 vertexColor 255 178 178 178 06157 [1] vertex 3 06158 normal 0.000 1.000 0.000 06159 uvTexture 0.000 0.000 06160 vertexColor 255 178 178 178 06161 [2] vertex 7 06162 normal 0.000 1.000 0.000 06163 uvTexture 0.000 0.000 06164 vertexColor 255 178 178 178 06165 [3] vertex 6 06166 normal 0.000 1.000 0.000 06167 uvTexture 0.000 0.000 06168 vertexColor 255 178 178 178 06169 } 06170 material 0 06171 } 06172 06173 edges 12 06174 { 06175 [1] vertices 3 2 06176 [2] vertices 2 0 06177 [3] vertices 0 1 06178 [4] vertices 1 3 06179 [5] vertices 7 3 06180 [6] vertices 1 5 06181 [7] vertices 5 7 06182 [8] vertices 6 7 06183 [9] vertices 5 4 06184 [10] vertices 4 6 06185 [11] vertices 2 6 06186 [12] vertices 4 0 06187 } 06188 } 06189 06190 material [0] 06191 { 06192 name "kazoo" 06193 type PHONG 06194 ambient 0.0 1.0 0.0 06195 diffuse 1.0 0.0 0.0 06196 specular 0.0 0.0 1.0 06197 exponent 50.0 06198 reflectivity 0.0 06199 transparency 0.0 06200 refracIndex 1.0 06201 glow 0 06202 coc 0.0 06203 } 06204 06205 texture [0] 06206 { 06207 name "/usr/users/foss/HOUSE/PICTURES/mellon" 06208 glbname "t2d1" 06209 anim STATIC 06210 method XY 06211 repeat 1 1 06212 scaling 1.000 1.000 06213 offset 0.000 0.000 06214 pixelInterp 06215 effect INTENSITY 06216 blending 1.000 06217 ambient 0.977 06218 diffuse 1.000 06219 specular 0.966 06220 reflect 0.000 06221 transp 0.000 06222 roughness 0.000 06223 reflMap 1.000 06224 rotation 0.000 06225 txtsup_rot 0.000 0.000 0.000 06226 txtsup_trans 0.000 0.000 0.000 06227 txtsup_scal 1.000 1.000 1.000 06228 } 06229 } 06230 06231 Modified: 06232 06233 25 June 1998 06234 06235 Author: 06236 06237 John Burkardt 06238 06239 */ 06240 { 06241 int iface; 06242 int ivert; 06243 int j; 06244 int jhi; 06245 int jlo; 06246 int jrel; 06247 int k; 06248 int npts; 06249 int nseg; 06250 int text_num; 06251 06252 nseg = 0; 06253 text_num = 0; 06254 06255 fprintf ( fileout, "HRCH: Softimage 4D Creative Environment v3.00\n" ); 06256 fprintf ( fileout, "\n" ); 06257 fprintf ( fileout, "\n" ); 06258 text_num = text_num + 3; 06259 06260 fprintf ( fileout, "model\n" ); 06261 fprintf ( fileout, "{\n" ); 06262 fprintf ( fileout, " name \"%s\"\n", object_name ); 06263 fprintf ( fileout, " scaling 1.000 1.000 1.000\n" ); 06264 fprintf ( fileout, " rotation 0.000 0.000 0.000\n" ); 06265 fprintf ( fileout, " translation 0.000 0.000 0.000\n" ); 06266 text_num = text_num + 6; 06267 06268 if ( face_num > 0 ) { 06269 06270 fprintf ( fileout, "\n" ); 06271 fprintf ( fileout, " mesh\n" ); 06272 fprintf ( fileout, " {\n" ); 06273 fprintf ( fileout, " flag ( PROCESS )\n" ); 06274 fprintf ( fileout, " discontinuity 60.000\n" ); 06275 text_num = text_num + 5; 06276 /* 06277 Point coordinates. 06278 */ 06279 if ( cor3_num > 0 ) { 06280 06281 fprintf ( fileout, "\n" ); 06282 fprintf ( fileout, " vertices %d\n", cor3_num ); 06283 fprintf ( fileout, " {\n" ); 06284 text_num = text_num + 3; 06285 06286 for ( j = 0; j < cor3_num; j++ ) { 06287 06288 fprintf ( fileout, " [%d] position %f %f %f\n", j, cor3[0][j], 06289 cor3[1][j], cor3[2][j] ); 06290 text_num = text_num + 1; 06291 } 06292 fprintf ( fileout, " }\n" ); 06293 text_num = text_num + 1; 06294 } 06295 /* 06296 Faces. 06297 */ 06298 fprintf ( fileout, "\n" ); 06299 fprintf ( fileout, " polygons %d\n", face_num ); 06300 fprintf ( fileout, " {\n" ); 06301 text_num = text_num + 3; 06302 06303 for ( iface = 0; iface < face_num; iface++ ) { 06304 06305 fprintf ( fileout, " [%d] nodes %d\n", iface, face_order[iface] ); 06306 fprintf ( fileout, " {\n" ); 06307 text_num = text_num + 2; 06308 06309 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 06310 06311 fprintf ( fileout, " [%d] vertex %d\n", ivert, face[ivert][iface] ); 06312 fprintf ( fileout, " normal %f %f %f\n", 06313 vertex_normal[0][ivert][iface], 06314 vertex_normal[1][ivert][iface], vertex_normal[2][ivert][iface] ); 06315 fprintf ( fileout, " uvTexture %f %f\n", 06316 vertex_tex_uv[0][ivert][iface], vertex_tex_uv[1][ivert][iface] ); 06317 fprintf ( fileout, " vertexColor 255 178 178 178\n" ); 06318 text_num = text_num + 4; 06319 } 06320 fprintf ( fileout, " }\n" ); 06321 fprintf ( fileout, " material %d\n", face_material[iface] ); 06322 text_num = text_num + 2; 06323 } 06324 fprintf ( fileout, " }\n" ); 06325 fprintf ( fileout, " }\n" ); 06326 text_num = text_num + 2; 06327 } 06328 /* 06329 IndexedLineSet. 06330 */ 06331 if ( line_num > 0 ) { 06332 06333 nseg = 0; 06334 06335 jhi = -1; 06336 06337 for ( ;; ) { 06338 06339 jlo = jhi + 1; 06340 /* 06341 Look for the next index JLO that is not -1. 06342 */ 06343 while ( jlo < line_num ) { 06344 if ( line_dex[jlo] != -1 ) { 06345 break; 06346 } 06347 jlo = jlo + 1; 06348 } 06349 06350 if ( jlo >= line_num ) { 06351 break; 06352 } 06353 /* 06354 Look for the highest following index JHI that is not -1. 06355 */ 06356 jhi = jlo + 1; 06357 06358 while ( jhi < line_num ) { 06359 if ( line_dex[jhi] == -1 ) { 06360 break; 06361 } 06362 jhi = jhi + 1; 06363 } 06364 06365 jhi = jhi - 1; 06366 /* 06367 Our next line segment involves LINE_DEX indices JLO through JHI. 06368 */ 06369 nseg = nseg + 1; 06370 npts = jhi + 1 - jlo; 06371 06372 fprintf ( fileout, "\n" ); 06373 fprintf ( fileout, " spline\n" ); 06374 fprintf ( fileout, " {\n" ); 06375 fprintf ( fileout, " name \"spl%d\"\n", nseg ); 06376 fprintf ( fileout, " type LINEAR\n" ); 06377 fprintf ( fileout, " nbKeys %d\n", npts ); 06378 fprintf ( fileout, " tension 0.000\n" ); 06379 fprintf ( fileout, " step 1\n" ); 06380 fprintf ( fileout, "\n" ); 06381 text_num = text_num + 9; 06382 06383 fprintf ( fileout, " controlpoints\n" ); 06384 fprintf ( fileout, " {\n" ); 06385 text_num = text_num + 2; 06386 06387 for ( j = jlo; j <= jhi; j++ ) { 06388 jrel = j - jlo; 06389 k = line_dex[j]; 06390 fprintf ( fileout, " [%d] position %f %f %f\n", jrel, 06391 cor3[0][k], cor3[1][k], cor3[2][k] ); 06392 text_num = text_num + 1; 06393 } 06394 06395 fprintf ( fileout, " }\n" ); 06396 fprintf ( fileout, " }\n" ); 06397 text_num = text_num + 2; 06398 } 06399 } 06400 /* 06401 MATERIALS 06402 */ 06403 for ( i = 0; i < material_num; i++ ) { 06404 06405 fprintf ( fileout, " material [%d]\n", i ); 06406 fprintf ( fileout, " {\n" ); 06407 fprintf ( fileout, " name \"%s\"\n", material_name[i] ); 06408 fprintf ( fileout, " type PHONG\n" ); 06409 fprintf ( fileout, " ambient %f %f %f\n", material_rgba[0][i], 06410 material_rgba[1][i], material_rgba[2][i] ); 06411 fprintf ( fileout, " diffuse %f %f %f\n", material_rgba[0][i], 06412 material_rgba[1][i], material_rgba[2][i] ); 06413 fprintf ( fileout, " specular %f %f %f\n", material_rgba[0][i], 06414 material_rgba[1][i], material_rgba[2][i] ); 06415 fprintf ( fileout, " exponent 50.0\n" ); 06416 fprintf ( fileout, " reflectivity 0.0\n" ); 06417 fprintf ( fileout, " transparency %f\n", 1.0 - material_rgba[3][i] ); 06418 fprintf ( fileout, " refracIndex 1.0\n" ); 06419 fprintf ( fileout, " glow 0\n" ); 06420 fprintf ( fileout, " coc 0.0\n" ); 06421 fprintf ( fileout, " }\n" ); 06422 06423 text_num = text_num + 14; 06424 06425 } 06426 /* 06427 TEXTURES 06428 */ 06429 for ( i = 0; i < texture_num; i++ ) { 06430 06431 fprintf ( fileout, " texture [%d]\n", i ); 06432 fprintf ( fileout, " {\n" ); 06433 fprintf ( fileout, " name \"%s\"\n", texture_name[i] ); 06434 fprintf ( fileout, " glbname \"t2d1\"\n" ); 06435 fprintf ( fileout, " anim STATIC\n" ); 06436 fprintf ( fileout, " method XY\n" ); 06437 fprintf ( fileout, " repeat 1 1\n" ); 06438 fprintf ( fileout, " scaling 1.000 1.000\n" ); 06439 fprintf ( fileout, " offset 0.000 0.000\n" ); 06440 fprintf ( fileout, " pixelInterp\n" ); 06441 fprintf ( fileout, " effect INTENSITY\n" ); 06442 fprintf ( fileout, " blending 1.000\n" ); 06443 fprintf ( fileout, " ambient 0.977\n" ); 06444 fprintf ( fileout, " diffuse 1.000\n" ); 06445 fprintf ( fileout, " specular 0.966\n" ); 06446 fprintf ( fileout, " reflect 0.000\n" ); 06447 fprintf ( fileout, " transp 0.000\n" ); 06448 fprintf ( fileout, " roughness 0.000\n" ); 06449 fprintf ( fileout, " reflMap 1.000\n" ); 06450 fprintf ( fileout, " rotation 0.000\n" ); 06451 fprintf ( fileout, " txtsup_rot 0.000 0.000 0.000\n" ); 06452 fprintf ( fileout, " txtsup_trans 0.000 0.000 0.000\n" ); 06453 fprintf ( fileout, " txtsup_scal 1.000 1.000 1.000\n" ); 06454 fprintf ( fileout, " }\n" ); 06455 06456 text_num = text_num + 25; 06457 06458 } 06459 fprintf ( fileout, "}\n" ); 06460 text_num = text_num + 1; 06461 /* 06462 Report. 06463 */ 06464 printf ( "\n" ); 06465 printf ( "HRC_WRITE - Wrote %d text lines.\n", text_num ); 06466 06467 return SUCCESS; 06468 } 06469 /******************************************************************************/ 06470 06471 void init_program_data ( void ) 06472 06473 /******************************************************************************/ 06474 06475 /* 06476 Purpose: 06477 06478 INIT_PROGRAM_DATA initializes the internal program data. 06479 06480 Modified: 06481 06482 26 May 1999 06483 06484 Author: 06485 06486 John Burkardt 06487 */ 06488 { 06489 byte_swap = FALSE; 06490 debug = 0; 06491 line_prune = 1; 06492 color_num = 0; 06493 cor3_num = 0; 06494 face_num = 0; 06495 line_num = 0; 06496 06497 if ( debug ) { 06498 printf ( "\n" ); 06499 printf ( "INIT_PROGRAM_DATA: Program data initialized.\n" ); 06500 } 06501 06502 return; 06503 06504 } 06505 /******************************************************************************/ 06506 06507 int interact ( void ) 06508 06509 /******************************************************************************/ 06510 06511 /* 06512 Purpose: 06513 06514 INTERACT carries on an interactive session with the user. 06515 06516 Modified: 06517 06518 22 May 1999 06519 06520 Author: 06521 06522 John Burkardt 06523 */ 06524 { 06525 int i; 06526 int icor3; 06527 int ierror; 06528 int iface; 06529 int itemp; 06530 int ivert; 06531 int j; 06532 int jvert; 06533 int m; 06534 char *next; 06535 float temp; 06536 float x; 06537 float y; 06538 float z; 06539 06540 strcpy ( filein_name, "NO_IN_NAME" ); 06541 strcpy ( fileout_name, "NO_OUT_NAME" ); 06542 06543 /* 06544 Say hello. 06545 */ 06546 hello ( ); 06547 /* 06548 Get the next user command. 06549 */ 06550 printf ( "\n" ); 06551 printf ( "Enter command (H for help)\n" ); 06552 06553 while ( fgets ( input, LINE_MAX_LEN, stdin ) != NULL ) { 06554 /* 06555 Advance to the first nonspace character in INPUT. 06556 */ 06557 for ( next = input; *next != '\0' && isspace(*next); next++ ) { 06558 } 06559 /* 06560 Skip blank lines and comments. 06561 */ 06562 if ( *next == '\0' ) { 06563 continue; 06564 } 06565 /* 06566 Command: << FILENAME 06567 Append new data to current graphics information. 06568 */ 06569 if ( *next == '<' && *(next+1) == '<' ) { 06570 06571 next = next + 2; 06572 sscanf ( next, "%s", filein_name ); 06573 06574 ierror = data_read ( ); 06575 06576 if ( ierror == ERROR ) { 06577 printf ( "\n" ); 06578 printf ( "INTERACT - Fatal error!\n" ); 06579 printf ( " DATA_READ failed to read input data.\n" ); 06580 } 06581 } 06582 /* 06583 Command: < FILENAME 06584 */ 06585 else if ( *next == '<' ) { 06586 06587 next = next + 1; 06588 sscanf ( next, "%s", filein_name ); 06589 06590 data_init ( ); 06591 06592 ierror = data_read ( ); 06593 06594 if ( ierror == ERROR ) { 06595 printf ( "\n" ); 06596 printf ( "INTERACT - Fatal error!\n" ); 06597 printf ( " DATA_READ failed to read input data.\n" ); 06598 } 06599 } 06600 /* 06601 Command: > FILENAME 06602 */ 06603 else if ( *next == '>' ) { 06604 06605 next = next + 1; 06606 sscanf ( next, "%s", fileout_name ); 06607 06608 ierror = data_write ( ); 06609 06610 if ( ierror == ERROR ) { 06611 printf ( "\n" ); 06612 printf ( "INTERACT - Fatal error!\n" ); 06613 printf ( " OUTPUT_DATA failed to write output data.\n" ); 06614 } 06615 06616 } 06617 /* 06618 B: Switch byte swapping option. 06619 */ 06620 else if ( *next == 'B' || *next == 'b' ) { 06621 06622 if ( byte_swap == TRUE ) { 06623 byte_swap = FALSE; 06624 printf ( "Byte_swapping reset to FALSE.\n" ); 06625 } 06626 else { 06627 byte_swap = TRUE; 06628 printf ( "Byte_swapping reset to TRUE.\n" ); 06629 } 06630 06631 } 06632 /* 06633 D: Switch debug option. 06634 */ 06635 else if ( *next == 'D' || *next == 'd' ) { 06636 if ( debug ) { 06637 debug = 0; 06638 printf ( "Debug reset to FALSE.\n" ); 06639 } 06640 else { 06641 debug = 1; 06642 printf ( "Debug reset to TRUE.\n" ); 06643 } 06644 } 06645 /* 06646 F: Check a face. 06647 */ 06648 else if ( *next == 'f' || *next == 'F' ) { 06649 printf ( "\n" ); 06650 printf ( " Enter a face index between 0 and %d:", face_num-1 ); 06651 scanf ( "%d", &iface ); 06652 face_print ( iface ); 06653 } 06654 /* 06655 H: Help 06656 */ 06657 else if ( *next == 'h' || *next == 'H' ) { 06658 help ( ); 06659 } 06660 /* 06661 I: Print change information. 06662 */ 06663 else if ( *next == 'i' || *next == 'I') { 06664 news ( ); 06665 } 06666 /* 06667 LINES: 06668 Convert face information to lines. 06669 */ 06670 else if ( *next == 'l' || *next == 'L') { 06671 06672 if ( face_num > 0 ) { 06673 06674 printf ( "\n" ); 06675 printf ( "INTERACT - Note:\n" ); 06676 printf ( " Face information will be converted\n" ); 06677 printf ( " to line information.\n" ); 06678 06679 face_to_line ( ); 06680 06681 if ( line_num > LINES_MAX ) { 06682 06683 printf ( "\n" ); 06684 printf ( "INTERACT - Note:\n" ); 06685 printf ( " Some face information was lost.\n" ); 06686 printf ( " The maximum number of lines is %d,\n", LINES_MAX ); 06687 printf ( " but we would need at least %d.\n", line_num ); 06688 06689 line_num = LINES_MAX; 06690 06691 } 06692 06693 face_num = 0; 06694 } 06695 else { 06696 06697 printf ( "\n" ); 06698 printf ( "INTERACT - Note:\n" ); 06699 printf ( " There were no faces to convert.\n" ); 06700 06701 } 06702 06703 } 06704 /* 06705 N: Recompute normal vectors. 06706 */ 06707 else if ( *next == 'n' || *next == 'N') { 06708 06709 for ( iface = 0; iface < face_num; iface++ ) { 06710 for ( i = 0; i < 3; i++ ) { 06711 face_normal[i][iface] = 0.0; 06712 } 06713 } 06714 06715 for ( iface = 0; iface < face_num; iface++ ) { 06716 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 06717 for ( i = 0; i < 3; i++ ) { 06718 vertex_normal[i][ivert][iface] = 0.0; 06719 } 06720 } 06721 } 06722 06723 vertex_normal_set ( ); 06724 06725 cor3_normal_set ( ); 06726 06727 face_normal_ave ( ); 06728 } 06729 /* 06730 P: Line pruning optiont 06731 */ 06732 else if ( *next == 'p' || *next == 'P' ) { 06733 06734 printf ( "\n" ); 06735 printf ( "INTERACT - SET LINE PRUNING OPTION.\n" ); 06736 printf ( "\n" ); 06737 printf ( " LINE_PRUNE = 0 means no line pruning.\n" ); 06738 printf ( " nonzero means line pruning.\n" ); 06739 printf ( "\n" ); 06740 printf ( " Current value is LINE_PRUNE = %d.\n", line_prune ); 06741 printf ( "\n" ); 06742 printf ( " Enter new value for LINE_PRUNE.\n" ); 06743 06744 if ( fgets ( input, LINE_MAX_LEN, stdin ) == NULL ) { 06745 printf ( " ??? Error trying to read input.\n" ); 06746 } 06747 else { 06748 sscanf ( input, "%d", &line_prune ); 06749 printf ( " New value is LINE_PRUNE = %d.\n", line_prune ); 06750 } 06751 } 06752 /* 06753 Q: Quit 06754 */ 06755 else if ( *next == 'q' || *next == 'Q' ) { 06756 printf ( "\n" ); 06757 printf ( "INTERACT - Normal end of execution.\n" ); 06758 return SUCCESS; 06759 } 06760 /* 06761 R: Reverse normal vectors. 06762 */ 06763 else if ( *next == 'r' || *next == 'R' ) { 06764 06765 for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { 06766 for ( i = 0; i < 3; i++ ) { 06767 cor3_normal[i][icor3] = - cor3_normal[i][icor3]; 06768 } 06769 } 06770 06771 for ( iface = 0; iface < face_num; iface++ ) { 06772 for ( i = 0; i < 3; i++ ) { 06773 face_normal[i][iface] = - face_normal[i][iface]; 06774 } 06775 } 06776 06777 for ( iface = 0; iface < face_num; iface++ ) { 06778 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 06779 for ( i = 0; i < 3; i++ ) { 06780 vertex_normal[i][ivert][iface] = 06781 - vertex_normal[i][ivert][iface]; 06782 } 06783 } 06784 } 06785 printf ( "\n" ); 06786 printf ( "INTERACT - Note:\n" ); 06787 printf ( " Reversed node, face and vertex normals.\n" ); 06788 } 06789 /* 06790 S: Select a few faces, discard the rest. 06791 */ 06792 else if ( *next == 's' || *next == 'S' ) { 06793 face_subset ( ); 06794 } 06795 /* 06796 T: Transform the data. 06797 */ 06798 else if ( *next == 't' || *next == 'T' ) { 06799 06800 printf ( "\n" ); 06801 printf ( "For now, we only offer point scaling.\n" ); 06802 printf ( "Enter X, Y, Z scale factors:\n" ); 06803 06804 scanf ( "%f %f %f", &x, &y, &z ); 06805 06806 for ( j = 0; j < cor3_num; j++ ) { 06807 cor3[0][j] = x * cor3[0][j]; 06808 cor3[1][j] = y * cor3[1][j]; 06809 cor3[2][j] = z * cor3[2][j]; 06810 } 06811 06812 for ( iface = 0; iface < face_num; iface++ ) { 06813 for ( i = 0; i < 3; i++ ) { 06814 face_normal[i][iface] = 0.0; 06815 } 06816 } 06817 06818 for ( iface = 0; iface < face_num; iface++ ) { 06819 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 06820 for ( i = 0; i < 3; i++ ) { 06821 vertex_normal[i][ivert][iface] = 0.0; 06822 } 06823 } 06824 } 06825 06826 vertex_normal_set ( ); 06827 06828 cor3_normal_set ( ); 06829 06830 face_normal_ave ( ); 06831 } 06832 /* 06833 U: Renumber faces, count objects: 06834 */ 06835 else if ( *next == 'u' || *next == 'U' ) { 06836 } 06837 /* 06838 V: Convert polygons to triangles: 06839 */ 06840 else if ( *next == 'v' || *next == 'V' ) { 06841 } 06842 /* 06843 W: Reverse the face node ordering. 06844 */ 06845 else if ( *next == 'w' || *next == 'W' ) { 06846 06847 if ( face_num > 0 ) { 06848 06849 for ( iface = 0; iface < face_num; iface++ ) { 06850 06851 m = face_order[iface]; 06852 06853 for ( ivert = 0; ivert < m/2; ivert++ ) { 06854 06855 jvert = m - ivert - 1; 06856 06857 itemp = face[ivert][iface]; 06858 face[ivert][iface] = face[jvert][iface]; 06859 face[jvert][iface] = itemp; 06860 06861 itemp = vertex_material[ivert][iface]; 06862 vertex_material[ivert][iface] = vertex_material[jvert][iface]; 06863 vertex_material[jvert][iface] = itemp; 06864 06865 for ( i = 0; i < 3; i++ ) { 06866 temp = vertex_normal[i][ivert][iface]; 06867 vertex_normal[i][ivert][iface] = 06868 vertex_normal[i][jvert][iface]; 06869 vertex_normal[i][jvert][iface] = temp; 06870 } 06871 } 06872 } 06873 printf ( "\n" ); 06874 printf ( "INTERACT - Note:\n" ); 06875 printf ( " Reversed face node ordering.\n" ); 06876 } 06877 } 06878 /* 06879 Command: ??? 06880 */ 06881 else { 06882 printf ( "\n" ); 06883 printf ( "INTERACT: Warning!\n" ); 06884 printf ( " Your command was not recognized.\n" ); 06885 } 06886 06887 printf ( "\n" ); 06888 printf ( "Enter command (H for help)\n" ); 06889 06890 } 06891 return SUCCESS; 06892 } 06893 /******************************************************************************/ 06894 06895 int iv_read ( FILE *filein ) 06896 06897 /******************************************************************************/ 06898 06899 /* 06900 Purpose: 06901 06902 IV_READ reads graphics information from an Inventor file. 06903 06904 Example: 06905 06906 #Inventor V2.0 ascii 06907 06908 Separator { 06909 Info { 06910 string "Inventor file generated by IVCON. 06911 Original data in file cube.iv." 06912 } 06913 Separator { 06914 LightModel { 06915 model PHONG 06916 } 06917 MatrixTransform { matrix 06918 0.9 0.0 0.0 0.0 06919 0.0 -0.9 0.0 0.0 06920 0.0 0.0 -1.5 0.0 06921 0.0 0.0 0.0 1.0 06922 } 06923 Material { 06924 ambientColor 0.2 0.2 0.2 06925 diffuseColor [ 06926 0.8 0.8 0.8, 06927 0.7 0.1 0.1, 06928 0.1 0.8 0.2, 06929 ] 06930 emissiveColor 0.0 0.0 0.0 06931 specularColor 0.0 0.0 0.0 06932 shininess 0.2 06933 transparency [ 06934 0.0, 0.5, 1.0, 06935 ] 06936 } 06937 Texture2 { 06938 filename "fred.rgb" 06939 wrapS REPEAT 06940 wrapT REPEAT 06941 model MODULATE 06942 blendColor 0.0 0.0 0.0 06943 } 06944 06945 MaterialBinding { 06946 value PER_VERTEX_INDEXED 06947 } 06948 NormalBinding { 06949 value PER_VERTEX_INDEXED 06950 } 06951 TextureCoordinateBinding { 06952 value PER_VERTEX_INDEXED 06953 } 06954 06955 ShapeHints { 06956 vertexOrdering COUNTERCLOCKWISE 06957 shapeType UNKNOWN_SHAPE_TYPE 06958 faceType CONVEX 06959 creaseAngle 6.28319 06960 } 06961 06962 Coordinate3 { 06963 point [ 06964 8.59816 5.55317 -3.05561, 06965 8.59816 2.49756 0.000000E+00, 06966 ...etc... 06967 2.48695 2.49756 -3.05561, 06968 ] 06969 } 06970 06971 Normal { 06972 vector [ 06973 0.71 0.71 0.0, 06974 ...etc... 06975 0.32 0.32 0.41, 06976 ] 06977 } 06978 06979 TextureCoordinate2 { 06980 point [ 06981 0.0 1.0, 06982 0.1, 0.8, 06983 ...etc... 06984 0.4 0.7, 06985 ] 06986 } 06987 06988 IndexedLineSet { 06989 coordIndex [ 06990 0, 1, 2, -1, 06991 3, 4, 5, -1, 06992 7, 8, 9, -1, 06993 ...etc... 06994 189, 190, 191, -1, 06995 ] 06996 materialIndex [ 06997 0, 0, 0, -1, 06998 1, 1, 1, -1, 06999 2, 2, 2, -1, 07000 ...etc... 07001 64, 64, 64, -1, 07002 ] 07003 } 07004 07005 IndexedFaceSet { 07006 coordIndex [ 07007 0, 1, 2, -1, 07008 3, 4, 5, -1, 07009 7, 8, 9, -1, 07010 ...etc... 07011 189, 190, 191, -1, 07012 ] 07013 materialIndex [ 07014 0, 0, 0, -1, 07015 1, 1, 1, -1, 07016 2, 2, 2, -1, 07017 ...etc... 07018 64, 64, 64, -1, 07019 ] 07020 normalIndex [ 07021 0, 0, 0, -1, 07022 1, 1, 1, -1, 07023 2, 2, 2, -1, 07024 ...etc... 07025 64, 64, 64, -1, 07026 ] 07027 textureCoordIndex [ 07028 0, 0, 0, -1, 07029 1, 1, 1, -1, 07030 2, 2, 2, -1, 07031 ...etc... 07032 64, 64, 64, -1, 07033 ] 07034 } 07035 07036 IndexedTriangleStripSet { 07037 vertexProperty VertexProperty { 07038 vertex [ x y z, 07039 ... 07040 x y z ] 07041 normal [ x y z, 07042 ... 07043 x y z ] 07044 materialBinding OVERALL 07045 normalBinding PER_VERTEX_INDEXED 07046 } 07047 coordIndex [ 07048 i, j, k, l, m, -1, 07049 n, o, p, q, r, s, t, u, -1, 07050 v, w, x, -1 07051 ..., -1 ] 07052 normalIndex -1 07053 } 07054 07055 } 07056 } 07057 07058 Modified: 07059 07060 01 July 1999 07061 07062 Author: 07063 07064 John Burkardt 07065 */ 07066 { 07067 char c; 07068 int count; 07069 int i; 07070 int icol; 07071 int icolor; 07072 int icface; 07073 int inormface; 07074 int iface_num; 07075 int irow; 07076 int iuv; 07077 int ivert; 07078 int iword; 07079 int ix; 07080 int ixyz; 07081 int iy; 07082 int iz; 07083 int j; 07084 int jval; 07085 int level; 07086 char *next; 07087 int nlbrack; 07088 int nrbrack; 07089 int nu; 07090 int null_index; 07091 int cor3_num_old; 07092 int line_num2; 07093 int face_num2; 07094 int normal_num_temp; 07095 int text_numure_temp; 07096 int nv; 07097 int result; 07098 float rval; 07099 int width; 07100 char word[LINE_MAX_LEN]; 07101 char word1[LINE_MAX_LEN]; 07102 char wordm1[LINE_MAX_LEN]; 07103 float xvec[3]; 07104 07105 icface = 0; 07106 icol = -1; 07107 inormface = 0; 07108 iface_num = face_num; 07109 irow = 0; 07110 ix = 0; 07111 ixyz = 0; 07112 iy = 0; 07113 iz = 0; 07114 jval = 0; 07115 level = 0; 07116 strcpy ( level_name[0], "Top" ); 07117 nlbrack = 0; 07118 nrbrack = 0; 07119 nu = 0; 07120 cor3_num_old = cor3_num; 07121 face_num2 = face_num; 07122 line_num2 = line_num; 07123 normal_num_temp = 0; 07124 text_numure_temp = 0; 07125 nv = 0; 07126 rval = 0.0; 07127 strcpy ( word, " " ); 07128 strcpy ( wordm1, " " ); 07129 /* 07130 Read the next line of text from the input file. 07131 */ 07132 for ( ;; ) { 07133 07134 if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) { 07135 break; 07136 } 07137 07138 text_num = text_num + 1; 07139 next = input; 07140 iword = 0; 07141 /* 07142 Remove all commas from the line, so we can use SSCANF to read 07143 numeric items. 07144 */ 07145 i = 0; 07146 while ( input[i] != '\0' ) { 07147 if ( input[i] == ',' ) { 07148 input[i] = ' '; 07149 } 07150 i++; 07151 } 07152 /* 07153 Force brackets and braces to be buffered by spaces. 07154 */ 07155 i = 0; 07156 while ( input[i] != '\0' ) { 07157 i++; 07158 } 07159 null_index = i; 07160 07161 i = 0; 07162 while ( input[i] != '\0' && i < LINE_MAX_LEN ) { 07163 07164 if ( input[i] == '[' || input[i] == ']' || 07165 input[i] == '{' || input[i] == '}' ) { 07166 07167 result = char_pad ( &i, &null_index, input, LINE_MAX_LEN ); 07168 if ( result == ERROR ) { 07169 break; 07170 } 07171 } 07172 else { 07173 i++; 07174 } 07175 } 07176 /* 07177 Read a word from the line. 07178 */ 07179 for ( ;; ) { 07180 07181 strcpy ( wordm1, word ); 07182 strcpy ( word, " " ); 07183 07184 count = sscanf ( next, "%s%n", word, &width ); 07185 next = next + width; 07186 07187 if ( count <= 0 ) { 07188 break; 07189 } 07190 07191 iword = iword + 1; 07192 07193 if ( iword == 1 ) { 07194 strcpy ( word1, word ); 07195 } 07196 /* 07197 The first line of the file must be the header. 07198 */ 07199 if ( text_num == 1 ) { 07200 07201 if ( leqi ( word1, "#Inventor" ) != TRUE ) { 07202 printf ( "\n" ); 07203 printf ( "IV_READ - Fatal error!\n" ); 07204 printf ( " The input file has a bad header.\n" ); 07205 return ERROR; 07206 } 07207 else { 07208 comment_num = comment_num + 1; 07209 } 07210 break; 07211 } 07212 /* 07213 A comment begins anywhere with '#'. 07214 Skip the rest of the line. 07215 */ 07216 if ( word[1] == '#' ) { 07217 comment_num = comment_num + 1; 07218 break; 07219 } 07220 /* 07221 If the word is a curly or square bracket, count it. 07222 If the word is a left bracket, the previous word is the name of a node. 07223 */ 07224 if ( strcmp ( word, "{" ) == 0 || strcmp ( word, "[" ) == 0 ) { 07225 nlbrack = nlbrack + 1; 07226 level = nlbrack - nrbrack; 07227 strcpy ( level_name[level], wordm1 ); 07228 if ( debug ) { 07229 printf ( "Begin level: %s\n", wordm1 ); 07230 } 07231 } 07232 else if ( strcmp ( word, "}" ) == 0 || strcmp ( word, "]" ) == 0 ) { 07233 nrbrack = nrbrack + 1; 07234 07235 if ( nlbrack < nrbrack ) { 07236 printf ( "\n" ); 07237 printf ( "IV_READ - Fatal error!\n" ); 07238 printf ( " Extraneous right bracket on line %d.\n", text_num ); 07239 printf ( " Currently processing field %s\n.", level_name[level] ); 07240 return ERROR; 07241 } 07242 } 07243 /* 07244 BASECOLOR 07245 */ 07246 if ( leqi ( level_name[level], "BASECOLOR" ) == TRUE ) { 07247 07248 if ( strcmp ( word, "{" ) == 0 ) { 07249 } 07250 else if ( strcmp ( word, "}" ) == 0 ) { 07251 level = nlbrack - nrbrack; 07252 } 07253 else if ( leqi ( word, "RGB" ) == TRUE ) { 07254 } 07255 else { 07256 bad_num = bad_num + 1; 07257 printf ( "Bad data %s\n", word ); 07258 } 07259 } 07260 /* 07261 COORDINATE3 07262 */ 07263 else if ( leqi ( level_name[level], "COORDINATE3" ) == TRUE ) { 07264 07265 if ( strcmp ( word, "{" ) == 0 ) { 07266 } 07267 else if ( strcmp ( word, "}" ) == 0 ) { 07268 level = nlbrack - nrbrack; 07269 } 07270 else if ( leqi ( word, "POINT" ) == TRUE ) { 07271 } 07272 else { 07273 bad_num = bad_num + 1; 07274 printf ( "COORDINATE3: Bad data %s\n", word ); 07275 } 07276 } 07277 /* 07278 COORDINATE4 07279 */ 07280 else if ( leqi ( level_name[level], "COORDINATE4" ) == TRUE ) { 07281 07282 if ( strcmp ( word, "{" ) == 0 ) { 07283 } 07284 else if ( strcmp ( word, "}" ) == 0 ) { 07285 level = nlbrack - nrbrack; 07286 } 07287 else if ( leqi ( word, "POINT" ) == TRUE ) { 07288 } 07289 else { 07290 bad_num = bad_num + 1; 07291 printf ( "COORDINATE4: Bad data %s\n", word ); 07292 } 07293 } 07294 /* 07295 COORDINDEX 07296 */ 07297 else if ( leqi ( level_name[level], "COORDINDEX" ) == TRUE ) { 07298 07299 if ( strcmp ( word, "[" ) == 0 ) { 07300 ivert = 0; 07301 } 07302 else if ( strcmp ( word, "]" ) == 0 ) { 07303 level = nlbrack - nrbrack; 07304 } 07305 /* 07306 (indexedlineset) COORDINDEX 07307 */ 07308 else if ( leqi ( level_name[level-1], "INDEXEDLINESET" ) == TRUE ) { 07309 07310 count = sscanf ( word, "%d%n", &jval, &width ); 07311 07312 if ( count > 0 ) { 07313 07314 if ( jval < -1 ) { 07315 bad_num = bad_num + 1; 07316 } 07317 else { 07318 if ( line_num < LINES_MAX ) { 07319 if ( jval != -1 ) { 07320 jval = jval + cor3_num_old; 07321 } 07322 line_dex[line_num] = jval; 07323 } 07324 line_num = line_num + 1; 07325 } 07326 } 07327 else { 07328 bad_num = bad_num + 1; 07329 } 07330 } 07331 /* 07332 (indexedfaceset) COORDINDEX 07333 Warning: If the list of indices is not terminated with a final -1, then 07334 the last face won't get counted. 07335 */ 07336 else if ( leqi ( level_name[level-1], "INDEXEDFACESET" ) == TRUE ) { 07337 07338 count = sscanf ( word, "%d%n", &jval, &width ); 07339 07340 if ( count > 0 ) { 07341 if ( jval == -1 ) { 07342 ivert = 0; 07343 face_num = face_num + 1; 07344 } 07345 else { 07346 if ( ivert == 0 ) { 07347 if ( face_num < FACE_MAX ) { 07348 face_order[face_num] = 0; 07349 } 07350 } 07351 if ( face_num < FACE_MAX ) { 07352 face_order[face_num] = face_order[face_num] + 1; 07353 face[ivert][face_num] = jval + cor3_num_old; 07354 ivert = ivert + 1; 07355 } 07356 } 07357 } 07358 } 07359 /* 07360 (indexednurbssurface) COORDINDEX 07361 */ 07362 else if ( leqi ( level_name[level-1], "INDEXEDNURBSSURFACE" ) == TRUE ) { 07363 } 07364 /* 07365 (indexedtrianglestripset) COORDINDEX 07366 07367 First three coordinate indices I1, I2, I3 define a triangle. 07368 Next triangle is defined by I2, I3, I4 (actually, I4, I3, I2 07369 to stay with same counterclockwise sense). 07370 Next triangle is defined by I3, I4, I5 ( do not need to reverse 07371 odd numbered triangles) and so on. 07372 List is terminated with -1. 07373 */ 07374 else if ( leqi ( level_name[level-1], "INDEXEDTRIANGLESTRIPSET" ) == TRUE ) { 07375 07376 count = sscanf ( word, "%d%n", &jval, &width ); 07377 07378 if ( count > 0 ) { 07379 07380 if ( jval == -1 ) { 07381 ivert = 0; 07382 } 07383 else { 07384 07385 ix = iy; 07386 iy = iz; 07387 iz = jval + cor3_num_old; 07388 07389 if ( ivert == 0 ) { 07390 if ( face_num < FACE_MAX ) { 07391 face[ivert][face_num] = jval + cor3_num_old; 07392 face_order[face_num] = 3; 07393 } 07394 } 07395 else if ( ivert == 1 ) { 07396 if ( face_num < FACE_MAX ) { 07397 face[ivert][face_num] = jval + cor3_num_old; 07398 } 07399 } 07400 else if ( ivert == 2 ) { 07401 if ( face_num < FACE_MAX ) { 07402 face[ivert][face_num] = jval + cor3_num_old; 07403 } 07404 face_num = face_num + 1; 07405 } 07406 else { 07407 07408 if ( face_num < FACE_MAX ) { 07409 face_order[face_num] = 3; 07410 if ( ( ivert % 2 ) == 0 ) { 07411 face[0][face_num] = ix; 07412 face[1][face_num] = iy; 07413 face[2][face_num] = iz; 07414 } 07415 else { 07416 face[0][face_num] = iz; 07417 face[1][face_num] = iy; 07418 face[2][face_num] = ix; 07419 } 07420 } 07421 face_num = face_num + 1; 07422 } 07423 ivert = ivert + 1; 07424 /* 07425 Very very tentative guess as to how indices into the normal 07426 vector array are set up... 07427 */ 07428 if ( face_num < FACE_MAX && ivert > 2 ) { 07429 for ( i = 0; i < 3; i++ ) { 07430 face_normal[i][face_num] = normal_temp[i][ix]; 07431 } 07432 } 07433 } 07434 } 07435 } 07436 } 07437 /* 07438 INDEXEDFACESET 07439 */ 07440 else if ( leqi ( level_name[level], "INDEXEDFACESET" ) == TRUE ) { 07441 07442 if ( strcmp ( word, "{" ) == 0 ) { 07443 } 07444 else if ( strcmp ( word, "}" ) == 0 ) { 07445 level = nlbrack - nrbrack; 07446 } 07447 else if ( leqi ( word, "COORDINDEX" ) == TRUE ) { 07448 ivert = 0; 07449 } 07450 else if ( leqi ( word, "MATERIALINDEX" ) == TRUE ) { 07451 } 07452 else if ( leqi ( word, "NORMALINDEX" ) == TRUE ) { 07453 } 07454 else if ( leqi ( word, "TEXTURECOORDINDEX" ) == TRUE ) { 07455 if ( texture_num <= 0 ) { 07456 texture_num = 1; 07457 strcpy ( texture_name[0], "Texture_0000" ); 07458 } 07459 } 07460 else { 07461 bad_num = bad_num + 1; 07462 printf ( "Bad data %s\n", word ); 07463 } 07464 } 07465 /* 07466 INDEXEDLINESET 07467 */ 07468 else if ( leqi ( level_name[level], "INDEXEDLINESET" ) == TRUE ) { 07469 07470 if ( strcmp ( word, "{" ) == 0 ) { 07471 } 07472 else if ( strcmp ( word, "}" ) == 0 ) { 07473 level = nlbrack - nrbrack; 07474 } 07475 else if ( leqi ( word, "COORDINDEX" ) == TRUE ) { 07476 } 07477 else if ( leqi ( word, "MATERIALINDEX" ) == TRUE ) { 07478 } 07479 else { 07480 bad_num = bad_num + 1; 07481 printf ( "Bad data %s\n", word ); 07482 } 07483 } 07484 /* 07485 INDEXEDNURBSSURFACE 07486 */ 07487 else if ( leqi ( level_name[level], "INDEXEDNURBSSURFACE" ) == TRUE ) { 07488 07489 if ( strcmp ( word, "{" ) == 0 ) { 07490 } 07491 else if ( strcmp ( word, "}" ) == 0 ) { 07492 level = nlbrack - nrbrack; 07493 } 07494 else if ( leqi ( word, "NUMUCONTROLPOINTS") == TRUE ) { 07495 07496 count = sscanf ( word, "%d%n", &jval, &width ); 07497 07498 if ( count > 0 ) { 07499 nu = jval; 07500 if ( debug ) { 07501 printf ( "NU = %d\n", nu ); 07502 } 07503 } 07504 else { 07505 nu = 0; 07506 bad_num = bad_num + 1; 07507 printf ( "Bad data %s\n", word ); 07508 } 07509 } 07510 else if ( leqi ( word, "NUMVCONTROLPOINTS" ) == TRUE ) { 07511 07512 count = sscanf ( word, "%d%n", &jval, &width ); 07513 07514 if ( count > 0 ) { 07515 nv = jval; 07516 if ( debug ) { 07517 printf ( "NV = %d\n", nv ); 07518 } 07519 } 07520 else { 07521 nv = 0; 07522 bad_num = bad_num + 1; 07523 } 07524 } 07525 else if ( leqi ( word, "COORDINDEX" ) == TRUE ) { 07526 } 07527 else if ( leqi ( word, "UKNOTVECTOR" ) == TRUE ) { 07528 } 07529 else if ( leqi ( word, "VKNOTVECTOR" ) == TRUE ) { 07530 } 07531 else { 07532 bad_num = bad_num + 1; 07533 printf ( "Bad data %s\n", word ); 07534 } 07535 } 07536 /* 07537 INDEXEDTRIANGLESTRIPSET 07538 */ 07539 else if ( leqi ( level_name[level], "INDEXEDTRIANGLESTRIPSET" ) == TRUE ) { 07540 07541 if ( strcmp ( word, "{" ) == 0 ) { 07542 } 07543 else if ( strcmp ( word, "}" ) == 0 ) { 07544 level = nlbrack - nrbrack; 07545 } 07546 else if ( leqi ( word, "VERTEXPROPERTY" ) == TRUE ) { 07547 count = sscanf ( next, "%s%n", word, &width ); 07548 next = next + width; 07549 } 07550 else if ( leqi ( word, "COORDINDEX" ) == TRUE ) { 07551 ivert = 0; 07552 } 07553 else if ( leqi ( word, "NORMALINDEX" ) == TRUE ) { 07554 count = sscanf ( next, "%s%n", word, &width ); 07555 next = next + width; 07556 } 07557 else { 07558 bad_num = bad_num + 1; 07559 printf ( "Bad data %s\n", word ); 07560 } 07561 } 07562 /* 07563 INFO 07564 */ 07565 else if ( leqi ( level_name[level], "INFO" ) == TRUE ) { 07566 07567 if ( strcmp ( word, "{" ) == 0 ) { 07568 } 07569 else if ( strcmp ( word, "}" ) == 0 ) { 07570 level = nlbrack - nrbrack; 07571 } 07572 else if ( leqi ( word, "STRING" ) == TRUE ) { 07573 } 07574 else if ( strcmp ( word, "\"" ) == 0 ) { 07575 } 07576 else { 07577 } 07578 } 07579 /* 07580 LIGHTMODEL 07581 Read, but ignore. 07582 */ 07583 else if ( leqi ( level_name[level], "LIGHTMODEL" ) == TRUE ) { 07584 07585 if ( strcmp ( word, "{" ) == 0 ) { 07586 } 07587 else if ( strcmp ( word, "}" ) == 0 ) { 07588 level = nlbrack - nrbrack; 07589 } 07590 else if ( leqi ( word, "model" ) == TRUE ) { 07591 } 07592 else { 07593 } 07594 } 07595 /* 07596 MATERIAL 07597 Read, but ignore. 07598 */ 07599 else if ( leqi ( level_name[level],"MATERIAL" ) == TRUE ) { 07600 07601 if ( strcmp ( word, "{" ) == 0 ) { 07602 } 07603 else if ( strcmp ( word, "}" ) == 0 ) { 07604 level = nlbrack - nrbrack; 07605 } 07606 else if ( leqi ( word, "AMBIENTCOLOR" ) == TRUE ) { 07607 } 07608 else if ( leqi ( word, "EMISSIVECOLOR" ) == TRUE ) { 07609 } 07610 else if ( leqi ( word, "DIFFUSECOLOR" ) == TRUE ) { 07611 } 07612 else if ( leqi ( word, "SHININESS" ) == TRUE ) { 07613 } 07614 else if ( leqi ( word, "SPECULARCOLOR" ) == TRUE ) { 07615 } 07616 else if ( leqi ( word, "TRANSPARENCY" ) == TRUE ) { 07617 } 07618 else { 07619 } 07620 } 07621 /* 07622 MATERIALBINDING 07623 Read, but ignore 07624 */ 07625 else if ( leqi ( level_name[level], "MATERIALBINDING" ) == TRUE ) { 07626 07627 if ( strcmp ( word, "{" ) == 0 ) { 07628 } 07629 else if ( strcmp ( word, "}" ) == 0 ) { 07630 level = nlbrack - nrbrack; 07631 } 07632 else if ( leqi ( word, "VALUE" ) == TRUE ) { 07633 count = sscanf ( next, "%s%n", material_binding, &width ); 07634 next = next + width; 07635 } 07636 else { 07637 count = sscanf ( next, "%f%n", &rval, &width ); 07638 next = next + width; 07639 07640 if ( count > 0 ) { 07641 } 07642 else { 07643 bad_num = bad_num + 1; 07644 printf ( "Bad data %s\n", word ); 07645 } 07646 } 07647 } 07648 /* 07649 MATERIALINDEX 07650 */ 07651 else if ( leqi ( level_name[level], "MATERIALINDEX" ) == TRUE ) { 07652 07653 if ( strcmp ( word, "[" ) == 0 ) { 07654 ivert = 0; 07655 } 07656 else if ( strcmp ( word, "]" ) == 0 ) { 07657 level = nlbrack - nrbrack; 07658 } 07659 /* 07660 (indexedfaceset) MATERIALINDEX 07661 */ 07662 else if ( leqi ( level_name[level-1], "INDEXEDFACESET" ) == TRUE ) { 07663 07664 count = sscanf ( word, "%d%n", &jval, &width ); 07665 07666 if ( count > 0 ) { 07667 07668 if ( jval == -1 ) { 07669 ivert = 0; 07670 face_num2 = face_num2 + 1; 07671 } 07672 else { 07673 07674 if ( face_num2 < FACE_MAX ) { 07675 if ( jval != -1 ) { 07676 jval = jval + cor3_num_old; 07677 } 07678 vertex_material[ivert][face_num2] = jval; 07679 ivert = ivert + 1; 07680 } 07681 } 07682 } 07683 else { 07684 bad_num = bad_num + 1; 07685 printf ( "Bad data %s\n", word ); 07686 } 07687 } 07688 /* 07689 (indexedlineset) MATERIALINDEX 07690 */ 07691 else if ( leqi ( level_name[level-1], "INDEXEDLINESET" ) == TRUE ) { 07692 07693 count = sscanf ( word, "%d%n", &jval, &width ); 07694 07695 if ( count > 0 ) { 07696 07697 if ( line_num2 < LINES_MAX ) { 07698 if ( jval != -1 ) { 07699 jval = jval + cor3_num_old; 07700 } 07701 line_material[line_num2] = jval; 07702 line_num2 = line_num2 + 1; 07703 } 07704 } 07705 else { 07706 bad_num = bad_num + 1; 07707 printf ( "Bad data %s\n", word ); 07708 } 07709 } 07710 else { 07711 count = sscanf ( word, "%d%n", &jval, &width ); 07712 07713 if ( count > 0 ) { 07714 } 07715 else { 07716 bad_num = bad_num + 1; 07717 printf ( "Bad data %s\n", word ); 07718 } 07719 } 07720 } 07721 /* 07722 MATRIXTRANSFORM. 07723 */ 07724 else if ( leqi ( level_name[level], "MATRIXTRANSFORM" ) == TRUE ) { 07725 07726 if ( strcmp ( word, "{" ) == 0 ) { 07727 } 07728 else if ( strcmp ( word, "}" ) == 0 ) { 07729 level = nlbrack - nrbrack; 07730 } 07731 else if ( leqi ( word, "MATRIX" ) == TRUE ) { 07732 icol = -1; 07733 irow = 0; 07734 } 07735 else { 07736 07737 count = sscanf ( word, "%f%n", &rval, &width ); 07738 07739 if ( count > 0 ) { 07740 07741 icol = icol + 1; 07742 if ( icol > 3 ) { 07743 icol = 0; 07744 irow = irow + 1; 07745 if ( irow > 3 ) { 07746 irow = 0; 07747 } 07748 } 07749 07750 transform_matrix[irow][icol] = rval; 07751 } 07752 07753 } 07754 } 07755 /* 07756 NORMAL 07757 The field "VECTOR" may be followed by three numbers, 07758 (handled here), or by a square bracket, and sets of three numbers. 07759 */ 07760 else if ( leqi ( level_name[level], "NORMAL" ) == TRUE ) { 07761 /* 07762 (vertexproperty) NORMAL 07763 */ 07764 if ( leqi ( level_name[level-1], "VERTEXPROPERTY" ) == TRUE ) { 07765 07766 if ( strcmp ( word, "[" ) == 0 ) { 07767 ixyz = 0; 07768 } 07769 else if ( strcmp ( word, "]" ) == 0 ) { 07770 level = nlbrack - nrbrack; 07771 } 07772 else { 07773 07774 count = sscanf ( word, "%f%n", &rval, &width ); 07775 07776 if ( count > 0 ) { 07777 07778 if ( inormface < FACE_MAX ) { 07779 face_normal[ixyz][inormface] = rval; 07780 } 07781 07782 ixyz = ixyz + 1; 07783 if ( ixyz > 2 ) { 07784 ixyz = 0; 07785 inormface = inormface + 1; 07786 } 07787 } 07788 } 07789 } 07790 /* 07791 (anythingelse) NORMAL 07792 */ 07793 else { 07794 07795 if ( strcmp ( word, "{" ) == 0 ) { 07796 ixyz = 0; 07797 } 07798 else if ( strcmp ( word, "}" ) == 0 ) { 07799 level = nlbrack - nrbrack; 07800 } 07801 else if ( leqi ( word, "VECTOR" ) == TRUE ) { 07802 } 07803 else { 07804 07805 count = sscanf ( word, "%f%n", &rval, &width ); 07806 07807 if ( count > 0 ) { 07808 07809 /* COMMENTED OUT 07810 07811 if ( nfnorm < FACE_MAX ) { 07812 normal[ixyz][nfnorm] = rval; 07813 } 07814 07815 */ 07816 ixyz = ixyz + 1; 07817 if ( ixyz > 2 ) { 07818 ixyz = 0; 07819 } 07820 } 07821 else { 07822 bad_num = bad_num + 1; 07823 printf ( "Bad data %s\n", word ); 07824 } 07825 } 07826 } 07827 } 07828 /* 07829 NORMALBINDING 07830 Read, but ignore 07831 */ 07832 else if ( leqi ( level_name[level], "NORMALBINDING" ) == TRUE ) { 07833 07834 if ( strcmp ( word, "{" ) == 0 ) { 07835 } 07836 else if ( strcmp ( word, "}" ) == 0 ) { 07837 level = nlbrack - nrbrack; 07838 } 07839 else if ( leqi ( word, "VALUE" ) == TRUE ) { 07840 count = sscanf ( next, "%s%n", normal_binding, &width ); 07841 next = next + width; 07842 } 07843 else { 07844 count = sscanf ( word, "%f%n", &rval, &width ); 07845 07846 if ( count > 0 ) { 07847 } 07848 else { 07849 bad_num = bad_num + 1; 07850 printf ( "Bad data %s\n", word ); 07851 } 07852 } 07853 } 07854 /* 07855 NORMALINDEX 07856 */ 07857 else if ( leqi ( level_name[level], "NORMALINDEX" ) == TRUE ) { 07858 /* 07859 (indexedtrianglestripset) NORMALINDEX 07860 */ 07861 if ( leqi ( level_name[level-1], "INDEXEDTRIANGLESTRIPSET" ) == TRUE ) { 07862 count = sscanf ( word, "%d%n", &jval, &width ); 07863 07864 if ( count > 0 ) { 07865 } 07866 else if ( strcmp ( word, "[" ) == 0 ) { 07867 } 07868 else if ( strcmp ( word, "]" ) == 0 ) { 07869 } 07870 } 07871 /* 07872 (anythingelse) NORMALINDEX 07873 */ 07874 else { 07875 07876 if ( strcmp ( word, "[" ) == 0 ) { 07877 ivert = 0; 07878 } 07879 else if ( strcmp ( word, "]" ) == 0 ) { 07880 level = nlbrack - nrbrack; 07881 } 07882 else { 07883 07884 count = sscanf ( word, "%d%n", &jval, &width ); 07885 07886 if ( count > 0 ) { 07887 if ( jval == -1 ) { 07888 ivert = 0; 07889 iface_num = iface_num + 1; 07890 } 07891 else { 07892 if ( iface_num < FACE_MAX ) { 07893 for ( i = 0; i < 3; i++ ){ 07894 vertex_normal[i][ivert][iface_num] = normal_temp[i][jval]; 07895 } 07896 ivert = ivert + 1; 07897 } 07898 } 07899 } 07900 else { 07901 bad_num = bad_num + 1; 07902 printf ( "Bad data %s\n", word ); 07903 } 07904 } 07905 } 07906 } 07907 /* 07908 (coordinate3) POINT 07909 */ 07910 else if ( leqi ( level_name[level], "POINT" ) == TRUE ) { 07911 07912 if ( leqi ( level_name[level-1], "COORDINATE3" ) == TRUE ) { 07913 07914 if ( strcmp ( word, "[" ) == 0 ) { 07915 ixyz = 0; 07916 cor3_num_old = cor3_num; 07917 } 07918 else if ( strcmp ( word, "]" ) == 0 ) { 07919 level = nlbrack - nrbrack; 07920 } 07921 else { 07922 07923 count = sscanf ( word, "%f%n", &rval, &width ); 07924 07925 if ( count > 0 ) { 07926 07927 if ( cor3_num < COR3_MAX ) { 07928 xvec[ixyz] = rval; 07929 } 07930 07931 ixyz = ixyz + 1; 07932 07933 if ( ixyz == 3 ) { 07934 07935 ixyz = 0; 07936 07937 tmat_mxp ( transform_matrix, xvec, xvec ); 07938 07939 cor3[0][cor3_num] = xvec[0]; 07940 cor3[1][cor3_num] = xvec[1]; 07941 cor3[2][cor3_num] = xvec[2]; 07942 07943 cor3_num = cor3_num + 1; 07944 07945 continue; 07946 } 07947 } 07948 else { 07949 bad_num = bad_num + 1; 07950 break; 07951 } 07952 } 07953 } 07954 /* 07955 (texturecoodinate2) POINT 07956 */ 07957 else if ( leqi ( level_name[level-1], "TEXTURECOORDINATE2" ) == TRUE ) { 07958 07959 if ( strcmp ( word, "[" ) == 0 ) { 07960 iuv = 0; 07961 text_numure_temp = 0; 07962 } 07963 else if ( strcmp ( word, "]" ) == 0 ) { 07964 level = nlbrack - nrbrack; 07965 } 07966 else { 07967 07968 count = sscanf ( word, "%f%n", &rval, &width ); 07969 07970 if ( count > 0 ) { 07971 07972 texture_temp[iuv][text_numure_temp] = rval; 07973 07974 iuv = iuv + 1; 07975 if ( iuv == 2 ) { 07976 iuv = 0; 07977 text_numure_temp = text_numure_temp + 1; 07978 } 07979 } 07980 else { 07981 printf ( "TextureCoordinate2 { Point [: Bad data\n" ); 07982 bad_num = bad_num + 1; 07983 break; 07984 } 07985 } 07986 } 07987 } 07988 /* 07989 RGB 07990 */ 07991 else if ( leqi ( level_name[level],"RGB" ) == TRUE ) { 07992 /* 07993 (basecolor) RGB 07994 */ 07995 if ( leqi ( level_name[level-1], "BASECOLOR" ) == TRUE ) { 07996 07997 if ( strcmp ( word, "[" ) == 0 ) { 07998 icolor = 0; 07999 } 08000 else if ( strcmp ( word, "]" ) == 0 ) { 08001 level = nlbrack - nrbrack; 08002 } 08003 else { 08004 08005 count = sscanf ( word, "%f%n", &rval, &width ); 08006 08007 if ( count > 0 ) { 08008 08009 rgbcolor[icolor][color_num] = rval; 08010 icolor = icolor + 1; 08011 08012 if ( icolor == 3 ) { 08013 icolor = 0; 08014 color_num = color_num + 1; 08015 } 08016 } 08017 else { 08018 bad_num = bad_num + 1; 08019 printf ( "Bad data %s\n", word ); 08020 } 08021 } 08022 } 08023 /* 08024 (anythingelse RGB) 08025 */ 08026 else { 08027 08028 printf ( "HALSBAND DES TODES!\n" ); 08029 08030 if ( strcmp ( word, "[" ) == 0 ) { 08031 icolor = 0; 08032 ivert = 0; 08033 } 08034 else if ( strcmp ( word, "]" ) == 0 ) { 08035 level = nlbrack - nrbrack; 08036 } 08037 else { 08038 08039 count = sscanf ( word, "%f%n", &rval, &width ); 08040 08041 if ( count > 0 ) { 08042 08043 if ( icface < FACE_MAX ) { 08044 08045 vertex_rgb[icolor][ivert][icface] = rval; 08046 08047 icolor = icolor + 1; 08048 if ( icolor == 3 ) { 08049 icolor = 0; 08050 color_num = color_num + 1; 08051 ivert = ivert + 1; 08052 if ( ivert == face_order[icface] ) { 08053 ivert = 0; 08054 icface = icface + 1; 08055 } 08056 } 08057 } 08058 } 08059 else { 08060 bad_num = bad_num + 1; 08061 printf ( "Bad data %s\n", word ); 08062 } 08063 } 08064 } 08065 08066 } 08067 /* 08068 SEPARATOR 08069 */ 08070 else if ( leqi ( level_name[level], "SEPARATOR" ) == TRUE ) { 08071 08072 if ( strcmp ( word, "{" ) == 0 ) { 08073 } 08074 else if ( strcmp ( word, "}" ) == 0 ) { 08075 level = nlbrack - nrbrack; 08076 } 08077 else { 08078 } 08079 } 08080 /* 08081 SHAPEHINTS 08082 Read, but ignore. 08083 */ 08084 else if ( leqi ( level_name[level], "SHAPEHINTS" ) == TRUE ) { 08085 08086 if ( strcmp ( word, "{" ) == 0 ) { 08087 } 08088 else if ( strcmp ( word, "}" ) == 0 ) { 08089 level = nlbrack - nrbrack; 08090 } 08091 else if ( leqi ( word, "CREASEANGLE" ) == TRUE ) { 08092 08093 count = sscanf ( next, "%f%n", &rval, &width ); 08094 next = next + width; 08095 08096 if ( count <= 0 ) { 08097 bad_num = bad_num + 1; 08098 printf ( "Bad data %s\n", word ); 08099 } 08100 } 08101 else if ( leqi ( word, "FACETYPE" ) == TRUE ) { 08102 count = sscanf ( next, "%s%n", word, &width ); 08103 next = next + width; 08104 } 08105 else if ( leqi ( word, "SHAPETYPE" ) == TRUE ) { 08106 count = sscanf ( next, "%s%n", word, &width ); 08107 next = next + width; 08108 } 08109 else if ( leqi ( word, "VERTEXORDERING" ) == TRUE ) { 08110 count = sscanf ( next, "%s%n", word, &width ); 08111 next = next + width; 08112 } 08113 else { 08114 bad_num = bad_num + 1; 08115 printf ( "Bad data %s\n", word ); 08116 } 08117 } 08118 /* 08119 TEXTURE2 08120 */ 08121 else if ( leqi ( level_name[level], "TEXTURE2" ) == TRUE ) { 08122 08123 if ( strcmp ( word, "{" ) == 0 ) { 08124 } 08125 else if ( strcmp ( word, "}" ) == 0 ) { 08126 level = nlbrack - nrbrack; 08127 texture_num = texture_num + 1; 08128 } 08129 else if ( leqi ( word, "BLENDCOLOR" ) == TRUE ) { 08130 } 08131 /* 08132 NEED TO REMOVE QUOTES SURROUNDING TEXTURE NAME. 08133 */ 08134 else if ( leqi ( word, "FILENAME" ) == TRUE ) { 08135 08136 count = sscanf ( next, "%s%n", word, &width ); 08137 next = next + width; 08138 08139 strcpy ( texture_name[texture_num], word ); 08140 08141 i = 0; 08142 j = 0; 08143 do { 08144 c = texture_name[texture_num][i]; 08145 i = i + 1; 08146 if ( c != '"' ) { 08147 texture_name[texture_num][j] = c; 08148 j = j + 1; 08149 } 08150 } while ( c != '\0' ); 08151 08152 } 08153 else if ( leqi ( word, "IMAGE" ) == TRUE ) { 08154 } 08155 else if ( leqi ( word, "MODEL" ) == TRUE ) { 08156 count = sscanf ( next, "%s%n", word, &width ); 08157 next = next + width; 08158 } 08159 else if ( leqi ( word, "WRAPS" ) == TRUE ) { 08160 count = sscanf ( next, "%s%n", word, &width ); 08161 next = next + width; 08162 } 08163 else if ( leqi ( word, "WRAPT" ) == TRUE ) { 08164 count = sscanf ( next, "%s%n", word, &width ); 08165 next = next + width; 08166 } 08167 else { 08168 } 08169 } 08170 /* 08171 TEXTURECOORDINATE2 08172 */ 08173 else if ( leqi ( level_name[level], "TEXTURECOORDINATE2" ) == TRUE ) { 08174 08175 if ( strcmp ( word, "{" ) == 0 ) { 08176 } 08177 else if ( strcmp ( word, "}" ) == 0 ) { 08178 level = nlbrack - nrbrack; 08179 } 08180 else if ( leqi ( word, "POINT" ) == TRUE ) { 08181 } 08182 else { 08183 bad_num = bad_num + 1; 08184 printf ( "TEXTURECOORDINATE2: Bad data %s\n", word ); 08185 } 08186 } 08187 /* 08188 TEXTURECOORDINATEBINDING 08189 */ 08190 else if ( leqi ( level_name[level], "TEXTURECOORDINATEBINDING" ) == TRUE ) { 08191 08192 if ( strcmp ( word, "{" ) == 0 ) { 08193 } 08194 else if ( strcmp ( word, "}" ) == 0 ) { 08195 level = nlbrack - nrbrack; 08196 } 08197 else if ( leqi ( word, "VALUE" ) == TRUE ) { 08198 count = sscanf ( next, "%s%n", texture_binding, &width ); 08199 next = next + width; 08200 } 08201 else { 08202 bad_num = bad_num + 1; 08203 printf ( "Bad data %s\n", word ); 08204 } 08205 } 08206 /* 08207 TEXTURECOORDINDEX 08208 */ 08209 else if ( leqi ( level_name[level], "TEXTURECOORDINDEX" ) == TRUE ) { 08210 08211 if ( strcmp ( word, "[" ) == 0 ) { 08212 ivert = 0; 08213 iface_num = 0; 08214 } 08215 else if ( strcmp ( word, "]" ) == 0 ) { 08216 level = nlbrack - nrbrack; 08217 } 08218 else { 08219 08220 count = sscanf ( word, "%d%n", &jval, &width ); 08221 08222 if ( count > 0 ) { 08223 08224 if ( jval == - 1 ) { 08225 ivert = 0; 08226 } 08227 else { 08228 08229 if ( iface_num < FACE_MAX ) { 08230 vertex_tex_uv[0][ivert][iface_num] = texture_temp[0][jval]; 08231 vertex_tex_uv[1][ivert][iface_num] = texture_temp[1][jval]; 08232 } 08233 08234 ivert = ivert + 1; 08235 08236 if ( ivert == face_order[iface_num] ) { 08237 ivert = 0; 08238 iface_num = iface_num + 1; 08239 } 08240 } 08241 08242 } 08243 else { 08244 bad_num = bad_num + 1; 08245 printf ( "Bad data %s\n", word ); 08246 } 08247 08248 } 08249 } 08250 /* 08251 UKNOTVECTOR 08252 */ 08253 else if ( leqi ( level_name[level], "UKNOTVECTOR" ) == TRUE ) { 08254 08255 if ( strcmp ( word, "[" ) == 0 ) { 08256 continue; 08257 } 08258 else if ( strcmp ( word, "]" ) == 0 ) { 08259 level = nlbrack - nrbrack; 08260 continue; 08261 } 08262 else { 08263 count = sscanf ( word, "%d%n", &jval, &width ); 08264 } 08265 } 08266 /* 08267 VECTOR 08268 */ 08269 else if ( leqi ( level_name[level], "VECTOR" ) == TRUE ) { 08270 if ( strcmp ( word, "[" ) == 0 ) { 08271 } 08272 else if ( strcmp ( word, "]" ) == 0 ) { 08273 level = nlbrack - nrbrack; 08274 } 08275 /* 08276 (normal) VECTOR 08277 */ 08278 else if ( leqi ( level_name[level-1], "NORMAL" ) == TRUE ) { 08279 08280 count = sscanf ( word, "%f%n", &rval, &width ); 08281 08282 if ( count > 0 ) { 08283 08284 if ( normal_num_temp < ORDER_MAX * FACE_MAX ) { 08285 normal_temp[ixyz][normal_num_temp] = rval; 08286 ixyz = ixyz + 1; 08287 if ( ixyz == 3 ) { 08288 ixyz = 0; 08289 normal_num_temp = normal_num_temp + 1; 08290 } 08291 } 08292 } 08293 else { 08294 bad_num = bad_num + 1; 08295 printf ( "NORMAL VECTOR: bad data %s\n", word ); 08296 } 08297 } 08298 } 08299 /* 08300 (vertexproperty) VERTEX 08301 */ 08302 else if ( leqi ( level_name[level], "VERTEX" ) == TRUE ) { 08303 08304 if ( leqi ( level_name[level-1], "VERTEXPROPERTY" ) == TRUE ) { 08305 08306 if ( strcmp ( word, "[" ) == 0 ) { 08307 ixyz = 0; 08308 cor3_num_old = cor3_num; 08309 } 08310 else if ( strcmp ( word, "]" ) == 0 ) { 08311 level = nlbrack - nrbrack; 08312 } 08313 else { 08314 count = sscanf ( word, "%f%n", &rval, &width ); 08315 08316 if ( count > 0 ) { 08317 08318 if ( cor3_num < COR3_MAX ) { 08319 cor3[ixyz][cor3_num] = rval; 08320 } 08321 ixyz = ixyz + 1; 08322 if ( ixyz == 3 ) { 08323 ixyz = 0; 08324 cor3_num = cor3_num + 1; 08325 } 08326 08327 } 08328 else { 08329 bad_num = bad_num + 1; 08330 printf ( "Bad data %s\n", word ); 08331 } 08332 } 08333 } 08334 } 08335 /* 08336 (indexedtrianglestripset) VERTEXPROPERTY 08337 */ 08338 else if ( leqi ( level_name[level], "VERTEXPROPERTY" ) == TRUE ) { 08339 08340 if ( strcmp ( word, "{" ) == 0 ) { 08341 } 08342 else if ( strcmp ( word, "}" ) == 0 ) { 08343 level = nlbrack - nrbrack; 08344 } 08345 else if ( leqi ( word, "VERTEX" ) == TRUE ) { 08346 } 08347 else if ( leqi ( word, "NORMAL" ) == TRUE ) { 08348 ixyz = 0; 08349 } 08350 else if ( leqi ( word, "MATERIALBINDING" ) == TRUE ) { 08351 count = sscanf ( next, "%s%n", word, &width ); 08352 next = next + width; 08353 } 08354 else if ( leqi ( word, "NORMALBINDING" ) == TRUE ) { 08355 count = sscanf ( next, "%s%n", word, &width ); 08356 next = next + width; 08357 } 08358 else { 08359 bad_num = bad_num + 1; 08360 printf ( "Bad data %s\n", word ); 08361 } 08362 } 08363 /* 08364 VKNOTVECTOR 08365 */ 08366 else if ( leqi ( level_name[level], "VKNOTVECTOR" ) == TRUE ) { 08367 08368 if ( strcmp ( word, "[" ) == 0 ) { 08369 continue; 08370 } 08371 else if ( strcmp ( word, "]" ) == 0 ) { 08372 level = nlbrack - nrbrack; 08373 continue; 08374 } 08375 else { 08376 count = sscanf ( word, "%d%n", &jval, &width ); 08377 } 08378 } 08379 /* 08380 Any other word: 08381 */ 08382 else { 08383 } 08384 } 08385 } 08386 /* 08387 Reset the transformation matrix to the identity, 08388 because, presumably, we've applied it by now. 08389 */ 08390 tmat_init ( transform_matrix ); 08391 08392 return SUCCESS; 08393 } 08394 /******************************************************************************/ 08395 08396 int iv_write ( FILE *fileout ) 08397 08398 /******************************************************************************/ 08399 08400 /* 08401 Purpose: 08402 08403 IV_WRITE writes graphics information to an Inventor file. 08404 08405 Modified: 08406 08407 29 June 1999 08408 08409 Author: 08410 08411 John Burkardt 08412 */ 08413 { 08414 int icor3; 08415 int iface; 08416 int itemp; 08417 int ivert; 08418 int j; 08419 int length; 08420 int text_num; 08421 08422 text_num = 0; 08423 08424 fprintf ( fileout, "#Inventor V2.0 ascii\n" ); 08425 fprintf ( fileout, "\n" ); 08426 fprintf ( fileout, "Separator {\n" ); 08427 fprintf ( fileout, " Info {\n" ); 08428 fprintf ( fileout, " string \"%s generated by IVCON.\"\n", fileout_name ); 08429 fprintf ( fileout, " string \"Original data in file %s.\"\n", filein_name ); 08430 fprintf ( fileout, " }\n" ); 08431 fprintf ( fileout, " Separator {\n" ); 08432 text_num = text_num + 8; 08433 /* 08434 LightModel: 08435 08436 BASE_COLOR ignores light sources, and uses only diffuse color 08437 and transparency. Even without normal vector information, 08438 the object will show up. However, you won't get shadow 08439 and lighting effects. 08440 08441 PHONG uses the Phong lighting model, accounting for light sources 08442 and surface orientation. This is the default. I believe 08443 you need accurate normal vector information in order for this 08444 option to produce nice pictures. 08445 08446 DEPTH ignores light sources, and calculates lighting based on 08447 the location of the object within the near and far planes 08448 of the current camera's view volume. 08449 */ 08450 fprintf ( fileout, " LightModel {\n" ); 08451 fprintf ( fileout, " model PHONG\n" ); 08452 fprintf ( fileout, " }\n" ); 08453 text_num = text_num + 3; 08454 /* 08455 Transformation matrix. 08456 */ 08457 fprintf ( fileout, " MatrixTransform { matrix\n" ); 08458 fprintf ( fileout, " %f %f %f %f\n", transform_matrix[0][0], 08459 transform_matrix[0][1], transform_matrix[0][2], transform_matrix[0][3] ); 08460 fprintf ( fileout, " %f %f %f %f\n", transform_matrix[1][0], 08461 transform_matrix[1][1], transform_matrix[1][2], transform_matrix[1][3] ); 08462 fprintf ( fileout, " %f %f %f %f\n", transform_matrix[2][0], 08463 transform_matrix[2][1], transform_matrix[2][2], transform_matrix[2][3] ); 08464 fprintf ( fileout, " %f %f %f %f\n", transform_matrix[3][0], 08465 transform_matrix[3][1], transform_matrix[3][2], transform_matrix[3][3] ); 08466 fprintf ( fileout, " }\n" ); 08467 text_num = text_num + 6; 08468 /* 08469 Material. 08470 */ 08471 fprintf ( fileout, " Material {\n" ); 08472 fprintf ( fileout, " ambientColor 0.2 0.2 0.2\n" ); 08473 fprintf ( fileout, " diffuseColor 0.8 0.8 0.8\n" ); 08474 fprintf ( fileout, " emissiveColor 0.0 0.0 0.0\n" ); 08475 fprintf ( fileout, " specularColor 0.0 0.0 0.0\n" ); 08476 fprintf ( fileout, " shininess 0.2\n" ); 08477 fprintf ( fileout, " transparency 0.0\n" ); 08478 fprintf ( fileout, " }\n" ); 08479 text_num = text_num + 8; 08480 /* 08481 MaterialBinding 08482 */ 08483 fprintf ( fileout, " MaterialBinding {\n" ); 08484 fprintf ( fileout, " value PER_VERTEX_INDEXED\n" ); 08485 fprintf ( fileout, " }\n" ); 08486 text_num = text_num + 3; 08487 /* 08488 NormalBinding 08489 08490 PER_VERTEX promises that we will write a list of normal vectors 08491 in a particular order, namely, the normal vectors for the vertices 08492 of the first face, then the second face, and so on. 08493 08494 PER_VERTEX_INDEXED promises that we will write a list of normal vectors, 08495 and then, as part of the IndexedFaceSet, we will give a list of 08496 indices referencing this normal vector list. 08497 */ 08498 fprintf ( fileout, " NormalBinding {\n" ); 08499 fprintf ( fileout, " value PER_VERTEX_INDEXED\n" ); 08500 fprintf ( fileout, " }\n" ); 08501 text_num = text_num + 3; 08502 /* 08503 Texture2. 08504 08505 FLAW: We can only handle on texture right now. 08506 */ 08507 if ( texture_num > 0 ) { 08508 fprintf ( fileout, " Texture2 {\n" ); 08509 fprintf ( fileout, " filename \"%s\"\n", texture_name[0] ); 08510 fprintf ( fileout, " wrapS REPEAT\n" ); 08511 fprintf ( fileout, " wrapT REPEAT\n" ); 08512 fprintf ( fileout, " model MODULATE\n" ); 08513 fprintf ( fileout, " blendColor 0.0 0.0 0.0\n" ); 08514 fprintf ( fileout, " }\n" ); 08515 text_num = text_num + 7; 08516 } 08517 /* 08518 TextureCoordinateBinding 08519 */ 08520 fprintf ( fileout, " TextureCoordinateBinding {\n" ); 08521 fprintf ( fileout, " value PER_VERTEX_INDEXED\n" ); 08522 fprintf ( fileout, " }\n" ); 08523 text_num = text_num + 3; 08524 /* 08525 ShapeHints 08526 */ 08527 fprintf ( fileout, " ShapeHints {\n" ); 08528 fprintf ( fileout, " vertexOrdering COUNTERCLOCKWISE\n" ); 08529 fprintf ( fileout, " shapeType UNKNOWN_SHAPE_TYPE\n" ); 08530 fprintf ( fileout, " faceType CONVEX\n" ); 08531 fprintf ( fileout, " creaseAngle 6.28319\n" ); 08532 fprintf ( fileout, " }\n" ); 08533 text_num = text_num + 6; 08534 /* 08535 Point coordinates. 08536 */ 08537 fprintf ( fileout, " Coordinate3 {\n" ); 08538 fprintf ( fileout, " point [\n" ); 08539 text_num = text_num + 2; 08540 08541 for ( j = 0; j < cor3_num; j++ ) { 08542 fprintf ( fileout, " %f %f %f,\n", cor3[0][j], cor3[1][j], cor3[2][j] ); 08543 text_num = text_num + 1; 08544 } 08545 fprintf ( fileout, " ]\n" ); 08546 fprintf ( fileout, " }\n" ); 08547 text_num = text_num + 2; 08548 /* 08549 Texture coordinates. 08550 */ 08551 fprintf ( fileout, " TextureCoordinate2 {\n" ); 08552 fprintf ( fileout, " point [\n" ); 08553 text_num = text_num + 2; 08554 08555 for ( iface = 0; iface < face_num; iface++ ) { 08556 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 08557 fprintf ( fileout, " %f %f,\n", vertex_tex_uv[0][ivert][iface], 08558 vertex_tex_uv[1][ivert][iface] ); 08559 text_num = text_num + 1; 08560 } 08561 } 08562 fprintf ( fileout, " ]\n" ); 08563 fprintf ( fileout, " }\n" ); 08564 text_num = text_num + 2; 08565 /* 08566 BaseColor. 08567 */ 08568 if ( color_num > 0 ) { 08569 08570 fprintf ( fileout, " BaseColor {\n" ); 08571 fprintf ( fileout, " rgb [\n" ); 08572 text_num = text_num + 2; 08573 08574 for ( j = 0; j < color_num; j++ ) { 08575 fprintf ( fileout, " %f %f %f,\n", rgbcolor[0][j], rgbcolor[1][j], 08576 rgbcolor[2][j] ); 08577 text_num = text_num + 1; 08578 } 08579 08580 fprintf ( fileout, " ]\n" ); 08581 fprintf ( fileout, " }\n" ); 08582 text_num = text_num + 2; 08583 } 08584 /* 08585 Normal vectors. 08586 Use the normal vectors associated with nodes. 08587 */ 08588 if ( face_num > 0 ) { 08589 08590 fprintf ( fileout, " Normal { \n" ); 08591 fprintf ( fileout, " vector [\n" ); 08592 text_num = text_num + 2; 08593 08594 for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { 08595 fprintf ( fileout, " %f %f %f,\n", 08596 cor3_normal[0][icor3], 08597 cor3_normal[1][icor3], 08598 cor3_normal[2][icor3] ); 08599 text_num = text_num + 1; 08600 } 08601 08602 fprintf ( fileout, " ]\n" ); 08603 fprintf ( fileout, " }\n" ); 08604 text_num = text_num + 2; 08605 } 08606 /* 08607 IndexedLineSet 08608 */ 08609 if ( line_num > 0 ) { 08610 08611 fprintf ( fileout, " IndexedLineSet {\n" ); 08612 /* 08613 IndexedLineSet coordIndex 08614 */ 08615 fprintf ( fileout, " coordIndex [\n" ); 08616 text_num = text_num + 2; 08617 08618 length = 0; 08619 08620 for ( j = 0; j < line_num; j++ ) { 08621 08622 if ( length == 0 ) { 08623 fprintf ( fileout, " " ); 08624 } 08625 08626 fprintf ( fileout, " %d,", line_dex[j] ); 08627 length = length + 1; 08628 08629 if ( line_dex[j] == -1 || length >= 10 || j == line_num-1 ) { 08630 fprintf ( fileout, "\n" ); 08631 text_num = text_num + 1; 08632 length = 0; 08633 } 08634 } 08635 08636 fprintf ( fileout, " ]\n" ); 08637 text_num = text_num + 1; 08638 /* 08639 IndexedLineSet materialIndex. 08640 */ 08641 fprintf ( fileout, " materialIndex [\n" ); 08642 text_num = text_num + 1; 08643 08644 length = 0; 08645 08646 for ( j = 0; j < line_num; j++ ) { 08647 08648 if ( length == 0 ) { 08649 fprintf ( fileout, " " ); 08650 } 08651 08652 fprintf ( fileout, " %d,", line_material[j] ); 08653 length = length + 1; 08654 08655 if ( line_material[j] == -1 || length >= 10 || j == line_num-1 ) { 08656 fprintf ( fileout, "\n" ); 08657 text_num = text_num + 1; 08658 length = 0; 08659 } 08660 } 08661 08662 fprintf ( fileout, " ]\n" ); 08663 fprintf ( fileout, " }\n" ); 08664 text_num = text_num + 2; 08665 } 08666 /* 08667 IndexedFaceSet. 08668 */ 08669 if ( face_num > 0 ) { 08670 08671 fprintf ( fileout, " IndexedFaceSet {\n" ); 08672 fprintf ( fileout, " coordIndex [\n" ); 08673 text_num = text_num + 2; 08674 08675 for ( iface = 0; iface < face_num; iface++ ) { 08676 08677 fprintf ( fileout, " " ); 08678 08679 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 08680 fprintf ( fileout, " %d,", face[ivert][iface] ); 08681 } 08682 fprintf ( fileout, " -1,\n" ); 08683 text_num = text_num + 1; 08684 } 08685 08686 fprintf ( fileout, " ]\n" ); 08687 text_num = text_num + 1; 08688 /* 08689 IndexedFaceSet normalIndex 08690 */ 08691 fprintf ( fileout, " normalIndex [\n" ); 08692 text_num = text_num + 1; 08693 08694 for ( iface = 0; iface < face_num; iface++ ) { 08695 08696 fprintf ( fileout, " " ); 08697 08698 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 08699 fprintf ( fileout, " %d,", face[ivert][iface] ); 08700 } 08701 fprintf ( fileout, " -1,\n" ); 08702 text_num = text_num + 1; 08703 } 08704 fprintf ( fileout, " ]\n" ); 08705 text_num = text_num + 1; 08706 /* 08707 IndexedFaceSet materialIndex 08708 */ 08709 fprintf ( fileout, " materialIndex [\n" ); 08710 text_num = text_num + 1; 08711 08712 for ( iface = 0; iface < face_num; iface++ ) { 08713 08714 fprintf ( fileout, " " ); 08715 08716 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 08717 fprintf ( fileout, " %d,", vertex_material[ivert][iface] ); 08718 } 08719 fprintf ( fileout, " -1,\n" ); 08720 text_num = text_num + 1; 08721 } 08722 08723 fprintf ( fileout, " ]\n" ); 08724 text_num = text_num + 1; 08725 /* 08726 IndexedFaceSet textureCoordIndex 08727 */ 08728 fprintf ( fileout, " textureCoordIndex [\n" ); 08729 text_num = text_num + 1; 08730 08731 itemp = 0; 08732 08733 for ( iface = 0; iface < face_num; iface++ ) { 08734 08735 fprintf ( fileout, " " ); 08736 08737 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 08738 fprintf ( fileout, " %d,", itemp ); 08739 itemp = itemp + 1; 08740 } 08741 fprintf ( fileout, " -1,\n" ); 08742 text_num = text_num + 1; 08743 } 08744 08745 fprintf ( fileout, " ]\n" ); 08746 08747 fprintf ( fileout, " }\n" ); 08748 text_num = text_num + 2; 08749 } 08750 /* 08751 Close up the Separator nodes. 08752 */ 08753 fprintf ( fileout, " }\n" ); 08754 fprintf ( fileout, "}\n" ); 08755 text_num = text_num + 2; 08756 /* 08757 Report. 08758 */ 08759 printf ( "\n" ); 08760 printf ( "IV_WRITE - Wrote %d text lines;\n", text_num ); 08761 08762 return SUCCESS; 08763 } 08764 /******************************************************************************/ 08765 08766 int ivec_max ( int n, int *a ) 08767 08768 /******************************************************************************/ 08769 08770 /* 08771 Purpose: 08772 08773 IVEC_MAX returns the maximum element in an integer array. 08774 08775 Modified: 08776 08777 09 October 1998 08778 08779 Author: 08780 08781 John Burkardt 08782 */ 08783 { 08784 int i; 08785 int *ia; 08786 int imax; 08787 08788 if ( n <= 0 ) { 08789 imax = 0; 08790 } 08791 else { 08792 ia = a; 08793 imax = *ia; 08794 for ( i = 1; i < n; i++ ) { 08795 ia = ia + 1; 08796 if ( imax < *ia ) { 08797 imax = *ia; 08798 } 08799 } 08800 } 08801 return imax; 08802 } 08803 /******************************************************************************/ 08804 08805 int leqi ( char* string1, char* string2 ) 08806 08807 /******************************************************************************/ 08808 08809 /* 08810 Purpose: 08811 08812 LEQI compares two strings for equality, disregarding case. 08813 08814 Modified: 08815 08816 15 September 1998 08817 08818 Author: 08819 08820 John Burkardt 08821 */ 08822 { 08823 int i; 08824 int nchar; 08825 int nchar1; 08826 int nchar2; 08827 08828 nchar1 = strlen ( string1 ); 08829 nchar2 = strlen ( string2 ); 08830 08831 if ( nchar1 < nchar2 ) { 08832 nchar = nchar1; 08833 } 08834 else { 08835 nchar = nchar2; 08836 } 08837 /* 08838 The strings are not equal if they differ over their common length. 08839 */ 08840 for ( i = 0; i < nchar; i++ ) { 08841 08842 if ( toupper ( string1[i] ) != toupper ( string2[i] ) ) { 08843 return FALSE; 08844 } 08845 } 08846 /* 08847 The strings are not equal if the longer one includes nonblanks 08848 in the tail. 08849 */ 08850 if ( nchar1 > nchar ) { 08851 for ( i = nchar; i < nchar1; i++ ) { 08852 if ( string1[i] != ' ' ) { 08853 return FALSE; 08854 } 08855 } 08856 } 08857 else if ( nchar2 > nchar ) { 08858 for ( i = nchar; i < nchar2; i++ ) { 08859 if ( string2[i] != ' ' ) { 08860 return FALSE; 08861 } 08862 } 08863 } 08864 return TRUE; 08865 } 08866 /******************************************************************************/ 08867 08868 long int long_int_read ( FILE *filein ) 08869 08870 /******************************************************************************/ 08871 08872 /* 08873 Purpose: 08874 08875 LONG_INT_READ reads a long int from a binary file. 08876 08877 Modified: 08878 08879 24 May 1999 08880 08881 Author: 08882 08883 John Burkardt 08884 */ 08885 { 08886 union { 08887 long int yint; 08888 char ychar[4]; 08889 } y; 08890 08891 if ( byte_swap == TRUE ) { 08892 y.ychar[3] = fgetc ( filein ); 08893 y.ychar[2] = fgetc ( filein ); 08894 y.ychar[1] = fgetc ( filein ); 08895 y.ychar[0] = fgetc ( filein ); 08896 } 08897 else { 08898 y.ychar[0] = fgetc ( filein ); 08899 y.ychar[1] = fgetc ( filein ); 08900 y.ychar[2] = fgetc ( filein ); 08901 y.ychar[3] = fgetc ( filein ); 08902 } 08903 08904 return y.yint; 08905 } 08906 /******************************************************************************/ 08907 08908 int long_int_write ( FILE *fileout, long int int_val ) 08909 08910 /******************************************************************************/ 08911 08912 /* 08913 Purpose: 08914 08915 LONG_INT_WRITE writes a long int to a binary file. 08916 08917 Modified: 08918 08919 14 October 1998 08920 08921 Author: 08922 08923 John Burkardt 08924 */ 08925 { 08926 union { 08927 long int yint; 08928 char ychar[4]; 08929 } y; 08930 08931 y.yint = int_val; 08932 08933 if ( byte_swap == TRUE ) { 08934 fputc ( y.ychar[3], fileout ); 08935 fputc ( y.ychar[2], fileout ); 08936 fputc ( y.ychar[1], fileout ); 08937 fputc ( y.ychar[0], fileout ); 08938 } 08939 else { 08940 fputc ( y.ychar[0], fileout ); 08941 fputc ( y.ychar[1], fileout ); 08942 fputc ( y.ychar[2], fileout ); 08943 fputc ( y.ychar[3], fileout ); 08944 } 08945 08946 return 4; 08947 } 08948 /******************************************************************************/ 08949 08950 void news ( void ) 08951 08952 /******************************************************************************/ 08953 08954 /* 08955 Purpose: 08956 08957 NEWS reports the program change history. 08958 08959 Modified: 08960 08961 26 September 1999 08962 08963 Author: 08964 08965 John Burkardt 08966 */ 08967 { 08968 printf ( "\n" ); 08969 printf ( "Recent changes:\n" ); 08970 printf ( "\n" ); 08971 printf ( " 04 July 2000\n" ); 08972 printf ( " Added preliminary XGL_WRITE.\n" ); 08973 printf ( " 26 September 1999\n" ); 08974 printf ( " After ASE_READ, call NODE_TO_VERTEX_MAT and VERTEX_TO_FACE_MATERIAL.\n" ); 08975 printf ( " 27 July 1999\n" ); 08976 printf ( " Corrected TMAT_ROT_VECTOR.\n" ); 08977 printf ( " 17 July 1999\n" ); 08978 printf ( " Added null edge and face deletion.\n" ); 08979 printf ( " Corrected a string problem in SMF_READ.\n" ); 08980 printf ( " 03 July 1999\n" ); 08981 printf ( " Fixed a problem with BINDING variables in SMF_READ.\n" ); 08982 printf ( " 02 July 1999\n" ); 08983 printf ( " Added limited texture support in 3DS/IV.\n" ); 08984 printf ( " 26 June 1999\n" ); 08985 printf ( " BYU_READ added.\n" ); 08986 printf ( " 25 June 1999\n" ); 08987 printf ( " BYU_WRITE added.\n" ); 08988 printf ( " 22 June 1999\n" ); 08989 printf ( " TRIB_READ added.\n" ); 08990 printf ( " 16 June 1999\n" ); 08991 printf ( " TRIB_WRITE Greg Hood binary triangle output routine added.\n" ); 08992 printf ( " 10 June 1999\n" ); 08993 printf ( " TRIA_WRITE Greg Hood ASCII triangle output routine added.\n" ); 08994 printf ( " 09 June 1999\n" ); 08995 printf ( " TEC_WRITE TECPLOT output routine added.\n" ); 08996 printf ( " IV_READ and IV_WRITE use TRANSFORM_MATRIX now.\n" ); 08997 printf ( " 26 May 1999\n" ); 08998 printf ( " LINE_PRUNE option added for VLA_WRITE.\n" ); 08999 printf ( " 24 May 1999\n" ); 09000 printf ( " Added << command to append new graphics data to old.\n" ); 09001 printf ( " Stuck in first draft STLB_READ/STLB_WRITE routines.\n" ); 09002 printf ( " STLA_WRITE and STLB_WRITE automatically decompose \n" ); 09003 printf ( " non-triangular faces before writing.\n" ); 09004 printf ( " 23 May 1999\n" ); 09005 printf ( " Stuck in first draft WRL_WRITE routine.\n" ); 09006 printf ( " 22 May 1999\n" ); 09007 printf ( " Faces converted to lines before calling VLA_WRITE.\n" ); 09008 printf ( " Added UCD_WRITE.\n" ); 09009 printf ( " Added MATERIAL/PATCH/TAGGEDPOINTS fields in HRC_READ.\n" ); 09010 printf ( " 17 May 1999\n" ); 09011 printf ( " Updated SMF_WRITE, SMF_READ to match code in IVREAD.\n" ); 09012 printf ( " Added transformation matrix routines.\n" ); 09013 printf ( " 16 May 1999\n" ); 09014 printf ( " Zik Saleeba improved DXF support to handle polygons.\n" ); 09015 printf ( " 15 April 1999\n" ); 09016 printf ( " Zik Saleeba added Golgotha GMOD file format support.\n" ); 09017 printf ( " 03 December 1998\n" ); 09018 printf ( " Set up simple hooks in TDS_READ_MATERIAL_SECTION.\n" ); 09019 printf ( " 02 December 1998\n" ); 09020 printf ( " Set up simple hooks for texture map names.\n" ); 09021 printf ( " 19 November 1998\n" ); 09022 printf ( " IV_WRITE uses PER_VERTEX normal binding.\n" ); 09023 printf ( " 18 November 1998\n" ); 09024 printf ( " Added node normals.\n" ); 09025 printf ( " Finally added the -RN option.\n" ); 09026 printf ( " 17 November 1998\n" ); 09027 printf ( " Added face node ordering reversal option.\n" ); 09028 printf ( " 20 October 1998\n" ); 09029 printf ( " Added DATA_REPORT.\n" ); 09030 printf ( " 19 October 1998\n" ); 09031 printf ( " SMF_READ and SMF_WRITE added.\n" ); 09032 printf ( " 16 October 1998\n" ); 09033 printf ( " Fixing a bug in IV_READ that chokes on ]} and other\n" ); 09034 printf ( " cases where brackets aren't properly spaced.\n" ); 09035 printf ( " 11 October 1998\n" ); 09036 printf ( " Added face subset selection option S.\n" ); 09037 printf ( " 09 October 1998\n" ); 09038 printf ( " Reworking normal vector treatments.\n" ); 09039 printf ( " Synchronizing IVREAD and IVCON.\n" ); 09040 printf ( " POV_WRITE added.\n" ); 09041 printf ( " 02 October 1998\n" ); 09042 printf ( " IVCON reproduces BOX.3DS and CONE.3DS exactly.\n" ); 09043 printf ( " 30 September 1998\n" ); 09044 printf ( " IVCON compiled on the PC.\n" ); 09045 printf ( " Interactive BYTE_SWAP option added for binary files.\n" ); 09046 printf ( " 25 September 1998\n" ); 09047 printf ( " OBJECT_NAME made available to store object name.\n" ); 09048 printf ( " 23 September 1998\n" ); 09049 printf ( " 3DS binary files can be written.\n" ); 09050 printf ( " 15 September 1998\n" ); 09051 printf ( " 3DS binary files can be read.\n" ); 09052 printf ( " 01 September 1998\n" ); 09053 printf ( " COR3_RANGE, FACE_NORMAL_AVE added.\n" ); 09054 printf ( " Major modifications to normal vectors.\n" ); 09055 printf ( " 24 August 1998\n" ); 09056 printf ( " HRC_READ added.\n" ); 09057 printf ( " 21 August 1998\n" ); 09058 printf ( " TXT_WRITE improved.\n" ); 09059 printf ( " 20 August 1998\n" ); 09060 printf ( " HRC_WRITE can output lines as linear splines.\n" ); 09061 printf ( " 19 August 1998\n" ); 09062 printf ( " Automatic normal computation for OBJ files.\n" ); 09063 printf ( " Added normal vector computation.\n" ); 09064 printf ( " HRC_WRITE is working.\n" ); 09065 printf ( " 18 August 1998\n" ); 09066 printf ( " IV_READ/IV_WRITE handle BASECOLOR RGB properly now.\n" ); 09067 printf ( " Improved treatment of face materials and normals.\n" ); 09068 printf ( " 17 August 1998\n" ); 09069 printf ( " ORDER_MAX increased to 35.\n" ); 09070 printf ( " FACE_PRINT routine added.\n" ); 09071 printf ( " INIT_DATA routine added.\n" ); 09072 printf ( " 14 August 1998\n" ); 09073 printf ( " IV_READ is working.\n" ); 09074 printf ( " 13 August 1998\n" ); 09075 printf ( " ASE_WRITE is working.\n" ); 09076 printf ( " IV_WRITE is working.\n" ); 09077 printf ( " 12 August 1998\n" ); 09078 printf ( " ASE_READ is working.\n" ); 09079 printf ( " 10 August 1998\n" ); 09080 printf ( " DXF_WRITE is working.\n" ); 09081 printf ( " DXF_READ is working.\n" ); 09082 printf ( " 27 July 1998\n" ); 09083 printf ( " Interactive mode is working.\n" ); 09084 printf ( " OBJ_READ is working.\n" ); 09085 printf ( " 25 July 1998\n" ); 09086 printf ( " OBJ_WRITE is working.\n" ); 09087 printf ( " 24 July 1998\n" ); 09088 printf ( " DATA_CHECK checks the input data.\n" ); 09089 printf ( " VLA_READ is working.\n" ); 09090 printf ( " VLA_WRITE is working.\n" ); 09091 printf ( " 23 July 1998\n" ); 09092 printf ( " STL_WRITE is working.\n" ); 09093 printf ( " 22 July 1998\n" ); 09094 printf ( " STL_READ is working.\n" ); 09095 printf ( " TXT_WRITE is working.\n" ); 09096 } 09097 /**********************************************************************/ 09098 09099 void node_to_vertex_material ( void ) 09100 09101 /**********************************************************************/ 09102 09103 /* 09104 Purpose: 09105 09106 NODE_TO_VERTEX_MAT extends node material definitions to vertices. 09107 09108 Discussion: 09109 09110 A NODE is a point in space. 09111 A VERTEX is a node as used in a particular face. 09112 One node may be used as a vertex in several faces, or none. 09113 09114 Modified: 09115 09116 22 May 1999 09117 09118 Author: 09119 09120 John Burkardt 09121 */ 09122 { 09123 int iface; 09124 int ivert; 09125 int node; 09126 09127 for ( iface = 0; iface < face_num; iface++ ) { 09128 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 09129 node = face[ivert][iface]; 09130 vertex_material[ivert][iface] = cor3_material[node]; 09131 } 09132 } 09133 09134 return; 09135 } 09136 /******************************************************************************/ 09137 09138 int obj_read ( FILE *filein ) 09139 09140 /******************************************************************************/ 09141 09142 /* 09143 Purpose: 09144 09145 OBJ_READ reads a Wavefront OBJ file. 09146 09147 Example: 09148 09149 # magnolia.obj 09150 09151 mtllib ./vp.mtl 09152 09153 g 09154 v -3.269770 -39.572201 0.876128 09155 v -3.263720 -39.507999 2.160890 09156 ... 09157 v 0.000000 -9.988540 0.000000 09158 g stem 09159 s 1 09160 usemtl brownskn 09161 f 8 9 11 10 09162 f 12 13 15 14 09163 ... 09164 f 788 806 774 09165 09166 Modified: 09167 09168 20 October 1998 09169 09170 Author: 09171 09172 John Burkardt 09173 */ 09174 { 09175 int count; 09176 int i; 09177 int ivert; 09178 char *next; 09179 char *next2; 09180 char *next3; 09181 int node; 09182 int vertex_normal_num; 09183 float r1; 09184 float r2; 09185 float r3; 09186 char token[LINE_MAX_LEN]; 09187 char token2[LINE_MAX_LEN]; 09188 int width; 09189 /* 09190 Initialize. 09191 */ 09192 vertex_normal_num = 0; 09193 /* 09194 Read the next line of the file into INPUT. 09195 */ 09196 while ( fgets ( input, LINE_MAX_LEN, filein ) != NULL ) { 09197 09198 text_num = text_num + 1; 09199 /* 09200 Advance to the first nonspace character in INPUT. 09201 */ 09202 for ( next = input; *next != '\0' && isspace(*next); next++ ) { 09203 } 09204 /* 09205 Skip blank lines and comments. 09206 */ 09207 09208 if ( *next == '\0' ) { 09209 continue; 09210 } 09211 09212 if ( *next == '#' || *next == '$' ) { 09213 comment_num = comment_num + 1; 09214 continue; 09215 } 09216 /* 09217 Extract the first word in this line. 09218 */ 09219 sscanf ( next, "%s%n", token, &width ); 09220 /* 09221 Set NEXT to point to just after this token. 09222 */ 09223 09224 next = next + width; 09225 /* 09226 BEVEL 09227 Bevel interpolation. 09228 */ 09229 if ( leqi ( token, "BEVEL" ) == TRUE ) { 09230 continue; 09231 } 09232 /* 09233 BMAT 09234 Basis matrix. 09235 */ 09236 else if ( leqi ( token, "BMAT" ) == TRUE ) { 09237 continue; 09238 } 09239 /* 09240 C_INTERP 09241 Color interpolation. 09242 */ 09243 else if ( leqi ( token, "C_INTERP" ) == TRUE ) { 09244 continue; 09245 } 09246 /* 09247 CON 09248 Connectivity between free form surfaces. 09249 */ 09250 else if ( leqi ( token, "CON" ) == TRUE ) { 09251 continue; 09252 } 09253 /* 09254 CSTYPE 09255 Curve or surface type. 09256 */ 09257 else if ( leqi ( token, "CSTYPE" ) == TRUE ) { 09258 continue; 09259 } 09260 /* 09261 CTECH 09262 Curve approximation technique. 09263 */ 09264 else if ( leqi ( token, "CTECH" ) == TRUE ) { 09265 continue; 09266 } 09267 /* 09268 CURV 09269 Curve. 09270 */ 09271 else if ( leqi ( token, "CURV" ) == TRUE ) { 09272 continue; 09273 } 09274 /* 09275 CURV2 09276 2D curve. 09277 */ 09278 else if ( leqi ( token, "CURV2" ) == TRUE ) { 09279 continue; 09280 } 09281 /* 09282 D_INTERP 09283 Dissolve interpolation. 09284 */ 09285 else if ( leqi ( token, "D_INTERP" ) == TRUE ) { 09286 continue; 09287 } 09288 /* 09289 DEG 09290 Degree. 09291 */ 09292 else if ( leqi ( token, "DEG" ) == TRUE ) { 09293 continue; 09294 } 09295 /* 09296 END 09297 End statement. 09298 */ 09299 else if ( leqi ( token, "END" ) == TRUE ) { 09300 continue; 09301 } 09302 /* 09303 F V1 V2 V3 09304 or 09305 F V1/VT1/VN1 V2/VT2/VN2 ... 09306 or 09307 F V1//VN1 V2//VN2 ... 09308 09309 Face. 09310 A face is defined by the vertices. 09311 Optionally, slashes may be used to include the texture vertex 09312 and vertex normal indices. 09313 09314 OBJ line node indices are 1 based rather than 0 based. 09315 So we have to decrement them before loading them into FACE. 09316 */ 09317 09318 else if ( leqi ( token, "F" ) == TRUE ) { 09319 09320 ivert = 0; 09321 face_order[face_num] = 0; 09322 /* 09323 Read each item in the F definition as a token, and then 09324 take it apart. 09325 */ 09326 for ( ;; ) { 09327 09328 count = sscanf ( next, "%s%n", token2, &width ); 09329 next = next + width; 09330 09331 if ( count != 1 ) { 09332 break; 09333 } 09334 09335 count = sscanf ( token2, "%d%n", &node, &width ); 09336 next2 = token2 + width; 09337 09338 if ( count != 1 ) { 09339 break; 09340 } 09341 09342 if ( ivert < ORDER_MAX && face_num < FACE_MAX ) { 09343 face[ivert][face_num] = node-1; 09344 vertex_material[ivert][face_num] = 0; 09345 face_order[face_num] = face_order[face_num] + 1; 09346 } 09347 /* 09348 If there's a slash, skip to the next slash, and extract the 09349 index of the normal vector. 09350 */ 09351 if ( *next2 == '/' ) { 09352 09353 for ( next3 = next2 + 1; next3 < token2 + LINE_MAX_LEN; next3++ ) { 09354 09355 if ( *next3 == '/' ) { 09356 next3 = next3 + 1; 09357 count = sscanf ( next3, "%d%n", &node, &width ); 09358 09359 node = node - 1; 09360 if ( 0 <= node && node < vertex_normal_num ) { 09361 for ( i = 0; i < 3; i++ ) { 09362 vertex_normal[i][ivert][face_num] = normal_temp[i][node]; 09363 } 09364 } 09365 break; 09366 } 09367 } 09368 } 09369 ivert = ivert + 1; 09370 } 09371 face_num = face_num + 1; 09372 } 09373 09374 /* 09375 G 09376 Group name. 09377 */ 09378 09379 else if ( leqi ( token, "G" ) == TRUE ) { 09380 continue; 09381 } 09382 /* 09383 HOLE 09384 Inner trimming hole. 09385 */ 09386 else if ( leqi ( token, "HOLE" ) == TRUE ) { 09387 continue; 09388 } 09389 /* 09390 L 09391 I believe OBJ line node indices are 1 based rather than 0 based. 09392 So we have to decrement them before loading them into LINE_DEX. 09393 */ 09394 09395 else if ( leqi ( token, "L" ) == TRUE ) { 09396 09397 for ( ;; ) { 09398 09399 count = sscanf ( next, "%d%n", &node, &width ); 09400 next = next + width; 09401 09402 if ( count != 1 ) { 09403 break; 09404 } 09405 09406 if ( line_num < LINES_MAX ) { 09407 line_dex[line_num] = node-1; 09408 line_material[line_num] = 0; 09409 } 09410 line_num = line_num + 1; 09411 09412 } 09413 09414 if ( line_num < LINES_MAX ) { 09415 line_dex[line_num] = -1; 09416 line_material[line_num] = -1; 09417 } 09418 line_num = line_num + 1; 09419 09420 } 09421 09422 /* 09423 LOD 09424 Level of detail. 09425 */ 09426 else if ( leqi ( token, "LOD" ) == TRUE ) { 09427 continue; 09428 } 09429 /* 09430 MG 09431 Merging group. 09432 */ 09433 else if ( leqi ( token, "MG" ) == TRUE ) { 09434 continue; 09435 } 09436 /* 09437 MTLLIB 09438 Material library. 09439 */ 09440 09441 else if ( leqi ( token, "MTLLIB" ) == TRUE ) { 09442 continue; 09443 } 09444 /* 09445 O 09446 Object name. 09447 */ 09448 else if ( leqi ( token, "O" ) == TRUE ) { 09449 continue; 09450 } 09451 /* 09452 P 09453 Point. 09454 */ 09455 else if ( leqi ( token, "P" ) == TRUE ) { 09456 continue; 09457 } 09458 /* 09459 PARM 09460 Parameter values. 09461 */ 09462 else if ( leqi ( token, "PARM" ) == TRUE ) { 09463 continue; 09464 } 09465 /* 09466 S 09467 Smoothing group 09468 */ 09469 else if ( leqi ( token, "S" ) == TRUE ) { 09470 continue; 09471 } 09472 /* 09473 SCRV 09474 Special curve. 09475 */ 09476 else if ( leqi ( token, "SCRV" ) == TRUE ) { 09477 continue; 09478 } 09479 /* 09480 SHADOW_OBJ 09481 Shadow casting. 09482 */ 09483 else if ( leqi ( token, "SHADOW_OBJ" ) == TRUE ) { 09484 continue; 09485 } 09486 /* 09487 SP 09488 Special point. 09489 */ 09490 else if ( leqi ( token, "SP" ) == TRUE ) { 09491 continue; 09492 } 09493 /* 09494 STECH 09495 Surface approximation technique. 09496 */ 09497 else if ( leqi ( token, "STECH" ) == TRUE ) { 09498 continue; 09499 } 09500 /* 09501 STEP 09502 Stepsize. 09503 */ 09504 else if ( leqi ( token, "CURV" ) == TRUE ) { 09505 continue; 09506 } 09507 /* 09508 SURF 09509 Surface. 09510 */ 09511 else if ( leqi ( token, "SURF" ) == TRUE ) { 09512 continue; 09513 } 09514 /* 09515 TRACE_OBJ 09516 Ray tracing. 09517 */ 09518 else if ( leqi ( token, "TRACE_OBJ" ) == TRUE ) { 09519 continue; 09520 } 09521 /* 09522 TRIM 09523 Outer trimming loop. 09524 */ 09525 else if ( leqi ( token, "TRIM" ) == TRUE ) { 09526 continue; 09527 } 09528 /* 09529 USEMTL 09530 Material name. 09531 */ 09532 else if ( leqi ( token, "USEMTL" ) == TRUE ) { 09533 continue; 09534 } 09535 09536 /* 09537 V X Y Z W 09538 Geometric vertex. 09539 W is optional, a weight for rational curves and surfaces. 09540 The default for W is 1. 09541 */ 09542 09543 else if ( leqi ( token, "V" ) == TRUE ) { 09544 09545 sscanf ( next, "%e %e %e", &r1, &r2, &r3 ); 09546 09547 if ( cor3_num < COR3_MAX ) { 09548 cor3[0][cor3_num] = r1; 09549 cor3[1][cor3_num] = r2; 09550 cor3[2][cor3_num] = r3; 09551 } 09552 09553 cor3_num = cor3_num + 1; 09554 09555 } 09556 /* 09557 VN 09558 Vertex normals. 09559 */ 09560 09561 else if ( leqi ( token, "VN" ) == TRUE ) { 09562 09563 sscanf ( next, "%e %e %e", &r1, &r2, &r3 ); 09564 09565 if ( vertex_normal_num < ORDER_MAX * FACE_MAX ) { 09566 normal_temp[0][vertex_normal_num] = r1; 09567 normal_temp[1][vertex_normal_num] = r2; 09568 normal_temp[2][vertex_normal_num] = r3; 09569 } 09570 09571 vertex_normal_num = vertex_normal_num + 1; 09572 09573 } 09574 /* 09575 VT 09576 Vertex texture. 09577 */ 09578 else if ( leqi ( token, "VT" ) == TRUE ) { 09579 continue; 09580 } 09581 /* 09582 VP 09583 Parameter space vertices. 09584 */ 09585 else if ( leqi ( token, "VP" ) == TRUE ) { 09586 continue; 09587 } 09588 /* 09589 Unrecognized 09590 */ 09591 else { 09592 bad_num = bad_num + 1; 09593 } 09594 09595 } 09596 return SUCCESS; 09597 } 09598 /******************************************************************************/ 09599 09600 int obj_write ( FILE *fileout ) 09601 09602 /******************************************************************************/ 09603 09604 /* 09605 Purpose: 09606 09607 OBJ_WRITE writes a Wavefront OBJ file. 09608 09609 Example: 09610 09611 # magnolia.obj 09612 09613 mtllib ./vp.mtl 09614 09615 g 09616 v -3.269770 -39.572201 0.876128 09617 v -3.263720 -39.507999 2.160890 09618 ... 09619 v 0.000000 -9.988540 0.000000 09620 g stem 09621 s 1 09622 usemtl brownskn 09623 f 8 9 11 10 09624 f 12 13 15 14 09625 ... 09626 f 788 806 774 09627 09628 Modified: 09629 09630 01 September 1998 09631 09632 Author: 09633 09634 John Burkardt 09635 */ 09636 { 09637 int i; 09638 int iface; 09639 int indexvn; 09640 int ivert; 09641 int k; 09642 int new; 09643 int text_num; 09644 float w; 09645 /* 09646 Initialize. 09647 */ 09648 text_num = 0; 09649 w = 1.0; 09650 09651 fprintf ( fileout, "# %s created by IVCON.\n", fileout_name ); 09652 fprintf ( fileout, "# Original data in %s.\n", filein_name ); 09653 fprintf ( fileout, "\n" ); 09654 fprintf ( fileout, "g %s\n", object_name ); 09655 fprintf ( fileout, "\n" ); 09656 09657 text_num = text_num + 5; 09658 /* 09659 V: vertex coordinates. 09660 */ 09661 for ( i = 0; i < cor3_num; i++ ) { 09662 fprintf ( fileout, "v %f %f %f\n", 09663 cor3[0][i], cor3[1][i], cor3[2][i]); 09664 text_num = text_num + 1; 09665 } 09666 09667 /* 09668 VN: Vertex face normal vectors. 09669 */ 09670 if ( face_num > 0 ) { 09671 fprintf ( fileout, "\n" ); 09672 text_num = text_num + 1; 09673 } 09674 09675 for ( iface = 0; iface < face_num; iface++ ) { 09676 09677 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 09678 09679 fprintf ( fileout, "vn %f %f %f\n", vertex_normal[0][ivert][iface], 09680 vertex_normal[1][ivert][iface], vertex_normal[2][ivert][iface] ); 09681 text_num = text_num + 1; 09682 } 09683 } 09684 /* 09685 F: faces. 09686 */ 09687 if ( face_num > 0 ) { 09688 fprintf ( fileout, "\n" ); 09689 text_num = text_num + 1; 09690 } 09691 09692 indexvn = 0; 09693 09694 for ( iface = 0; iface < face_num; iface++ ) { 09695 09696 fprintf ( fileout, "f" ); 09697 for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { 09698 indexvn = indexvn + 1; 09699 fprintf ( fileout, " %d//%d", face[ivert][iface]+1, indexvn ); 09700 } 09701 fprintf ( fileout, "\n" ); 09702 text_num = text_num + 1; 09703 } 09704 /* 09705 L: lines. 09706 */ 09707 if ( line_num > 0 ) { 09708 fprintf ( fileout, "\n" ); 09709 text_num = text_num + 1; 09710 } 09711 09712 new = TRUE; 09713 09714 for ( i = 0; i < line_num; i++ ) { 09715 09716 k = line_dex[i]; 09717 09718 if ( k == -1 ) { 09719 fprintf ( fileout, "\n" ); 09720 text_num = text_num + 1; 09721 new = TRUE; 09722 } 09723 else { 09724 if ( new == TRUE ) { 09725 fprintf ( fileout, "l" ); 09726 new = FALSE; 09727 } 09728 fprintf ( fileout, " %d", k+1 ); 09729 } 09730 09731 } 09732 09733 fprintf ( fileout, "\n" ); 09734 text_num = text_num + 1; 09735 /* 09736 Report. 09737 */ 09738 printf ( "\n" ); 09739 printf ( "OBJ_WRITE - Wrote %d text lines.\n", text_num ); 09740 09741 return SUCCESS; 09742 } 09743 /******************************************************************************/ 09744 09745 int pov_write ( FILE *fileout ) 09746 09747 /******************************************************************************/ 09748 09749 /* 09750 Purpose: 09751 09752 POV_WRITE writes graphics information to a POV file. 09753 09754 Example: 09755 09756 // cone.pov created by IVCON. 09757 // Original data in cone.iv 09758 09759 #version 3.0 09760 #include "colors.inc" 09761 #include "shapes.inc" 09762 global_settings { assumed_gamma 2.2 } 09763 09764 camera { 09765 right < 4/3, 0, 0> 09766 up < 0, 1, 0 > 09767 sky < 0, 1, 0 > 09768 angle 20 09769 location < 0, 0, -300 > 09770 look_at < 0, 0, 0> 09771 } 09772 09773 light_source { < 20, 50, -100 > color White } 09774 09775 background { color SkyBlue } 09776 09777 #declare RedText = texture { 09778 pigment { color rgb < 0.8, 0.2, 0.2> } 09779 finish { ambient 0.2 diffuse 0.5 } 09780 } 09781 09782 #declare BlueText = texture { 09783 pigment { color rgb < 0.2, 0.2, 0.8> } 09784 finish { ambient 0.2 diffuse 0.5 } 09785 } 09786 mesh { 09787 smooth_triangle { 09788 < 0.29, -0.29, 0.0>, < 0.0, 0.0, -1.0 >, 09789 < 38.85, 10.03, 0.0>, < 0.0, 0.0, -1.0 >, 09790 < 40.21, -0.29, 0.0>, < 0.0, 0.0, -1.0 > 09791 texture { RedText } } 09792 ... 09793 smooth_triangle { 09794 < 0.29, -0.29, 70.4142 >, < 0.0, 0.0, 1.0 >, 09795 < 8.56, -2.51, 70.4142 >, < 0.0, 0.0, 1.0 >, 09796 < 8.85, -0.29, 70.4142 >, < 0.0, 0.0, 1.0 > 09797 texture { BlueText } } 09798 } 09799 09800 Modified: 09801 09802 08 October 1998 09803 09804 Author: 09805 09806 John Burkardt 09807 */ 09808 { 09809 int i; 09810 int j; 09811 int jj; 09812 int jlo; 09813 int k; 09814 int text_num; 09815 09816 text_num = 0; 09817 fprintf ( fileout, "// %s created by IVCON.\n", fileout_name ); 09818 fprintf ( fileout, "// Original data in %s.\n", filein_name ); 09819 text_num = text_num + 2; 09820 /* 09821 Initial declarations. 09822 */ 09823 fprintf ( fileout, "\n" ); 09824 fprintf ( fileout, "#version 3.0\n" ); 09825 fprintf ( fileout, "#include \"colors.inc\"\n" ); 09826 fprintf ( fileout, "#include \"shapes.inc\"\n" ); 09827 fprintf ( fileout, "global_settings { assumed_gamma 2.2 }\n" ); 09828 fprintf ( fileout, "\n" ); 09829 fprintf ( fileout, "camera {\n" ); 09830 fprintf ( fileout, " right < 4/3, 0, 0>\n" ); 09831 fprintf ( fileout, " up < 0, 1, 0 >\n" ); 09832 fprintf ( fileout, " sky < 0, 1, 0 >\n" ); 09833 fprintf ( fileout, " angle 20\n" ); 09834 fprintf ( fileout, " location < 0, 0, -300 >\n" ); 09835 fprintf ( fileout, " look_at < 0, 0, 0>\n" ); 09836 fprintf ( fileout, "}\n" ); 09837 fprintf ( fileout, "\n" ); 09838 fprintf ( fileout, "light_source { < 20, 50, -100 > color White }\n" ); 09839 fprintf ( fileout, "\n" ); 09840 fprintf ( fileout, "background { color SkyBlue }\n" ); 09841 09842 text_num = text_num + 15; 09843 /* 09844 Declare RGB textures. 09845 */ 09846 fprintf ( fileout, "\n" ); 09847 fprintf ( fileout, "#declare RedText = texture {\n" ); 09848 fprintf ( fileout, " pigment { color rgb < 0.8, 0.2, 0.2> }\n" ); 09849 fprintf ( fileout, " finish { ambient 0.2 diffuse 0.5 }\n" ); 09850 fprintf ( fileout, "}\n" ); 09851 fprintf ( fileout, "\n" ); 09852 fprintf ( fileout, "#declare GreenText = texture {\n" ); 09853 fprintf ( fileout, " pigment { color rgb < 0.2, 0.8, 0.2> }\n" ); 09854 fprintf ( fileout, " finish { ambient 0.2 diffuse 0.5 }\n" ); 09855 fprintf ( fileout, "}\n" ); 09856 fprintf ( fileout, "\n" ); 09857 fprintf ( fileout, "#declare BlueText = texture {\n" ); 09858 fprintf ( fileout, " pigment { color rgb < 0.2, 0.2, 0.8> }\n" ); 09859 fprintf ( fileout, " finish { ambient 0.2 diffuse 0.5 }\n" ); 09860 fprintf ( fileout, "}\n" ); 09861 /* 09862 Write one big object. 09863 */ 09864 fprintf ( fileout, "mesh {\n" ); 09865 text_num = text_num + 1; 09866 /* 09867 Do the next face. 09868 */ 09869 for ( i = 0; i < face_num; i++ ) { 09870 /* 09871 Break the face up into triangles, anchored at node 1. 09872 */ 09873 for ( jlo = 0; jlo < face_order[i] - 2; jlo++ ) { 09874 fprintf ( fileout, " smooth_triangle {\n" ); 09875 text_num = text_num + 1; 09876 09877 for ( j = jlo; j < jlo + 3; j++ ) { 09878 09879 if ( j == jlo ) { 09880 jj = 0; 09881 } 09882 else { 09883 jj = j; 09884 } 09885 09886 k = face[jj][i]; 09887 09888 fprintf ( fileout, "<%f, %f, %f>, <%f, %f, %f>", 09889 cor3[0][k], cor3[1][k], cor3[2][k], 09890 vertex_normal[0][jj][i], 09891 vertex_normal[1][jj][i], 09892 vertex_normal[2][jj][i] ); 09893 09894 if ( j < jlo + 2 ) { 09895 fprintf ( fileout, ",\n" ); 09896 } 09897 else { 09898 fprintf ( fileout, "\n" ); 09899 } 09900 text_num = text_num + 1; 09901 09902 } 09903 09904 if (i%6 == 1 ) { 09905 fprintf ( fileout, "texture { RedText } }\n" ); 09906 } 09907 else if ( i%2 == 0 ) { 09908 fprintf ( fileout, "texture { BlueText } }\n" ); 09909 } 09910 else { 09911 fprintf ( fileout, "texture { GreenText } }\n" ); 09912 } 09913 text_num = text_num + 1; 09914 09915 } 09916 09917 } 09918 09919 fprintf ( fileout, "}\n" ); 09920 text_num = text_num + 1; 09921 /* 09922 Report. 09923 */ 09924 printf ( "\n" ); 09925 printf ( "POV_WRITE - Wrote %d text lines.\n", text_num ); 09926 09927 return SUCCESS; 09928 } 09929 /******************************************************************************/ 09930 09931 int rcol_find ( float a[][COR3_MAX], int m, int n, float r[] ) 09932 09933 /******************************************************************************/ 09934 09935 /* 09936 Purpose: 09937 09938 RCOL_FIND finds if a vector occurs in a table. 09939 09940 Comment: 09941 09942 Explicitly forcing the second dimension to be COR3_MAX is a kludge. 09943 I have to figure out how to do this as pointer references. 09944 09945 Also, since the array is not sorted, this routine should not be carelessly 09946 called repeatedly for really big values of N, because you'll waste a 09947 lot of time. 09948 09949 Modified: 09950 09951 27 April 1999 09952 09953 Author: 09954 09955 John Burkardt 09956 */ 09957 { 09958 int i; 09959 int icol; 09960 int j; 09961 09962 icol = -1; 09963 09964 for ( j = 0; j < n; j++ ) { 09965 for ( i = 0; i < m; i++ ) { 09966 if ( a[i][j] != r[i] ) { 09967 break; 09968 } 09969 if ( i == m-1 ) { 09970 return j; 09971 } 09972 } 09973 } 09974 09975 return icol; 09976 } 09977 /**********************************************************************/ 09978 09979 float rgb_to_hue ( float r, float g, float b ) 09980 09981 /**********************************************************************/ 09982 09983 /* 09984 Purpose: 09985 09986 RGB_TO_HUE converts (R,G,B) colors to a hue value between 0 and 1. 09987 09988 Discussion: 09989 09990 The hue computed here should be the same as the H value computed 09991 for HLS and HSV, except that it ranges from 0 to 1 instead of 09992 0 to 360. 09993 09994 A monochromatic color ( white, black, or a shade of gray) does not 09995 have a hue. This routine will return a special value of H = -1 09996 for such cases. 09997 09998 Examples: 09999 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; 10376 tmat_init ( transform_matrix ); 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; 10547 face_order[face_num] = face_order[face_num] + 1; 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 10641 tmat_rot_axis ( transform_matrix, transform_matrix, angle, axis ); 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 10732 tmat_trans ( transform_matrix, transform_matrix, x, y, z ); 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 10782 face_to_vertex_material ( ); 10783 10784 vertex_to_node_material ( ); 10785 10786 } 10787 else if ( strcmp ( material_binding, "PER_VERTEX" ) == 0 ) { 10788 10789 node_to_vertex_material ( ); 10790 10791 vertex_to_face_material ( ); 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++ ) { 11140 vertex_normal[i][ivert][face_num] = face_normal[i][face_num]; 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 ); 13541 bytes_num = bytes_num + tds_write_string ( fileout, object_name ); 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 ); 13686 bytes_num = bytes_num + tds_write_string ( fileout, object_name ); 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], 15138 transform_matrix[i][1], transform_matrix[i][2], transform_matrix[i][3] ); 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 15687 void vertex_to_face_material ( void ) 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 15723 void vertex_to_node_material ( void ) 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", 16595 background_rgb[0], background_rgb[1], background_rgb[2] ); 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 }