ModelViewer 0.1
Template for CPP projects
Loading...
Searching...
No Matches
model_viewer::loaders::ObjLoader Class Referencefinal

Class for loading OBJ models. More...

#include <ObjLoader.hpp>

Inheritance diagram for model_viewer::loaders::ObjLoader:
Collaboration diagram for model_viewer::loaders::ObjLoader:

Public Member Functions

 ObjLoader ()
 Constructor.
 
 ~ObjLoader () override=default
 Destructor.
 
bool loadModel (const std::string &filepath) override
 Load an OBJ model from a file.
 
QQuick3DGeometry * geometry () const override
 Get the geometry of the loaded model.
 
material::MTLMaterialmaterial () const override
 Get the material of the loaded model.
 
const std::vector< geometry::Vector3 > & getVertices () const
 
const std::vector< geometry::TextureCoordinate > & getTextureCoords () const
 
const std::vector< geometry::Vector3 > & getNormals () const
 
const std::vector< geometry::FaceIndex > & getFaces () const
 
const std::string & getModelPath () const
 
- Public Member Functions inherited from model_viewer::loaders::ILoader
virtual ~ILoader ()=default
 Virtual destructor.
 

Private Member Functions

void reset ()
 Reset the OBJ loader state.
 
void parseModel (std::ifstream &file)
 Parse an OBJ file line by line.
 
void setModelData ()
 Set the model data to the geometry.
 
void resetObj ()
 Reset the OBJ model state.
 
void parseVertice (const std::string &line)
 Parse a vertice line from the OBJ file.
 
void parseNormal (const std::string &line)
 Parse a normal vertice line from the OBJ file.
 
void parseTextureCoordinate (const std::string &line)
 Parse a texture coordinate vertice line from the OBJ file.
 
void parseFace (const std::string &line)
 Parse a face line from the OBJ file.
 
geometry::FaceIndex parseFaceIndex (const std::string &token)
 Parse a face index token from the OBJ file.
 
void retrieveMaterial (const std::string &line)
 Retrieve material from a material library line and call material's parsing method.
 

Private Attributes

std::vector< geometry::Vector3_vertices
 Vertices of the model.
 
std::vector< geometry::TextureCoordinate_textureCoords
 Texture coordinates of the model.
 
std::vector< geometry::Vector3_normals
 Normals of the model.
 
std::vector< geometry::FaceIndex_faces
 Faces of the model.
 
std::string _modelPath
 Path to the model file.
 
std::unordered_map< std::string, std::function< void(const std::string &)> > _parseFunctions
 Map of parsing functions for different OBJ line prefixes.
 
std::unique_ptr< geometry::ObjGeometry_geometry
 Geometry of the model.
 
std::unique_ptr< material::MTLMaterial_material
 Material of the model.
 

Detailed Description

Class for loading OBJ models.

Constructor & Destructor Documentation

◆ ObjLoader()

model_viewer::loaders::ObjLoader::ObjLoader ( )

Constructor.

15 : _geometry(std::make_unique<geometry::ObjGeometry>()),
16 _material(std::make_unique<material::MTLMaterial>()) {
18 {"v", [this](const std::string &l) { parseVertice(l); }},
19 {"vn", [this](const std::string &l) { parseNormal(l); }},
20 {"vt", [this](const std::string &l) { parseTextureCoordinate(l); }},
21 {"f", [this](const std::string &l) { parseFace(l); }},
22 {"mtllib", [this](const std::string &l) { retrieveMaterial(l); }},
23 };
24}
std::unique_ptr< material::MTLMaterial > _material
Material of the model.
Definition ObjLoader.hpp:51
void parseVertice(const std::string &line)
Parse a vertice line from the OBJ file.
Definition ObjLoader.cpp:87
void parseFace(const std::string &line)
Parse a face line from the OBJ file.
Definition ObjLoader.cpp:111
std::unique_ptr< geometry::ObjGeometry > _geometry
Geometry of the model.
Definition ObjLoader.hpp:48
void parseNormal(const std::string &line)
Parse a normal vertice line from the OBJ file.
Definition ObjLoader.cpp:95
std::unordered_map< std::string, std::function< void(const std::string &)> > _parseFunctions
Map of parsing functions for different OBJ line prefixes.
Definition ObjLoader.hpp:45
void retrieveMaterial(const std::string &line)
Retrieve material from a material library line and call material's parsing method.
Definition ObjLoader.cpp:140
void parseTextureCoordinate(const std::string &line)
Parse a texture coordinate vertice line from the OBJ file.
Definition ObjLoader.cpp:103

