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