📄 plyfile.cpp
字号:
fprintf (fp, "property list ");
write_scalar_type (fp, prop->count_external);
fprintf (fp, " ");
write_scalar_type (fp, prop->external_type);
fprintf (fp, " %s\n", prop->name);
}
else {
fprintf (fp, "property ");
write_scalar_type (fp, prop->external_type);
fprintf (fp, " %s\n", prop->name);
}
}
}
fprintf (fp, "end_header\n");
}
/******************************************************************************
Specify which elements are going to be written. This should be called
before a call to the routine ply_put_element().
Entry:
plyfile - file identifier
elem_name - name of element we're talking about
******************************************************************************/
void ply_put_element_setup(PlyFile *plyfile, char *elem_name)
{
PlyElement *elem;
elem = find_element (plyfile, elem_name);
if (elem == NULL) {
fprintf(stderr, "ply_elements_setup: can't find element '%s'\n", elem_name);
exit (-1);
}
plyfile->which_elem = elem;
}
/******************************************************************************
Write an element to the file. This routine assumes that we're
writing the type of element specified in the last call to the routine
ply_put_element_setup().
Entry:
plyfile - file identifier
elem_ptr - pointer to the element
******************************************************************************/
void ply_put_element(PlyFile *plyfile, void *elem_ptr)
{
int i,j,k;
FILE *fp = plyfile->fp;
PlyElement *elem;
PlyProperty *prop;
char *elem_data,*item;
char **item_ptr;
int list_count;
int item_size;
int int_val;
unsigned int uint_val;
double double_val;
char **other_ptr;
elem = plyfile->which_elem;
elem_data = (char*) elem_ptr;
other_ptr = (char **) (((char *) elem_ptr) + elem->other_offset);
/* write out either to an ascii or binary file */
if (plyfile->file_type == PLY_ASCII) {
/* write an ascii 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) {
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 {
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) {
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 {
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);
}
}
}
}
/******************************************************************************
Specify a comment that will be written in the header.
Entry:
plyfile - file identifier
comment - the comment to be written
******************************************************************************/
void ply_put_comment(PlyFile *plyfile, char *comment)
{
/* (re)allocate space for new comment */
if (plyfile->num_comments == 0)
plyfile->comments = (char **) myalloc (sizeof (char *));
else
plyfile->comments = (char **) realloc (plyfile->comments,
sizeof (char *) * (plyfile->num_comments + 1));
/* add comment to list */
plyfile->comments[plyfile->num_comments] = strdup (comment);
plyfile->num_comments++;
}
/******************************************************************************
Specify a piece of object information (arbitrary text) that will be written
in the header.
Entry:
plyfile - file identifier
obj_info - the text information to be written
******************************************************************************/
void ply_put_obj_info(PlyFile *plyfile, char *obj_info)
{
/* (re)allocate space for new info */
if (plyfile->num_obj_info == 0)
plyfile->obj_info = (char **) myalloc (sizeof (char *));
else
plyfile->obj_info = (char **) realloc (plyfile->obj_info,
sizeof (char *) * (plyfile->num_obj_info + 1));
/* add info to list */
plyfile->obj_info[plyfile->num_obj_info] = strdup (obj_info);
plyfile->num_obj_info++;
}
/*************/
/* Reading */
/*************/
/******************************************************************************
Given a file pointer, get ready to read PLY data from the file.
Entry:
fp - the given file pointer
Exit:
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->nelems = 0;
plyfile->comments = NULL;
plyfile->num_comments = 0;
plyfile->obj_info = NULL;
plyfile->num_obj_info = 0;
plyfile->fp = fp;
plyfile->other_elems = 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->nelems; 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->nelems);
for (i = 0; i < plyfile->nelems; i++)
elist[i] = strdup (plyfile->elems[i]->name);
*elem_names = elist;
*nelems = plyfile->nelems;
/* return a pointer to the file's information */
return (plyfile);
}
/******************************************************************************
Open a polygon file for reading.
Entry:
filename - name of file to read from
Exit:
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 about
Exit:
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 **ply_get_element_description(
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 be
called before a call to the routine ply_get_element().
Entry:
plyfile - file identifier
elem_name - which element we're talking about
nprops - number of properties
prop_list - list of properties
******************************************************************************/
void ply_get_element_setup(
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -