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