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
00035 #ifdef __cplusplus
00036 extern "C" {
00037 #endif
00038
00039 #include <blort/TomGine/ply.h>
00040
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #include <math.h>
00044 #include <string.h>
00045
00046 #ifdef WIN32
00047 #pragma warning(push)
00048 #pragma warning(disable: 4996 4244)
00049 #endif
00050
00051
00052 char *type_names[] = {
00053 "invalid",
00054 "char", "short", "int",
00055 "uchar", "ushort", "uint",
00056 "float", "double",
00057 };
00058
00059 int ply_type_size[] = {
00060 0, 1, 2, 4, 1, 2, 4, 4, 8
00061 };
00062
00063 #define NO_OTHER_PROPS -1
00064
00065 #define DONT_STORE_PROP 0
00066 #define STORE_PROP 1
00067
00068 #define OTHER_PROP 0
00069 #define NAMED_PROP 1
00070
00071
00072
00073 int equal_strings(char *, char *);
00074
00075
00076 PlyElement *find_element(PlyFile *, char *);
00077
00078
00079 PlyProperty *find_property(PlyElement *, char *, int *);
00080
00081
00082 void write_scalar_type (FILE *, int);
00083
00084
00085 char **get_words(FILE *, int *, char **);
00086 char **old_get_words(FILE *, int *);
00087
00088
00089 void write_binary_item(FILE *, int, unsigned int, double, int);
00090 void write_ascii_item(FILE *, int, unsigned int, double, int);
00091 double old_write_ascii_item(FILE *, char *, int);
00092
00093
00094 void add_element(PlyFile *, char **, int);
00095 void add_property(PlyFile *, char **, int);
00096 void add_comment(PlyFile *, char *);
00097 void add_obj_info(PlyFile *, char *);
00098
00099
00100 void copy_property(PlyProperty *, PlyProperty *);
00101
00102
00103 void store_item(char *, int, int, unsigned int, double);
00104
00105
00106 void get_stored_item( void *, int, int *, unsigned int *, double *);
00107
00108
00109 double get_item_value(char *, int);
00110
00111
00112 void get_ascii_item(char *, int, int *, unsigned int *, double *);
00113 void get_binary_item(FILE *, int, int *, unsigned int *, double *);
00114
00115
00116 void ascii_get_element(PlyFile *, char *);
00117 void binary_get_element(PlyFile *, char *);
00118
00119
00120 char *my_alloc(int, int, char *);
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 PlyFile *ply_write(
00142 FILE *fp,
00143 int nelems,
00144 char **elem_names,
00145 int file_type
00146 )
00147 {
00148 int i;
00149 PlyFile *plyfile;
00150 PlyElement *elem;
00151
00152
00153 if (fp == NULL)
00154 return (NULL);
00155
00156
00157
00158 plyfile = (PlyFile *) myalloc (sizeof (PlyFile));
00159 plyfile->file_type = file_type;
00160 plyfile->num_comments = 0;
00161 plyfile->num_obj_info = 0;
00162 plyfile->nelems = nelems;
00163 plyfile->version = 1.0;
00164 plyfile->fp = fp;
00165 plyfile->other_elems = NULL;
00166
00167
00168
00169 plyfile->elems = (PlyElement **) myalloc (sizeof (PlyElement *) * nelems);
00170 for (i = 0; i < nelems; i++) {
00171 elem = (PlyElement *) myalloc (sizeof (PlyElement));
00172 plyfile->elems[i] = elem;
00173 elem->name = strdup (elem_names[i]);
00174 elem->num = 0;
00175 elem->nprops = 0;
00176 }
00177
00178
00179 return (plyfile);
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 PlyFile *ply_open_for_writing(
00198 char *filename,
00199 int nelems,
00200 char **elem_names,
00201 int file_type,
00202 float *version
00203 )
00204 {
00205
00206 PlyFile *plyfile;
00207
00208 char *name;
00209 FILE *fp;
00210
00211
00212
00213 name = (char *) myalloc (sizeof (char) * (strlen (filename) + 5));
00214 strcpy (name, filename);
00215 if (strlen (name) < 4 ||
00216 strcmp (name + strlen (name) - 4, ".ply") != 0)
00217 strcat (name, ".ply");
00218
00219
00220
00221 fp = fopen (name, "w");
00222 if (fp == NULL) {
00223 return (NULL);
00224 }
00225
00226
00227
00228 plyfile = ply_write (fp, nelems, elem_names, file_type);
00229 if (plyfile == NULL)
00230 return (NULL);
00231
00232
00233 *version = plyfile->version;
00234
00235
00236 return (plyfile);
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 void ply_describe_element(
00253 PlyFile *plyfile,
00254 char *elem_name,
00255 int nelems,
00256 int nprops,
00257 PlyProperty *prop_list
00258 )
00259 {
00260 int i;
00261 PlyElement *elem;
00262 PlyProperty *prop;
00263
00264
00265 elem = find_element (plyfile, elem_name);
00266 if (elem == NULL) {
00267 fprintf(stderr,"ply_describe_element: can't find element '%s'\n",elem_name);
00268 exit (-1);
00269 }
00270
00271 elem->num = nelems;
00272
00273
00274
00275 elem->nprops = nprops;
00276 elem->props = (PlyProperty **) myalloc (sizeof (PlyProperty *) * nprops);
00277 elem->store_prop = (char *) myalloc (sizeof (char) * nprops);
00278
00279 for (i = 0; i < nprops; i++) {
00280 prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
00281 elem->props[i] = prop;
00282 elem->store_prop[i] = NAMED_PROP;
00283 copy_property (prop, &prop_list[i]);
00284 }
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 void ply_describe_property(
00298 PlyFile *plyfile,
00299 char *elem_name,
00300 PlyProperty *prop
00301 )
00302 {
00303 PlyElement *elem;
00304 PlyProperty *elem_prop;
00305
00306
00307 elem = find_element (plyfile, elem_name);
00308 if (elem == NULL) {
00309 fprintf(stderr, "ply_describe_property: can't find element '%s'\n",
00310 elem_name);
00311 return;
00312 }
00313
00314
00315
00316 if (elem->nprops == 0) {
00317 elem->props = (PlyProperty **) myalloc (sizeof (PlyProperty *));
00318 elem->store_prop = (char *) myalloc (sizeof (char));
00319 elem->nprops = 1;
00320 }
00321 else {
00322 elem->nprops++;
00323 elem->props = (PlyProperty **)
00324 realloc (elem->props, sizeof (PlyProperty *) * elem->nprops);
00325 elem->store_prop = (char *)
00326 realloc (elem->store_prop, sizeof (char) * elem->nprops);
00327 }
00328
00329
00330
00331 elem_prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
00332 elem->props[elem->nprops - 1] = elem_prop;
00333 elem->store_prop[elem->nprops - 1] = NAMED_PROP;
00334 copy_property (elem_prop, prop);
00335 }
00336
00337
00338
00339
00340
00341
00342
00343 void ply_describe_other_properties(
00344 PlyFile *plyfile,
00345 PlyOtherProp *other,
00346 int offset
00347 )
00348 {
00349 int i;
00350 PlyElement *elem;
00351 PlyProperty *prop;
00352
00353
00354 elem = find_element (plyfile, other->name);
00355 if (elem == NULL) {
00356 fprintf(stderr, "ply_describe_other_properties: can't find element '%s'\n",
00357 other->name);
00358 return;
00359 }
00360
00361
00362
00363 if (elem->nprops == 0) {
00364 elem->props = (PlyProperty **)
00365 myalloc (sizeof (PlyProperty *) * other->nprops);
00366 elem->store_prop = (char *) myalloc (sizeof (char) * other->nprops);
00367 elem->nprops = 0;
00368 }
00369 else {
00370 int newsize;
00371 newsize = elem->nprops + other->nprops;
00372 elem->props = (PlyProperty **)
00373 realloc (elem->props, sizeof (PlyProperty *) * newsize);
00374 elem->store_prop = (char *)
00375 realloc (elem->store_prop, sizeof (char) * newsize);
00376 }
00377
00378
00379
00380 for (i = 0; i < other->nprops; i++) {
00381 prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
00382 copy_property (prop, other->props[i]);
00383 elem->props[elem->nprops] = prop;
00384 elem->store_prop[elem->nprops] = OTHER_PROP;
00385 elem->nprops++;
00386 }
00387
00388
00389 elem->other_size = other->size;
00390 elem->other_offset = offset;
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 void ply_element_count(
00404 PlyFile *plyfile,
00405 char *elem_name,
00406 int nelems
00407 )
00408 {
00409
00410 PlyElement *elem;
00411
00412
00413
00414 elem = find_element (plyfile, elem_name);
00415 if (elem == NULL) {
00416 fprintf(stderr,"ply_element_count: can't find element '%s'\n",elem_name);
00417 exit (-1);
00418 }
00419
00420 elem->num = nelems;
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 void ply_header_complete(PlyFile *plyfile)
00433 {
00434 int i,j;
00435 FILE *fp = plyfile->fp;
00436 PlyElement *elem;
00437 PlyProperty *prop;
00438
00439 fprintf (fp, "ply\n");
00440
00441 switch (plyfile->file_type) {
00442 case PLY_ASCII:
00443 fprintf (fp, "format ascii 1.0\n");
00444 break;
00445 case PLY_BINARY_BE:
00446 fprintf (fp, "format binary_big_endian 1.0\n");
00447 break;
00448 case PLY_BINARY_LE:
00449 fprintf (fp, "format binary_little_endian 1.0\n");
00450 break;
00451 default:
00452 fprintf (stderr, "ply_header_complete: bad file type = %d\n",
00453 plyfile->file_type);
00454 exit (-1);
00455 }
00456
00457
00458
00459 for (i = 0; i < plyfile->num_comments; i++)
00460 fprintf (fp, "comment %s\n", plyfile->comments[i]);
00461
00462
00463
00464 for (i = 0; i < plyfile->num_obj_info; i++)
00465 fprintf (fp, "obj_info %s\n", plyfile->obj_info[i]);
00466
00467
00468
00469 for (i = 0; i < plyfile->nelems; i++) {
00470
00471 elem = plyfile->elems[i];
00472 fprintf (fp, "element %s %d\n", elem->name, elem->num);
00473
00474
00475 for (j = 0; j < elem->nprops; j++) {
00476 prop = elem->props[j];
00477 if (prop->is_list) {
00478 fprintf (fp, "property list ");
00479 write_scalar_type (fp, prop->count_external);
00480 fprintf (fp, " ");
00481 write_scalar_type (fp, prop->external_type);
00482 fprintf (fp, " %s\n", prop->name);
00483 }
00484 else {
00485 fprintf (fp, "property ");
00486 write_scalar_type (fp, prop->external_type);
00487 fprintf (fp, " %s\n", prop->name);
00488 }
00489 }
00490 }
00491
00492 fprintf (fp, "end_header\n");
00493 }
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 void ply_put_element_setup(PlyFile *plyfile, char *elem_name)
00506 {
00507 PlyElement *elem;
00508
00509 elem = find_element (plyfile, elem_name);
00510 if (elem == NULL) {
00511 fprintf(stderr, "ply_elements_setup: can't find element '%s'\n", elem_name);
00512 exit (-1);
00513 }
00514
00515 plyfile->which_elem = elem;
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529 void ply_put_element(PlyFile *plyfile, void *elem_ptr)
00530 {
00531 int j,k;
00532 FILE *fp = plyfile->fp;
00533 PlyElement *elem;
00534 PlyProperty *prop;
00535 char *elem_data,*item;
00536 char **item_ptr;
00537 int list_count;
00538 int item_size;
00539 int int_val;
00540 unsigned int uint_val;
00541 double double_val;
00542 char **other_ptr;
00543
00544 elem = plyfile->which_elem;
00545 elem_data = elem_ptr;
00546 other_ptr = (char **) (((char *) elem_ptr) + elem->other_offset);
00547
00548
00549
00550 if (plyfile->file_type == PLY_ASCII) {
00551
00552
00553
00554
00555 for (j = 0; j < elem->nprops; j++) {
00556 prop = elem->props[j];
00557 if (elem->store_prop[j] == OTHER_PROP)
00558 elem_data = *other_ptr;
00559 else
00560 elem_data = elem_ptr;
00561 if (prop->is_list) {
00562 item = elem_data + prop->count_offset;
00563 get_stored_item ((void *) item, prop->count_internal,
00564 &int_val, &uint_val, &double_val);
00565 write_ascii_item (fp, int_val, uint_val, double_val,
00566 prop->count_external);
00567 list_count = uint_val;
00568 item_ptr = (char **) (elem_data + prop->offset);
00569 item = item_ptr[0];
00570 item_size = ply_type_size[prop->internal_type];
00571 for (k = 0; k < list_count; k++) {
00572 get_stored_item ((void *) item, prop->internal_type,
00573 &int_val, &uint_val, &double_val);
00574 write_ascii_item (fp, int_val, uint_val, double_val,
00575 prop->external_type);
00576 item += item_size;
00577 }
00578 }
00579 else {
00580 item = elem_data + prop->offset;
00581 get_stored_item ((void *) item, prop->internal_type,
00582 &int_val, &uint_val, &double_val);
00583 write_ascii_item (fp, int_val, uint_val, double_val,
00584 prop->external_type);
00585 }
00586 }
00587
00588 fprintf (fp, "\n");
00589 }
00590 else {
00591
00592
00593
00594
00595 for (j = 0; j < elem->nprops; j++) {
00596 prop = elem->props[j];
00597 if (elem->store_prop[j] == OTHER_PROP)
00598 elem_data = *other_ptr;
00599 else
00600 elem_data = elem_ptr;
00601 if (prop->is_list) {
00602 item = elem_data + prop->count_offset;
00603 item_size = ply_type_size[prop->count_internal];
00604 get_stored_item ((void *) item, prop->count_internal,
00605 &int_val, &uint_val, &double_val);
00606 write_binary_item (fp, int_val, uint_val, double_val,
00607 prop->count_external);
00608 list_count = uint_val;
00609 item_ptr = (char **) (elem_data + prop->offset);
00610 item = item_ptr[0];
00611 item_size = ply_type_size[prop->internal_type];
00612 for (k = 0; k < list_count; k++) {
00613 get_stored_item ((void *) item, prop->internal_type,
00614 &int_val, &uint_val, &double_val);
00615 write_binary_item (fp, int_val, uint_val, double_val,
00616 prop->external_type);
00617 item += item_size;
00618 }
00619 }
00620 else {
00621 item = elem_data + prop->offset;
00622 item_size = ply_type_size[prop->internal_type];
00623 get_stored_item ((void *) item, prop->internal_type,
00624 &int_val, &uint_val, &double_val);
00625 write_binary_item (fp, int_val, uint_val, double_val,
00626 prop->external_type);
00627 }
00628 }
00629
00630 }
00631 }
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642 void ply_put_comment(PlyFile *plyfile, char *comment)
00643 {
00644
00645 if (plyfile->num_comments == 0)
00646 plyfile->comments = (char **) myalloc (sizeof (char *));
00647 else
00648 plyfile->comments = (char **) realloc (plyfile->comments,
00649 sizeof (char *) * (plyfile->num_comments + 1));
00650
00651
00652 plyfile->comments[plyfile->num_comments] = strdup (comment);
00653 plyfile->num_comments++;
00654 }
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666 void ply_put_obj_info(PlyFile *plyfile, char *obj_info)
00667 {
00668
00669 if (plyfile->num_obj_info == 0)
00670 plyfile->obj_info = (char **) myalloc (sizeof (char *));
00671 else
00672 plyfile->obj_info = (char **) realloc (plyfile->obj_info,
00673 sizeof (char *) * (plyfile->num_obj_info + 1));
00674
00675
00676 plyfile->obj_info[plyfile->num_obj_info] = strdup (obj_info);
00677 plyfile->num_obj_info++;
00678 }
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704 PlyFile *ply_read(FILE *fp, int *nelems, char ***elem_names)
00705 {
00706 int i,j;
00707 PlyFile *plyfile;
00708 int nwords;
00709 char **words;
00710
00711 char **elist;
00712 PlyElement *elem;
00713 char *orig_line;
00714
00715
00716 if (fp == NULL)
00717 return (NULL);
00718
00719
00720
00721 plyfile = (PlyFile *) myalloc (sizeof (PlyFile));
00722 plyfile->nelems = 0;
00723 plyfile->comments = NULL;
00724 plyfile->num_comments = 0;
00725 plyfile->obj_info = NULL;
00726 plyfile->num_obj_info = 0;
00727 plyfile->fp = fp;
00728 plyfile->other_elems = NULL;
00729
00730
00731
00732 words = get_words (plyfile->fp, &nwords, &orig_line);
00733 if (!words || !equal_strings (words[0], "ply"))
00734 return (NULL);
00735
00736 while (words) {
00737
00738
00739
00740 if (equal_strings (words[0], "format")) {
00741 if (nwords != 3)
00742 return (NULL);
00743 if (equal_strings (words[1], "ascii"))
00744 plyfile->file_type = PLY_ASCII;
00745 else if (equal_strings (words[1], "binary_big_endian"))
00746 plyfile->file_type = PLY_BINARY_BE;
00747 else if (equal_strings (words[1], "binary_little_endian"))
00748 plyfile->file_type = PLY_BINARY_LE;
00749 else
00750 return (NULL);
00751 plyfile->version = atof (words[2]);
00752
00753 }
00754 else if (equal_strings (words[0], "element"))
00755 add_element (plyfile, words, nwords);
00756 else if (equal_strings (words[0], "property"))
00757 add_property (plyfile, words, nwords);
00758 else if (equal_strings (words[0], "comment"))
00759 add_comment (plyfile, orig_line);
00760 else if (equal_strings (words[0], "obj_info"))
00761 add_obj_info (plyfile, orig_line);
00762 else if (equal_strings (words[0], "end_header"))
00763 break;
00764
00765
00766 free (words);
00767
00768 words = get_words (plyfile->fp, &nwords, &orig_line);
00769 }
00770
00771
00772
00773
00774 for (i = 0; i < plyfile->nelems; i++) {
00775 elem = plyfile->elems[i];
00776 elem->store_prop = (char *) myalloc (sizeof (char) * elem->nprops);
00777 for (j = 0; j < elem->nprops; j++)
00778 elem->store_prop[j] = DONT_STORE_PROP;
00779 elem->other_offset = NO_OTHER_PROPS;
00780 }
00781
00782
00783
00784 elist = (char **) myalloc (sizeof (char *) * plyfile->nelems);
00785 for (i = 0; i < plyfile->nelems; i++)
00786 elist[i] = strdup (plyfile->elems[i]->name);
00787
00788 *elem_names = elist;
00789 *nelems = plyfile->nelems;
00790
00791
00792
00793 return (plyfile);
00794 }
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 PlyFile *ply_open_for_reading(
00812 const char *filename,
00813 int *nelems,
00814 char ***elem_names,
00815 int *file_type,
00816 float *version
00817 )
00818 {
00819 FILE *fp;
00820 PlyFile *plyfile;
00821 char *name;
00822
00823
00824
00825 name = (char *) myalloc (sizeof (char) * (strlen (filename) + 5));
00826 strcpy (name, filename);
00827 if (strlen (name) < 4 ||
00828 strcmp (name + strlen (name) - 4, ".ply") != 0)
00829 strcat (name, ".ply");
00830
00831
00832
00833 fp = fopen (name, "r");
00834 if (fp == NULL)
00835 return (NULL);
00836
00837
00838
00839 plyfile = ply_read (fp, nelems, elem_names);
00840
00841
00842
00843 *file_type = plyfile->file_type;
00844 *version = plyfile->version;
00845
00846
00847
00848 return (plyfile);
00849 }
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 PlyProperty **ply_get_element_description(
00866 PlyFile *plyfile,
00867 char *elem_name,
00868 int *nelems,
00869 int *nprops
00870 )
00871 {
00872 int i;
00873 PlyElement *elem;
00874 PlyProperty *prop;
00875 PlyProperty **prop_list;
00876
00877
00878 elem = find_element (plyfile, elem_name);
00879 if (elem == NULL)
00880 return (NULL);
00881
00882 *nelems = elem->num;
00883 *nprops = elem->nprops;
00884
00885
00886 prop_list = (PlyProperty **) myalloc (sizeof (PlyProperty *) * elem->nprops);
00887 for (i = 0; i < elem->nprops; i++) {
00888 prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
00889 copy_property (prop, elem->props[i]);
00890 prop_list[i] = prop;
00891 }
00892
00893
00894 return (prop_list);
00895 }
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909 void ply_get_element_setup(
00910 PlyFile *plyfile,
00911 char *elem_name,
00912 int nprops,
00913 PlyProperty *prop_list
00914 )
00915 {
00916 int i;
00917 PlyElement *elem;
00918 PlyProperty *prop;
00919 int index;
00920
00921
00922 elem = find_element (plyfile, elem_name);
00923 plyfile->which_elem = elem;
00924
00925
00926 for (i = 0; i < nprops; i++) {
00927
00928
00929 prop = find_property (elem, prop_list[i].name, &index);
00930 if (prop == NULL) {
00931 fprintf (stderr, "Warning: Can't find property '%s' in element '%s'\n",
00932 prop_list[i].name, elem_name);
00933 continue;
00934 }
00935
00936
00937 prop->internal_type = prop_list[i].internal_type;
00938 prop->offset = prop_list[i].offset;
00939 prop->count_internal = prop_list[i].count_internal;
00940 prop->count_offset = prop_list[i].count_offset;
00941
00942
00943 elem->store_prop[index] = STORE_PROP;
00944 }
00945 }
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960 void ply_get_property(
00961 PlyFile *plyfile,
00962 char *elem_name,
00963 PlyProperty *prop
00964 )
00965 {
00966 PlyElement *elem;
00967 PlyProperty *prop_ptr;
00968 int index;
00969
00970
00971 elem = find_element (plyfile, elem_name);
00972 plyfile->which_elem = elem;
00973
00974
00975
00976 prop_ptr = find_property (elem, prop->name, &index);
00977 if (prop_ptr == NULL) {
00978 fprintf (stderr, "Warning: Can't find property '%s' in element '%s'\n",
00979 prop->name, elem_name);
00980 return;
00981 }
00982 prop_ptr->internal_type = prop->internal_type;
00983 prop_ptr->offset = prop->offset;
00984 prop_ptr->count_internal = prop->count_internal;
00985 prop_ptr->count_offset = prop->count_offset;
00986
00987
00988 elem->store_prop[index] = STORE_PROP;
00989 }
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002 void ply_get_element(PlyFile *plyfile, void *elem_ptr)
01003 {
01004 if (plyfile->file_type == PLY_ASCII)
01005 ascii_get_element (plyfile, (char *) elem_ptr);
01006 else
01007 binary_get_element (plyfile, (char *) elem_ptr);
01008 }
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022 char **ply_get_comments(PlyFile *plyfile, int *num_comments)
01023 {
01024 *num_comments = plyfile->num_comments;
01025 return (plyfile->comments);
01026 }
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041 char **ply_get_obj_info(PlyFile *plyfile, int *num_obj_info)
01042 {
01043 *num_obj_info = plyfile->num_obj_info;
01044 return (plyfile->obj_info);
01045 }
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059 void setup_other_props(PlyFile *plyfile, PlyElement *elem)
01060 {
01061 int i;
01062 PlyProperty *prop;
01063 int size = 0;
01064 int type_size;
01065
01066
01067
01068
01069
01070 for (type_size = 8; type_size > 0; type_size /= 2) {
01071
01072
01073
01074
01075 for (i = 0; i < elem->nprops; i++) {
01076
01077
01078 if (elem->store_prop[i])
01079 continue;
01080
01081 prop = elem->props[i];
01082
01083
01084 prop->internal_type = prop->external_type;
01085 prop->count_internal = prop->count_external;
01086
01087
01088 if (prop->is_list) {
01089
01090
01091 if (type_size == sizeof (void *)) {
01092 prop->offset = size;
01093 size += sizeof (void *);
01094 }
01095
01096
01097 if (type_size == ply_type_size[prop->count_external]) {
01098 prop->count_offset = size;
01099 size += ply_type_size[prop->count_external];
01100 }
01101 }
01102
01103 else if (type_size == ply_type_size[prop->external_type]) {
01104 prop->offset = size;
01105 size += ply_type_size[prop->external_type];
01106 }
01107 }
01108
01109 }
01110
01111
01112 elem->other_size = size;
01113 }
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130 PlyOtherProp *ply_get_other_properties(
01131 PlyFile *plyfile,
01132 char *elem_name,
01133 int offset
01134 )
01135 {
01136 int i;
01137 PlyElement *elem;
01138 PlyOtherProp *other;
01139 PlyProperty *prop;
01140 int nprops;
01141
01142
01143 elem = find_element (plyfile, elem_name);
01144 if (elem == NULL) {
01145 fprintf (stderr, "ply_get_other_properties: Can't find element '%s'\n",
01146 elem_name);
01147 return (NULL);
01148 }
01149
01150
01151 plyfile->which_elem = elem;
01152
01153
01154 elem->other_offset = offset;
01155
01156
01157 setup_other_props (plyfile, elem);
01158
01159
01160 other = (PlyOtherProp *) myalloc (sizeof (PlyOtherProp));
01161 other->name = strdup (elem_name);
01162 #if 0
01163 if (elem->other_offset == NO_OTHER_PROPS) {
01164 other->size = 0;
01165 other->props = NULL;
01166 other->nprops = 0;
01167 return (other);
01168 }
01169 #endif
01170 other->size = elem->other_size;
01171 other->props = (PlyProperty **) myalloc (sizeof(PlyProperty) * elem->nprops);
01172
01173
01174 nprops = 0;
01175 for (i = 0; i < elem->nprops; i++) {
01176 if (elem->store_prop[i])
01177 continue;
01178 prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
01179 copy_property (prop, elem->props[i]);
01180 other->props[nprops] = prop;
01181 nprops++;
01182 }
01183 other->nprops = nprops;
01184
01185 #if 1
01186
01187 if (other->nprops == 0) {
01188 elem->other_offset = NO_OTHER_PROPS;
01189 }
01190 #endif
01191
01192
01193 return (other);
01194 }
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219 PlyOtherElems *ply_get_other_element (
01220 PlyFile *plyfile,
01221 char *elem_name,
01222 int elem_count
01223 )
01224 {
01225 int i;
01226 PlyElement *elem;
01227 PlyOtherElems *other_elems;
01228 OtherElem *other;
01229
01230
01231
01232 elem = find_element (plyfile, elem_name);
01233 if (elem == NULL) {
01234 fprintf (stderr,
01235 "ply_get_other_element: can't find element '%s'\n", elem_name);
01236 exit (-1);
01237 }
01238
01239
01240
01241
01242 if (plyfile->other_elems == NULL) {
01243 plyfile->other_elems = (PlyOtherElems *) myalloc (sizeof (PlyOtherElems));
01244 other_elems = plyfile->other_elems;
01245 other_elems->other_list = (OtherElem *) myalloc (sizeof (OtherElem));
01246 other = &(other_elems->other_list[0]);
01247 other_elems->num_elems = 1;
01248 }
01249 else {
01250 other_elems = plyfile->other_elems;
01251 other_elems->other_list = (OtherElem *) realloc (other_elems->other_list,
01252 sizeof (OtherElem) * other_elems->num_elems + 1);
01253 other = &(other_elems->other_list[other_elems->num_elems]);
01254 other_elems->num_elems++;
01255 }
01256
01257
01258 other->elem_count = elem_count;
01259
01260
01261 other->elem_name = strdup (elem_name);
01262
01263
01264 other->other_data = (OtherData **)
01265 malloc (sizeof (OtherData *) * other->elem_count);
01266
01267
01268 other->other_props = ply_get_other_properties (plyfile, elem_name,
01269 offsetof(OtherData,other_props));
01270
01271
01272 for (i = 0; i < other->elem_count; i++) {
01273
01274 other->other_data[i] = (OtherData *) malloc (sizeof (OtherData));
01275 ply_get_element (plyfile, (void *) other->other_data[i]);
01276 }
01277
01278
01279 return (other_elems);
01280 }
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292 void ply_describe_other_elements (
01293 PlyFile *plyfile,
01294 PlyOtherElems *other_elems
01295 )
01296 {
01297 int i;
01298 OtherElem *other;
01299
01300
01301 if (other_elems == NULL)
01302 return;
01303
01304
01305 plyfile->other_elems = other_elems;
01306
01307
01308
01309 for (i = 0; i < other_elems->num_elems; i++) {
01310 other = &(other_elems->other_list[i]);
01311 ply_element_count (plyfile, other->elem_name, other->elem_count);
01312 ply_describe_other_properties (plyfile, other->other_props,
01313 offsetof(OtherData,other_props));
01314 }
01315 }
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325 void ply_put_other_elements (PlyFile *plyfile)
01326 {
01327 int i,j;
01328 OtherElem *other;
01329
01330
01331 if (plyfile->other_elems == NULL)
01332 return;
01333
01334
01335
01336 for (i = 0; i < plyfile->other_elems->num_elems; i++) {
01337
01338 other = &(plyfile->other_elems->other_list[i]);
01339 ply_put_element_setup (plyfile, other->elem_name);
01340
01341
01342 for (j = 0; j < other->elem_count; j++)
01343 ply_put_element (plyfile, (void *) other->other_data[j]);
01344 }
01345 }
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355 void ply_free_other_elements (PlyOtherElems *other_elems)
01356 {
01357
01358 }
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375 void ply_close(PlyFile *plyfile)
01376 {
01377 fclose (plyfile->fp);
01378
01379
01380 free (plyfile);
01381 }
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395 void ply_get_info(PlyFile *ply, float *version, int *file_type)
01396 {
01397 if (ply == NULL)
01398 return;
01399
01400 *version = ply->version;
01401 *file_type = ply->file_type;
01402 }
01403
01404
01405
01406
01407
01408
01409 int equal_strings(char *s1, char *s2)
01410 {
01411
01412
01413 while (*s1 && *s2)
01414 if (*s1++ != *s2++)
01415 return (0);
01416
01417 if (*s1 != *s2)
01418 return (0);
01419 else
01420 return (1);
01421 }
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435 PlyElement *find_element(PlyFile *plyfile, char *element)
01436 {
01437 int i;
01438
01439 for (i = 0; i < plyfile->nelems; i++)
01440 if (equal_strings (element, plyfile->elems[i]->name))
01441 return (plyfile->elems[i]);
01442
01443 return (NULL);
01444 }
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459 PlyProperty *find_property(PlyElement *elem, char *prop_name, int *index)
01460 {
01461 int i;
01462
01463 for (i = 0; i < elem->nprops; i++)
01464 if (equal_strings (prop_name, elem->props[i]->name)) {
01465 *index = i;
01466 return (elem->props[i]);
01467 }
01468
01469 *index = -1;
01470 return (NULL);
01471 }
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482 void ascii_get_element(PlyFile *plyfile, char *elem_ptr)
01483 {
01484 int j,k;
01485 PlyElement *elem;
01486 PlyProperty *prop;
01487 char **words;
01488 int nwords;
01489 int which_word;
01490
01491 char *elem_data,*item = 0;
01492 char *item_ptr;
01493 int item_size;
01494 int int_val;
01495 unsigned int uint_val;
01496 double double_val;
01497 int list_count;
01498 int store_it;
01499 char **store_array;
01500 char *orig_line;
01501 char *other_data = 0;
01502 int other_flag;
01503
01504
01505 elem = plyfile->which_elem;
01506
01507
01508
01509 if (elem->other_offset != NO_OTHER_PROPS) {
01510 char **ptr;
01511 other_flag = 1;
01512
01513 other_data = (char *) myalloc (elem->other_size);
01514
01515 ptr = (char **) (elem_ptr + elem->other_offset);
01516 *ptr = other_data;
01517 }
01518 else
01519 other_flag = 0;
01520
01521
01522
01523 words = get_words (plyfile->fp, &nwords, &orig_line);
01524 if (words == NULL) {
01525 fprintf (stderr, "ply_get_element: unexpected end of file\n");
01526 exit (-1);
01527 }
01528
01529 which_word = 0;
01530
01531 for (j = 0; j < elem->nprops; j++) {
01532
01533 prop = elem->props[j];
01534 store_it = (elem->store_prop[j] | other_flag);
01535
01536
01537 if (elem->store_prop[j])
01538 elem_data = elem_ptr;
01539 else
01540 elem_data = other_data;
01541
01542 if (prop->is_list) {
01543
01544
01545 get_ascii_item (words[which_word++], prop->count_external,
01546 &int_val, &uint_val, &double_val);
01547 if (store_it) {
01548 item = elem_data + prop->count_offset;
01549 store_item(item, prop->count_internal, int_val, uint_val, double_val);
01550 }
01551
01552
01553 list_count = int_val;
01554 item_size = ply_type_size[prop->internal_type];
01555 store_array = (char **) (elem_data + prop->offset);
01556
01557 if (list_count == 0) {
01558 if (store_it)
01559 *store_array = NULL;
01560 }
01561 else {
01562 if (store_it) {
01563 item_ptr = (char *) myalloc (sizeof (char) * item_size * list_count);
01564 item = item_ptr;
01565 *store_array = item_ptr;
01566 }
01567
01568
01569 for (k = 0; k < list_count; k++) {
01570 get_ascii_item (words[which_word++], prop->external_type,
01571 &int_val, &uint_val, &double_val);
01572 if (store_it) {
01573 store_item (item, prop->internal_type,
01574 int_val, uint_val, double_val);
01575 item += item_size;
01576 }
01577 }
01578 }
01579
01580 }
01581 else {
01582 get_ascii_item (words[which_word++], prop->external_type,
01583 &int_val, &uint_val, &double_val);
01584 if (store_it) {
01585 item = elem_data + prop->offset;
01586 store_item (item, prop->internal_type, int_val, uint_val, double_val);
01587 }
01588 }
01589
01590 }
01591
01592 free (words);
01593 }
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604 void binary_get_element(PlyFile *plyfile, char *elem_ptr)
01605 {
01606 int j,k;
01607 PlyElement *elem;
01608 PlyProperty *prop;
01609 FILE *fp = plyfile->fp;
01610 char *elem_data,*item = 0;
01611 char *item_ptr;
01612 int item_size = 0;
01613 int int_val;
01614 unsigned int uint_val;
01615 double double_val;
01616 int list_count;
01617 int store_it;
01618 char **store_array;
01619 char *other_data = 0;
01620 int other_flag;
01621
01622
01623 elem = plyfile->which_elem;
01624
01625
01626
01627 if (elem->other_offset != NO_OTHER_PROPS) {
01628 char **ptr;
01629 other_flag = 1;
01630
01631 other_data = (char *) myalloc (elem->other_size);
01632
01633 ptr = (char **) (elem_ptr + elem->other_offset);
01634 *ptr = other_data;
01635 }
01636 else
01637 other_flag = 0;
01638
01639
01640
01641 for (j = 0; j < elem->nprops; j++) {
01642
01643 prop = elem->props[j];
01644 store_it = (elem->store_prop[j] | other_flag);
01645
01646
01647 if (elem->store_prop[j])
01648 elem_data = elem_ptr;
01649 else
01650 elem_data = other_data;
01651
01652 if (prop->is_list) {
01653
01654
01655 get_binary_item (fp, prop->count_external,
01656 &int_val, &uint_val, &double_val);
01657 if (store_it) {
01658 item = elem_data + prop->count_offset;
01659 store_item(item, prop->count_internal, int_val, uint_val, double_val);
01660 }
01661
01662
01663 list_count = int_val;
01664
01665
01666
01667
01668 if (store_it) {
01669 item_size = ply_type_size[prop->internal_type];
01670 }
01671 store_array = (char **) (elem_data + prop->offset);
01672 if (list_count == 0) {
01673 if (store_it)
01674 *store_array = NULL;
01675 }
01676 else {
01677 if (store_it) {
01678 item_ptr = (char *) myalloc (sizeof (char) * item_size * list_count);
01679 item = item_ptr;
01680 *store_array = item_ptr;
01681 }
01682
01683
01684 for (k = 0; k < list_count; k++) {
01685 get_binary_item (fp, prop->external_type,
01686 &int_val, &uint_val, &double_val);
01687 if (store_it) {
01688 store_item (item, prop->internal_type,
01689 int_val, uint_val, double_val);
01690 item += item_size;
01691 }
01692 }
01693 }
01694
01695 }
01696 else {
01697 get_binary_item (fp, prop->external_type,
01698 &int_val, &uint_val, &double_val);
01699 if (store_it) {
01700 item = elem_data + prop->offset;
01701 store_item (item, prop->internal_type, int_val, uint_val, double_val);
01702 }
01703 }
01704
01705 }
01706 }
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717 void write_scalar_type (FILE *fp, int code)
01718 {
01719
01720
01721 if (code <= PLY_START_TYPE || code >= PLY_END_TYPE) {
01722 fprintf (stderr, "write_scalar_type: bad data code = %d\n", code);
01723 exit (-1);
01724 }
01725
01726
01727
01728 fprintf (fp, "%s", type_names[code]);
01729 }
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747 char **get_words(FILE *fp, int *nwords, char **orig_line)
01748 {
01749 #define BIG_STRING 4096
01750
01751 static char str[BIG_STRING];
01752 static char str_copy[BIG_STRING];
01753 char **words;
01754 int max_words = 10;
01755 int num_words = 0;
01756 char *ptr,*ptr2;
01757 char *result;
01758
01759 words = (char **) myalloc (sizeof (char *) * max_words);
01760
01761
01762 result = fgets (str, BIG_STRING, fp);
01763 if (result == NULL) {
01764 *nwords = 0;
01765 *orig_line = NULL;
01766 return (NULL);
01767 }
01768
01769
01770
01771
01772
01773 str[BIG_STRING-2] = ' ';
01774 str[BIG_STRING-1] = '\0';
01775
01776 for (ptr = str, ptr2 = str_copy; *ptr != '\0'; ptr++, ptr2++) {
01777 *ptr2 = *ptr;
01778 if (*ptr == '\t') {
01779 *ptr = ' ';
01780 *ptr2 = ' ';
01781 }
01782 else if (*ptr == '\n') {
01783 *ptr = ' ';
01784 *ptr2 = '\0';
01785 break;
01786 }
01787 }
01788
01789
01790
01791 ptr = str;
01792 while (*ptr != '\0') {
01793
01794
01795 while (*ptr == ' ')
01796 ptr++;
01797
01798
01799 if (*ptr == '\0')
01800 break;
01801
01802
01803 if (num_words >= max_words) {
01804 max_words += 10;
01805
01806
01807
01808 char** words_backup = words;
01809 words = (char **) realloc (words, sizeof (char *) * max_words);
01810 if(words == NULL)
01811 {
01812 free(words_backup);
01813 return NULL;
01814 }
01815 }
01816 words[num_words++] = ptr;
01817
01818
01819 while (*ptr != ' ')
01820 ptr++;
01821
01822
01823 *ptr++ = '\0';
01824 }
01825
01826
01827 *nwords = num_words;
01828 *orig_line = str_copy;
01829 return (words);
01830 }
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844 double get_item_value(char *item, int type)
01845 {
01846 unsigned char *puchar;
01847 char *pchar;
01848 short int *pshort;
01849 unsigned short int *pushort;
01850 int *pint;
01851 unsigned int *puint;
01852 float *pfloat;
01853 double *pdouble;
01854 int int_value;
01855 unsigned int uint_value;
01856 double double_value;
01857
01858 switch (type) {
01859 case PLY_CHAR:
01860 pchar = (char *) item;
01861 int_value = *pchar;
01862 return ((double) int_value);
01863 case PLY_UCHAR:
01864 puchar = (unsigned char *) item;
01865 int_value = *puchar;
01866 return ((double) int_value);
01867 case PLY_SHORT:
01868 pshort = (short int *) item;
01869 int_value = *pshort;
01870 return ((double) int_value);
01871 case PLY_USHORT:
01872 pushort = (unsigned short int *) item;
01873 int_value = *pushort;
01874 return ((double) int_value);
01875 case PLY_INT:
01876 pint = (int *) item;
01877 int_value = *pint;
01878 return ((double) int_value);
01879 case PLY_UINT:
01880 puint = (unsigned int *) item;
01881 uint_value = *puint;
01882 return ((double) uint_value);
01883 case PLY_FLOAT:
01884 pfloat = (float *) item;
01885 double_value = *pfloat;
01886 return (double_value);
01887 case PLY_DOUBLE:
01888 pdouble = (double *) item;
01889 double_value = *pdouble;
01890 return (double_value);
01891 default:
01892 fprintf (stderr, "get_item_value: bad type = %d\n", type);
01893 exit (-1);
01894 }
01895 }
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909 void write_binary_item(
01910 FILE *fp,
01911 int int_val,
01912 unsigned int uint_val,
01913 double double_val,
01914 int type
01915 )
01916 {
01917 unsigned char uchar_val;
01918 char char_val;
01919 unsigned short ushort_val;
01920 short short_val;
01921 float float_val;
01922
01923 switch (type) {
01924 case PLY_CHAR:
01925 char_val = int_val;
01926 fwrite (&char_val, 1, 1, fp);
01927 break;
01928 case PLY_SHORT:
01929 short_val = int_val;
01930 fwrite (&short_val, 2, 1, fp);
01931 break;
01932 case PLY_INT:
01933 fwrite (&int_val, 4, 1, fp);
01934 break;
01935 case PLY_UCHAR:
01936 uchar_val = uint_val;
01937 fwrite (&uchar_val, 1, 1, fp);
01938 break;
01939 case PLY_USHORT:
01940 ushort_val = uint_val;
01941 fwrite (&ushort_val, 2, 1, fp);
01942 break;
01943 case PLY_UINT:
01944 fwrite (&uint_val, 4, 1, fp);
01945 break;
01946 case PLY_FLOAT:
01947 float_val = double_val;
01948 fwrite (&float_val, 4, 1, fp);
01949 break;
01950 case PLY_DOUBLE:
01951 fwrite (&double_val, 8, 1, fp);
01952 break;
01953 default:
01954 fprintf (stderr, "write_binary_item: bad type = %d\n", type);
01955 exit (-1);
01956 }
01957 }
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971 void write_ascii_item(
01972 FILE *fp,
01973 int int_val,
01974 unsigned int uint_val,
01975 double double_val,
01976 int type
01977 )
01978 {
01979 switch (type) {
01980 case PLY_CHAR:
01981 case PLY_SHORT:
01982 case PLY_INT:
01983 fprintf (fp, "%d ", int_val);
01984 break;
01985 case PLY_UCHAR:
01986 case PLY_USHORT:
01987 case PLY_UINT:
01988 fprintf (fp, "%u ", uint_val);
01989 break;
01990 case PLY_FLOAT:
01991 case PLY_DOUBLE:
01992 fprintf (fp, "%g ", double_val);
01993 break;
01994 default:
01995 fprintf (stderr, "write_ascii_item: bad type = %d\n", type);
01996 exit (-1);
01997 }
01998 }
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013 double old_write_ascii_item(FILE *fp, char *item, int type)
02014 {
02015 unsigned char *puchar;
02016 char *pchar;
02017 short int *pshort;
02018 unsigned short int *pushort;
02019 int *pint;
02020 unsigned int *puint;
02021 float *pfloat;
02022 double *pdouble;
02023 int int_value;
02024 unsigned int uint_value;
02025 double double_value;
02026
02027 switch (type) {
02028 case PLY_CHAR:
02029 pchar = (char *) item;
02030 int_value = *pchar;
02031 fprintf (fp, "%d ", int_value);
02032 return ((double) int_value);
02033 case PLY_UCHAR:
02034 puchar = (unsigned char *) item;
02035 int_value = *puchar;
02036 fprintf (fp, "%d ", int_value);
02037 return ((double) int_value);
02038 case PLY_SHORT:
02039 pshort = (short int *) item;
02040 int_value = *pshort;
02041 fprintf (fp, "%d ", int_value);
02042 return ((double) int_value);
02043 case PLY_USHORT:
02044 pushort = (unsigned short int *) item;
02045 int_value = *pushort;
02046 fprintf (fp, "%d ", int_value);
02047 return ((double) int_value);
02048 case PLY_INT:
02049 pint = (int *) item;
02050 int_value = *pint;
02051 fprintf (fp, "%d ", int_value);
02052 return ((double) int_value);
02053 case PLY_UINT:
02054 puint = (unsigned int *) item;
02055 uint_value = *puint;
02056 fprintf (fp, "%u ", uint_value);
02057 return ((double) uint_value);
02058 case PLY_FLOAT:
02059 pfloat = (float *) item;
02060 double_value = *pfloat;
02061 fprintf (fp, "%g ", double_value);
02062 return (double_value);
02063 case PLY_DOUBLE:
02064 pdouble = (double *) item;
02065 double_value = *pdouble;
02066 fprintf (fp, "%g ", double_value);
02067 return (double_value);
02068 default:
02069 fprintf (stderr, "old_write_ascii_item: bad type = %d\n", type);
02070 exit (-1);
02071 }
02072 }
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089 void get_stored_item(
02090 void *ptr,
02091 int type,
02092 int *int_val,
02093 unsigned int *uint_val,
02094 double *double_val
02095 )
02096 {
02097 switch (type) {
02098 case PLY_CHAR:
02099 *int_val = *((char *) ptr);
02100 *uint_val = *int_val;
02101 *double_val = *int_val;
02102 break;
02103 case PLY_UCHAR:
02104 *uint_val = *((unsigned char *) ptr);
02105 *int_val = *uint_val;
02106 *double_val = *uint_val;
02107 break;
02108 case PLY_SHORT:
02109 *int_val = *((short int *) ptr);
02110 *uint_val = *int_val;
02111 *double_val = *int_val;
02112 break;
02113 case PLY_USHORT:
02114 *uint_val = *((unsigned short int *) ptr);
02115 *int_val = *uint_val;
02116 *double_val = *uint_val;
02117 break;
02118 case PLY_INT:
02119 *int_val = *((int *) ptr);
02120 *uint_val = *int_val;
02121 *double_val = *int_val;
02122 break;
02123 case PLY_UINT:
02124 *uint_val = *((unsigned int *) ptr);
02125 *int_val = *uint_val;
02126 *double_val = *uint_val;
02127 break;
02128 case PLY_FLOAT:
02129 *double_val = *((float *) ptr);
02130 *int_val = *double_val;
02131 *uint_val = *double_val;
02132 break;
02133 case PLY_DOUBLE:
02134 *double_val = *((double *) ptr);
02135 *int_val = *double_val;
02136 *uint_val = *double_val;
02137 break;
02138 default:
02139 fprintf (stderr, "get_stored_item: bad type = %d\n", type);
02140 exit (-1);
02141 }
02142 }
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159 void get_binary_item(
02160 FILE *fp,
02161 int type,
02162 int *int_val,
02163 unsigned int *uint_val,
02164 double *double_val
02165 )
02166 {
02167 char c[8];
02168 void *ptr;
02169
02170 ptr = (void *) c;
02171 size_t size = 0;
02172
02173 switch (type) {
02174 case PLY_CHAR:
02175 size = fread (ptr, 1, 1, fp);
02176 *int_val = *((char *) ptr);
02177 *uint_val = *int_val;
02178 *double_val = *int_val;
02179 break;
02180 case PLY_UCHAR:
02181 size = fread (ptr, 1, 1, fp);
02182 *uint_val = *((unsigned char *) ptr);
02183 *int_val = *uint_val;
02184 *double_val = *uint_val;
02185 break;
02186 case PLY_SHORT:
02187 size = fread (ptr, 2, 1, fp);
02188 *int_val = *((short int *) ptr);
02189 *uint_val = *int_val;
02190 *double_val = *int_val;
02191 break;
02192 case PLY_USHORT:
02193 size = fread (ptr, 2, 1, fp);
02194 *uint_val = *((unsigned short int *) ptr);
02195 *int_val = *uint_val;
02196 *double_val = *uint_val;
02197 break;
02198 case PLY_INT:
02199 size = fread (ptr, 4, 1, fp);
02200 *int_val = *((int *) ptr);
02201 *uint_val = *int_val;
02202 *double_val = *int_val;
02203 break;
02204 case PLY_UINT:
02205 size = fread (ptr, 4, 1, fp);
02206 *uint_val = *((unsigned int *) ptr);
02207 *int_val = *uint_val;
02208 *double_val = *uint_val;
02209 break;
02210 case PLY_FLOAT:
02211 size = fread (ptr, 4, 1, fp);
02212 *double_val = *((float *) ptr);
02213 *int_val = *double_val;
02214 *uint_val = *double_val;
02215 break;
02216 case PLY_DOUBLE:
02217 size = fread (ptr, 8, 1, fp);
02218 *double_val = *((double *) ptr);
02219 *int_val = *double_val;
02220 *uint_val = *double_val;
02221 break;
02222 default:
02223 fprintf (stderr, "get_binary_item: bad type = %d\n", type);
02224 exit (-1);
02225 }
02226 printf("read size: %zu", size);
02227 }
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244 void get_ascii_item(
02245 char *word,
02246 int type,
02247 int *int_val,
02248 unsigned int *uint_val,
02249 double *double_val
02250 )
02251 {
02252 switch (type) {
02253 case PLY_CHAR:
02254 case PLY_UCHAR:
02255 case PLY_SHORT:
02256 case PLY_USHORT:
02257 case PLY_INT:
02258 *int_val = atoi (word);
02259 *uint_val = *int_val;
02260 *double_val = *int_val;
02261 break;
02262
02263 case PLY_UINT:
02264 *uint_val = strtoul (word, (char **) NULL, 10);
02265 *int_val = *uint_val;
02266 *double_val = *uint_val;
02267 break;
02268
02269 case PLY_FLOAT:
02270 case PLY_DOUBLE:
02271 *double_val = atof (word);
02272 *int_val = (int) *double_val;
02273 *uint_val = (unsigned int) *double_val;
02274 break;
02275
02276 default:
02277 fprintf (stderr, "get_ascii_item: bad type = %d\n", type);
02278 exit (-1);
02279 }
02280 }
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297 void store_item (
02298 char *item,
02299 int type,
02300 int int_val,
02301 unsigned int uint_val,
02302 double double_val
02303 )
02304 {
02305 unsigned char *puchar;
02306 short int *pshort;
02307 unsigned short int *pushort;
02308 int *pint;
02309 unsigned int *puint;
02310 float *pfloat;
02311 double *pdouble;
02312
02313 switch (type) {
02314 case PLY_CHAR:
02315 *item = int_val;
02316 break;
02317 case PLY_UCHAR:
02318 puchar = (unsigned char *) item;
02319 *puchar = uint_val;
02320 break;
02321 case PLY_SHORT:
02322 pshort = (short *) item;
02323 *pshort = int_val;
02324 break;
02325 case PLY_USHORT:
02326 pushort = (unsigned short *) item;
02327 *pushort = uint_val;
02328 break;
02329 case PLY_INT:
02330 pint = (int *) item;
02331 *pint = int_val;
02332 break;
02333 case PLY_UINT:
02334 puint = (unsigned int *) item;
02335 *puint = uint_val;
02336 break;
02337 case PLY_FLOAT:
02338 pfloat = (float *) item;
02339 *pfloat = double_val;
02340 break;
02341 case PLY_DOUBLE:
02342 pdouble = (double *) item;
02343 *pdouble = double_val;
02344 break;
02345 default:
02346 fprintf (stderr, "store_item: bad type = %d\n", type);
02347 exit (-1);
02348 }
02349 }
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361 void add_element (PlyFile *plyfile, char **words, int nwords)
02362 {
02363 PlyElement *elem;
02364
02365
02366 elem = (PlyElement *) myalloc (sizeof (PlyElement));
02367 elem->name = strdup (words[1]);
02368 elem->num = atoi (words[2]);
02369 elem->nprops = 0;
02370
02371
02372 if (plyfile->nelems == 0)
02373 plyfile->elems = (PlyElement **) myalloc (sizeof (PlyElement *));
02374 else
02375 plyfile->elems = (PlyElement **) realloc (plyfile->elems,
02376 sizeof (PlyElement *) * (plyfile->nelems + 1));
02377
02378
02379 plyfile->elems[plyfile->nelems] = elem;
02380 plyfile->nelems++;
02381 }
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394 int get_prop_type(char *type_name)
02395 {
02396 int i;
02397
02398 for (i = PLY_START_TYPE + 1; i < PLY_END_TYPE; i++)
02399 if (equal_strings (type_name, type_names[i]))
02400 return (i);
02401
02402
02403 return (0);
02404 }
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416 void add_property (PlyFile *plyfile, char **words, int nwords)
02417 {
02418
02419
02420 PlyProperty *prop;
02421 PlyElement *elem;
02422
02423
02424
02425 prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
02426
02427 if (equal_strings (words[1], "list")) {
02428 prop->count_external = get_prop_type (words[2]);
02429 prop->external_type = get_prop_type (words[3]);
02430 prop->name = strdup (words[4]);
02431 prop->is_list = 1;
02432 }
02433 else {
02434 prop->external_type = get_prop_type (words[1]);
02435 prop->name = strdup (words[2]);
02436 prop->is_list = 0;
02437 }
02438
02439
02440
02441 elem = plyfile->elems[plyfile->nelems - 1];
02442
02443 if (elem->nprops == 0)
02444 elem->props = (PlyProperty **) myalloc (sizeof (PlyProperty *));
02445 else
02446 elem->props = (PlyProperty **) realloc (elem->props,
02447 sizeof (PlyProperty *) * (elem->nprops + 1));
02448
02449 elem->props[elem->nprops] = prop;
02450 elem->nprops++;
02451 }
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462 void add_comment (PlyFile *plyfile, char *line)
02463 {
02464 int i;
02465
02466
02467 i = 7;
02468 while (line[i] == ' ' || line[i] == '\t')
02469 i++;
02470
02471 ply_put_comment (plyfile, &line[i]);
02472 }
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483 void add_obj_info (PlyFile *plyfile, char *line)
02484 {
02485 int i;
02486
02487
02488 i = 8;
02489 while (line[i] == ' ' || line[i] == '\t')
02490 i++;
02491
02492 ply_put_obj_info (plyfile, &line[i]);
02493 }
02494
02495
02496
02497
02498
02499
02500 void copy_property(PlyProperty *dest, PlyProperty *src)
02501 {
02502 dest->name = strdup (src->name);
02503 dest->external_type = src->external_type;
02504 dest->internal_type = src->internal_type;
02505 dest->offset = src->offset;
02506
02507 dest->is_list = src->is_list;
02508 dest->count_external = src->count_external;
02509 dest->count_internal = src->count_internal;
02510 dest->count_offset = src->count_offset;
02511 }
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523 char *my_alloc(int size, int lnum, char *fname)
02524 {
02525 char *ptr;
02526
02527 ptr = (char *) malloc (size);
02528
02529 if (ptr == 0) {
02530 fprintf(stderr, "Memory allocation bombed on line %d in %s\n", lnum, fname);
02531 }
02532
02533 return (ptr);
02534 }
02535
02536 #ifdef __cplusplus
02537 }
02538 #endif
02539
02540 #ifdef WIN32
02541 #pragma warning(pop)
02542 #endif