316 lines
9.9 KiB
C++
316 lines
9.9 KiB
C++
////////////////////////////////////////////////////////////////////
|
|
// PLY.h
|
|
//
|
|
// Copyright 2023 cDc@seacave
|
|
// Distributed under the Boost Software License, Version 1.0
|
|
// (See http://www.boost.org/LICENSE_1_0.txt)
|
|
//
|
|
// PLY polygon files parser.
|
|
// (originally by Greg Turk, heavily modified by cDc@seacave)
|
|
//
|
|
// 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 three floating-point values x,y,z and three unsigned
|
|
// chars for red, green and blue.
|
|
|
|
|
|
#ifndef __SEACAVE_PLY_H__
|
|
#define __SEACAVE_PLY_H__
|
|
|
|
|
|
// I N C L U D E S /////////////////////////////////////////////////
|
|
|
|
|
|
// D E F I N E S ///////////////////////////////////////////////////
|
|
|
|
#define PLY_OKAY 0 // ply routine worked okay
|
|
#define PLY_ERROR -1 // error in ply routine
|
|
|
|
|
|
// S T R U C T S ///////////////////////////////////////////////////
|
|
|
|
class IO_API PLY
|
|
{
|
|
public:
|
|
// scalar data types supported by PLY format
|
|
enum FileType {
|
|
ASCII = 1, // ascii PLY file
|
|
BINARY_BE = 2, // binary PLY file, big endian
|
|
BINARY_LE = 3, // binary PLY file, little endian
|
|
};
|
|
enum DataType {
|
|
StartType = 0,
|
|
Int8 = 1,
|
|
Int16 = 2,
|
|
Int32 = 3,
|
|
Uint8 = 4,
|
|
Uint16 = 5,
|
|
Uint32 = 6,
|
|
Float32 = 7,
|
|
Float64 = 8,
|
|
EndType = 9,
|
|
};
|
|
enum ListType {
|
|
SCALAR = 0,
|
|
LIST = 1,
|
|
STRING = 2,
|
|
};
|
|
enum RuleType {
|
|
AVERAGE_RULE = 1,
|
|
MAJORITY_RULE = 2,
|
|
MINIMUM_RULE = 3,
|
|
MAXIMUM_RULE = 4,
|
|
SAME_RULE = 5,
|
|
RANDOM_RULE = 6,
|
|
};
|
|
|
|
// description of a property
|
|
struct PlyProperty {
|
|
std::string name; // property name
|
|
int external_type; // file's data type
|
|
int internal_type; // program's data type
|
|
int offset; // offset bytes of prop in a struct
|
|
|
|
int is_list; // 0 = scalar, 1 = list, 2 = char string
|
|
int count_external; // file's count type
|
|
int count_internal; // program's count type
|
|
int count_offset; // offset byte for list count
|
|
};
|
|
|
|
// description of an element
|
|
struct PlyElement {
|
|
std::string name; // element name
|
|
int num; // number of elements in this object
|
|
int size; // size of element (bytes) or -1 if variable
|
|
std::vector<PlyProperty*> props;// list of properties in the file
|
|
std::vector<char> store_prop; // flags: property wanted by user?
|
|
int other_offset; // offset to un-asked-for props, or -1 if none
|
|
int other_size; // size of other_props structure
|
|
};
|
|
|
|
// describes other properties in an element
|
|
struct PlyOtherProp {
|
|
std::string name; // element name
|
|
int size; // size of other_props
|
|
std::vector<PlyProperty*> props;// list of properties in other_props
|
|
};
|
|
|
|
// for storing other_props for an other element
|
|
struct OtherData {
|
|
void* other_props;
|
|
};
|
|
|
|
// data for one "other" element
|
|
struct OtherElem {
|
|
std::string elem_name; // names of other elements
|
|
int elem_count; // count of instances of each element
|
|
OtherData** other_data; // actual property data for the elements
|
|
PlyOtherProp* other_props; // description of the property data
|
|
};
|
|
|
|
// "other" elements, not interpreted by user
|
|
struct PlyOtherElems {
|
|
std::vector<OtherElem> other_list;// list of data for other elements
|
|
};
|
|
|
|
// rules for combining "other" properties
|
|
struct PlyPropRules {
|
|
PlyElement* elem; // element whose rules we are making
|
|
int* rule_list; // types of rules (AVERAGE_PLY, MAJORITY_PLY, etc.)
|
|
uint32_t max_props; // maximum number of properties we have room for now
|
|
std::vector<void*> props; // list of properties we're combining
|
|
std::vector<float> weights; // list of weights of the properties
|
|
};
|
|
|
|
struct PlyRuleList {
|
|
LPCSTR name; // name of the rule
|
|
char* element; // name of element that rule applies to
|
|
char* property; // name of property that rule applies to
|
|
struct PlyRuleList* next; // pointer for linked list of rules
|
|
};
|
|
|
|
// property propagation rules
|
|
struct RuleName {
|
|
int code;
|
|
std::string name;
|
|
};
|
|
|
|
protected:
|
|
struct ValueType {
|
|
union {
|
|
int8_t i8;
|
|
int16_t i16;
|
|
int32_t i32;
|
|
uint8_t u8;
|
|
uint16_t u16;
|
|
uint32_t u32;
|
|
float f;
|
|
double d;
|
|
};
|
|
};
|
|
|
|
public:
|
|
PLY();
|
|
~PLY();
|
|
|
|
bool read(LPCSTR);
|
|
bool read(SEACAVE::ISTREAM*);
|
|
bool write(LPCSTR, int, LPCSTR*, int, size_t memBufferSize=0);
|
|
bool write(SEACAVE::OSTREAM*, int, LPCSTR*, int, size_t memBufferSize=0);
|
|
void release();
|
|
|
|
void set_legacy_type_names();
|
|
|
|
void get_info(float*, int*);
|
|
|
|
void append_comment(const char*);
|
|
void append_obj_info(const char*);
|
|
void copy_comments(const PLY&);
|
|
void copy_obj_info(const PLY&);
|
|
std::vector<std::string>& get_comments();
|
|
std::vector<std::string>& get_obj_info();
|
|
|
|
void describe_property(const char*, const PlyProperty&);
|
|
void describe_property(const char*, int nprops, const PlyProperty*);
|
|
void get_property(const char*, PlyProperty*);
|
|
void get_element(void*);
|
|
|
|
PlyOtherElems* get_other_element();
|
|
|
|
int get_element_list(std::vector<std::string>&) const;
|
|
void setup_property(const PlyProperty&);
|
|
LPCSTR setup_element_read(int, int*);
|
|
PlyOtherProp* get_other_properties(int);
|
|
|
|
int get_elements_count() const { return (int)elems.size(); }
|
|
int get_current_element_count() const { return which_elem->num; }
|
|
void element_count(const char*, int);
|
|
void describe_element(const char*, int);
|
|
void describe_property(const PlyProperty&);
|
|
void describe_other_properties(PlyOtherProp*, int);
|
|
void describe_other_elements( PlyOtherElems*);
|
|
void get_element_setup(const char*, int, PlyProperty*);
|
|
int get_element_description(const char*, std::vector<PlyProperty*>&) const;
|
|
void element_layout(const char*, int, int, PlyProperty*);
|
|
|
|
bool header_complete();
|
|
void put_element_setup(const char*);
|
|
void put_element(const void*);
|
|
void put_other_elements();
|
|
|
|
PlyPropRules* init_rule(const char*);
|
|
void modify_rule(PlyPropRules*, const char*, int);
|
|
void start_props(PlyPropRules*);
|
|
void weight_props(float, void*);
|
|
void* get_new_props();
|
|
void set_prop_rules(PlyRuleList*);
|
|
PlyRuleList* append_prop_rule(PlyRuleList*, const char*, const char*);
|
|
|
|
// find an element in a ply's list
|
|
PlyElement* find_element(const char*) const;
|
|
// find a property in an element's list
|
|
int find_property(PlyElement*, const char*) const;
|
|
|
|
static inline bool equal_strings(const char* s1, const char* s2) { return _tcscmp(s1, s2) == 0; }
|
|
|
|
protected:
|
|
// write to a file the word describing a PLY file data type
|
|
void write_scalar_type(int);
|
|
|
|
// read a line from a file and break it up into separate words
|
|
typedef SEACAVE::TokenInputStream<false> STRISTREAM;
|
|
char** get_words(STRISTREAM&, int*, char**);
|
|
|
|
// write an item to a file
|
|
void write_binary_item(const ValueType&, int, int);
|
|
void write_ascii_item(const ValueType&, int, int);
|
|
|
|
// return the value of a stored item
|
|
static void get_stored_item(const void*, int, ValueType&);
|
|
|
|
// get binary or ascii item and store it according to ptr and type
|
|
void get_binary_item(int, ValueType&);
|
|
static void get_ascii_item(const char*, int, ValueType&);
|
|
|
|
// store a value into where a pointer and a type specify
|
|
static void store_item(void*, int, const ValueType&, int);
|
|
|
|
// add information to a PLY file descriptor
|
|
void add_element(const char**, int);
|
|
void add_property(const char**, int);
|
|
void add_comment(const char*);
|
|
void add_obj_info(const char*);
|
|
|
|
// get a bunch of elements from a file
|
|
void ascii_get_element(uint8_t*);
|
|
void binary_get_element(uint8_t*);
|
|
|
|
void setup_other_props(PlyElement*);
|
|
PlyOtherProp* get_other_properties(PlyElement*, int);
|
|
PlyOtherProp* get_other_properties(const char*, int);
|
|
|
|
int matches_rule_name(const char*);
|
|
int get_prop_type(const char*);
|
|
|
|
// copy a property
|
|
static void copy_property(PlyProperty&, const PlyProperty&);
|
|
|
|
// return the value as T stored in val as type
|
|
template <typename T>
|
|
static inline T ValueType2Type(const ValueType& val, int type) {
|
|
switch (type) {
|
|
case Int8:
|
|
return (T)val.i8;
|
|
case Int16:
|
|
return (T)val.i16;
|
|
case Int32:
|
|
return (T)val.i32;
|
|
case Uint8:
|
|
return (T)val.u8;
|
|
case Uint16:
|
|
return (T)val.u16;
|
|
case Uint32:
|
|
return (T)val.u32;
|
|
case Float32:
|
|
return (T)val.f;
|
|
case Float64:
|
|
return (T)val.d;
|
|
}
|
|
ASSERT("error: bad type" == NULL);
|
|
return T(0);
|
|
}
|
|
|
|
protected:
|
|
// description of PLY file
|
|
std::string filename; // file name
|
|
int file_type; // ascii or binary
|
|
float version; // version number of file
|
|
std::vector<PlyElement*> elems; // list of elements
|
|
std::vector<std::string> comments;// list of comments
|
|
std::vector<std::string> obj_info;// list of object info items
|
|
PlyElement* which_elem; // element we're currently reading or writing
|
|
PlyOtherElems* other_elems; // "other" elements from a PLY file
|
|
PlyPropRules* current_rules; // current propagation rules
|
|
PlyRuleList* rule_list; // rule list from user
|
|
std::vector<double> vals; // rule list from user
|
|
|
|
union {
|
|
SEACAVE::ISTREAM* istream; // input file pointer
|
|
SEACAVE::OSTREAM* ostream; // output file pointer
|
|
};
|
|
SEACAVE::MemFile* mfp; // mem-file pointer (optional)
|
|
const char* const* write_type_names; // names of scalar types to be used for writing (new types by default)
|
|
|
|
static const char* const type_names[9]; // names of scalar types
|
|
static const char* const old_type_names[9]; // old names of types for backward compatibility
|
|
static const int ply_type_size[9];
|
|
static const RuleName rule_name_list[7];
|
|
};
|
|
|
|
#endif // __SEACAVE_PLY_H__
|