References _parseFunctions, parseFace(), parseNormal(), parseTextureCoordinate(), parseVertice(), and retrieveMaterial().

Here is the call graph for this function:

◆ ~ObjLoader()

model_viewer::loaders::ObjLoader::~ObjLoader ( )
overridedefault

Destructor.

Member Function Documentation

◆ geometry()

QQuick3DGeometry * model_viewer::loaders::ObjLoader::geometry ( ) const
inlineoverridevirtual

Get the geometry of the loaded model.

Returns
Geometry of the loaded model

Implements model_viewer::loaders::ILoader.

72{ return _geometry.get(); };

References _geometry.

◆ getFaces()

const std::vector< geometry::FaceIndex > & model_viewer::loaders::ObjLoader::getFaces ( ) const
inline
94{ return _faces; }
std::vector< geometry::FaceIndex > _faces
Faces of the model.
Definition ObjLoader.hpp:38

References _faces.

◆ getModelPath()

const std::string & model_viewer::loaders::ObjLoader::getModelPath ( ) const
inline
96{ return _modelPath; }
std::string _modelPath
Path to the model file.
Definition ObjLoader.hpp:41

References _modelPath.

◆ getNormals()

const std::vector< geometry::Vector3 > & model_viewer::loaders::ObjLoader::getNormals ( ) const
inline
90 {
91 return _normals;
92 }
std::vector< geometry::Vector3 > _normals
Normals of the model.
Definition ObjLoader.hpp:35

References _normals.

◆ getTextureCoords()

const std::vector< geometry::TextureCoordinate > & model_viewer::loaders::ObjLoader::getTextureCoords ( ) const
inline
86 {
87 return _textureCoords;
88 }
std::vector< geometry::TextureCoordinate > _textureCoords
Texture coordinates of the model.
Definition ObjLoader.hpp:32

References _textureCoords.

◆ getVertices()

const std::vector< geometry::Vector3 > & model_viewer::loaders::ObjLoader::getVertices ( ) const
inline
82 {
83 return _vertices;
84 }
std::vector< geometry::Vector3 > _vertices
Vertices of the model.
Definition ObjLoader.hpp:29

References _vertices.

◆ loadModel()

bool model_viewer::loaders::ObjLoader::loadModel ( const std::string & filepath)
overridevirtual

Load an OBJ model from a file.

Parameters
filepathPath to the OBJ file
Returns
Boolean indicating whether the model was loaded successfully
Todo
Add support for groups and multiple materials

Implements model_viewer::loaders::ILoader.

26 {
27 reset();
29 std::ifstream in(_modelPath, std::ios::in);
30 if (!in.is_open()) {
31 std::cerr << "ObjLoader: Could not open file " << _modelPath << ": "
32 << std::strerror(errno) << std::endl;
33 return false;
34 }
35 parseModel(in);
37 return true;
38}
void parseModel(std::ifstream &file)
Parse an OBJ file line by line.
Definition ObjLoader.cpp:45
void setModelData()
Set the model data to the geometry.
Definition ObjLoader.cpp:56
void reset()
Reset the OBJ loader state.
Definition ObjLoader.cpp:40
std::string normalizePath(std::string p)
Normalize a file path by removing "file://" scheme and leading slash on Windows paths.
Definition StringHelpers.hpp:89

References _modelPath, model_viewer::string_helpers::normalizePath(), parseModel(), reset(), and setModelData().

Here is the call graph for this function:

◆ material()

material::MTLMaterial * model_viewer::loaders::ObjLoader::material ( ) const
inlineoverridevirtual

Get the material of the loaded model.

Returns
Material of the loaded model

Implements model_viewer::loaders::ILoader.

78 {
79 return _material.get();
80 };

References _material.

◆ parseFace()

void model_viewer::loaders::ObjLoader::parseFace ( const std::string & line)
private

Parse a face line from the OBJ file.

