1// Copyright (C) 2017 The Qt Company Ltd and/or its subsidiary(-ies).
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "stlgeometryloader.h"
5
6#include <QtCore/QDataStream>
7#include <QtCore/QLoggingCategory>
8#include <QtCore/QIODevice>
9
10QT_BEGIN_NAMESPACE
11
12namespace Qt3DRender {
13
14Q_LOGGING_CATEGORY(StlGeometryLoaderLog, "Qt3D.StlGeometryLoader", QtWarningMsg)
15
16bool StlGeometryLoader::doLoad(QIODevice *ioDev, const QString &subMesh)
17{
18 Q_UNUSED(subMesh);
19
20 if (loadBinary(ioDev))
21 return true;
22
23 return loadAscii(ioDev);
24}
25
26bool StlGeometryLoader::loadAscii(QIODevice *ioDev)
27{
28 // TODO stricter syntax checking
29
30 ioDev->setTextModeEnabled(true);
31 if (!ioDev->seek(pos: 0))
32 return false;
33
34 char signature[5];
35 if (ioDev->peek(data: signature, maxlen: sizeof(signature)) != sizeof(signature))
36 return false;
37
38 if (qstrncmp(str1: signature, str2: "solid", len: 5) != 0)
39 return false;
40
41 while (!ioDev->atEnd()) {
42 QByteArray lineBuffer = ioDev->readLine();
43
44 const char *begin = lineBuffer.constData();
45 const char *end = begin + lineBuffer.size();
46
47 const ByteArraySplitter tokens(begin, end, ' ', Qt::SkipEmptyParts);
48
49 if (qstrncmp(str1: tokens.charPtrAt(index: 0), str2: "vertex ", len: 7) == 0) {
50 if (tokens.size() < 4) {
51 qCWarning(StlGeometryLoaderLog) << "Unsupported number of components in vertex";
52 } else {
53 const float x = tokens.floatAt(index: 1);
54 const float y = tokens.floatAt(index: 2);
55 const float z = tokens.floatAt(index: 3);
56 m_points.push_back(x: QVector3D(x, y, z));
57 m_indices.push_back(x: uint(m_indices.size()));
58 }
59 }
60 }
61
62 return true;
63}
64
65bool StlGeometryLoader::loadBinary(QIODevice *ioDev)
66{
67 static const int headerSize = 80;
68
69 if (ioDev->read(maxlen: headerSize).size() != headerSize)
70 return false;
71
72 ioDev->setTextModeEnabled(false);
73
74 QDataStream stream(ioDev);
75 stream.setByteOrder(QDataStream::LittleEndian);
76 stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
77
78 quint32 triangleCount;
79 stream >> triangleCount;
80
81 if (quint64(ioDev->size()) != headerSize + sizeof(quint32) + (triangleCount * 50))
82 return false;
83
84 m_points.reserve(n: triangleCount * 3);
85 m_indices.reserve(n: triangleCount * 3);
86
87 for (unsigned i = 0; i < triangleCount; ++i) {
88 QVector3D normal;
89 stream >> normal;
90
91 for (int j = 0; j < 3; ++j) {
92 QVector3D point;
93 stream >> point;
94 m_points.push_back(x: point);
95 m_indices.push_back(x: (i * 3) + j);
96 }
97
98 quint16 attributeCount;
99 stream >> attributeCount;
100 }
101
102 return true;
103}
104
105} // namespace Qt3DRender
106
107QT_END_NAMESPACE
108

source code of qt3d/src/plugins/geometryloaders/default/stlgeometryloader.cpp