1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "meshloader_p.h"
5
6#include <QtCore/QFile>
7#include <QtCore/QStringList>
8#include <QtCore/QList>
9#include <QtGui/QVector2D>
10
11QT_BEGIN_NAMESPACE
12
13QString slashTag = QStringLiteral("/");
14
15bool MeshLoader::loadOBJ(const QString &path, QList<QVector3D> &out_vertices,
16 QList<QVector2D> &out_uvs, QList<QVector3D> &out_normals)
17{
18 QList<unsigned int> vertexIndices, uvIndices, normalIndices;
19 QList<QVector3D> temp_vertices;
20 QList<QVector2D> temp_uvs;
21 QList<QVector3D> temp_normals;
22
23 QFile file(path);
24 if (!file.open(flags: QIODevice::ReadOnly | QIODevice::Text)) {
25 qWarning(msg: "Cannot open the file");
26 return false;
27 }
28
29 QTextStream textIn(&file);
30 while (!textIn.atEnd()) {
31 QString line = textIn.readLine();
32 QStringList lineContents = line.split(QStringLiteral(" "));
33 if (!lineContents.at(i: 0).compare(QStringLiteral("v"))) {
34 QVector3D vertex;
35 vertex.setX(lineContents.at(i: 1).toFloat());
36 vertex.setY(lineContents.at(i: 2).toFloat());
37 vertex.setZ(lineContents.at(i: 3).toFloat());
38 temp_vertices.append(t: vertex);
39 }
40 else if (!lineContents.at(i: 0).compare(QStringLiteral("vt"))) {
41 QVector2D uv;
42 uv.setX(lineContents.at(i: 1).toFloat());
43 uv.setY(lineContents.at(i: 2).toFloat()); // invert this if using DDS textures
44 temp_uvs.append(t: uv);
45 }
46 else if (!lineContents.at(i: 0).compare(QStringLiteral("vn"))) {
47 QVector3D normal;
48 normal.setX(lineContents.at(i: 1).toFloat());
49 normal.setY(lineContents.at(i: 2).toFloat());
50 normal.setZ(lineContents.at(i: 3).toFloat());
51 temp_normals.append(t: normal);
52 }
53 else if (!lineContents.at(i: 0).compare(QStringLiteral("f"))) {
54 unsigned int vertexIndex[3], uvIndex[3], normalIndex[3];
55 QStringList set1 = lineContents.at(i: 1).split(sep: slashTag);
56 QStringList set2 = lineContents.at(i: 2).split(sep: slashTag);
57 QStringList set3 = lineContents.at(i: 3).split(sep: slashTag);
58 if (set1.size() < 3 || set2.size() < 3 || set3.size() < 3) {
59 qWarning(msg: "The file being loaded is missing UVs and/or normals");
60 return false;
61 }
62 vertexIndex[0] = set1.at(i: 0).toUInt();
63 vertexIndex[1] = set2.at(i: 0).toUInt();
64 vertexIndex[2] = set3.at(i: 0).toUInt();
65 uvIndex[0] = set1.at(i: 1).toUInt();
66 uvIndex[1] = set2.at(i: 1).toUInt();
67 uvIndex[2] = set3.at(i: 1).toUInt();
68 normalIndex[0] = set1.at(i: 2).toUInt();
69 normalIndex[1] = set2.at(i: 2).toUInt();
70 normalIndex[2] = set3.at(i: 2).toUInt();
71 vertexIndices.append(t: vertexIndex[0]);
72 vertexIndices.append(t: vertexIndex[1]);
73 vertexIndices.append(t: vertexIndex[2]);
74 uvIndices.append(t: uvIndex[0]);
75 uvIndices.append(t: uvIndex[1]);
76 uvIndices.append(t: uvIndex[2]);
77 normalIndices.append(t: normalIndex[0]);
78 normalIndices.append(t: normalIndex[1]);
79 normalIndices.append(t: normalIndex[2]);
80 }
81 }
82
83 // For each vertex of each triangle
84 for (int i = 0; i < vertexIndices.size(); i++) {
85 // Get the indices of its attributes
86 unsigned int vertexIndex = vertexIndices[i];
87 unsigned int uvIndex = uvIndices[i];
88 unsigned int normalIndex = normalIndices[i];
89
90 // Get the attributes thanks to the index
91 QVector3D vertex = temp_vertices[vertexIndex - 1];
92 QVector2D uv = temp_uvs[uvIndex - 1];
93 QVector3D normal = temp_normals[normalIndex - 1];
94
95 // Put the attributes in buffers
96 out_vertices.append(t: vertex);
97 out_uvs.append(t: uv);
98 out_normals.append(t: normal);
99 }
100
101 return true;
102}
103
104QT_END_NAMESPACE
105

source code of qtdatavis3d/src/datavisualization/utils/meshloader.cpp