CGII/framework/include/cgv/media/mesh/obj_reader.h
2018-05-17 15:50:03 +02:00

116 lines
4.2 KiB
C++

#pragma once
#include <cgv/math/fvec.h>
#include <cgv/media/illum/obj_material.hh>
#include <cgv/utils/tokenizer.h>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cgv/media/lib_begin.h>
namespace cgv {
namespace media {
namespace mesh {
/** implements the pure reading of an obj file and calls virtual callback
functions to allow a derived class to handle the read information.
The default implementations of the processing methods are implemented
to simply ignore the read information. */
template <typename T>
class CGV_API obj_reader_generic
{
public:
/// type of coordinates
typedef T crd_type;
/// type used to store texture coordinates
typedef cgv::math::fvec<T,2> v2d_type;
/// type used to store positions and normal vectors
typedef cgv::math::fvec<T,3> v3d_type;
/// type used for rgba colors
typedef illum::obj_material::color_type color_type;
private:
/// keep track of the current group
unsigned group_index;
/// number of groups
unsigned nr_groups;
/// keep track of current material index
unsigned material_index;
/// number of materials
unsigned nr_materials;
/// mapping from material names to material indices
std::map<std::string,unsigned> material_index_lut;
///
static bool is_double(const char* begin, const char* end, crd_type& value);
protected:
/**@name helpers for reading*/
//@{
/// parse 2d vector
v2d_type parse_v2d(const std::vector<cgv::utils::token>& t) const;
/// parse 3d vector
v3d_type parse_v3d(const std::vector<cgv::utils::token>& t) const;
/// parse a color, if alpha not given it defaults to 1
color_type parse_color(const std::vector<cgv::utils::token>& t, unsigned off = 0) const;
int minus;
unsigned nr_normals, nr_texcoords;
bool have_default_material;
std::set<std::string> mtl_lib_files;
void parse_face(const std::vector<cgv::utils::token>& tokens);
void parse_material(const std::vector<cgv::utils::token>& tokens);
//@}
/**@name status info during reading*/
//@{
/// store the path name
std::string path_name;
/// return the index of the currently selected group or -1 if no group is defined
unsigned get_current_group() const;
/// return the index of the currently selected material or -1 if no material is defined
unsigned get_current_material() const;
//@}
/**@name virtual interface*/
//@{
/// overide this function to process a comment
virtual void process_comment(const std::string& comment);
/// overide this function to process a vertex
virtual void process_vertex(const v3d_type& p);
/// overide this function to process a texcoord
virtual void process_texcoord(const v2d_type& t);
/// overide this function to process a color (this called for vc prefixes which is is not in the standard but for example used in pobj-files)
virtual void process_color(const color_type& c);
/// overide this function to process a normal
virtual void process_normal(const v3d_type& n);
/// convert negative indices to positive ones by adding the number of elements
void convert_to_positive(unsigned vcount, int *vertices,
int *texcoords, int *normals,
unsigned v, unsigned n, unsigned t);
/// overide this function to process a face, the indices start with 0
virtual void process_face(unsigned vcount, int *vertices,
int *texcoords = 0, int *normals=0);
/// overide this function to process a group given by name and parameter string
virtual void process_group(const std::string& name, const std::string& parameters);
/// process a material definition. If a material with a certain name is overwritten, it will receive the same index
virtual void process_material(const cgv::media::illum::obj_material& mtl, unsigned idx);
//@}
public:
/// default constructor
obj_reader_generic();
/// clear the reader such that a new file can be read
virtual void clear();
/// read an obj file
virtual bool read_obj(const std::string& file_name);
/// read a material file
virtual bool read_mtl(const std::string& file_name);
};
typedef obj_reader_generic<float> obj_readerf;
typedef obj_reader_generic<double> obj_readerd;
typedef obj_reader_generic<double> obj_reader;
}
}
}
#include <cgv/config/lib_end.h>