src/parser.cpp

Sun, 25 Jul 2021 20:39:21 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Sun, 25 Jul 2021 20:39:21 +0300
changeset 112
5760cbb32bc0
parent 105
6ca6e8c647d4
child 115
ed884a2fb009
permissions
-rw-r--r--

use QT_NO_KEYWORDS

3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
1 /*
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
2 * LDForge: LDraw parts authoring CAD
24
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
3 * Copyright (C) 2013 - 2020 Teemu Piippo
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
4 *
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
5 * This program is free software: you can redistribute it and/or modify
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
6 * it under the terms of the GNU General Public License as published by
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
7 * the Free Software Foundation, either version 3 of the License, or
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
8 * (at your option) any later version.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
9 *
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
10 * This program is distributed in the hope that it will be useful,
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
13 * GNU General Public License for more details.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
14 *
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
17 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
18
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
19 #include "model.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
20 #include "parser.h"
14
20d2ed3af73d renamings
Teemu Piippo <teemu@hecknology.net>
parents: 13
diff changeset
21 #include "linetypes/comment.h"
20d2ed3af73d renamings
Teemu Piippo <teemu@hecknology.net>
parents: 13
diff changeset
22 #include "linetypes/conditionaledge.h"
20d2ed3af73d renamings
Teemu Piippo <teemu@hecknology.net>
parents: 13
diff changeset
23 #include "linetypes/edge.h"
20d2ed3af73d renamings
Teemu Piippo <teemu@hecknology.net>
parents: 13
diff changeset
24 #include "linetypes/errorline.h"
20d2ed3af73d renamings
Teemu Piippo <teemu@hecknology.net>
parents: 13
diff changeset
25 #include "linetypes/metacommand.h"
20d2ed3af73d renamings
Teemu Piippo <teemu@hecknology.net>
parents: 13
diff changeset
26 #include "linetypes/object.h"
15
9e18ec63eec3 split quadrilateral and triangle into their own source files
Teemu Piippo <teemu@hecknology.net>
parents: 14
diff changeset
27 #include "linetypes/quadrilateral.h"
14
20d2ed3af73d renamings
Teemu Piippo <teemu@hecknology.net>
parents: 13
diff changeset
28 #include "linetypes/subfilereference.h"
15
9e18ec63eec3 split quadrilateral and triangle into their own source files
Teemu Piippo <teemu@hecknology.net>
parents: 14
diff changeset
29 #include "linetypes/triangle.h"
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
30
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
31 struct BodyParseError
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
32 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
33 QString message;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
34 };
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
35
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
36 /*
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
37 * Constructs an LDraw parser
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
38 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
39 Parser::Parser(QIODevice& device, QObject* parent) :
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
40 QObject {parent},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
41 device {device} {}
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
42
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
43 /*
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
44 * Reads a single line from the device.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
45 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
46 QString Parser::readLine()
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
47 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
48 return QString::fromUtf8(this->device.readLine()).trimmed();
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
49 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
50
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
51 static const QMap<QString, LDHeader::FileType> typeStrings {
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
52 {"Part", LDHeader::Part},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
53 {"Subpart", LDHeader::Subpart},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
54 {"Shortcut", LDHeader::Shortcut},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
55 {"Primitive", LDHeader::Primitive},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
56 {"8_Primitive", LDHeader::Primitive_8},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
57 {"48_Primitive", LDHeader::Primitive_48},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
58 {"Configuration", LDHeader::Configuration},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
59 };
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
60
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
61 /*
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
62 * Parses a single line of the header.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
63 * Possible parse results:
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
64 * · ParseSuccess: the header line was parsed successfully.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
65 * · ParseFailure: the header line was parsed incorrectly and needs to be handled otherwise.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
66 * · StopParsing: the line does not belong in the header and header parsing needs to stop.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
67 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
68 Parser::HeaderParseResult Parser::parseHeaderLine(
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
69 LDHeader& header,
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
70 Winding& winding,
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
71 const QString& line
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
72 ) {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
73 if (line.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
74 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
75 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
76 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
77 else if (not line.startsWith("0") or line.startsWith("0 //"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
78 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
79 return StopParsing;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
80 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
81 else if (line.startsWith("0 !LDRAW_ORG "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
82 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
83 QStringList tokens = line
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
84 .mid(strlen("0 !LDRAW_ORG "))
105
6ca6e8c647d4 added preview layer code and fixed build warnings
Teemu Piippo <teemu@hecknology.net>
parents: 77
diff changeset
85 .split(" ", Qt::SkipEmptyParts);
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
86 if (not tokens.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
87 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
88 QString partTypeString = tokens[0];
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
89 // Anything that enters LDForge becomes unofficial in any case if saved.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
90 // Therefore we don't need to give the Unofficial type any special
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
91 // consideration.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
92 if (partTypeString.startsWith("Unofficial_"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
93 partTypeString = partTypeString.mid(strlen("Unofficial_"));
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
94 header.type = typeStrings.value(partTypeString, LDHeader::Part);
33
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
95 header.qualfiers = {};
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
96 if (tokens.contains("Alias"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
97 header.qualfiers |= LDHeader::Alias;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
98 if (tokens.contains("Physical_Color"))
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
99 header.qualfiers |= LDHeader::PhysicalColour;
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
100 if (tokens.contains("Flexible_Section"))
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
101 header.qualfiers |= LDHeader::FlexibleSection;
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
102 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
103 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
104 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
105 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
106 return ParseFailure;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
107 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
108 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
109 else if (line == "0 BFC CERTIFY CCW")
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
110 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
111 winding = Anticlockwise;
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
112 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
113 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
114 else if (line == "0 BFC CERTIFY CW")
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
115 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
116 winding = Clockwise;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
117 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
118 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
119 else if (line == "0 BFC NOCERTIFY")
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
120 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
121 winding = NoWinding;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
122 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
123 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
124 else if (line.startsWith("0 !HISTORY "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
125 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
126 static const QRegExp historyRegexp {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
127 R"(0 !HISTORY\s+(\d{4}-\d{2}-\d{2})\s+)"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
128 R"((\{[^}]+|\[[^]]+)[\]}]\s+(.+))"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
129 };
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
130 if (historyRegexp.exactMatch(line))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
131 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
132 QString dateString = historyRegexp.capturedTexts().value(1);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
133 QString authorWithPrefix = historyRegexp.capturedTexts().value(2);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
134 QString description = historyRegexp.capturedTexts().value(3);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
135 LDHeader::HistoryEntry historyEntry;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
136 historyEntry.date = QDate::fromString(dateString, Qt::ISODate);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
137 historyEntry.description = description;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
138
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
139 if (authorWithPrefix[0] == '{')
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
140 historyEntry.author = authorWithPrefix + "}";
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
141 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
142 historyEntry.author = authorWithPrefix.mid(1);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
143
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
144 header.history.append(historyEntry);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
145 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
146 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
147 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
148 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
149 return ParseFailure;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
150 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
151 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
152 else if (line.startsWith("0 Author: "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
153 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
154 header.author = line.mid(strlen("0 Author: "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
155 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
156 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
157 else if (line.startsWith("0 Name: "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
158 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
159 header.name = line.mid(strlen("0 Name: "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
160 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
161 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
162 else if (line.startsWith("0 !HELP "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
163 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
164 if (not header.help.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
165 header.help += "\n";
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
166 header.help += line.mid(strlen("0 !HELP "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
167 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
168 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
169 else if (line.startsWith("0 !KEYWORDS "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
170 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
171 if (not header.keywords.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
172 header.keywords += "\n";
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
173 header.keywords += line.mid(strlen("0 !KEYWORDS "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
174 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
175 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
176 else if (line.startsWith("0 !CATEGORY "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
177 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
178 header.category = line.mid(strlen("0 !CATEGORY "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
179 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
180 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
181 else if (line.startsWith("0 !CMDLINE "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
182 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
183 header.cmdline = line.mid(strlen("0 !CMDLINE "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
184 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
185 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
186 else if (line.startsWith("0 !LICENSE Redistributable under CCAL version 2.0"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
187 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
188 header.license = LDHeader::CaLicense;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
189 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
190 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
191 else if (line.startsWith("0 !LICENSE Not redistributable"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
192 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
193 header.license = LDHeader::NonCaLicense;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
194 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
195 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
196 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
197 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
198 return ParseFailure;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
199 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
200 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
201
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
202 /*
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
203 * Parses the header from the device given at construction and returns
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
204 * the resulting header structure.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
205 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
206 LDHeader Parser::parseHeader(Winding& winding)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
207 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
208 LDHeader header = {};
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
209 if (not this->device.atEnd())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
210 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
211 // Parse the description
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
212 QString descriptionLine = this->readLine();
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
213 if (descriptionLine.startsWith("0 "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
214 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
215 header.description = descriptionLine.mid(strlen("0 ")).trimmed();
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
216 // Parse the rest of the header
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
217 while (not this->device.atEnd())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
218 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
219 const QString& line = this->readLine();
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
220 auto result = parseHeaderLine(header, winding, line);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
221 if (result == ParseFailure)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
222 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
223 // Failed to parse this header line, add it as a comment into the body later.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
224 this->bag.append(line);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
225 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
226 else if (result == StopParsing)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
227 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
228 // Header parsing stops, add this line to the body.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
229 this->bag.append(line);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
230 break;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
231 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
232 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
233 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
234 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
235 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
236 this->bag.append(descriptionLine);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
237 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
238 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
239 return header;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
240 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
241
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
242 /**
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
243 * @brief Parses the model body into the given model.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
244 * @param editor Handle to model edit context
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
245 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
246 void Parser::parseBody(Model::EditContext& editor)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
247 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
248 bool invertNext = false;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
249 while (not this->device.atEnd())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
250 this->bag.append(this->readLine());
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
251 for (const QString& line : this->bag)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
252 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
253 if (line == "0 BFC INVERTNEXT" or line == "0 BFC CERTIFY INVERTNEXT")
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
254 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
255 invertNext = true;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
256 continue;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
257 }
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
258 std::unique_ptr<ldraw::Object> object = parseFromString(line);
26
3a9e761e4faa at least VAOs work now
Teemu Piippo <teemu@hecknology.net>
parents: 24
diff changeset
259 auto id = editor.append(std::move(object));
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
260 if (invertNext)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
261 {
26
3a9e761e4faa at least VAOs work now
Teemu Piippo <teemu@hecknology.net>
parents: 24
diff changeset
262 editor.invertObject(id);
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
263 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
264 invertNext = false;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
265 }
77
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
266 // Test quadrilateral splitting by splitting all the quadrilaterals
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
267 QVector<ldraw::quadrilateralid_t> quadrilateral_ids;
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
268 for (int i = 0; i < editor.model().size(); i += 1)
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
269 {
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
270 const ldraw::id_t id = editor.model().resolve(editor.model().index(i));
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
271 const ldraw::quadrilateralid_t quad_id = editor.model().checkType<ldraw::Quadrilateral>(id);
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
272 if (not(quad_id == ldraw::NULL_ID))
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
273 {
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
274 quadrilateral_ids.push_back(quad_id);
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
275 }
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
276 }
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
277 for (const ldraw::quadrilateralid_t id : quadrilateral_ids)
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
278 {
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
279 ldraw::splitQuadrilateral(editor, id);
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
280 }
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
281 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
282
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
283 static ldraw::Color colorFromString(const QString& colorString)
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
284 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
285 bool colorSucceeded;
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
286 const ldraw::Color color = {colorString.toInt(&colorSucceeded)};
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
287 if (colorSucceeded)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
288 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
289 return color;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
290 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
291 else
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
292 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
293 throw BodyParseError{"colour was not an integer value"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
294 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
295 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
296
33
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
297 static glm::vec3 vertexFromStrings(
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
298 const QStringList& tokens,
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
299 const int startingPosition)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
300 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
301 bool ok_x;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
302 const float x = tokens[startingPosition].toFloat(&ok_x);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
303 bool ok_y;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
304 const float y = tokens[startingPosition + 1].toFloat(&ok_y);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
305 bool ok_z;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
306 const float z = tokens[startingPosition + 2].toFloat(&ok_z);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
307 if (not ok_x or not ok_y or not ok_z)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
308 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
309 throw BodyParseError{"vertex contained illegal co-ordinates"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
310 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
311 return {x, y, z};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
312 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
313
33
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
314 static glm::mat4 matrixFromStrings(const QStringList& tokens, const int startingPosition, const int positionStartingIndex)
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
315 {
33
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
316 glm::mat4 result = glm::mat4{1};
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
317 for (int i = 0; i < 9; i += 1)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
318 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
319 const int row = i / 3;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
320 const int column = i % 3;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
321 const int index = i + startingPosition;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
322 if (index >= tokens.size())
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
323 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
324 throw BodyParseError{"too few tokens available"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
325 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
326 bool ok;
33
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
327 // note that glm::mat4 is column-major
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
328 result[column][row] = tokens[index].toFloat(&ok);
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
329 if (not ok)
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
330 {
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
331 throw BodyParseError{"non-numeric values for matrix"};
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
332 }
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
333 }
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
334 for (int i = 0; i < 3; i += 1)
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
335 {
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
336 bool ok;
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
337 const auto value = tokens[i + positionStartingIndex].toFloat(&ok);
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
338 result[3][i] = value;
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
339 if (not ok)
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
340 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
341 throw BodyParseError{"non-numeric values for matrix"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
342 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
343 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
344 return result;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
345 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
346
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
347 static std::unique_ptr<ldraw::Object> parseType0Line(
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
348 const QString& line,
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
349 const QStringList& tokens)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
350 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
351 Q_UNUSED(tokens)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
352 if (line.startsWith("0 //"))
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
353 {
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
354 return std::make_unique<ldraw::Comment>(line.mid(std::strlen("0 //")).simplified());
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
355 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
356 else
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
357 {
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
358 return std::make_unique<ldraw::MetaCommand>(line.mid(1).simplified());
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
359 }
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
360 }
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
361
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
362 static std::unique_ptr<ldraw::SubfileReference> parseType1Line(
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
363 const QString& line,
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
364 const QStringList& tokens)
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
365 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
366 Q_UNUSED(line)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
367 constexpr int colorPosition = 1;
23
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
368 constexpr int positionPosition = 2; // 2..4
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
369 constexpr int transformPosition = 5; // 5..13
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
370 constexpr int namePosition = 14;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
371 if (tokens.size() != 15)
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
372 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
373 throw BodyParseError{"wrong amount of tokens in a type-1 line"};
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
374 }
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
375 const ldraw::Color color = colorFromString(tokens[colorPosition]);
33
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
376 const glm::mat4 transform = matrixFromStrings(tokens, transformPosition, positionPosition);
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
377 const QString& name = tokens[namePosition];
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
378 return std::make_unique<ldraw::SubfileReference>(transform, name, color);
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
379 }
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
380
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
381 template<typename T, int NumVertices>
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
382 static std::unique_ptr<T> parsePolygon(
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
383 const QString& line,
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
384 const QStringList& tokens)
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
385 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
386 Q_UNUSED(line)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
387 constexpr int colorPosition = 1;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
388 auto vertexPosition = [](int n) { return 2 + 3*n; };
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
389 if (tokens.size() != 2 + 3 * NumVertices)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
390 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
391 throw BodyParseError{"wrong amount of tokens"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
392 }
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
393 const ldraw::Color color = colorFromString(tokens[colorPosition]);
77
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
394 std::array<glm::vec3, NumVertices> vertices;
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
395 for (int i = 0; i < NumVertices; i += 1)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
396 {
77
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
397 vertices[unsigned_cast(i)] = vertexFromStrings(tokens, vertexPosition(i));
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
398 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
399 return std::make_unique<T>(vertices, color);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
400 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
401
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
402 std::unique_ptr<ldraw::Object> Parser::parseFromString(QString line)
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
403 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
404 line = line.simplified();
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
405 try
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
406 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
407 const QStringList tokens = line.split(QRegExp{R"(\s+)"});
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
408 if (tokens.empty() or tokens == QStringList{{""}})
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
409 {
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
410 return std::make_unique<ldraw::Empty>();
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
411 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
412 bool ok_code;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
413 const int code = tokens[0].toInt(&ok_code);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
414 if (not ok_code)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
415 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
416 throw BodyParseError{"line type was not an integer"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
417 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
418 switch (code)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
419 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
420 case 0:
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
421 return parseType0Line(line, tokens);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
422 case 1:
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
423 return parseType1Line(line, tokens);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
424 case 2:
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
425 return parsePolygon<ldraw::Edge, 2>(line, tokens);
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
426 case 3:
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
427 return parsePolygon<ldraw::Triangle, 3>(line, tokens);
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
428 case 4:
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
429 return parsePolygon<ldraw::Quadrilateral, 4>(line, tokens);
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
430 case 5:
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
431 return parsePolygon<ldraw::ConditionalEdge, 4>(line, tokens);
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
432 default:
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
433 throw BodyParseError{utility::format("bad line type '%1'", code)};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
434 }
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
435 }
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
436 catch(const BodyParseError& error)
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
437 {
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
438 return std::make_unique<ldraw::ErrorLine>(line, error.message);
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
439 }
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
440 }

mercurial