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