00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <assert.h>
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <math.h>
00038 #include <string.h>
00039 #include <ply.h>
00040
00041
00042 #define ROUND(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
00043
00044
00045
00046
00047
00048
00049 #ifdef __GNUC__
00050 #define _strdup strdup
00051 #endif
00052
00053
00054
00055
00056 char *type_names[] = {
00057 "invalid",
00058 "int8", "int16", "int32", "uint8", "uint16", "uint32", "float32", "float64",
00059 };
00060
00061 char *old_type_names[] = {
00062 "invalid",
00063 "char", "short", "int", "uchar", "ushort", "uint", "float", "double",
00064 };
00065
00066 int ply_type_size[] = {
00067 0, 1, 2, 4, 1, 2, 4, 4, 8
00068 };
00069
00070 #define NO_OTHER_PROPS -1
00071
00072 #define DONT_STORE_PROP 0
00073 #define STORE_PROP 1
00074
00075 #define OTHER_PROP 0
00076 #define NAMED_PROP 1
00077
00078
00079 int equal_strings(const char *, const char *);
00080
00081
00082 PlyElement *find_element(PlyFile *, char *);
00083
00084
00085 PlyProperty *find_property(const PlyElement *, const char *, int *);
00086
00087
00088 void write_scalar_type (FILE *, int);
00089
00090
00091 char **get_words(FILE *, int *, char **);
00092
00093
00094 void write_binary_item(FILE *, int, unsigned int, double, int);
00095 void write_ascii_item(FILE *, int, unsigned int, double, int);
00096
00097
00098 void add_element(PlyFile *, char **, int);
00099 void add_property(PlyFile *, char **, int);
00100 void add_comment(PlyFile *, char *);
00101 void add_obj_info(PlyFile *, char *);
00102
00103
00104 void copy_property(PlyProperty *, PlyProperty *);
00105
00106
00107 void store_item(char *, int, int, unsigned int, double);
00108
00109
00110 void get_stored_item( void *, int, int *, unsigned int *, double *);
00111
00112
00113 double get_item_value(char *, int);
00114
00115
00116 void get_ascii_item(char *, int, int *, unsigned int *, double *);
00117 void get_binary_item(FILE *, int, int *, unsigned int *, double *);
00118
00119
00120 void ascii_get_element(PlyFile *, char *);
00121 void binary_get_element(PlyFile *, char *);
00122
00123
00124 static char *my_alloc(int, int, char *);
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 PlyFile *ply_write(
00146 FILE *fp,
00147 int nelems,
00148 char **elem_names,
00149 int file_type
00150 )
00151 {
00152 int i;
00153 PlyFile *plyfile;
00154 PlyElement *elem;
00155
00156
00157 if (fp == NULL)
00158 return (NULL);
00159
00160
00161
00162 plyfile = (PlyFile *) myalloc (sizeof (PlyFile));
00163 plyfile->file_type = file_type;
00164 plyfile->num_comments = 0;
00165 plyfile->num_obj_info = 0;
00166 plyfile->num_elem_types = nelems;
00167 plyfile->version = 1.0;
00168 plyfile->fp = fp;
00169 plyfile->other_elems = NULL;
00170
00171
00172
00173 plyfile->elems = (PlyElement **) myalloc (sizeof (PlyElement *) * nelems);
00174 for (i = 0; i < nelems; i++) {
00175 elem = (PlyElement *) myalloc (sizeof (PlyElement));
00176 plyfile->elems[i] = elem;
00177 elem->name = _strdup(elem_names[i]);
00178 elem->num = 0;
00179 elem->nprops = 0;
00180 }
00181
00182
00183 return (plyfile);
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 PlyFile *open_for_writing_ply(
00201 char *filename,
00202 int nelems,
00203 char **elem_names,
00204 int file_type
00205 )
00206 {
00207 PlyFile *plyfile;
00208 char *name;
00209 FILE *fp;
00210
00211
00212
00213 name = (char *) myalloc (sizeof (char) * (strlen (filename) + 5));
00214 strcpy (name, filename);
00215 if (strlen (name) < 4 ||
00216 strcmp (name + strlen (name) - 4, ".ply") != 0)
00217 strcat (name, ".ply");
00218
00219
00220
00221 fp = fopen (name, "w");
00222 if (fp == NULL) {
00223 return (NULL);
00224 }
00225
00226
00227
00228 plyfile = ply_write (fp, nelems, elem_names, file_type);
00229 if (plyfile == NULL)
00230 return (NULL);
00231
00232
00233 return (plyfile);
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 void element_layout_ply(
00250 PlyFile *plyfile,
00251 char *elem_name,
00252 int nelems,
00253 int nprops,
00254 PlyProperty *prop_list
00255 )
00256 {
00257 int i;
00258 PlyElement *elem;
00259 PlyProperty *prop;
00260
00261
00262 elem = find_element (plyfile, elem_name);
00263 if (elem == NULL) {
00264 fprintf(stderr,"element_layout_ply: can't find element '%s'\n",elem_name);
00265 exit (-1);
00266 }
00267
00268 elem->num = nelems;
00269
00270
00271
00272 elem->nprops = nprops;
00273 elem->props = (PlyProperty **) myalloc (sizeof (PlyProperty *) * nprops);
00274 elem->store_prop = (char *) myalloc (sizeof (char) * nprops);
00275
00276 for (i = 0; i < nprops; i++) {
00277 prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
00278 elem->props[i] = prop;
00279 elem->store_prop[i] = NAMED_PROP;
00280 copy_property (prop, &prop_list[i]);
00281 }
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 void ply_describe_property(
00295 PlyFile *plyfile,
00296 char *elem_name,
00297 PlyProperty *prop
00298 )
00299 {
00300 PlyElement *elem;
00301 PlyProperty *elem_prop;
00302
00303
00304 elem = find_element (plyfile, elem_name);
00305 if (elem == NULL) {
00306 fprintf(stderr, "ply_describe_property: can't find element '%s'\n",
00307 elem_name);
00308 return;
00309 }
00310
00311
00312
00313 if (elem->nprops == 0) {
00314 elem->props = (PlyProperty **) myalloc (sizeof (PlyProperty *));
00315 elem->store_prop = (char *) myalloc (sizeof (char));
00316 elem->nprops = 1;
00317 }
00318 else {
00319 elem->nprops++;
00320 elem->props = (PlyProperty **)
00321 realloc (elem->props, sizeof (PlyProperty *) * elem->nprops);
00322 elem->store_prop = (char *)
00323 realloc (elem->store_prop, sizeof (char) * elem->nprops);
00324 }
00325
00326
00327
00328 elem_prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
00329 elem->props[elem->nprops - 1] = elem_prop;
00330 elem->store_prop[elem->nprops - 1] = NAMED_PROP;
00331 copy_property (elem_prop, prop);
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 void element_count_ply(
00345 PlyFile *plyfile,
00346 char *elem_name,
00347 int nelems
00348 )
00349 {
00350
00351 PlyElement *elem;
00352
00353
00354 elem = find_element (plyfile, elem_name);
00355 if (elem == NULL) {
00356 fprintf(stderr,"element_count_ply: can't find element '%s'\n",elem_name);
00357 exit (-1);
00358 }
00359
00360 elem->num = nelems;
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 void header_complete_ply(PlyFile *plyfile)
00373 {
00374 int i,j;
00375 FILE *fp = plyfile->fp;
00376 PlyElement *elem;
00377 PlyProperty *prop;
00378
00379 fprintf (fp, "ply\n");
00380
00381 switch (plyfile->file_type) {
00382 case PLY_ASCII:
00383 fprintf (fp, "format ascii 1.0\n");
00384 break;
00385 case PLY_BINARY_BE:
00386 fprintf (fp, "format binary_big_endian 1.0\n");
00387 break;
00388 case PLY_BINARY_LE:
00389 fprintf (fp, "format binary_little_endian 1.0\n");
00390 break;
00391 default:
00392 fprintf (stderr, "ply_header_complete: bad file type = %d\n",
00393 plyfile->file_type);
00394 exit (-1);
00395 }
00396
00397
00398
00399 for (i = 0; i < plyfile->num_comments; i++)
00400 fprintf (fp, "comment %s\n", plyfile->comments[i]);
00401
00402
00403
00404 for (i = 0; i < plyfile->num_obj_info; i++)
00405 fprintf (fp, "obj_info %s\n", plyfile->obj_info[i]);
00406
00407
00408
00409 for (i = 0; i < plyfile->num_elem_types; i++) {
00410
00411 elem = plyfile->elems[i];
00412 fprintf (fp, "element %s %d\n", elem->name, elem->num);
00413
00414
00415 for (j = 0; j < elem->nprops; j++) {
00416 prop = elem->props[j];
00417 if (prop->is_list == PLY_LIST) {
00418 fprintf (fp, "property list ");
00419 write_scalar_type (fp, prop->count_external);
00420 fprintf (fp, " ");
00421 write_scalar_type (fp, prop->external_type);
00422 fprintf (fp, " %s\n", prop->name);
00423 }
00424 else if (prop->is_list == PLY_STRING) {
00425 fprintf (fp, "property string");
00426 fprintf (fp, " %s\n", prop->name);
00427 }
00428 else {
00429 fprintf (fp, "property ");
00430 write_scalar_type (fp, prop->external_type);
00431 fprintf (fp, " %s\n", prop->name);
00432 }
00433 }
00434 }
00435
00436 fprintf (fp, "end_header\n");
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 void put_element_setup_ply(PlyFile *plyfile, char *elem_name)
00450 {
00451 PlyElement *elem;
00452
00453 elem = find_element (plyfile, elem_name);
00454 if (elem == NULL) {
00455 fprintf(stderr, "put_element_setup_ply: can't find element '%s'\n", elem_name);
00456 exit (-1);
00457 }
00458
00459 plyfile->which_elem = elem;
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 void put_element_ply(PlyFile *plyfile, void *elem_ptr)
00474 {
00475 int j,k;
00476 FILE *fp = plyfile->fp;
00477 PlyElement *elem;
00478 PlyProperty *prop;
00479 char *item;
00480 char *elem_data;
00481 char **item_ptr;
00482 int list_count;
00483 int item_size;
00484 int int_val;
00485 unsigned int uint_val;
00486 double double_val;
00487 char **other_ptr;
00488
00489 elem = plyfile->which_elem;
00490 elem_data = (char *) elem_ptr;
00491 other_ptr = (char **) (((char *) elem_ptr) + elem->other_offset);
00492
00493
00494
00495 if (plyfile->file_type == PLY_ASCII) {
00496
00497
00498
00499
00500 for (j = 0; j < elem->nprops; j++) {
00501
00502 prop = elem->props[j];
00503
00504 if (elem->store_prop[j] == OTHER_PROP)
00505 elem_data = *other_ptr;
00506 else
00507 elem_data = (char *) elem_ptr;
00508
00509 if (prop->is_list == PLY_LIST) {
00510 item = elem_data + prop->count_offset;
00511 get_stored_item ((void *) item, prop->count_internal,
00512 &int_val, &uint_val, &double_val);
00513 write_ascii_item (fp, int_val, uint_val, double_val,
00514 prop->count_external);
00515 list_count = uint_val;
00516 item_ptr = (char **) (elem_data + prop->offset);
00517 item = item_ptr[0];
00518 item_size = ply_type_size[prop->internal_type];
00519 for (k = 0; k < list_count; k++) {
00520 get_stored_item ((void *) item, prop->internal_type,
00521 &int_val, &uint_val, &double_val);
00522 write_ascii_item (fp, int_val, uint_val, double_val,
00523 prop->external_type);
00524 item += item_size;
00525 }
00526 }
00527 else if (prop->is_list == PLY_STRING) {
00528 char **str;
00529 item = elem_data + prop->offset;
00530 str = (char **) item;
00531 fprintf (fp, "\"%s\"", *str);
00532 }
00533 else {
00534 item = elem_data + prop->offset;
00535 get_stored_item ((void *) item, prop->internal_type,
00536 &int_val, &uint_val, &double_val);
00537 write_ascii_item (fp, int_val, uint_val, double_val,
00538 prop->external_type);
00539 }
00540 }
00541
00542 fprintf (fp, "\n");
00543 }
00544 else {
00545
00546
00547
00548
00549 for (j = 0; j < elem->nprops; j++) {
00550 prop = elem->props[j];
00551 if (elem->store_prop[j] == OTHER_PROP)
00552 elem_data = *other_ptr;
00553 else
00554 elem_data = (char *) elem_ptr;
00555 if (prop->is_list == PLY_LIST) {
00556 item = elem_data + prop->count_offset;
00557 item_size = ply_type_size[prop->count_internal];
00558 get_stored_item ((void *) item, prop->count_internal,
00559 &int_val, &uint_val, &double_val);
00560 write_binary_item (fp, int_val, uint_val, double_val,
00561 prop->count_external);
00562 list_count = uint_val;
00563 item_ptr = (char **) (elem_data + prop->offset);
00564 item = item_ptr[0];
00565 item_size = ply_type_size[prop->internal_type];
00566 for (k = 0; k < list_count; k++) {
00567 get_stored_item ((void *) item, prop->internal_type,
00568 &int_val, &uint_val, &double_val);
00569 write_binary_item (fp, int_val, uint_val, double_val,
00570 prop->external_type);
00571 item += item_size;
00572 }
00573 }
00574 else if (prop->is_list == PLY_STRING) {
00575 int len;
00576 char **str;
00577 item = elem_data + prop->offset;
00578 str = (char **) item;
00579
00580
00581 len = strlen(*str) + 1;
00582 fwrite (&len, sizeof(int), 1, fp);
00583
00584
00585 fwrite (*str, len, 1, fp);
00586 }
00587 else {
00588 item = elem_data + prop->offset;
00589 item_size = ply_type_size[prop->internal_type];
00590 get_stored_item ((void *) item, prop->internal_type,
00591 &int_val, &uint_val, &double_val);
00592 write_binary_item (fp, int_val, uint_val, double_val,
00593 prop->external_type);
00594 }
00595 }
00596
00597 }
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623 PlyFile *ply_read(FILE *fp, int *nelems, char ***elem_names)
00624 {
00625 int i,j;
00626 PlyFile *plyfile;
00627 int nwords;
00628 char **words;
00629 int found_format = 0;
00630 char **elist;
00631 PlyElement *elem;
00632 char *orig_line;
00633
00634
00635 if (fp == NULL)
00636 return (NULL);
00637
00638
00639
00640 plyfile = (PlyFile *) myalloc (sizeof (PlyFile));
00641 plyfile->num_elem_types = 0;
00642 plyfile->comments = NULL;
00643 plyfile->num_comments = 0;
00644 plyfile->obj_info = NULL;
00645 plyfile->num_obj_info = 0;
00646 plyfile->fp = fp;
00647 plyfile->other_elems = NULL;
00648 plyfile->rule_list = NULL;
00649
00650
00651
00652 words = get_words (plyfile->fp, &nwords, &orig_line);
00653
00654 if (words == NULL || !equal_strings (words[0], "ply"))
00655 return (NULL);
00656
00657 while (words) {
00658
00659
00660
00661
00662 if (equal_strings (words[0], "format")) {
00663 if (nwords != 3)
00664 return (NULL);
00665
00666 if (equal_strings (words[1], "ascii"))
00667 plyfile->file_type = PLY_ASCII;
00668 else if (equal_strings (words[1], "binary_big_endian"))
00669 plyfile->file_type = PLY_BINARY_BE;
00670 else if (equal_strings (words[1], "binary_little_endian"))
00671 plyfile->file_type = PLY_BINARY_LE;
00672 else
00673 return (NULL);
00674 plyfile->version = (float)atof (words[2]);
00675 found_format = 1;
00676 }
00677 else if (equal_strings (words[0], "element"))
00678 add_element (plyfile, words, nwords);
00679 else if (equal_strings (words[0], "property"))
00680 add_property (plyfile, words, nwords);
00681 else if (equal_strings (words[0], "comment"))
00682 add_comment (plyfile, orig_line);
00683 else if (equal_strings (words[0], "obj_info"))
00684 add_obj_info (plyfile, orig_line);
00685 else if (equal_strings (words[0], "end_header"))
00686 break;
00687
00688
00689 free (words);
00690
00691 words = get_words (plyfile->fp, &nwords, &orig_line);
00692 }
00693
00694
00695
00696
00697 for (i = 0; i < plyfile->num_elem_types; i++) {
00698 elem = plyfile->elems[i];
00699 elem->store_prop = (char *) myalloc (sizeof (char) * elem->nprops);
00700 for (j = 0; j < elem->nprops; j++)
00701 elem->store_prop[j] = DONT_STORE_PROP;
00702 elem->other_offset = NO_OTHER_PROPS;
00703 }
00704
00705
00706
00707 elist = (char **) myalloc (sizeof (char *) * plyfile->num_elem_types);
00708 for (i = 0; i < plyfile->num_elem_types; i++)
00709 elist[i] = _strdup(plyfile->elems[i]->name);
00710
00711 *elem_names = elist;
00712 *nelems = plyfile->num_elem_types;
00713
00714
00715
00716 return (plyfile);
00717 }
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734 PlyFile *ply_open_for_reading(
00735 char *filename,
00736 int *nelems,
00737 char ***elem_names,
00738 int *file_type,
00739 float *version
00740 )
00741 {
00742 FILE *fp;
00743 PlyFile *plyfile;
00744 char *name;
00745
00746
00747
00748 name = (char *) myalloc (sizeof (char) * (strlen (filename) + 5));
00749 strcpy (name, filename);
00750 if (strlen (name) < 4 ||
00751 strcmp (name + strlen (name) - 4, ".ply") != 0)
00752 strcat (name, ".ply");
00753
00754
00755
00756 fp = fopen (name, "r");
00757 if (fp == NULL)
00758 return (NULL);
00759
00760
00761
00762 plyfile = ply_read (fp, nelems, elem_names);
00763
00764
00765
00766 *file_type = plyfile->file_type;
00767 *version = plyfile->version;
00768
00769
00770
00771 return (plyfile);
00772 }
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788 PlyProperty **get_element_description_ply(
00789 PlyFile *plyfile,
00790 char *elem_name,
00791 int *nelems,
00792 int *nprops
00793 )
00794 {
00795 int i;
00796 PlyElement *elem;
00797 PlyProperty *prop;
00798 PlyProperty **prop_list;
00799
00800
00801 elem = find_element (plyfile, elem_name);
00802 if (elem == NULL)
00803 return (NULL);
00804
00805 *nelems = elem->num;
00806 *nprops = elem->nprops;
00807
00808
00809 prop_list = (PlyProperty **) myalloc (sizeof (PlyProperty *) * elem->nprops);
00810 for (i = 0; i < elem->nprops; i++) {
00811 prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
00812 copy_property (prop, elem->props[i]);
00813 prop_list[i] = prop;
00814 }
00815
00816
00817 return (prop_list);
00818 }
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832 void get_element_setup_ply(
00833 PlyFile *plyfile,
00834 char *elem_name,
00835 int nprops,
00836 PlyProperty *prop_list
00837 )
00838 {
00839 int i;
00840 PlyElement *elem;
00841 PlyProperty *prop;
00842 int index;
00843
00844
00845 elem = find_element (plyfile, elem_name);
00846 plyfile->which_elem = elem;
00847
00848
00849 for (i = 0; i < nprops; i++) {
00850
00851
00852 prop = find_property (elem, prop_list[i].name, &index);
00853 if (prop == NULL) {
00854 fprintf (stderr, "Warning: Can't find property '%s' in element '%s'\n",
00855 prop_list[i].name, elem_name);
00856 continue;
00857 }
00858
00859
00860 prop->internal_type = prop_list[i].internal_type;
00861 prop->offset = prop_list[i].offset;
00862 prop->count_internal = prop_list[i].count_internal;
00863 prop->count_offset = prop_list[i].count_offset;
00864
00865
00866 elem->store_prop[index] = STORE_PROP;
00867 }
00868 }
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883 void ply_get_property(
00884 PlyFile *plyfile,
00885 char *elem_name,
00886 PlyProperty *prop
00887 )
00888 {
00889 PlyElement *elem;
00890 PlyProperty *prop_ptr;
00891 int index;
00892
00893
00894 elem = find_element (plyfile, elem_name);
00895 plyfile->which_elem = elem;
00896
00897
00898
00899 prop_ptr = find_property (elem, prop->name, &index);
00900 if (prop_ptr == NULL) {
00901 fprintf (stderr, "Warning: Can't find property '%s' in element '%s'\n",
00902 prop->name, elem_name);
00903 return;
00904 }
00905 prop_ptr->internal_type = prop->internal_type;
00906 prop_ptr->offset = prop->offset;
00907 prop_ptr->count_internal = prop->count_internal;
00908 prop_ptr->count_offset = prop->count_offset;
00909
00910
00911 elem->store_prop[index] = STORE_PROP;
00912 }
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 void ply_get_element(PlyFile *plyfile, void *elem_ptr)
00926 {
00927 if (plyfile->file_type == PLY_ASCII)
00928 ascii_get_element (plyfile, (char *) elem_ptr);
00929 else
00930 binary_get_element (plyfile, (char *) elem_ptr);
00931 }
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945 char **get_comments_ply(PlyFile *plyfile, int *num_comments)
00946 {
00947 *num_comments = plyfile->num_comments;
00948 return (plyfile->comments);
00949 }
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964 char **get_obj_info_ply(PlyFile *plyfile, int *num_obj_info)
00965 {
00966 *num_obj_info = plyfile->num_obj_info;
00967 return (plyfile->obj_info);
00968 }
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982 void setup_other_props(PlyFile * unused_file, PlyElement *elem)
00983 {
00984 int i;
00985 PlyProperty *prop;
00986 int size = 0;
00987 int type_size;
00988 unused_file = unused_file;
00989
00990
00991
00992
00993 for (type_size = 8; type_size > 0; type_size /= 2) {
00994
00995
00996
00997
00998 for (i = 0; i < elem->nprops; i++) {
00999
01000
01001 if (elem->store_prop[i])
01002 continue;
01003
01004 prop = elem->props[i];
01005
01006
01007 prop->internal_type = prop->external_type;
01008 prop->count_internal = prop->count_external;
01009
01010
01011 if (prop->is_list == PLY_LIST) {
01012
01013
01014 if (type_size == sizeof (void *)) {
01015 prop->offset = size;
01016 size += sizeof (void *);
01017 }
01018
01019
01020 if (type_size == ply_type_size[prop->count_external]) {
01021 prop->count_offset = size;
01022 size += ply_type_size[prop->count_external];
01023 }
01024 }
01025
01026 else if (prop->is_list == PLY_STRING) {
01027
01028 if (type_size == sizeof (char *)) {
01029 prop->offset = size;
01030 size += sizeof (char *);
01031 }
01032 }
01033
01034 else if (type_size == ply_type_size[prop->external_type]) {
01035 prop->offset = size;
01036 size += ply_type_size[prop->external_type];
01037 }
01038 }
01039
01040 }
01041
01042
01043 elem->other_size = size;
01044 }
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060 static PlyOtherProp *get_other_properties(
01061 PlyFile *plyfile,
01062 PlyElement *elem,
01063 int offset
01064 )
01065 {
01066 int i;
01067 PlyOtherProp *other;
01068 PlyProperty *prop;
01069 int nprops;
01070
01071
01072 plyfile->which_elem = elem;
01073
01074
01075 elem->other_offset = offset;
01076
01077
01078 setup_other_props (plyfile, elem);
01079
01080
01081 other = (PlyOtherProp *) myalloc (sizeof (PlyOtherProp));
01082 other->name = _strdup (elem->name);
01083 #if 0
01084 if (elem->other_offset == NO_OTHER_PROPS) {
01085 other->size = 0;
01086 other->props = NULL;
01087 other->nprops = 0;
01088 return (other);
01089 }
01090 #endif
01091 other->size = elem->other_size;
01092 other->props = (PlyProperty **) myalloc (sizeof(PlyProperty) * elem->nprops);
01093
01094
01095 nprops = 0;
01096 for (i = 0; i < elem->nprops; i++) {
01097 if (elem->store_prop[i])
01098 continue;
01099 prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
01100 copy_property (prop, elem->props[i]);
01101 other->props[nprops] = prop;
01102 nprops++;
01103 }
01104 other->nprops = nprops;
01105
01106
01107 if (other->nprops == 0) {
01108 elem->other_offset = NO_OTHER_PROPS;
01109 }
01110
01111
01112 return (other);
01113 }
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130 PlyOtherProp *ply_get_other_properties(
01131 PlyFile *plyfile,
01132 char *elem_name,
01133 int offset
01134 )
01135 {
01136 PlyElement *elem;
01137 PlyOtherProp *other;
01138
01139
01140 elem = find_element (plyfile, elem_name);
01141 if (elem == NULL) {
01142 fprintf (stderr, "ply_get_other_properties: Can't find element '%s'\n",
01143 elem_name);
01144 return (NULL);
01145 }
01146
01147 other = get_other_properties (plyfile, elem, offset);
01148 return (other);
01149 }
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173 PlyOtherElems *get_other_element_ply (PlyFile *plyfile)
01174 {
01175 int i;
01176 PlyElement *elem;
01177 char *elem_name;
01178 int elem_count;
01179 PlyOtherElems *other_elems;
01180 OtherElem *other;
01181
01182 elem = plyfile->which_elem;
01183 elem_name = elem->name;
01184 elem_count = elem->num;
01185
01186
01187
01188
01189 if (plyfile->other_elems == NULL) {
01190 plyfile->other_elems = (PlyOtherElems *) myalloc (sizeof (PlyOtherElems));
01191 other_elems = plyfile->other_elems;
01192 other_elems->other_list = (OtherElem *) myalloc (sizeof (OtherElem));
01193 other = &(other_elems->other_list[0]);
01194 other_elems->num_elems = 1;
01195 }
01196 else {
01197 other_elems = plyfile->other_elems;
01198 other_elems->other_list = (OtherElem *) realloc (other_elems->other_list,
01199 sizeof (OtherElem) * other_elems->num_elems + 1);
01200 other = &(other_elems->other_list[other_elems->num_elems]);
01201 other_elems->num_elems++;
01202 }
01203
01204
01205 other->elem_count = elem_count;
01206
01207
01208 other->elem_name = _strdup (elem_name);
01209
01210
01211 other->other_data = (OtherData **)
01212 malloc (sizeof (OtherData *) * other->elem_count);
01213
01214
01215 other->other_props = ply_get_other_properties (plyfile, elem_name,
01216 offsetof(OtherData,other_props));
01217
01218
01219 for (i = 0; i < other->elem_count; i++) {
01220
01221 other->other_data[i] = (OtherData *) malloc (sizeof (OtherData));
01222 ply_get_element (plyfile, (void *) other->other_data[i]);
01223 }
01224
01225
01226 return (other_elems);
01227 }
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237 void put_other_elements_ply (PlyFile *plyfile)
01238 {
01239 int i,j;
01240 OtherElem *other;
01241
01242
01243 if (plyfile->other_elems == NULL)
01244 return;
01245
01246
01247
01248 for (i = 0; i < plyfile->other_elems->num_elems; i++) {
01249
01250 other = &(plyfile->other_elems->other_list[i]);
01251 put_element_setup_ply (plyfile, other->elem_name);
01252
01253
01254 for (j = 0; j < other->elem_count; j++)
01255 put_element_ply (plyfile, (void *) other->other_data[j]);
01256 }
01257 }
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267 void free_other_elements_ply (PlyOtherElems * other_elems)
01268 {
01269 other_elems = other_elems;
01270 }
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287 void ply_close(PlyFile *plyfile)
01288 {
01289 fclose (plyfile->fp);
01290
01291
01292 free (plyfile);
01293 }
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307 void get_info_ply(PlyFile *ply, float *version, int *file_type)
01308 {
01309 if (ply == NULL)
01310 return;
01311
01312 *version = ply->version;
01313 *file_type = ply->file_type;
01314 }
01315
01316
01317
01318
01319
01320
01321 int equal_strings(const char *s1, const char *s2)
01322 {
01323
01324 while (*s1 && *s2)
01325 if (*s1++ != *s2++)
01326 return (0);
01327
01328 if (*s1 != *s2)
01329 return (0);
01330 else
01331 return (1);
01332 }
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343 char *recreate_command_line (int argc, char *argv[])
01344 {
01345 int i;
01346 char *line;
01347 int len = 0;
01348
01349
01350 for (i = 0; i < argc; i++)
01351 len += strlen(argv[i]) + 1;
01352
01353
01354 line = (char *) malloc (sizeof(char) * len);
01355 line[0] = '\0';
01356
01357
01358 for (i = 0; i < argc; i++) {
01359 strcat (line, argv[i]);
01360 if (i != argc - 1)
01361 strcat (line, " ");
01362 }
01363
01364 return (line);
01365 }
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379 PlyElement *find_element(PlyFile *plyfile, char *element)
01380 {
01381 int i;
01382
01383 for (i = 0; i < plyfile->num_elem_types; i++)
01384 if (equal_strings (element, plyfile->elems[i]->name))
01385 return (plyfile->elems[i]);
01386
01387 return (NULL);
01388 }
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403 PlyProperty *find_property(const PlyElement *elem, const char *prop_name, int *index)
01404 {
01405 int i;
01406
01407 for (i = 0; i < elem->nprops; i++)
01408 if (equal_strings (prop_name, elem->props[i]->name)) {
01409 *index = i;
01410 return (elem->props[i]);
01411 }
01412
01413 *index = -1;
01414 return (NULL);
01415 }
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426 void ascii_get_element(PlyFile *plyfile, char *elem_ptr)
01427 {
01428 int j,k;
01429 PlyElement *elem;
01430 PlyProperty *prop;
01431 char **words;
01432 int nwords;
01433 int which_word;
01434 char *elem_data,*item;
01435 char *item_ptr;
01436 int item_size;
01437 int int_val;
01438 unsigned int uint_val;
01439 double double_val;
01440 int list_count;
01441 int store_it;
01442 char **store_array;
01443 char *orig_line;
01444 char *other_data;
01445 int other_flag;
01446
01447
01448 elem = plyfile->which_elem;
01449
01450
01451
01452 if (elem->other_offset != NO_OTHER_PROPS) {
01453 char **ptr;
01454 other_flag = 1;
01455
01456 other_data = (char *) myalloc (elem->other_size);
01457
01458 ptr = (char **) (elem_ptr + elem->other_offset);
01459 *ptr = other_data;
01460 }
01461 else
01462 other_flag = 0;
01463
01464
01465
01466 words = get_words (plyfile->fp, &nwords, &orig_line);
01467 if (words == NULL) {
01468 fprintf (stderr, "ply_get_element: unexpected end of file\n");
01469 exit (-1);
01470 }
01471
01472 which_word = 0;
01473
01474 for (j = 0; j < elem->nprops; j++) {
01475
01476 prop = elem->props[j];
01477 store_it = (elem->store_prop[j] | other_flag);
01478
01479
01480 if (elem->store_prop[j])
01481 elem_data = elem_ptr;
01482 else
01483 elem_data = other_data;
01484
01485 if (prop->is_list == PLY_LIST) {
01486
01487
01488 get_ascii_item (words[which_word++], prop->count_external,
01489 &int_val, &uint_val, &double_val);
01490 if (store_it) {
01491 item = elem_data + prop->count_offset;
01492 store_item(item, prop->count_internal, int_val, uint_val, double_val);
01493 }
01494
01495
01496 list_count = int_val;
01497 item_size = ply_type_size[prop->internal_type];
01498 store_array = (char **) (elem_data + prop->offset);
01499
01500 if (list_count == 0) {
01501 if (store_it)
01502 *store_array = NULL;
01503 }
01504 else {
01505 if (store_it) {
01506 item_ptr = (char *) myalloc (sizeof (char) * item_size * list_count);
01507 item = item_ptr;
01508 *store_array = item_ptr;
01509 }
01510
01511
01512 for (k = 0; k < list_count; k++) {
01513 get_ascii_item (words[which_word++], prop->external_type,
01514 &int_val, &uint_val, &double_val);
01515 if (store_it) {
01516 store_item (item, prop->internal_type,
01517 int_val, uint_val, double_val);
01518 item += item_size;
01519 }
01520 }
01521 }
01522
01523 }
01524 else if (prop->is_list == PLY_STRING) {
01525 if (store_it) {
01526 char *str;
01527 char **str_ptr;
01528 str = _strdup (words[which_word++]);
01529 item = elem_data + prop->offset;
01530 str_ptr = (char **) item;
01531 *str_ptr = str;
01532 }
01533 else {
01534 which_word++;
01535 }
01536 }
01537 else {
01538 get_ascii_item (words[which_word++], prop->external_type,
01539 &int_val, &uint_val, &double_val);
01540 if (store_it) {
01541 item = elem_data + prop->offset;
01542 store_item (item, prop->internal_type, int_val, uint_val, double_val);
01543 }
01544 }
01545
01546 }
01547
01548 free (words);
01549 }
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560 void binary_get_element(PlyFile *plyfile, char *elem_ptr)
01561 {
01562 int j,k;
01563 PlyElement *elem;
01564 PlyProperty *prop;
01565 FILE *fp = plyfile->fp;
01566 char *elem_data;
01567 char *item;
01568 char *item_ptr;
01569 int item_size;
01570 int int_val;
01571 unsigned int uint_val;
01572 double double_val;
01573 int list_count;
01574 int store_it;
01575 char **store_array;
01576 char *other_data;
01577 int other_flag;
01578
01579
01580 elem = plyfile->which_elem;
01581
01582
01583
01584 if (elem->other_offset != NO_OTHER_PROPS) {
01585 char **ptr;
01586 other_flag = 1;
01587
01588 other_data = (char *) myalloc (elem->other_size);
01589
01590 ptr = (char **) (elem_ptr + elem->other_offset);
01591 *ptr = other_data;
01592 }
01593 else
01594 other_flag = 0;
01595
01596
01597
01598 for (j = 0; j < elem->nprops; j++) {
01599
01600 prop = elem->props[j];
01601
01602 store_it = (elem->store_prop[j] | other_flag);
01603
01604
01605 if (elem->store_prop[j])
01606 elem_data = elem_ptr;
01607 else
01608 elem_data = other_data;
01609
01610 if (prop->is_list == PLY_LIST) {
01611
01612
01613 get_binary_item (fp, prop->count_external,
01614 &int_val, &uint_val, &double_val);
01615 if (store_it) {
01616 item = elem_data + prop->count_offset;
01617 store_item(item, prop->count_internal, int_val, uint_val, double_val);
01618 }
01619
01620
01621 list_count = int_val;
01622 item_size = ply_type_size[prop->internal_type];
01623 store_array = (char **) (elem_data + prop->offset);
01624 if (list_count == 0) {
01625 if (store_it)
01626 *store_array = NULL;
01627 }
01628 else {
01629 if (store_it) {
01630 item_ptr = (char *) myalloc (sizeof (char) * item_size * list_count);
01631 item = item_ptr;
01632 *store_array = item_ptr;
01633 }
01634
01635
01636 for (k = 0; k < list_count; k++) {
01637 get_binary_item (fp, prop->external_type,
01638 &int_val, &uint_val, &double_val);
01639 if (store_it) {
01640 store_item (item, prop->internal_type,
01641 int_val, uint_val, double_val);
01642 item += item_size;
01643 }
01644 }
01645 }
01646
01647 }
01648 else if (prop->is_list == PLY_STRING) {
01649 int len;
01650 char *str;
01651 if(fread (&len, sizeof(int), 1, fp) != 1) {
01652 fprintf (stderr,"binary_get_elements: Error reading ply string.\n");
01653 return;
01654 }
01655
01656 str = (char *) myalloc (len);
01657 if( fread (str, len, 1, fp) != 1) {
01658 fprintf (stderr, "get_new_props_ply: Error combining properties that should be the same.\n");
01659 return;
01660 }
01661 if (store_it) {
01662 char **str_ptr;
01663 item = elem_data + prop->offset;
01664 str_ptr = (char **) item;
01665 *str_ptr = str;
01666 }
01667 }
01668 else {
01669 get_binary_item (fp, prop->external_type,
01670 &int_val, &uint_val, &double_val);
01671 if (store_it) {
01672 item = elem_data + prop->offset;
01673 store_item (item, prop->internal_type, int_val, uint_val, double_val);
01674 }
01675 }
01676
01677 }
01678 }
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689 void write_scalar_type (FILE *fp, int code)
01690 {
01691
01692
01693 if (code <= StartType || code >= EndType) {
01694 fprintf (stderr, "write_scalar_type: bad data code = %d\n", code);
01695 exit (-1);
01696 }
01697
01698
01699
01700 fprintf (fp, "%s", type_names[code]);
01701 }
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719 char **get_words(FILE *fp, int *nwords, char **orig_line)
01720 {
01721 #define BIG_STRING 4096
01722 static char str[BIG_STRING];
01723 static char str_copy[BIG_STRING];
01724 char **words;
01725 int max_words = 10;
01726 int num_words = 0;
01727 char *ptr,*ptr2;
01728 char *result;
01729
01730 words = (char **) myalloc (sizeof (char *) * max_words);
01731
01732
01733 result = fgets (str, BIG_STRING, fp);
01734
01735 if (result == NULL) {
01736 *nwords = 0;
01737 *orig_line = NULL;
01738 return (NULL);
01739 }
01740
01741
01742
01743
01744
01745 str[BIG_STRING-2] = ' ';
01746 str[BIG_STRING-1] = '\0';
01747
01748 for (ptr = str, ptr2 = str_copy; *ptr != '\0'; ptr++, ptr2++) {
01749 *ptr2 = *ptr;
01750 if (*ptr == '\t') {
01751 *ptr = ' ';
01752 *ptr2 = ' ';
01753 }
01754 else if (*ptr == '\r') {
01755 *ptr = ' ';
01756 *ptr2 = ' ';
01757 }
01758 else if (*ptr == '\n') {
01759 *ptr = ' ';
01760 *ptr2 = '\0';
01761 break;
01762 }
01763 }
01764
01765
01766
01767 ptr = str;
01768 while (*ptr != '\0') {
01769
01770
01771 while (*ptr == ' ')
01772 ptr++;
01773
01774
01775 if (*ptr == '\0')
01776 break;
01777
01778
01779 if (num_words >= max_words) {
01780 max_words += 10;
01781 words = (char **) realloc (words, sizeof (char *) * max_words);
01782 }
01783
01784 if (*ptr == '\"') {
01785
01786
01787 ptr++;
01788
01789
01790 words[num_words++] = ptr;
01791
01792
01793 while (*ptr != '\"' && *ptr != '\0')
01794 ptr++;
01795
01796
01797
01798 if (*ptr != '\0')
01799 *ptr++ = '\0';
01800 }
01801 else {
01802
01803
01804 words[num_words++] = ptr;
01805
01806
01807 while (*ptr != ' ')
01808 ptr++;
01809
01810
01811 *ptr++ = '\0';
01812 }
01813 }
01814
01815
01816 *nwords = num_words;
01817 *orig_line = str_copy;
01818 return (words);
01819 }
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833 double get_item_value(char *item, int type)
01834 {
01835 unsigned char *puchar;
01836 char *pchar;
01837 short int *pshort;
01838 unsigned short int *pushort;
01839 int *pint;
01840 unsigned int *puint;
01841 float *pfloat;
01842 double *pdouble;
01843 int int_value;
01844 unsigned int uint_value;
01845 double double_value;
01846
01847 switch (type) {
01848 case Int8:
01849 pchar = (char *) item;
01850 int_value = *pchar;
01851 return ((double) int_value);
01852 case Uint8:
01853 puchar = (unsigned char *) item;
01854 int_value = *puchar;
01855 return ((double) int_value);
01856 case Int16:
01857 pshort = (short int *) item;
01858 int_value = *pshort;
01859 return ((double) int_value);
01860 case Uint16:
01861 pushort = (unsigned short int *) item;
01862 int_value = *pushort;
01863 return ((double) int_value);
01864 case Int32:
01865 pint = (int *) item;
01866 int_value = *pint;
01867 return ((double) int_value);
01868 case Uint32:
01869 puint = (unsigned int *) item;
01870 uint_value = *puint;
01871 return ((double) uint_value);
01872 case Float32:
01873 pfloat = (float *) item;
01874 double_value = *pfloat;
01875 return (double_value);
01876 case Float64:
01877 pdouble = (double *) item;
01878 double_value = *pdouble;
01879 return (double_value);
01880 default:
01881 fprintf (stderr, "get_item_value: bad type = %d\n", type);
01882 exit (-1);
01883 }
01884
01885 return (0.0);
01886 }
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900 void write_binary_item(
01901 FILE *fp,
01902 int int_val,
01903 unsigned int uint_val,
01904 double double_val,
01905 int type
01906 )
01907 {
01908 unsigned char uchar_val;
01909 char char_val;
01910 unsigned short ushort_val;
01911 short short_val;
01912 float float_val;
01913
01914 switch (type) {
01915 case Int8:
01916 char_val = int_val;
01917 fwrite (&char_val, 1, 1, fp);
01918 break;
01919 case Int16:
01920 short_val = int_val;
01921 fwrite (&short_val, 2, 1, fp);
01922 break;
01923 case Int32:
01924 fwrite (&int_val, 4, 1, fp);
01925 break;
01926 case Uint8:
01927 uchar_val = uint_val;
01928 fwrite (&uchar_val, 1, 1, fp);
01929 break;
01930 case Uint16:
01931 ushort_val = uint_val;
01932 fwrite (&ushort_val, 2, 1, fp);
01933 break;
01934 case Uint32:
01935 fwrite (&uint_val, 4, 1, fp);
01936 break;
01937 case Float32:
01938 float_val = (float)double_val;
01939 fwrite (&float_val, 4, 1, fp);
01940 break;
01941 case Float64:
01942 fwrite (&double_val, 8, 1, fp);
01943 break;
01944 default:
01945 fprintf (stderr, "write_binary_item: bad type = %d\n", type);
01946 exit (-1);
01947 }
01948 }
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962 void write_ascii_item(
01963 FILE *fp,
01964 int int_val,
01965 unsigned int uint_val,
01966 double double_val,
01967 int type
01968 )
01969 {
01970 switch (type) {
01971 case Int8:
01972 case Int16:
01973 case Int32:
01974 fprintf (fp, "%d ", int_val);
01975 break;
01976 case Uint8:
01977 case Uint16:
01978 case Uint32:
01979 fprintf (fp, "%u ", uint_val);
01980 break;
01981 case Float32:
01982 case Float64:
01983 fprintf (fp, "%g ", double_val);
01984 break;
01985 default:
01986 fprintf (stderr, "write_ascii_item: bad type = %d\n", type);
01987 exit (-1);
01988 }
01989 }
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006 void get_stored_item(
02007 void *ptr,
02008 int type,
02009 int *int_val,
02010 unsigned int *uint_val,
02011 double *double_val
02012 )
02013 {
02014 switch (type) {
02015 case Int8:
02016 *int_val = *((char *) ptr);
02017 *uint_val = *int_val;
02018 *double_val = *int_val;
02019 break;
02020 case Uint8:
02021 *uint_val = *((unsigned char *) ptr);
02022 *int_val = *uint_val;
02023 *double_val = *uint_val;
02024 break;
02025 case Int16:
02026 *int_val = *((short int *) ptr);
02027 *uint_val = *int_val;
02028 *double_val = *int_val;
02029 break;
02030 case Uint16:
02031 *uint_val = *((unsigned short int *) ptr);
02032 *int_val = *uint_val;
02033 *double_val = *uint_val;
02034 break;
02035 case Int32:
02036 *int_val = *((int *) ptr);
02037 *uint_val = *int_val;
02038 *double_val = *int_val;
02039 break;
02040 case Uint32:
02041 *uint_val = *((unsigned int *) ptr);
02042 *int_val = *uint_val;
02043 *double_val = *uint_val;
02044 break;
02045 case Float32:
02046 *double_val = *((float *) ptr);
02047 *int_val = ROUND(*double_val);
02048 *uint_val = (long)(*double_val+0.5);
02049 break;
02050 case Float64:
02051 *double_val = *((double *) ptr);
02052 *int_val = ROUND(*double_val);
02053 *uint_val = (long)(*double_val+0.5);
02054 break;
02055 default:
02056 fprintf (stderr, "get_stored_item: bad type = %d\n", type);
02057 exit (-1);
02058 }
02059 }
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076 void get_binary_item(
02077 FILE *fp,
02078 int type,
02079 int *int_val,
02080 unsigned int *uint_val,
02081 double *double_val
02082 )
02083 {
02084 char c[8];
02085 void *ptr;
02086
02087 ptr = (void *) c;
02088
02089 switch (type) {
02090 case Int8:
02091 if(fread (ptr, 1, 1, fp) != 1) {
02092 fprintf (stderr,"get_binary_item: Error getting Int8.\n");
02093 return;
02094 }
02095 *int_val = *((char *) ptr);
02096 *uint_val = *int_val;
02097 *double_val = *int_val;
02098 break;
02099 case Uint8:
02100 if(fread (ptr, 1, 1, fp) != 1) {
02101 fprintf (stderr,"get_binary_item: Error getting Int8.\n");
02102 return;
02103 }
02104 *uint_val = *((unsigned char *) ptr);
02105 *int_val = *uint_val;
02106 *double_val = *uint_val;
02107 break;
02108 case Int16:
02109 if(fread (ptr, 2, 1, fp) != 1) {
02110 fprintf (stderr,"get_binary_item: Error getting Int16.\n");
02111 return;
02112 }
02113
02114 *int_val = *((short int *) ptr);
02115 *uint_val = *int_val;
02116 *double_val = *int_val;
02117 break;
02118 case Uint16:
02119 if(fread (ptr, 2, 1, fp) != 1) {
02120 fprintf (stderr,"get_binary_item: Error getting UInt16.\n");
02121 return;
02122 }
02123 *uint_val = *((unsigned short int *) ptr);
02124 *int_val = *uint_val;
02125 *double_val = *uint_val;
02126 break;
02127 case Int32:
02128 if(fread (ptr, 4, 1, fp) != 1) {
02129 fprintf (stderr,"get_binary_item: Error getting Int32.\n");
02130 return;
02131 }
02132
02133 *int_val = *((int *) ptr);
02134 *uint_val = *int_val;
02135 *double_val = *int_val;
02136 break;
02137 case Uint32:
02138 if(fread (ptr, 4, 1, fp) != 1) {
02139 fprintf (stderr,"get_binary_item: Error getting UInt32.\n");
02140 return;
02141 }
02142 *uint_val = *((unsigned int *) ptr);
02143 *int_val = *uint_val;
02144 *double_val = *uint_val;
02145 break;
02146 case Float32:
02147 if(fread (ptr, 4, 1, fp) != 1) {
02148 fprintf (stderr,"get_binary_item: Error getting Float32.\n");
02149 return;
02150 }
02151 *double_val = *((float *) ptr);
02152 *int_val = ROUND(*double_val);
02153 *uint_val = (long)(*double_val+0.5);
02154 break;
02155 case Float64:
02156 if(fread (ptr, 8, 1, fp) != 1) {
02157 fprintf (stderr,"get_binary_item: Error getting Float32.\n");
02158 return;
02159 }
02160
02161 *double_val = *((double *) ptr);
02162 *int_val = ROUND(*double_val);
02163 *uint_val = (long)(*double_val+0.5);
02164 break;
02165 default:
02166 fprintf (stderr, "get_binary_item: bad type = %d\n", type);
02167 exit (-1);
02168 }
02169 }
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186 void get_ascii_item(
02187 char *word,
02188 int type,
02189 int *int_val,
02190 unsigned int *uint_val,
02191 double *double_val
02192 )
02193 {
02194 switch (type) {
02195 case Int8:
02196 case Uint8:
02197 case Int16:
02198 case Uint16:
02199 case Int32:
02200 *int_val = atoi (word);
02201 *uint_val = *int_val;
02202 *double_val = *int_val;
02203 break;
02204
02205 case Uint32:
02206 *uint_val = strtoul (word, (char **) NULL, 10);
02207 *int_val = *uint_val;
02208 *double_val = *uint_val;
02209 break;
02210
02211 case Float32:
02212 case Float64:
02213 *double_val = atof (word);
02214 *int_val = (int) *double_val;
02215 *uint_val = (unsigned int) *double_val;
02216 break;
02217
02218 default:
02219 fprintf (stderr, "get_ascii_item: bad type = %d\n", type);
02220 exit (-1);
02221 }
02222 }
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239 void store_item (
02240 char *item,
02241 int type,
02242 int int_val,
02243 unsigned int uint_val,
02244 double double_val
02245 )
02246 {
02247 unsigned char *puchar;
02248 short int *pshort;
02249 unsigned short int *pushort;
02250 int *pint;
02251 unsigned int *puint;
02252 float *pfloat;
02253 double *pdouble;
02254
02255 switch (type) {
02256 case Int8:
02257 *item = int_val;
02258 break;
02259 case Uint8:
02260 puchar = (unsigned char *) item;
02261 *puchar = uint_val;
02262 break;
02263 case Int16:
02264 pshort = (short *) item;
02265 *pshort = int_val;
02266 break;
02267 case Uint16:
02268 pushort = (unsigned short *) item;
02269 *pushort = uint_val;
02270 break;
02271 case Int32:
02272 pint = (int *) item;
02273 *pint = int_val;
02274 break;
02275 case Uint32:
02276 puint = (unsigned int *) item;
02277 *puint = uint_val;
02278 break;
02279 case Float32:
02280 pfloat = (float *) item;
02281 *pfloat = (float)double_val;
02282 break;
02283 case Float64:
02284 pdouble = (double *) item;
02285 *pdouble = double_val;
02286 break;
02287 default:
02288 fprintf (stderr, "store_item: bad type = %d\n", type);
02289 exit (-1);
02290 }
02291 }
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303 void add_element (PlyFile *plyfile, char **words, int nwords)
02304 {
02305
02306 PlyElement *elem;
02307
02308 nwords = nwords;
02309
02310
02311
02312 elem = (PlyElement *) myalloc (sizeof (PlyElement));
02313 elem->name = _strdup (words[1]);
02314 elem->num = atoi (words[2]);
02315 elem->nprops = 0;
02316
02317
02318 if (plyfile->num_elem_types == 0)
02319 plyfile->elems = (PlyElement **) myalloc (sizeof (PlyElement *));
02320 else
02321 plyfile->elems = (PlyElement **) realloc (plyfile->elems,
02322 sizeof (PlyElement *) * (plyfile->num_elem_types + 1));
02323
02324
02325 plyfile->elems[plyfile->num_elem_types] = elem;
02326 plyfile->num_elem_types++;
02327 }
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340 int get_prop_type(char *type_name)
02341 {
02342 int i;
02343
02344
02345 for (i = StartType + 1; i < EndType; i++)
02346 if (equal_strings (type_name, type_names[i]))
02347 return (i);
02348
02349
02350 for (i = StartType + 1; i < EndType; i++)
02351 if (equal_strings (type_name, old_type_names[i]))
02352 return (i);
02353
02354
02355 return (0);
02356 }
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368 void add_property (PlyFile *plyfile, char **words, int nwords)
02369 {
02370 PlyProperty *prop;
02371 PlyElement *elem;
02372
02373 nwords = nwords;
02374
02375
02376 prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
02377
02378 if (equal_strings (words[1], "list")) {
02379 prop->count_external = get_prop_type (words[2]);
02380 prop->external_type = get_prop_type (words[3]);
02381 prop->name = _strdup (words[4]);
02382 prop->is_list = PLY_LIST;
02383 }
02384 else if (equal_strings (words[1], "string")) {
02385 prop->count_external = Int8;
02386 prop->external_type = Int8;
02387 prop->name = _strdup (words[2]);
02388 prop->is_list = PLY_STRING;
02389 }
02390 else {
02391 prop->external_type = get_prop_type (words[1]);
02392 prop->name = _strdup (words[2]);
02393 prop->is_list = PLY_SCALAR;
02394 }
02395
02396
02397
02398 elem = plyfile->elems[plyfile->num_elem_types - 1];
02399
02400 if (elem->nprops == 0)
02401 elem->props = (PlyProperty **) myalloc (sizeof (PlyProperty *));
02402 else
02403 elem->props = (PlyProperty **) realloc (elem->props,
02404 sizeof (PlyProperty *) * (elem->nprops + 1));
02405
02406 elem->props[elem->nprops] = prop;
02407 elem->nprops++;
02408 }
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419 void add_comment (PlyFile *plyfile, char *line)
02420 {
02421 int i;
02422
02423
02424 i = 7;
02425 while (line[i] == ' ' || line[i] == '\t')
02426 i++;
02427
02428 append_comment_ply (plyfile, &line[i]);
02429 }
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440 void add_obj_info (PlyFile *plyfile, char *line)
02441 {
02442 int i;
02443
02444
02445 i = 8;
02446 while (line[i] == ' ' || line[i] == '\t')
02447 i++;
02448
02449 append_obj_info_ply (plyfile, &line[i]);
02450 }
02451
02452
02453
02454
02455
02456
02457 void copy_property(PlyProperty *dest, PlyProperty *src)
02458 {
02459 dest->name = _strdup (src->name);
02460 dest->external_type = src->external_type;
02461 dest->internal_type = src->internal_type;
02462 dest->offset = src->offset;
02463
02464 dest->is_list = src->is_list;
02465 dest->count_external = src->count_external;
02466 dest->count_internal = src->count_internal;
02467 dest->count_offset = src->count_offset;
02468 }
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480 static char *my_alloc(int size, int lnum, char *fname)
02481 {
02482 char *ptr;
02483
02484 ptr = (char *) malloc (size);
02485
02486 if (ptr == 0) {
02487 fprintf(stderr, "Memory allocation bombed on line %d in %s\n", lnum, fname);
02488 }
02489
02490 return (ptr);
02491 }
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513 PlyFile *read_ply(FILE *fp)
02514 {
02515 PlyFile *ply;
02516 int num_elems;
02517 char **elem_names;
02518
02519 ply = ply_read (fp, &num_elems, &elem_names);
02520
02521 return (ply);
02522 }
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538 PlyFile *write_ply(
02539 FILE *fp,
02540 int nelems,
02541 char **elem_names,
02542 int file_type
02543 )
02544 {
02545 PlyFile *ply;
02546
02547 ply = ply_write (fp, nelems, elem_names, file_type);
02548
02549 return (ply);
02550 }
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564 char **get_element_list_ply(PlyFile *ply, int *num_elems)
02565 {
02566 int i;
02567 char **elist;
02568
02569
02570
02571 elist = (char **) myalloc (sizeof (char *) * ply->num_elem_types);
02572 for (i = 0; i < ply->num_elem_types; i++)
02573 elist[i] = _strdup (ply->elems[i]->name);
02574
02575
02576 *num_elems = ply->num_elem_types;
02577 return (elist);
02578 }
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589 void append_comment_ply(PlyFile *ply, char *comment)
02590 {
02591
02592 if (ply->num_comments == 0)
02593 ply->comments = (char **) myalloc (sizeof (char *));
02594 else
02595 ply->comments = (char **) realloc (ply->comments,
02596 sizeof (char *) * (ply->num_comments + 1));
02597
02598
02599 ply->comments[ply->num_comments] = _strdup (comment);
02600 ply->num_comments++;
02601 }
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612 void copy_comments_ply(PlyFile *out_ply, PlyFile *in_ply)
02613 {
02614 int i;
02615
02616 for (i = 0; i < in_ply->num_comments; i++)
02617 append_comment_ply (out_ply, in_ply->comments[i]);
02618 }
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629 void append_obj_info_ply(PlyFile *ply, char *obj_info)
02630 {
02631
02632 if (ply->num_obj_info == 0)
02633 ply->obj_info = (char **) myalloc (sizeof (char *));
02634 else
02635 ply->obj_info = (char **) realloc (ply->obj_info,
02636 sizeof (char *) * (ply->num_obj_info + 1));
02637
02638
02639 ply->obj_info[ply->num_obj_info] = _strdup (obj_info);
02640 ply->num_obj_info++;
02641 }
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652 void copy_obj_info_ply(PlyFile *out_ply, PlyFile *in_ply)
02653 {
02654 int i;
02655
02656 for (i = 0; i < in_ply->num_obj_info; i++)
02657 append_obj_info_ply (out_ply, in_ply->obj_info[i]);
02658 }
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668 void close_ply(PlyFile *plyfile)
02669 {
02670 fclose (plyfile->fp);
02671 }
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681 void free_ply(PlyFile *plyfile)
02682 {
02683
02684 free (plyfile);
02685 }
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700 char *setup_element_read_ply (PlyFile *ply, int index, int *elem_count)
02701 {
02702 PlyElement *elem;
02703
02704 if (index < 0 || index > ply->num_elem_types) {
02705 fprintf (stderr, "Warning: No element with index %d\n", index);
02706 return (0);
02707 }
02708
02709 elem = ply->elems[index];
02710
02711
02712 ply->which_elem = elem;
02713
02714
02715 *elem_count = elem->num;
02716 return (elem->name);
02717 }
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730 void get_element_ply (PlyFile *plyfile, void *elem_ptr)
02731 {
02732 if (plyfile->file_type == PLY_ASCII)
02733 ascii_get_element (plyfile, (char *) elem_ptr);
02734 else
02735 binary_get_element (plyfile, (char *) elem_ptr);
02736 }
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749 void setup_property_ply(
02750 PlyFile *plyfile,
02751 PlyProperty *prop
02752 )
02753 {
02754 PlyElement *elem;
02755 PlyProperty *prop_ptr;
02756 int index;
02757
02758 elem = plyfile->which_elem;
02759
02760
02761
02762 prop_ptr = find_property (elem, prop->name, &index);
02763 if (prop_ptr == NULL) {
02764 fprintf (stderr, "Warning: Can't find property '%s' in element '%s'\n",
02765 prop->name, elem->name);
02766 return;
02767 }
02768 prop_ptr->internal_type = prop->internal_type;
02769 prop_ptr->offset = prop->offset;
02770 prop_ptr->count_internal = prop->count_internal;
02771 prop_ptr->count_offset = prop->count_offset;
02772
02773
02774 elem->store_prop[index] = STORE_PROP;
02775 }
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790 PlyOtherProp *get_other_properties_ply(
02791 PlyFile *plyfile,
02792 int offset
02793 )
02794 {
02795 PlyOtherProp *other;
02796
02797 other = get_other_properties (plyfile, plyfile->which_elem, offset);
02798 return (other);
02799 }
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812 void describe_element_ply(
02813 PlyFile *plyfile,
02814 char *elem_name,
02815 int nelems
02816 )
02817 {
02818 PlyElement *elem;
02819
02820
02821 elem = find_element (plyfile, elem_name);
02822 if (elem == NULL) {
02823 fprintf(stderr,"describe_element_ply: can't find element '%s'\n",elem_name);
02824 exit (-1);
02825 }
02826
02827 elem->num = nelems;
02828
02829
02830 plyfile->which_elem = elem;
02831 }
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842 void describe_property_ply(
02843 PlyFile *plyfile,
02844 PlyProperty *prop
02845 )
02846 {
02847 PlyElement *elem;
02848 PlyProperty *elem_prop;
02849
02850 elem = plyfile->which_elem;
02851
02852
02853
02854 if (elem->nprops == 0) {
02855 elem->props = (PlyProperty **) myalloc (sizeof (PlyProperty *));
02856 elem->store_prop = (char *) myalloc (sizeof (char));
02857 elem->nprops = 1;
02858 }
02859 else {
02860 elem->nprops++;
02861 elem->props = (PlyProperty **)
02862 realloc (elem->props, sizeof (PlyProperty *) * elem->nprops);
02863 elem->store_prop = (char *)
02864 realloc (elem->store_prop, sizeof (char) * elem->nprops);
02865 }
02866
02867
02868
02869 elem_prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
02870 elem->props[elem->nprops - 1] = elem_prop;
02871 elem->store_prop[elem->nprops - 1] = NAMED_PROP;
02872 copy_property (elem_prop, prop);
02873 }
02874
02875
02876
02877
02878
02879
02880
02881 void describe_other_properties_ply(
02882 PlyFile *plyfile,
02883 PlyOtherProp *other,
02884 int offset
02885 )
02886 {
02887 int i;
02888 PlyElement *elem;
02889 PlyProperty *prop;
02890
02891
02892 elem = find_element (plyfile, other->name);
02893 if (elem == NULL) {
02894 fprintf(stderr, "describe_other_properties_ply: can't find element '%s'\n",
02895 other->name);
02896 return;
02897 }
02898
02899
02900
02901 if (elem->nprops == 0) {
02902 elem->props = (PlyProperty **)
02903 myalloc (sizeof (PlyProperty *) * other->nprops);
02904 elem->store_prop = (char *) myalloc (sizeof (char) * other->nprops);
02905 elem->nprops = 0;
02906 }
02907 else {
02908 int newsize;
02909 newsize = elem->nprops + other->nprops;
02910 elem->props = (PlyProperty **)
02911 realloc (elem->props, sizeof (PlyProperty *) * newsize);
02912 elem->store_prop = (char *)
02913 realloc (elem->store_prop, sizeof (char) * newsize);
02914 }
02915
02916
02917
02918 for (i = 0; i < other->nprops; i++) {
02919 prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
02920 copy_property (prop, other->props[i]);
02921 elem->props[elem->nprops] = prop;
02922 elem->store_prop[elem->nprops] = OTHER_PROP;
02923 elem->nprops++;
02924 }
02925
02926
02927 elem->other_size = other->size;
02928 elem->other_offset = offset;
02929 }
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941 void describe_other_elements_ply (
02942 PlyFile *plyfile,
02943 PlyOtherElems *other_elems
02944 )
02945 {
02946 int i;
02947 OtherElem *other;
02948
02949
02950 if (other_elems == NULL)
02951 return;
02952
02953
02954 plyfile->other_elems = other_elems;
02955
02956
02957
02958 for (i = 0; i < other_elems->num_elems; i++) {
02959 other = &(other_elems->other_list[i]);
02960 element_count_ply (plyfile, other->elem_name, other->elem_count);
02961 describe_other_properties_ply (plyfile, other->other_props,
02962 offsetof(OtherData,other_props));
02963 }
02964 }
02965
02966
02967
02968
02969
02970
02971 typedef struct RuleName {
02972 int code;
02973 char *name;
02974 } RuleName;
02975
02976 RuleName rule_name_list[] = {
02977 {AVERAGE_RULE, "avg"},
02978 {RANDOM_RULE, "rnd"},
02979 {MINIMUM_RULE, "max"},
02980 {MAXIMUM_RULE, "min"},
02981 {MAJORITY_RULE, "major"},
02982 {SAME_RULE, "same"},
02983 {-1, "end_marker"},
02984 };
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000 PlyPropRules *init_rule_ply (PlyFile *ply, char *elem_name)
03001 {
03002 int i,j;
03003 PlyElement *elem;
03004 PlyPropRules *rules;
03005 PlyRuleList *list;
03006 int found_prop;
03007
03008 elem = find_element (ply, elem_name);
03009 if (elem == NULL) {
03010 fprintf (stderr, "init_rule_ply: Can't find element '%s'\n", elem_name);
03011 exit (-1);
03012 }
03013
03014 rules = (PlyPropRules *) myalloc (sizeof (PlyPropRules));
03015 rules->elem = elem;
03016 rules->rule_list = (int *) myalloc (sizeof(int) * elem->nprops);
03017 rules->max_props = 0;
03018 rules->nprops = 0;
03019
03020
03021 for (i = 0; i < elem->nprops; i++)
03022 rules->rule_list[i] = AVERAGE_RULE;
03023
03024
03025
03026 if (ply->rule_list == NULL)
03027 return (rules);
03028
03029
03030
03031 for (list = ply->rule_list; list != NULL; list = list->next) {
03032
03033 if (!equal_strings (list->element, elem->name))
03034 continue;
03035
03036 found_prop = 0;
03037
03038 for (i = 0; i < elem->nprops; i++)
03039 if (equal_strings (list->property, elem->props[i]->name)) {
03040
03041 found_prop = 1;
03042
03043
03044 for (j = 0; rule_name_list[j].code != -1; j++)
03045 if (equal_strings (list->name, rule_name_list[j].name)) {
03046 rules->rule_list[i] = rule_name_list[j].code;
03047 break;
03048 }
03049 }
03050
03051 if (!found_prop) {
03052 fprintf (stderr, "Can't find property '%s' for rule '%s'\n",
03053 list->property, list->name);
03054 continue;
03055 }
03056 }
03057
03058 return (rules);
03059 }
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069
03070
03071 void modify_rule_ply (PlyPropRules *rules, char *prop_name, int rule_type)
03072 {
03073 int i;
03074 PlyElement *elem = rules->elem;
03075
03076
03077
03078 for (i = 0; i < elem->nprops; i++)
03079 if (equal_strings (elem->props[i]->name, prop_name)) {
03080 rules->rule_list[i] = rule_type;
03081 return;
03082 }
03083
03084
03085 fprintf (stderr, "modify_rule_ply: Can't find property '%s'\n", prop_name);
03086 exit (-1);
03087 }
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098 void start_props_ply (PlyFile *ply, PlyPropRules *rules)
03099 {
03100
03101 ply->current_rules = rules;
03102
03103
03104 rules->nprops = 0;
03105 }
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117 void weight_props_ply (PlyFile *ply, float weight, void *other_props)
03118 {
03119 PlyPropRules *rules = ply->current_rules;
03120
03121
03122 if (rules->max_props == 0) {
03123 rules->max_props = 6;
03124 rules->props = (void **) myalloc (sizeof (void *) * rules->max_props);
03125 rules->weights = (float *) myalloc (sizeof (float) * rules->max_props);
03126 }
03127 if (rules->nprops == rules->max_props) {
03128 rules->max_props *= 2;
03129 rules->props = (void **) realloc (rules->props,
03130 sizeof (void *) * rules->max_props);
03131 rules->weights = (float *) realloc (rules->weights,
03132 sizeof (float) * rules->max_props);
03133 }
03134
03135
03136
03137 rules->props[rules->nprops] = other_props;
03138 rules->weights[rules->nprops] = weight;
03139 rules->nprops++;
03140 }
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152 void *get_new_props_ply(PlyFile *ply)
03153 {
03154 int i,j;
03155 static double *vals;
03156 static int max_vals = 0;
03157 PlyPropRules *rules = ply->current_rules;
03158 PlyElement *elem = rules->elem;
03159 PlyProperty *prop;
03160 char *data;
03161 char *new_data;
03162 void *ptr;
03163 int offset;
03164 int type;
03165 double double_val;
03166 int int_val;
03167 unsigned int uint_val;
03168 int random_pick;
03169
03170
03171 if (elem->other_size == 0) {
03172 return (NULL);
03173 }
03174
03175
03176 new_data = (char *) myalloc (sizeof (char) * elem->other_size);
03177
03178
03179
03180 if (max_vals == 0) {
03181 max_vals = rules->nprops;
03182 vals = (double *) myalloc (sizeof (double) * rules->nprops);
03183 }
03184 if (rules->nprops >= max_vals) {
03185 max_vals = rules->nprops;
03186 vals = (double *) realloc (vals, sizeof (double) * rules->nprops);
03187 }
03188
03189
03190 random_pick = (int) floor (rules->nprops * rand());
03191
03192
03193
03194 for (i = 0; i < elem->nprops; i++) {
03195
03196
03197 if (elem->store_prop[i])
03198 continue;
03199
03200 prop = elem->props[i];
03201 offset = prop->offset;
03202 type = prop->external_type;
03203
03204
03205
03206 for (j = 0; j < rules->nprops; j++) {
03207 data = (char *) rules->props[j];
03208 ptr = (void *) (data + offset);
03209 get_stored_item ((void *) ptr, type, &int_val, &uint_val, &double_val);
03210 vals[j] = double_val;
03211 }
03212
03213
03214
03215 switch (rules->rule_list[i]) {
03216 case AVERAGE_RULE: {
03217 double sum = 0;
03218 double weight_sum = 0;
03219 for (j = 0; j < rules->nprops; j++) {
03220 sum += vals[j] * rules->weights[j];
03221 weight_sum += rules->weights[j];
03222 }
03223 double_val = sum / weight_sum;
03224 break;
03225 }
03226 case MINIMUM_RULE: {
03227 double_val = vals[0];
03228 for (j = 1; j < rules->nprops; j++)
03229 if (double_val > vals[j])
03230 double_val = vals[j];
03231 break;
03232 }
03233 case MAXIMUM_RULE: {
03234 double_val = vals[0];
03235 for (j = 1; j < rules->nprops; j++)
03236 if (double_val < vals[j])
03237 double_val = vals[j];
03238 break;
03239 }
03240 case RANDOM_RULE: {
03241 double_val = vals[random_pick];
03242 break;
03243 }
03244 case SAME_RULE: {
03245 double_val = vals[0];
03246 for (j = 1; j < rules->nprops; j++)
03247 if (double_val != vals[j]) {
03248 fprintf (stderr,
03249 "get_new_props_ply: Error combining properties that should be the same.\n");
03250 exit (-1);
03251 }
03252 break;
03253 }
03254 default:
03255 fprintf (stderr, "get_new_props_ply: Bad rule = %d\n",
03256 rules->rule_list[i]);
03257 exit (-1);
03258 }
03259
03260
03261
03262 int_val = (int) double_val;
03263 uint_val = (unsigned int) double_val;
03264 ptr = (void *) (new_data + offset);
03265 store_item ((char *) ptr, type, int_val, uint_val, double_val);
03266 }
03267
03268 return ((void *) new_data);
03269 }
03270
03271
03272
03273
03274
03275
03276 void set_prop_rules_ply (PlyFile *ply, PlyRuleList *prop_rules)
03277 {
03278 ply->rule_list = prop_rules;
03279 }
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294 PlyRuleList *append_prop_rule (
03295 PlyRuleList *rule_list,
03296 char *name,
03297 char *property
03298 )
03299 {
03300 PlyRuleList *rule;
03301 PlyRuleList *rule_ptr;
03302 char *str,*str2;
03303 char *ptr;
03304
03305
03306 str = _strdup (property);
03307 for (ptr = str; *ptr != '\0' && *ptr != '.'; ptr++) ;
03308
03309
03310 if (*ptr == '.') {
03311 *ptr = '\0';
03312 str2 = ptr + 1;
03313 }
03314 else {
03315 fprintf (stderr, "Can't find property '%s' for rule '%s'\n",
03316 property, name);
03317 return (rule_list);
03318 }
03319
03320 rule = (PlyRuleList *) malloc (sizeof (PlyRuleList));
03321 rule->name = name;
03322 rule->element = str;
03323 rule->property = str2;
03324 rule->next = NULL;
03325
03326
03327
03328 if (rule_list == NULL)
03329 rule_list = rule;
03330 else {
03331 rule_ptr = rule_list;
03332 while (rule_ptr->next != NULL)
03333 rule_ptr = rule_ptr->next;
03334 rule_ptr->next = rule;
03335 }
03336
03337
03338
03339 return (rule_list);
03340 }
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353 int matches_rule_name (char *name)
03354 {
03355 int i;
03356
03357 for (i = 0; rule_name_list[i].code != -1; i++)
03358 if (equal_strings (rule_name_list[i].name, name))
03359 return (1);
03360
03361 return (0);
03362 }
03363