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