src/parser.cpp

Sun, 03 Nov 2019 12:17:41 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Sun, 03 Nov 2019 12:17:41 +0200
changeset 8
44679e468ba9
parent 5
593a658cba8e
child 12
fe67489523b5
permissions
-rw-r--r--

major update with many things

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
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
3 * Copyright (C) 2013 - 2018 Teemu Piippo
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"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
21 #include "objecttypes/comment.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
22 #include "objecttypes/conditionaledge.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
23 #include "objecttypes/edge.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
24 #include "objecttypes/errorline.h"
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
25 #include "objecttypes/metacommand.h"
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
26 #include "objecttypes/modelobject.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
27 #include "objecttypes/polygon.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
28 #include "objecttypes/subfilereference.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
29
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
30 struct BodyParseError
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
31 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
32 QString message;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
33 };
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
34
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
35 /*
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
36 * Constructs an LDraw parser
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
37 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
38 Parser::Parser(QIODevice& device, QObject* parent) :
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
39 QObject {parent},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
40 device {device} {}
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
41
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 * Reads a single line from the device.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
44 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
45 QString Parser::readLine()
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
46 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
47 return QString::fromUtf8(this->device.readLine()).trimmed();
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
48 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
49
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
50 static const QMap<QString, LDHeader::FileType> typeStrings {
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
51 {"Part", LDHeader::Part},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
52 {"Subpart", LDHeader::Subpart},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
53 {"Shortcut", LDHeader::Shortcut},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
54 {"Primitive", LDHeader::Primitive},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
55 {"8_Primitive", LDHeader::Primitive_8},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
56 {"48_Primitive", LDHeader::Primitive_48},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
57 {"Configuration", LDHeader::Configuration},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
58 };
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 * Parses a single line of the header.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
62 * Possible parse results:
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
63 * · ParseSuccess: the header line was parsed successfully.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
64 * · 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
65 * · 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
66 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
67 Parser::HeaderParseResult Parser::parseHeaderLine(
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
68 LDHeader& header,
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
69 Winding& winding,
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
70 const QString& line
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
71 ) {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
72 if (line.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
73 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
74 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
75 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
76 else if (not line.startsWith("0") or line.startsWith("0 //"))
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 return StopParsing;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
79 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
80 else if (line.startsWith("0 !LDRAW_ORG "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
81 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
82 QStringList tokens = line
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
83 .mid(strlen("0 !LDRAW_ORG "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
84 .split(" ", QString::SkipEmptyParts);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
85 if (not tokens.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
86 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
87 QString partTypeString = tokens[0];
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
88 // Anything that enters LDForge becomes unofficial in any case if saved.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
89 // 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
90 // consideration.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
91 if (partTypeString.startsWith("Unofficial_"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
92 partTypeString = partTypeString.mid(strlen("Unofficial_"));
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
93 header.type = typeStrings.value(partTypeString, LDHeader::Part);
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
94 header.qualfiers = 0;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
95 if (tokens.contains("Alias"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
96 header.qualfiers |= LDHeader::Alias;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
97 if (tokens.contains("Physical_Color"))
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
98 header.qualfiers |= LDHeader::PhysicalColour;
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
99 if (tokens.contains("Flexible_Section"))
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
100 header.qualfiers |= LDHeader::FlexibleSection;
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
101 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
102 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
103 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
104 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
105 return ParseFailure;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
106 }
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 else if (line == "0 BFC CERTIFY CCW")
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
109 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
110 winding = Anticlockwise;
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
111 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
112 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
113 else if (line == "0 BFC CERTIFY CW")
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
114 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
115 winding = Clockwise;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
116 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
117 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
118 else if (line == "0 BFC NOCERTIFY")
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 winding = NoWinding;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
121 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
122 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
123 else if (line.startsWith("0 !HISTORY "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
124 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
125 static const QRegExp historyRegexp {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
126 R"(0 !HISTORY\s+(\d{4}-\d{2}-\d{2})\s+)"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
127 R"((\{[^}]+|\[[^]]+)[\]}]\s+(.+))"
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 (historyRegexp.exactMatch(line))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
130 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
131 QString dateString = historyRegexp.capturedTexts().value(1);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
132 QString authorWithPrefix = historyRegexp.capturedTexts().value(2);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
133 QString description = historyRegexp.capturedTexts().value(3);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
134 LDHeader::HistoryEntry historyEntry;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
135 historyEntry.date = QDate::fromString(dateString, Qt::ISODate);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
136 historyEntry.description = description;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
137
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
138 if (authorWithPrefix[0] == '{')
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
139 historyEntry.author = authorWithPrefix + "}";
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
140 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
141 historyEntry.author = authorWithPrefix.mid(1);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
142
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
143 header.history.append(historyEntry);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
144 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
145 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
146 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
147 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
148 return ParseFailure;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
149 }
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 else if (line.startsWith("0 Author: "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
152 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
153 header.author = line.mid(strlen("0 Author: "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
154 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
155 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
156 else if (line.startsWith("0 Name: "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
157 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
158 header.name = line.mid(strlen("0 Name: "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
159 return ParseSuccess;
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 else if (line.startsWith("0 !HELP "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
162 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
163 if (not header.help.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
164 header.help += "\n";
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
165 header.help += line.mid(strlen("0 !HELP "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
166 return ParseSuccess;
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 else if (line.startsWith("0 !KEYWORDS "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
169 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
170 if (not header.keywords.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
171 header.keywords += "\n";
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
172 header.keywords += line.mid(strlen("0 !KEYWORDS "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
173 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
174 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
175 else if (line.startsWith("0 !CATEGORY "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
176 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
177 header.category = line.mid(strlen("0 !CATEGORY "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
178 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
179 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
180 else if (line.startsWith("0 !CMDLINE "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
181 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
182 header.cmdline = line.mid(strlen("0 !CMDLINE "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
183 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
184 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
185 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
186 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
187 header.license = LDHeader::CaLicense;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
188 return ParseSuccess;
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 else if (line.startsWith("0 !LICENSE Not redistributable"))
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 header.license = LDHeader::NonCaLicense;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
193 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
194 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
195 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
196 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
197 return ParseFailure;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
198 }
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 * Parses the header from the device given at construction and returns
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
203 * the resulting header structure.
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 LDHeader Parser::parseHeader(Winding& winding)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
206 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
207 LDHeader header = {};
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
208 if (not this->device.atEnd())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
209 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
210 // Parse the description
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
211 QString descriptionLine = this->readLine();
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
212 if (descriptionLine.startsWith("0 "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
213 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
214 header.description = descriptionLine.mid(strlen("0 ")).trimmed();
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
215 // Parse the rest of the header
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
216 while (not this->device.atEnd())
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 const QString& line = this->readLine();
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
219 auto result = parseHeaderLine(header, winding, line);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
220 if (result == ParseFailure)
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 // 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
223 this->bag.append(line);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
224 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
225 else if (result == StopParsing)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
226 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
227 // Header parsing stops, add this line to the body.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
228 this->bag.append(line);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
229 break;
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 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
234 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
235 this->bag.append(descriptionLine);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
236 }
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 return header;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
239 }
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 * @brief Parses the model body into the given model.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
243 * @param editor Handle to model edit context
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
244 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
245 void Parser::parseBody(Model::EditContext& editor)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
246 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
247 bool invertNext = false;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
248 while (not this->device.atEnd())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
249 this->bag.append(this->readLine());
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
250 for (const QString& line : this->bag)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
251 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
252 if (line == "0 BFC INVERTNEXT" or line == "0 BFC CERTIFY INVERTNEXT")
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
253 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
254 invertNext = true;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
255 continue;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
256 }
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
257 std::unique_ptr<modelobjects::BaseObject> object = parseFromString(line);
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
258 if (invertNext)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
259 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
260 editor.setObjectProperty(object.get(), modelobjects::Property::IsInverted, true);
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
261 }
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
262 editor.append(std::move(object));
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
263 invertNext = false;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
264 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
265 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
266
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
267 static Color colorFromString(const QString& colorString)
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
268 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
269 bool colorSucceeded;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
270 const Color color = {colorString.toInt(&colorSucceeded)};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
271 if (colorSucceeded)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
272 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
273 return color;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
274 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
275 else
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
276 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
277 throw BodyParseError{"colour was not an integer value"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
278 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
279 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
280
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
281 static Vertex vertexFromStrings(
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
282 const QStringList& tokens,
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
283 const int startingPosition)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
284 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
285 bool ok_x;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
286 const float x = tokens[startingPosition].toFloat(&ok_x);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
287 bool ok_y;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
288 const float y = tokens[startingPosition + 1].toFloat(&ok_y);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
289 bool ok_z;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
290 const float z = tokens[startingPosition + 2].toFloat(&ok_z);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
291 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
292 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
293 throw BodyParseError{"vertex contained illegal co-ordinates"};
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 return {x, y, z};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
296 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
297
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
298 static Matrix3x3 matrixFromStrings(const QStringList& tokens, const int startingPosition)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
299 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
300 Matrix3x3 result;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
301 for (int i = 0; i < 9; i += 1)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
302 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
303 const int row = i / 3;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
304 const int column = i % 3;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
305 const int index = i + startingPosition;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
306 if (index >= tokens.size())
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
307 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
308 throw BodyParseError{"too few tokens available"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
309 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
310 bool ok;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
311 result(row, column) = tokens[index].toFloat(&ok);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
312 if (not ok)
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
313 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
314 throw BodyParseError{"non-numeric values for matrix"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
315 }
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 return result;
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
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
320 static std::unique_ptr<modelobjects::BaseObject> parseType0Line(
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
321 const QString& line,
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
322 const QStringList& tokens)
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 Q_UNUSED(tokens)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
325 if (line.startsWith("0 //"))
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
326 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
327 return std::make_unique<modelobjects::Comment>(line.mid(std::strlen("0 //")).simplified());
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
328 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
329 else
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
330 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
331 return std::make_unique<modelobjects::MetaCommand>(line.mid(1).simplified());
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
332 }
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
333 }
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
334
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
335 static std::unique_ptr<modelobjects::SubfileReference> parseType1Line(
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
336 const QString& line,
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
337 const QStringList& tokens)
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
338 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
339 Q_UNUSED(line)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
340 constexpr int colorPosition = 1;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
341 constexpr int transformPosition = 2; // 2..10
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
342 constexpr int positionPosition = 11; // 11..13
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
343 constexpr int namePosition = 14;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
344 if (tokens.size() != 15)
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
345 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
346 throw BodyParseError{"wrong amount of tokens in a type-1 line"};
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
347 }
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
348 const Color color = colorFromString(tokens[colorPosition]);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
349 const Vertex position = vertexFromStrings(tokens, positionPosition);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
350 const Matrix3x3 transform = matrixFromStrings(tokens, transformPosition);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
351 const QString& name = tokens[namePosition];
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
352 return std::make_unique<modelobjects::SubfileReference>(position, transform, name, color);
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
353 }
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
354
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
355 template<typename T, int NumVertices>
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
356 static std::unique_ptr<T> parsePolygon(
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
357 const QString& line,
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
358 const QStringList& tokens)
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
359 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
360 Q_UNUSED(line)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
361 constexpr int colorPosition = 1;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
362 auto vertexPosition = [](int n) { return 2 + 3*n; };
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
363 if (tokens.size() != 2 + 3 * NumVertices)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
364 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
365 throw BodyParseError{"wrong amount of tokens"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
366 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
367 const Color color = colorFromString(tokens[colorPosition]);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
368 QVector<Vertex> vertices;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
369 vertices.reserve(NumVertices);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
370 for (int i = 0; i < NumVertices; i += 1)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
371 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
372 vertices.append(vertexFromStrings(tokens, vertexPosition(i)));
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
373 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
374 return std::make_unique<T>(vertices, color);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
375 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
376
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
377 std::unique_ptr<modelobjects::BaseObject> Parser::parseFromString(QString line)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
378 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
379 line = line.simplified();
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
380 try
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
381 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
382 const QStringList tokens = line.split(QRegExp{R"(\s+)"});
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
383 if (tokens.empty())
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
384 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
385 return std::make_unique<modelobjects::Empty>();
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
386 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
387 bool ok_code;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
388 const int code = tokens[0].toInt(&ok_code);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
389 if (not ok_code)
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{"line type was not an integer"};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
392 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
393 switch (code)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
394 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
395 case 0:
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
396 return parseType0Line(line, tokens);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
397 case 1:
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
398 return parseType1Line(line, tokens);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
399 case 2:
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
400 return parsePolygon<modelobjects::Edge, 2>(line, tokens);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
401 case 3:
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
402 return parsePolygon<modelobjects::Triangle, 3>(line, tokens);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
403 case 4:
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
404 return parsePolygon<modelobjects::Quadrilateral, 4>(line, tokens);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
405 case 5:
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
406 return parsePolygon<modelobjects::ConditionalEdge, 4>(line, tokens);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
407 default:
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
408 throw BodyParseError{utility::format("bad line type '%1'", code)};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
409 }
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
410 }
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
411 catch(const BodyParseError& error)
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
412 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
413 return std::make_unique<modelobjects::ErrorLine>(line, error.message);
5
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
414 }
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
415 }

mercurial