src/parser.cpp

Sat, 05 Mar 2022 13:18:40 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Sat, 05 Mar 2022 13:18:40 +0200
changeset 161
6fe485a84d06
parent 152
03f8e6d42e13
child 176
cd9d6bf6f649
permissions
-rw-r--r--

Icons update

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
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
51 /*
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
52 * Parses a single line of the header.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
53 * Possible parse results:
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
54 * · ParseSuccess: the header line was parsed successfully.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
55 * · 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
56 * · 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
57 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
58 Parser::HeaderParseResult Parser::parseHeaderLine(
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
59 LDHeader& header,
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
60 Winding& winding,
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
61 const QString& line
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
62 ) {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
63 if (line.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
64 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
65 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
66 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
67 else if (not line.startsWith("0") or line.startsWith("0 //"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
68 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
69 return StopParsing;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
70 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
71 else if (line.startsWith("0 !LDRAW_ORG "))
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 QStringList tokens = line
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
74 .mid(strlen("0 !LDRAW_ORG "))
105
6ca6e8c647d4 added preview layer code and fixed build warnings
Teemu Piippo <teemu@hecknology.net>
parents: 77
diff changeset
75 .split(" ", Qt::SkipEmptyParts);
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
76 if (not tokens.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
77 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
78 QString partTypeString = tokens[0];
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
79 // Anything that enters LDForge becomes unofficial in any case if saved.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
80 // 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
81 // consideration.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
82 if (partTypeString.startsWith("Unofficial_"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
83 partTypeString = partTypeString.mid(strlen("Unofficial_"));
140
2f383e88acf4 work on saving
Teemu Piippo <teemu@hecknology.net>
parents: 115
diff changeset
84 header.type = headerTypeFromString(partTypeString);
33
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
85 header.qualfiers = {};
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
86 if (tokens.contains("Alias"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
87 header.qualfiers |= LDHeader::Alias;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
88 if (tokens.contains("Physical_Color"))
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
89 header.qualfiers |= LDHeader::PhysicalColour;
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
90 if (tokens.contains("Flexible_Section"))
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
91 header.qualfiers |= LDHeader::FlexibleSection;
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
92 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
93 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
94 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
95 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
96 return ParseFailure;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
97 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
98 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
99 else if (line == "0 BFC CERTIFY CCW")
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
100 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
101 winding = Anticlockwise;
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 if (line == "0 BFC CERTIFY CW")
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 winding = Clockwise;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
107 return ParseSuccess;
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 NOCERTIFY")
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
110 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
111 winding = NoWinding;
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.startsWith("0 !HISTORY "))
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 static const QRegExp historyRegexp {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
117 R"(0 !HISTORY\s+(\d{4}-\d{2}-\d{2})\s+)"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
118 R"((\{[^}]+|\[[^]]+)[\]}]\s+(.+))"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
119 };
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
120 if (historyRegexp.exactMatch(line))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
121 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
122 QString dateString = historyRegexp.capturedTexts().value(1);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
123 QString authorWithPrefix = historyRegexp.capturedTexts().value(2);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
124 QString description = historyRegexp.capturedTexts().value(3);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
125 LDHeader::HistoryEntry historyEntry;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
126 historyEntry.date = QDate::fromString(dateString, Qt::ISODate);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
127 historyEntry.description = description;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
128
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
129 if (authorWithPrefix[0] == '{')
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
130 historyEntry.author = authorWithPrefix + "}";
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
131 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
132 historyEntry.author = authorWithPrefix.mid(1);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
133
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
134 header.history.append(historyEntry);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
135 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
136 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
137 else
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 return ParseFailure;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
140 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
141 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
142 else if (line.startsWith("0 Author: "))
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.author = line.mid(strlen("0 Author: "));
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 if (line.startsWith("0 Name: "))
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 header.name = line.mid(strlen("0 Name: "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
150 return ParseSuccess;
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 !HELP "))
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 if (not header.help.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
155 header.help += "\n";
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
156 header.help += line.mid(strlen("0 !HELP "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
157 return ParseSuccess;
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 else if (line.startsWith("0 !KEYWORDS "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
160 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
161 if (not header.keywords.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
162 header.keywords += "\n";
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
163 header.keywords += line.mid(strlen("0 !KEYWORDS "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
164 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
165 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
166 else if (line.startsWith("0 !CATEGORY "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
167 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
168 header.category = line.mid(strlen("0 !CATEGORY "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
169 return ParseSuccess;
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 else if (line.startsWith("0 !CMDLINE "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
172 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
173 header.cmdline = line.mid(strlen("0 !CMDLINE "));
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 }
140
2f383e88acf4 work on saving
Teemu Piippo <teemu@hecknology.net>
parents: 115
diff changeset
176 else if (line.startsWith(LDHeader::caLicenseString))
3
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.license = LDHeader::CaLicense;
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 }
140
2f383e88acf4 work on saving
Teemu Piippo <teemu@hecknology.net>
parents: 115
diff changeset
181 else if (line.startsWith(LDHeader::nonCaLicenseString))
3
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.license = LDHeader::NonCaLicense;
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
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 return ParseFailure;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
189 }
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
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 * Parses the header from the device given at construction and returns
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
194 * the resulting header structure.
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 LDHeader Parser::parseHeader(Winding& winding)
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 LDHeader header = {};
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
199 if (not this->device.atEnd())
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 // Parse the description
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
202 QString descriptionLine = this->readLine();
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
203 if (descriptionLine.startsWith("0 "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
204 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
205 header.description = descriptionLine.mid(strlen("0 ")).trimmed();
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
206 // Parse the rest of the header
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
207 while (not this->device.atEnd())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
208 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
209 const QString& line = this->readLine();
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
210 auto result = parseHeaderLine(header, winding, line);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
211 if (result == ParseFailure)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
212 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
213 // 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
214 this->bag.append(line);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
215 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
216 else if (result == StopParsing)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
217 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
218 // Header parsing stops, add this line to the body.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
219 this->bag.append(line);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
220 break;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
221 }
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 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
224 else
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 this->bag.append(descriptionLine);
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 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
229 return header;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
230 }
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 * @brief Parses the model body into the given model.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
234 * @param editor Handle to model edit context
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
235 */
152
03f8e6d42e13 Major refactoring
Teemu Piippo <teemu@hecknology.net>
parents: 144
diff changeset
236 void Parser::parseBody(Model& model)
3
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 bool invertNext = false;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
239 while (not this->device.atEnd())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
240 this->bag.append(this->readLine());
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
241 for (const QString& line : this->bag)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
242 {
144
5d73a6717321 Fix handling of "BFC INVERTNEXT" with multiple inner whitespaces
Teemu Piippo <teemu@hecknology.net>
parents: 141
diff changeset
243 // Some LDraw parts such as 53588.dat can contain "BFC INVERTNEXT" with multiple inner whitespaces.
5d73a6717321 Fix handling of "BFC INVERTNEXT" with multiple inner whitespaces
Teemu Piippo <teemu@hecknology.net>
parents: 141
diff changeset
244 // So we need to pass the string through QString::simplified to catch these cases.
5d73a6717321 Fix handling of "BFC INVERTNEXT" with multiple inner whitespaces
Teemu Piippo <teemu@hecknology.net>
parents: 141
diff changeset
245 const QString simplifiedLine = line.simplified();
5d73a6717321 Fix handling of "BFC INVERTNEXT" with multiple inner whitespaces
Teemu Piippo <teemu@hecknology.net>
parents: 141
diff changeset
246 if (simplifiedLine == "0 BFC INVERTNEXT" or simplifiedLine == "0 BFC CERTIFY INVERTNEXT")
3
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 invertNext = true;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
249 continue;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
250 }
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
251 std::unique_ptr<ldraw::Object> object = parseFromString(line);
152
03f8e6d42e13 Major refactoring
Teemu Piippo <teemu@hecknology.net>
parents: 144
diff changeset
252 model.append(std::move(object));
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
253 if (invertNext)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
254 {
152
03f8e6d42e13 Major refactoring
Teemu Piippo <teemu@hecknology.net>
parents: 144
diff changeset
255 model[model.size() - 1]->invert();
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
256 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
257 invertNext = false;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
258 }
141
185eb297dc1e Saving works now
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
259 /*
77
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
260 // 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
261 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
262 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
263 {
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
264 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
265 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
266 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
267 {
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
268 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
269 }
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
270 }
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
271 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
272 {
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
273 ldraw::splitQuadrilateral(editor, id);
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
274 }
141
185eb297dc1e Saving works now
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
275 */
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
276 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
277
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
278 static ldraw::Color colorFromString(const QString& colorString)
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
279 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
280 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
281 const ldraw::Color color = {colorString.toInt(&colorSucceeded)};
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
282 if (colorSucceeded)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
283 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
284 return color;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
285 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
286 else
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
287 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
288 throw BodyParseError{"colour was not an integer value"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
289 }
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
33
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
292 static glm::vec3 vertexFromStrings(
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
293 const QStringList& tokens,
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
294 const int startingPosition)
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 bool ok_x;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
297 const float x = tokens[startingPosition].toFloat(&ok_x);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
298 bool ok_y;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
299 const float y = tokens[startingPosition + 1].toFloat(&ok_y);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
300 bool ok_z;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
301 const float z = tokens[startingPosition + 2].toFloat(&ok_z);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
302 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
303 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
304 throw BodyParseError{"vertex contained illegal co-ordinates"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
305 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
306 return {x, y, z};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
307 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
308
115
ed884a2fb009 fix too long lines
Teemu Piippo <teemu@hecknology.net>
parents: 105
diff changeset
309 static glm::mat4 matrixFromStrings(
ed884a2fb009 fix too long lines
Teemu Piippo <teemu@hecknology.net>
parents: 105
diff changeset
310 const QStringList& tokens,
ed884a2fb009 fix too long lines
Teemu Piippo <teemu@hecknology.net>
parents: 105
diff changeset
311 const int startingPosition,
ed884a2fb009 fix too long lines
Teemu Piippo <teemu@hecknology.net>
parents: 105
diff changeset
312 const int positionStartingIndex)
8
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 glm::mat4 result = glm::mat4{1};
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
315 for (int i = 0; i < 9; i += 1)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
316 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
317 const int row = i / 3;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
318 const int column = i % 3;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
319 const int index = i + startingPosition;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
320 if (index >= tokens.size())
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
321 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
322 throw BodyParseError{"too few tokens available"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
323 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
324 bool ok;
33
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
325 // note that glm::mat4 is column-major
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
326 result[column][row] = tokens[index].toFloat(&ok);
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
327 if (not ok)
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
328 {
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
329 throw BodyParseError{"non-numeric values for matrix"};
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 }
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
332 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
333 {
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
334 bool ok;
4c41bfe2ec6e replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents: 26
diff changeset
335 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
336 result[3][i] = value;
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
337 if (not ok)
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
338 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
339 throw BodyParseError{"non-numeric values for matrix"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
340 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
341 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
342 return result;
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
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
345 static std::unique_ptr<ldraw::Object> parseType0Line(
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
346 const QString& line,
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
347 const QStringList& tokens)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
348 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
349 Q_UNUSED(tokens)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
350 if (line.startsWith("0 //"))
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
351 {
141
185eb297dc1e Saving works now
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
352 // lol wut
185eb297dc1e Saving works now
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
353 return std::make_unique<ldraw::Comment>(line.mid(std::strlen("0 //")).trimmed());
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
354 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
355 else
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
356 {
141
185eb297dc1e Saving works now
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
357 return std::make_unique<ldraw::MetaCommand>(line.mid(1).trimmed());
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
358 }
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
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
361 static std::unique_ptr<ldraw::SubfileReference> parseType1Line(
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
362 const QString& line,
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
363 const QStringList& tokens)
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
364 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
365 Q_UNUSED(line)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
366 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
367 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
368 constexpr int transformPosition = 5; // 5..13
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
369 constexpr int namePosition = 14;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
370 if (tokens.size() != 15)
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
371 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
372 throw BodyParseError{"wrong amount of tokens in a type-1 line"};
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
373 }
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
374 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
375 const glm::mat4 transform = matrixFromStrings(tokens, transformPosition, positionPosition);
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
376 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
377 return std::make_unique<ldraw::SubfileReference>(transform, name, color);
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
378 }
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
379
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
380 template<typename T, int NumVertices>
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
381 static std::unique_ptr<T> parsePolygon(
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
382 const QString& line,
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
383 const QStringList& tokens)
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
384 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
385 Q_UNUSED(line)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
386 constexpr int colorPosition = 1;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
387 auto vertexPosition = [](int n) { return 2 + 3*n; };
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
388 if (tokens.size() != 2 + 3 * NumVertices)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
389 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
390 throw BodyParseError{"wrong amount of tokens"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
391 }
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
392 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
393 std::array<glm::vec3, NumVertices> vertices;
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
394 for (int i = 0; i < NumVertices; i += 1)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
395 {
77
028798a72591 added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
396 vertices[unsigned_cast(i)] = vertexFromStrings(tokens, vertexPosition(i));
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
397 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
398 return std::make_unique<T>(vertices, color);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
399 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
400
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
401 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
402 {
141
185eb297dc1e Saving works now
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
403 line = line.trimmed();
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
404 try
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
405 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
406 const QStringList tokens = line.split(QRegExp{R"(\s+)"});
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
407 if (tokens.empty() or tokens == QStringList{{""}})
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
408 {
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
409 return std::make_unique<ldraw::Empty>();
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
410 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
411 bool ok_code;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
412 const int code = tokens[0].toInt(&ok_code);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
413 if (not ok_code)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
414 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
415 throw BodyParseError{"line type was not an integer"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
416 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
417 switch (code)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
418 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
419 case 0:
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
420 return parseType0Line(line, tokens);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
421 case 1:
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
422 return parseType1Line(line, tokens);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
423 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
424 return parsePolygon<ldraw::Edge, 2>(line, tokens);
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
425 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
426 return parsePolygon<ldraw::Triangle, 3>(line, tokens);
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
427 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
428 return parsePolygon<ldraw::Quadrilateral, 4>(line, tokens);
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
429 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
430 return parsePolygon<ldraw::ConditionalEdge, 4>(line, tokens);
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
431 default:
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
432 throw BodyParseError{utility::format("bad line type '%1'", code)};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
433 }
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
434 }
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
435 catch(const BodyParseError& error)
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
436 {
35
98906a94732f renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents: 33
diff changeset
437 return std::make_unique<ldraw::ErrorLine>(line, error.message);
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
438 }
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
439 }

mercurial