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