1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd and/or its subsidiary(-ies).
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt3D module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "stlgeometryloader.h"
41
42#include <QtCore/QDataStream>
43#include <QtCore/QLoggingCategory>
44
45QT_BEGIN_NAMESPACE
46
47namespace Qt3DRender {
48
49Q_LOGGING_CATEGORY(StlGeometryLoaderLog, "Qt3D.StlGeometryLoader", QtWarningMsg)
50
51bool StlGeometryLoader::doLoad(QIODevice *ioDev, const QString &subMesh)
52{
53 Q_UNUSED(subMesh);
54
55 if (loadBinary(ioDev))
56 return true;
57
58 return loadAscii(ioDev);
59}
60
61bool StlGeometryLoader::loadAscii(QIODevice *ioDev)
62{
63 // TODO stricter syntax checking
64
65 ioDev->setTextModeEnabled(true);
66 if (!ioDev->seek(pos: 0))
67 return false;
68
69 char signature[5];
70 if (ioDev->peek(data: signature, maxlen: sizeof(signature)) != sizeof(signature))
71 return false;
72
73 if (qstrncmp(str1: signature, str2: "solid", len: 5) != 0)
74 return false;
75
76 while (!ioDev->atEnd()) {
77 QByteArray lineBuffer = ioDev->readLine();
78
79 const char *begin = lineBuffer.constData();
80 const char *end = begin + lineBuffer.size();
81
82 const ByteArraySplitter tokens(begin, end, ' ', Qt::SkipEmptyParts);
83
84 if (qstrncmp(str1: tokens.charPtrAt(index: 0), str2: "vertex ", len: 7) == 0) {
85 if (tokens.size() < 4) {
86 qCWarning(StlGeometryLoaderLog) << "Unsupported number of components in vertex";
87 } else {
88 const float x = tokens.floatAt(index: 1);
89 const float y = tokens.floatAt(index: 2);
90 const float z = tokens.floatAt(index: 3);
91 m_points.append(t: QVector3D(x, y, z));
92 m_indices.append(t: m_indices.size());
93 }
94 }
95 }
96
97 return true;
98}
99
100bool StlGeometryLoader::loadBinary(QIODevice *ioDev)
101{
102 static const int headerSize = 80;
103
104 if (ioDev->read(maxlen: headerSize).size() != headerSize)
105 return false;
106
107 ioDev->setTextModeEnabled(false);
108
109 QDataStream stream(ioDev);
110 stream.setByteOrder(QDataStream::LittleEndian);
111 stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
112
113 quint32 triangleCount;
114 stream >> triangleCount;
115
116 if (quint64(ioDev->size()) != headerSize + sizeof(quint32) + (triangleCount * 50))
117 return false;
118
119 m_points.reserve(asize: triangleCount * 3);
120 m_indices.reserve(asize: triangleCount * 3);
121
122 for (unsigned i = 0; i < triangleCount; ++i) {
123 QVector3D normal;
124 stream >> normal;
125
126 for (int j = 0; j < 3; ++j) {
127 QVector3D point;
128 stream >> point;
129 m_points.append(t: point);
130
131 m_indices.append(t: (i * 3) + j);
132 }
133
134 quint16 attributeCount;
135 stream >> attributeCount;
136 }
137
138 return true;
139}
140
141} // namespace Qt3DRender
142
143QT_END_NAMESPACE
144

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