Parameters
lineLine to parse
111 {
112 std::istringstream f(line.substr(2));
113 std::string token;
114 std::vector<geometry::FaceIndex> face;
115 while (f >> token) face.push_back(parseFaceIndex(token));
116 for (size_t i = 1; i + 1 < face.size(); ++i) {
117 this->_faces.push_back(face[0]);
118 this->_faces.push_back(face[i]);
119 this->_faces.push_back(face[i + 1]);
120 }
121}
geometry::FaceIndex parseFaceIndex(const std::string &token)
Parse a face index token from the OBJ file.
Definition ObjLoader.cpp:123

References _faces, and parseFaceIndex().

Referenced by ObjLoader().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parseFaceIndex()

geometry::FaceIndex model_viewer::loaders::ObjLoader::parseFaceIndex ( const std::string & token)
private

Parse a face index token from the OBJ file.

Parameters
tokenToken to parse
Returns
Parsed FaceIndex struct
123 {
124 geometry::FaceIndex idx;
125 std::sscanf(token.c_str(), "%d/%d/%d", &idx.v, &idx.vt, &idx.vn);
126
127 if (token.find("//") != std::string::npos) {
128 std::sscanf(token.c_str(), "%d//%d", &idx.v, &idx.vn);
129 idx.vt = 0;
130 } else if (token.find('/') != std::string::npos &&
131 std::ranges::count(token, '/') == 1) {
132 std::sscanf(token.c_str(), "%d/%d", &idx.v, &idx.vt);
133 idx.vn = 0;
134 } else if (token.find('/') == std::string::npos) {
135 std::sscanf(token.c_str(), "%d", &idx.v);
136 }
137 return idx;
138}

References model_viewer::geometry::FaceIndex::v, model_viewer::geometry::FaceIndex::vn, and model_viewer::geometry::FaceIndex::vt.

Referenced by parseFace().

Here is the caller graph for this function:

◆ parseModel()

void model_viewer::loaders::ObjLoader::parseModel ( std::ifstream & file)
private

Parse an OBJ file line by line.

Parameters
fileInput file stream to parse
Todo
Optimize parsing of the model
45 {
46 std::string line;
47 while (std::getline(file, line)) {
48 const auto pos = line.find(' ');
49 const std::string lineStart =
50 string_helpers::trim_copy(line.substr(0, pos));
51 if (_parseFunctions.contains(lineStart))
52 _parseFunctions.at(lineStart)(line);
53 }
54}
std::string trim_copy(std::string s)
Trim from both ends (copying)
Definition StringHelpers.hpp:78

References _parseFunctions, and model_viewer::string_helpers::trim_copy().

Referenced by loadModel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parseNormal()

void model_viewer::loaders::ObjLoader::parseNormal ( const std::string & line)
private

Parse a normal vertice line from the OBJ file.

Parameters
lineLine to parse
95 {
96 float x, y, z;
97 if (std::sscanf(line.c_str() + 2, "%f %f %f", &x, &y, &z) < 3)
98 std::cerr << "Invalid normal at line " << line << std::endl;
99 else
100 this->_normals.push_back({x, y, z});
101}

References _normals.

Referenced by ObjLoader().

Here is the caller graph for this function:

◆ parseTextureCoordinate()

void model_viewer::loaders::ObjLoader::parseTextureCoordinate ( const std::string & line)
private

Parse a texture coordinate vertice line from the OBJ file.

Parameters
lineLine to parse
103 {
104 float u, v; // Missing w
105 if (std::sscanf(line.c_str() + 2, "%f %f", &u, &v) < 2)
106 std::cerr << "Invalid normal at line " << line << std::endl;
107 else
108 this->_textureCoords.push_back({u, v});
109}

References _textureCoords.

Referenced by ObjLoader().

Here is the caller graph for this function:

◆ parseVertice()

void model_viewer::loaders::ObjLoader::parseVertice ( const std::string & line)
private

Parse a vertice line from the OBJ file.

Parameters
lineLine to parse
87 {
88 float x, y, z; // Missing optional w
89 if (std::sscanf(line.c_str() + 2, "%f %f %f", &x, &y, &z) < 3)
90 std::cerr << "Invalid vertice at line " << line << std::endl;
91 else
92 this->_vertices.push_back({x, y, z});
93}

References _vertices.

Referenced by ObjLoader().

Here is the caller graph for this function:

◆ reset()

