📄 ply.c
字号:
for (j = 0; j < elem->nprops; j++) { prop = elem->props[j]; if (elem->store_prop[j] == OTHER_PROP) elem_data = *other_ptr; else elem_data = (char *) elem_ptr; if (prop->is_list == PLY_LIST) { /* list */ item = elem_data + prop->count_offset; get_stored_item ((void *) item, prop->count_internal, &int_val, &uint_val, &double_val); write_ascii_item (fp, int_val, uint_val, double_val, prop->count_external); list_count = uint_val; item_ptr = (char **) (elem_data + prop->offset); item = item_ptr[0]; item_size = ply_type_size[prop->internal_type]; for (k = 0; k < list_count; k++) { get_stored_item ((void *) item, prop->internal_type, &int_val, &uint_val, &double_val); write_ascii_item (fp, int_val, uint_val, double_val, prop->external_type); item += item_size; } } else if (prop->is_list == PLY_STRING) { /* string */ char **str; item = elem_data + prop->offset; str = (char **) item; fprintf (fp, "\"%s\"", *str); } else { /* scalar */ item = elem_data + prop->offset; get_stored_item ((void *) item, prop->internal_type, &int_val, &uint_val, &double_val); write_ascii_item (fp, int_val, uint_val, double_val, prop->external_type); } } fprintf (fp, "\n"); } else { /* write a binary file */ /* write out each property of the element */ for (j = 0; j < elem->nprops; j++) { prop = elem->props[j]; if (elem->store_prop[j] == OTHER_PROP) elem_data = *other_ptr; else elem_data = (char *) elem_ptr; if (prop->is_list == PLY_LIST) { /* list */ item = elem_data + prop->count_offset; item_size = ply_type_size[prop->count_internal]; get_stored_item ((void *) item, prop->count_internal, &int_val, &uint_val, &double_val); write_binary_item (fp, int_val, uint_val, double_val, prop->count_external); list_count = uint_val; item_ptr = (char **) (elem_data + prop->offset); item = item_ptr[0]; item_size = ply_type_size[prop->internal_type]; for (k = 0; k < list_count; k++) { get_stored_item ((void *) item, prop->internal_type, &int_val, &uint_val, &double_val); write_binary_item (fp, int_val, uint_val, double_val, prop->external_type); item += item_size; } } else if (prop->is_list == PLY_STRING) { /* string */ int len; char **str; item = elem_data + prop->offset; str = (char **) item; /* write the length */ len = strlen(*str) + 1; fwrite (&len, sizeof(int), 1, fp); /* write the string, including the null character */ fwrite (*str, len, 1, fp); } else { /* scalar */ item = elem_data + prop->offset; item_size = ply_type_size[prop->internal_type]; get_stored_item ((void *) item, prop->internal_type, &int_val, &uint_val, &double_val); write_binary_item (fp, int_val, uint_val, double_val, prop->external_type); } } }}/*************//* Reading *//*************//******************************************************************************Given a file pointer, get ready to read PLY data from the file.Entry: fp - the given file pointerExit: nelems - number of elements in object elem_names - list of element names returns a pointer to a PlyFile, used to refer to this file, or NULL if error******************************************************************************/PlyFile *ply_read(FILE *fp, int *nelems, char ***elem_names){ int i,j; PlyFile *plyfile; int nwords; char **words; int found_format = 0; char **elist; PlyElement *elem; char *orig_line; /* check for NULL file pointer */ if (fp == NULL) return (NULL); /* create record for this object */ plyfile = (PlyFile *) myalloc (sizeof (PlyFile)); plyfile->num_elem_types = 0; plyfile->comments = NULL; plyfile->num_comments = 0; plyfile->obj_info = NULL; plyfile->num_obj_info = 0; plyfile->fp = fp; plyfile->other_elems = NULL; plyfile->rule_list = NULL; /* read and parse the file's header */ words = get_words (plyfile->fp, &nwords, &orig_line); if (!words || !equal_strings (words[0], "ply")) return (NULL); while (words) { /* parse words */ if (equal_strings (words[0], "format")) { if (nwords != 3) return (NULL); if (equal_strings (words[1], "ascii")) plyfile->file_type = PLY_ASCII; else if (equal_strings (words[1], "binary_big_endian")) plyfile->file_type = PLY_BINARY_BE; else if (equal_strings (words[1], "binary_little_endian")) plyfile->file_type = PLY_BINARY_LE; else return (NULL); plyfile->version = atof (words[2]); found_format = 1; } else if (equal_strings (words[0], "element")) add_element (plyfile, words, nwords); else if (equal_strings (words[0], "property")) add_property (plyfile, words, nwords); else if (equal_strings (words[0], "comment")) add_comment (plyfile, orig_line); else if (equal_strings (words[0], "obj_info")) add_obj_info (plyfile, orig_line); else if (equal_strings (words[0], "end_header")) break; /* free up words space */ free (words); words = get_words (plyfile->fp, &nwords, &orig_line); } /* create tags for each property of each element, to be used */ /* later to say whether or not to store each property for the user */ for (i = 0; i < plyfile->num_elem_types; i++) { elem = plyfile->elems[i]; elem->store_prop = (char *) myalloc (sizeof (char) * elem->nprops); for (j = 0; j < elem->nprops; j++) elem->store_prop[j] = DONT_STORE_PROP; elem->other_offset = NO_OTHER_PROPS; /* no "other" props by default */ } /* set return values about the elements */ elist = (char **) myalloc (sizeof (char *) * plyfile->num_elem_types); for (i = 0; i < plyfile->num_elem_types; i++) elist[i] = strdup (plyfile->elems[i]->name); *elem_names = elist; *nelems = plyfile->num_elem_types; /* return a pointer to the file's information */ return (plyfile);}/******************************************************************************Open a polygon file for reading.Entry: filename - name of file to read fromExit: nelems - number of elements in object elem_names - list of element names file_type - file type, either ascii or binary version - version number of PLY file returns a file identifier, used to refer to this file, or NULL if error******************************************************************************/PlyFile *ply_open_for_reading( char *filename, int *nelems, char ***elem_names, int *file_type, float *version){ FILE *fp; PlyFile *plyfile; char *name; /* 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 reading */ fp = fopen (name, "r"); if (fp == NULL) return (NULL); /* create the PlyFile data structure */ plyfile = ply_read (fp, nelems, elem_names); /* determine the file type and version */ *file_type = plyfile->file_type; *version = plyfile->version; /* return a pointer to the file's information */ return (plyfile);}/******************************************************************************Get information about a particular element.Entry: plyfile - file identifier elem_name - name of element to get information aboutExit: nelems - number of elements of this type in the file nprops - number of properties returns a list of properties, or NULL if the file doesn't contain that elem******************************************************************************/PlyProperty **get_element_description_ply( PlyFile *plyfile, char *elem_name, int *nelems, int *nprops){ int i; PlyElement *elem; PlyProperty *prop; PlyProperty **prop_list; /* find information about the element */ elem = find_element (plyfile, elem_name); if (elem == NULL) return (NULL); *nelems = elem->num; *nprops = elem->nprops; /* make a copy of the element's property list */ prop_list = (PlyProperty **) myalloc (sizeof (PlyProperty *) * elem->nprops); for (i = 0; i < elem->nprops; i++) { prop = (PlyProperty *) myalloc (sizeof (PlyProperty)); copy_property (prop, elem->props[i]); prop_list[i] = prop; } /* return this duplicate property list */ return (prop_list);}/******************************************************************************Specify which properties of an element are to be returned. This should becalled before a call to the routine get_element_ply().Entry: plyfile - file identifier elem_name - which element we're talking about nprops - number of properties prop_list - list of properties******************************************************************************/void get_element_setup_ply( PlyFile *plyfile, char *elem_name, int nprops, PlyProperty *prop_list){ int i; PlyElement *elem; PlyProperty *prop; int index; /* find information about the element */ elem = find_element (plyfile, elem_name); plyfile->which_elem = elem; /* deposit the property information into the element's description */ for (i = 0; i < nprops; i++) { /* look for actual property */ prop = find_property (elem, prop_list[i].name, &index); if (prop == NULL) { fprintf (stderr, "Warning: Can't find property '%s' in element '%s'\n", prop_list[i].name, elem_name); continue; } /* store its description */ prop->internal_type = prop_list[i].internal_type; prop->offset = prop_list[i].offset; prop->count_internal = prop_list[i].count_internal; prop->count_offset = prop_list[i].count_offset; /* specify that the user wants this property */ elem->store_prop[index] = STORE_PROP; }}/******************************************************************************Specify a property of an element that is to be returned. This should becalled (usually multiple times) before a call to the routine ply_get_element().This routine should be used in preference to the less flexible old routinecalled ply_get_element_setup().Entry: plyfile - file identifier elem_name - which element we're talking about prop - property to add to those that will be returned******************************************************************************/void ply_get_property( PlyFile *plyfile, char *elem_name, PlyProperty *prop){ PlyElement *elem; PlyProperty *prop_ptr; int index; /* find information about the element */ elem = find_element (plyfile, elem_name); plyfile->which_elem = elem; /* deposit the property information into the element's description */ prop_ptr = find_property (elem, prop->name, &index); if (prop_ptr == NULL) { fprintf (stderr, "Warning: Can't find property '%s' in element '%s'\n", prop->name, elem_name); return; } prop_ptr->internal_type = prop->internal_type; prop_ptr->offset = prop->offset; prop_ptr->count_internal = prop->count_internal; prop_ptr->count_offset = prop->count_offset; /* specify that the user wants this property */ elem->store_prop[index] = STORE_PROP;}/******************************************************************************Read one element from the file. This routine assumes that we're readingthe type of element specified in the last call to the routineply_get_element_setup().Entry: plyfile - file identifier elem_ptr - pointer to location where the element information should be put******************************************************************************/void ply_get_element(PlyFile *plyfile, void *elem_ptr){ if (plyfile->file_type == PLY_ASCII) ascii_get_element (plyfile, (char *) elem_ptr); else binary_get_element (plyfile, (char *) elem_ptr);}/******************************************************************************Extract the comments from the header information of a PLY file.Entry: plyfile - file identifierExit: num_comments - number of comments returned returns a pointer to a list of comments******************************************************************************/char **get_comments_ply(PlyFile *plyfile, int *num_comments){ *num_comments = plyfile->num_comments; return (plyfile->comments);}/******************************************************************************Extract the object information (arbitrary text) from the header informationof a PLY file.Entry: plyfile - file identifierExit: num_obj_info - number of lines of text information returned returns a pointer to a list of object info lines******************************************************************************/char **get_obj_info_ply(PlyFile *plyfile, int *num_obj_info){ *num_obj_info = plyfile->num_obj_info; return (plyfile->obj_info);}/******************************************************************************Make ready for "other" properties of an element-- those properties thatthe user has not explicitly asked for, but that are to be stashed awayin a special structure to be carried along with the element's otherinformation.Entry: plyfile - file identifier elem - element for which we want to save away other properties******************************************************************************/void setup_other_props(PlyFile *plyfile, PlyElement *elem){ int i; PlyProperty *prop; int size = 0; int type_size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -