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