void model_viewer::loaders::ObjLoader::reset ( )
private

Reset the OBJ loader state.

40 {
41 resetObj();
42 _material->resetMaterial();
43}
void resetObj()
Reset the OBJ model state.
Definition ObjLoader.cpp:80

References _material, and resetObj().

Referenced by loadModel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ resetObj()

void model_viewer::loaders::ObjLoader::resetObj ( )
private

Reset the OBJ model state.

80 {
81 _faces.clear();
82 _vertices.clear();
83 _normals.clear();
84 _textureCoords.clear();
85}

References _faces, _normals, _textureCoords, and _vertices.

Referenced by reset().

Here is the caller graph for this function:

◆ retrieveMaterial()

void model_viewer::loaders::ObjLoader::retrieveMaterial ( const std::string & line)
private

Retrieve material from a material library line and call material's parsing method.

Parameters
lineLine to parse
140 {
141 const std::string name =
142 string_helpers::trim_copy(line.substr(sizeof("mtllib")));
143 const std::filesystem::path path =
144 std::filesystem::path(_modelPath).parent_path() / name;
145 _material->parseMTL(path.string());
146}

References _material, _modelPath, and model_viewer::string_helpers::trim_copy().

Referenced by ObjLoader().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setModelData()

void model_viewer::loaders::ObjLoader::setModelData ( )
private

Set the model data to the geometry.

56 {
57 std::vector<geometry::Vector3> vVector;
58 std::vector<geometry::TextureCoordinate> vtVector;
59 std::vector<geometry::Vector3> vnVector;
60 for (auto [v, vt, vn] : _faces) {
61 if (!_vertices.empty() && v != 0) {
62 const int vIdx = v > 0 ? v - 1 : _vertices.size() + v;
63 vVector.push_back(_vertices[vIdx]);
64 }
65 if (!_textureCoords.empty() && vt != 0) {
66 const int vtIdx = vt > 0 ? vt - 1 : _vertices.size() + vt;
67 vtVector.push_back(_textureCoords[vtIdx]);
68 }
69 if (!_normals.empty() && vn != 0) {
70 const int vnIdx = vn > 0 ? vn - 1 : _vertices.size() + vn;
71 vnVector.push_back(_normals[vnIdx]);
72 }
73 }
74 _vertices = vVector;
75 _textureCoords = vtVector;
76 _normals = vnVector;
78}

References _faces, _geometry, _normals, _textureCoords, and _vertices.

Referenced by loadModel().

Here is the caller graph for this function:

Member Data Documentation

◆ _faces

std::vector<geometry::FaceIndex> model_viewer::loaders::ObjLoader::_faces
private

Faces of the model.

Referenced by getFaces(), parseFace(), resetObj(), and setModelData().

◆ _geometry

std::unique_ptr<geometry::ObjGeometry> model_viewer::loaders::ObjLoader::_geometry
private

Geometry of the model.

Referenced by geometry(), and setModelData().

◆ _material

std::unique_ptr<material::MTLMaterial> model_viewer::loaders::ObjLoader::_material
private

Material of the model.

Referenced by material(), reset(), and retrieveMaterial().

◆ _modelPath

std::string model_viewer::loaders::ObjLoader::_modelPath
private

Path to the model file.

Referenced by getModelPath(), loadModel(), and retrieveMaterial().

◆ _normals

std::vector<geometry::Vector3> model_viewer::loaders::ObjLoader::_normals
private

Normals of the model.

Referenced by getNormals(), parseNormal(), resetObj(), and setModelData().

◆ _parseFunctions

std::unordered_map<std::string, std::function<void(const std::string &)> > model_viewer::loaders::ObjLoader::_parseFunctions
private

Map of parsing functions for different OBJ line prefixes.

Referenced by ObjLoader(), and parseModel().

◆ _textureCoords

std::vector<geometry::TextureCoordinate> model_viewer::loaders::ObjLoader::_textureCoords
private

Texture coordinates of the model.

Referenced by getTextureCoords(), parseTextureCoordinate(), resetObj(), and setModelData().

◆ _vertices

std::vector<geometry::Vector3> model_viewer::loaders::ObjLoader::_vertices
private

Vertices of the model.

Referenced by getVertices(), parseVertice(), resetObj(), and setModelData().


The documentation for this class was generated from the following files: