/*
The interface routines for reading and writing PLY polygon files.
Greg Turk, February 1994
---------------------------------------------------------------
A PLY file contains a single polygonal _object_.
An object is composed of lists of _elements_. Typical elements are
vertices, faces, edges and materials.
Each type of element for a given object has one or more _properties_
associated with the element type. For instance, a vertex element may
have as properties the floating-point values x,y,z and the three unsigned
chars representing red, green and blue.
*/
#include
#include
#include
#include
#include
#include
#include "ply.h" #include
using namespace std; char *type_names[] = { "invalid", "char", "short", "int", "uchar", "ushort", "uint", "float", "double", }; int ply_type_size[] = { 0, 1, 2, 4, 1, 2, 4, 4, 8 }; #define NO_OTHER_PROPS -1 #define DONT_STORE_PROP 0 #define STORE_PROP 1 #define OTHER_PROP 0 #define NAMED_PROP 1 /* returns 1 if strings are equal, 0 if not */ /* find an element in a plyfile's list */ PlyElement *find_element(PlyFile *, char *); /* find a property in an element's list */ PlyProperty *find_property(PlyElement *, char *, int *); /* write to a file the word describing a PLY file data type */ void write_scalar_type (FILE *, int); /* read a line from a file and break it up into separate words */ char **get_words(FILE *, int *, char **); char **old_get_words(FILE *, int *); /* write an item to a file */ void write_binary_item(FILE *, int, unsigned int, double, int); void write_ascii_item(FILE *, int, unsigned int, double, int); double old_write_ascii_item(FILE *, char *, int); /* add information to a PLY file descriptor */ void add_element(PlyFile *, char **, int); void add_property(PlyFile *, char **, int); void add_comment(PlyFile *, char *); void add_obj_info(PlyFile *, char *); /* copy a property */ void copy_property(PlyProperty *, PlyProperty *); /* store a value into where a pointer and a type specify */ void store_item(char *, int, int, unsigned int, double); /* return the value of a stored item */ void get_stored_item( void *, int, int *, unsigned int *, double *); /* return the value stored in an item, given ptr to it and its type */ double get_item_value(char *, int); /* get binary or ascii item and store it according to ptr and type */ void get_ascii_item(char *, int, int *, unsigned int *, double *); void get_binary_item(FILE *, int, int *, unsigned int *, double *); /* get a bunch of elements from a file */ void ascii_get_element(PlyFile *, char *); void binary_get_element(PlyFile *, char *); /* memory allocation */ char *my_alloc(int, int, char *); /*************/ /* Writing */ /*************/ /****************************************************************************** Given a file pointer, get ready to write PLY data to the file. Entry: fp - the given file pointer nelems - number of elements in object elem_names - list of element names file_type - file type, either ascii or binary Exit: returns a pointer to a PlyFile, used to refer to this file, or NULL if error ******************************************************************************/ PlyFile *ply_write( FILE *fp, int nelems, char **elem_names, int file_type ) { int i; PlyFile *plyfile; PlyElement *elem; /* check for NULL file pointer */ if (fp == NULL) return (NULL); /* create a record for this object */ plyfile = (PlyFile *) myalloc (sizeof (PlyFile)); plyfile->file_type = file_type; plyfile->num_comments = 0; plyfile->num_obj_info = 0; plyfile->nelems = nelems; plyfile->version = 1.0; plyfile->fp = fp; plyfile->other_elems = NULL; /* tuck aside the names of the elements */ plyfile->elems = (PlyElement **) myalloc (sizeof (PlyElement *) * nelems); for (i = 0; i < nelems; i++) { elem = (PlyElement *) myalloc (sizeof (PlyElement)); plyfile->elems[i] = elem; elem->name = strdup (elem_names[i]); elem->num = 0; elem->nprops = 0; } /* return pointer to the file descriptor */ return (plyfile); } /****************************************************************************** Open a polygon file for writing. Entry: filename - name of file to read from nelems - number of elements in object elem_names - list of element names file_type - file type, either ascii or binary Exit: version - version number of PLY file returns a file identifier, used to refer to this file, or NULL if error ******************************************************************************/ PlyFile *ply_open_for_writing( char *filename, int nelems, char **elem_names, int file_type, float *version ) { int i; PlyFile *plyfile; PlyElement *elem; char *name; FILE *fp; /* tack on the extension .ply, if necessary */ name = (char *) myalloc (sizeof (char) * (strlen (filename) + 5)); strcpy (name, filename); if (strlen (name) < 4 || strcmp (name + strlen (name) - 4, ".ply") != 0) strcat (name, ".ply"); /* open the file for writing */ fp = inFile (name, "w"); if (fp == NULL) { return (NULL); } /* create the actual PlyFile structure */ plyfile = ply_write (fp, nelems, elem_names, file_type); if (plyfile == NULL) return (NULL); /* say what PLY file version number we're writing */ *version = plyfile->version; /* return pointer to the file descriptor */ return (plyfile); }