📄 plyfile.cpp
字号:
}
/******************************************************************************
Specify a property of an element that is to be returned. This should be
called (usually multiple times) before a call to the routine ply_get_element().
This routine should be used in preference to the less flexible old routine
called 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 reading
the type of element specified in the last call to the routine
ply_get_element_setup().
Entry:
plyfile - file identifier
elem_ptr - pointer to location where the element information should be put
******************************************************************************/
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 identifier
Exit:
num_comments - number of comments returned
returns a pointer to a list of comments
******************************************************************************/
char **ply_get_comments(PlyFile *plyfile, int *num_comments)
{
*num_comments = plyfile->num_comments;
return (plyfile->comments);
}
/******************************************************************************
Extract the object information (arbitrary text) from the header information
of a PLY file.
Entry:
plyfile - file identifier
Exit:
num_obj_info - number of lines of text information returned
returns a pointer to a list of object info lines
******************************************************************************/
char **ply_get_obj_info(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 that
the user has not explicitly asked for, but that are to be stashed away
in a special structure to be carried along with the element's other
information.
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;
/* Examine each property in decreasing order of size. */
/* We do this so that all data types will be aligned by */
/* word, half-word, or whatever within the structure. */
for (type_size = 8; type_size > 0; type_size /= 2) {
/* add up the space taken by each property, and save this information */
/* away in the property descriptor */
for (i = 0; i < elem->nprops; i++) {
/* don't bother with properties we've been asked to store explicitly */
if (elem->store_prop[i])
continue;
prop = elem->props[i];
/* internal types will be same as external */
prop->internal_type = prop->external_type;
prop->count_internal = prop->count_external;
/* check list case */
if (prop->is_list) {
/* pointer to list */
if (type_size == sizeof (void *)) {
prop->offset = size;
size += sizeof (void *); /* always use size of a pointer here */
}
/* count of number of list elements */
if (type_size == ply_type_size[prop->count_external]) {
prop->count_offset = size;
size += ply_type_size[prop->count_external];
}
}
/* not list */
else if (type_size == ply_type_size[prop->external_type]) {
prop->offset = size;
size += ply_type_size[prop->external_type];
}
}
}
/* save the size for the other_props structure */
elem->other_size = size;
}
/******************************************************************************
Specify that we want the "other" properties of an element to be tucked
away within the user's structure. The user needn't be concerned for how
these properties are stored.
Entry:
plyfile - file identifier
elem_name - name of element that we want to store other_props in
offset - offset to where other_props will be stored inside user's structure
Exit:
returns pointer to structure containing description of other_props
******************************************************************************/
PlyOtherProp *ply_get_other_properties(
PlyFile *plyfile,
char *elem_name,
int offset
)
{
int i;
PlyElement *elem;
PlyOtherProp *other;
PlyProperty *prop;
int nprops;
/* find information about the element */
elem = find_element (plyfile, elem_name);
if (elem == NULL) {
fprintf (stderr, "ply_get_other_properties: Can't find element '%s'\n",
elem_name);
return (NULL);
}
/* remember that this is the "current" element */
plyfile->which_elem = elem;
/* save the offset to where to store the other_props */
elem->other_offset = offset;
/* place the appropriate pointers, etc. in the element's property list */
setup_other_props (plyfile, elem);
/* create structure for describing other_props */
other = (PlyOtherProp *) myalloc (sizeof (PlyOtherProp));
other->name = strdup (elem_name);
#if 0
if (elem->other_offset == NO_OTHER_PROPS) {
other->size = 0;
other->props = NULL;
other->nprops = 0;
return (other);
}
#endif
other->size = elem->other_size;
other->props = (PlyProperty **) myalloc (sizeof(PlyProperty) * elem->nprops);
/* save descriptions of each "other" property */
nprops = 0;
for (i = 0; i < elem->nprops; i++) {
if (elem->store_prop[i])
continue;
prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
copy_property (prop, elem->props[i]);
other->props[nprops] = prop;
nprops++;
}
other->nprops = nprops;
#if 1
/* set other_offset pointer appropriately if there are NO other properties */
if (other->nprops == 0) {
elem->other_offset = NO_OTHER_PROPS;
}
#endif
/* return structure */
return (other);
}
/*************************/
/* Other Element Stuff */
/*************************/
/******************************************************************************
Grab all the data for an element that a user does not want to explicitly
read in.
Entry:
plyfile - pointer to file
elem_name - name of element whose data is to be read in
elem_count - number of instances of this element stored in the file
Exit:
returns pointer to ALL the "other" element data for this PLY file
******************************************************************************/
PlyOtherElems *ply_get_other_element (
PlyFile *plyfile,
char *elem_name,
int elem_count
)
{
int i;
PlyElement *elem;
PlyOtherElems *other_elems;
OtherElem *other;
int num_elems;
/* look for appropriate element */
elem = find_element (plyfile, elem_name);
if (elem == NULL) {
fprintf (stderr,
"ply_get_other_element: can't find element '%s'\n", elem_name);
exit (-1);
}
/* create room for the new "other" element, initializing the */
/* other data structure if necessary */
if (plyfile->other_elems == NULL) {
plyfile->other_elems = (PlyOtherElems *) myalloc (sizeof (PlyOtherElems));
other_elems = plyfile->other_elems;
other_elems->other_list = (OtherElem *) myalloc (sizeof (OtherElem));
other = &(other_elems->other_list[0]);
other_elems->num_elems = 1;
}
else {
other_elems = plyfile->other_elems;
other_elems->other_list = (OtherElem *) realloc (other_elems->other_list,
sizeof (OtherElem) * other_elems->num_elems + 1);
other = &(other_elems->other_list[other_elems->num_elems]);
other_elems->num_elems++;
}
/* count of element instances in file */
other->elem_count = elem_count;
/* save name of element */
other->elem_name = strdup (elem_name);
/* create a list to hold all the current elements */
other->other_data = (OtherData **)
malloc (sizeof (OtherData *) * other->elem_count);
/* set up for getting elements */
other->other_props = ply_get_other_properties (plyfile, elem_name,
offsetof(OtherData,other_props));
/* grab all these elements */
for (i = 0; i < other->elem_count; i++) {
/* grab and element from the file */
other->other_data[i] = (OtherData *) malloc (sizeof (OtherData));
ply_get_element (plyfile, (void *) other->other_data[i]);
}
/* return pointer to the other elements data */
return (other_elems);
}
/******************************************************************************
Pass along a pointer to "other" elements that we want to save in a given
PLY file. These other elements were presumably read from another PLY file.
Entry:
plyfile - file pointer in which to store this other element info
other_elems - info about other elements that we want to store
******************************************************************************/
void ply_describe_other_elements (
PlyFile *plyfile,
PlyOtherElems *other_elems
)
{
int i;
OtherElem *other;
/* ignore this call if there is no other element */
if (other_elems == NULL)
return;
/* save pointer to this information */
plyfile->other_elems = other_elems;
/* describe the other properties of this element */
for (i = 0; i < other_elems->num_elems; i++) {
other = &(other_elems->other_list[i]);
ply_element_count (plyfile, other->elem_name, other->elem_count);
ply_describe_other_properties (plyfile, other->other_props,
offsetof(OtherData,other_props));
}
}
/******************************************************************************
Write out the "other" elements specified for this PLY file.
Entry:
plyfile - pointer to PLY file to write out other elements for
******************************************************************************/
void ply_put_other_elements (PlyFile *plyfile)
{
int i,j;
OtherElem *other;
/* make sure we have other elements to write */
if (plyfile->other_elems == NULL)
return;
/* write out the data for each "other" element */
for (i = 0; i < plyfile->other_elems->num_elems; i++) {
other = &(plyfile->other_elems->other_list[i]);
ply_put_element_setup (plyfile, other->elem_name);
/* write out each instance of the current element */
for (j = 0; j < other->elem_count; j++)
ply_put_element (plyfile, (void *) other->other_data[j]);
}
}
/******************************************************************************
Free up storage used by an "other" elements data structure.
Entry:
other_elems - data structure to free up
******************************************************************************/
void ply_free_other_elements (PlyOtherElems *other_elems)
{
}
/*******************/
/* Miscellaneous */
/*******************/
/******************************************************************************
Close a PLY file.
Entry:
plyfile - identifier of file to close
******************************************************************************/
void ply_close(PlyFile *plyfile)
{
fclose (plyfile->fp);
/* free up memory associated with the PLY file */
free (plyfile);
}
/******************************************************************************
Get version number and file type of a PlyFile.
Entry:
ply - pointer to PLY file
Exit:
version - version of the file
file_type - PLY_ASCII, PLY_BINARY_BE, or PLY_BINARY_LE
******************************************************************************/
void ply_get_info(PlyFile *ply, float *version, int *file_type)
{
if (ply == NULL)
return;
*version = ply->version;
*file_type = ply->file_type;
}
/******************************************************************************
Compare two strings. Returns 1 if they are the same, 0 if not.
******************************************************************************/
int equal_strings(char *s1, char *s2)
{
int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -