3 #include <QString> |
3 #include <QString> |
4 #include <QStringView> |
4 #include <QStringView> |
5 #include "main.h" |
5 #include "main.h" |
6 #include "colors.h" |
6 #include "colors.h" |
7 #include "gl/common.h" |
7 #include "gl/common.h" |
|
8 #include "linetypes/propertygenerics.h" |
|
9 |
|
10 class Model; |
8 |
11 |
9 namespace ldraw |
12 namespace ldraw |
10 { |
13 { |
11 struct GetPolygonsContext; |
14 struct GetPolygonsContext; |
12 enum class Property; |
|
13 class Object; |
15 class Object; |
14 class ColoredObject; |
16 class ColoredObject; |
15 class Empty; |
17 class Empty; |
16 class UnhandledProperty; |
18 class UnhandledProperty; |
17 template<int N> |
|
18 class PolygonObject; |
|
19 } |
19 } |
20 |
20 |
21 class DocumentManager; |
21 class DocumentManager; |
22 |
22 |
23 struct ldraw::GetPolygonsContext |
23 struct ldraw::GetPolygonsContext |
24 { |
24 { |
25 ::DocumentManager* documents; |
25 ::DocumentManager* documents; |
26 }; |
26 }; |
27 |
|
28 /** |
|
29 * @brief Different properties that can be queried with getProperty |
|
30 */ |
|
31 enum class ldraw::Property |
|
32 { |
|
33 Color, // Color of the object |
|
34 Text, // Text contained in a comment |
|
35 Point0, // First vertex in a polygon or edge line |
|
36 Point1, // Second vertex in a polygon or edge line |
|
37 Point2, // Third vertex in a polygon |
|
38 Point3, // Fourth vertex in a quadrilateral |
|
39 Transformation, // 4x4 transformation matrix of a subfile reference |
|
40 ReferenceName, // Subfile reference name |
|
41 IsInverted, // Whether or not the object has been inverted with BFC INVERTNEXT |
|
42 ErrorMessage // For error lines, why parsing failed |
|
43 }; |
|
44 |
|
45 // Mapping of properties to types |
|
46 #define LDFORGE_DEFINE_PROPERTY_TYPE(PROPERTY, TYPE) \ |
|
47 namespace ldraw { \ |
|
48 template<> struct PropertyType<ldraw::Property::PROPERTY> { using type = TYPE; }; \ |
|
49 } |
|
50 |
|
51 namespace ldraw |
|
52 { |
|
53 template<ldraw::Property property> |
|
54 struct PropertyType |
|
55 { |
|
56 }; |
|
57 |
|
58 template<ldraw::Property property> |
|
59 using PropertyType_t = typename PropertyType<property>::type; |
|
60 |
|
61 struct PropertyKeyValue |
|
62 { |
|
63 Property key; |
|
64 QVariant value; |
|
65 }; |
|
66 |
|
67 constexpr Property pointProperty(int n) |
|
68 { |
|
69 Q_ASSERT(n >= 0 and n < 4); |
|
70 return static_cast<Property>(static_cast<int>(Property::Point0) + n); |
|
71 } |
|
72 } |
|
73 |
|
74 LDFORGE_DEFINE_PROPERTY_TYPE(Color, int) |
|
75 LDFORGE_DEFINE_PROPERTY_TYPE(Text, QString) |
|
76 LDFORGE_DEFINE_PROPERTY_TYPE(Point0, glm::vec3) |
|
77 LDFORGE_DEFINE_PROPERTY_TYPE(Point1, glm::vec3) |
|
78 LDFORGE_DEFINE_PROPERTY_TYPE(Point2, glm::vec3) |
|
79 LDFORGE_DEFINE_PROPERTY_TYPE(Point3, glm::vec3) |
|
80 LDFORGE_DEFINE_PROPERTY_TYPE(Transformation, glm::mat4) |
|
81 LDFORGE_DEFINE_PROPERTY_TYPE(ReferenceName, QString) |
|
82 LDFORGE_DEFINE_PROPERTY_TYPE(IsInverted, bool) |
|
83 LDFORGE_DEFINE_PROPERTY_TYPE(ErrorMessage, QString) |
|
84 |
|
85 #define LDRAW_OBJECT_HANDLE_SET_PROPERTY(PROPERTY, HANDLER) \ |
|
86 {this->handle<ldraw::Property::PROPERTY>(result, pair, \ |
|
87 [&](const ldraw::PropertyType_t<ldraw::Property::PROPERTY>& value) HANDLER);} |
|
88 |
27 |
89 class ldraw::Object |
28 class ldraw::Object |
90 { |
29 { |
91 public: |
30 public: |
92 enum class SetPropertyResult |
31 enum class SetPropertyResult |
106 virtual ~Object(); |
45 virtual ~Object(); |
107 const id_t id; |
46 const id_t id; |
108 virtual bool hasColor() const; |
47 virtual bool hasColor() const; |
109 virtual QVariant getProperty(Property id) const; |
48 virtual QVariant getProperty(Property id) const; |
110 template<ldraw::Property property> |
49 template<ldraw::Property property> |
111 SetPropertyResult setProperty(const PropertyType_t<property>& value); |
50 SetPropertyResult setProperty(const PropertyType<property>& value); |
112 SetPropertyResult setProperty(const PropertyKeyValue& pair); |
51 SetPropertyResult setProperty(const PropertyKeyValue& pair); |
113 virtual QString textRepresentation() const = 0; |
52 virtual QString textRepresentation() const = 0; |
114 virtual QBrush textRepresentationForeground() const; |
53 virtual QBrush textRepresentationForeground() const; |
115 virtual QBrush textRepresentationBackground() const; |
54 virtual QBrush textRepresentationBackground() const; |
116 virtual QFont textRepresentationFont() const; |
55 virtual QFont textRepresentationFont() const; |
123 void handle(SetPropertyResult* result, const PropertyKeyValue& pair, Function function); |
62 void handle(SetPropertyResult* result, const PropertyKeyValue& pair, Function function); |
124 virtual void setProperty(SetPropertyResult* result, const PropertyKeyValue& pair); |
63 virtual void setProperty(SetPropertyResult* result, const PropertyKeyValue& pair); |
125 }; |
64 }; |
126 |
65 |
127 template<ldraw::Property property> |
66 template<ldraw::Property property> |
128 ldraw::Object::SetPropertyResult ldraw::Object::setProperty(const PropertyType_t<property>& value) |
67 ldraw::Object::SetPropertyResult ldraw::Object::setProperty(const ldraw::PropertyType<property>& value) |
129 { |
68 { |
130 SetPropertyResult result = SetPropertyResult::PropertyNotHandled; |
69 SetPropertyResult result = SetPropertyResult::PropertyNotHandled; |
131 this->setProperty(&result, PropertyKeyValue{property, QVariant::fromValue(value)}); |
70 this->setProperty(&result, PropertyKeyValue{property, QVariant::fromValue(value)}); |
132 return result; |
71 return result; |
133 } |
72 } |
135 template<ldraw::Property property, typename Function> |
74 template<ldraw::Property property, typename Function> |
136 void ldraw::Object::handle(SetPropertyResult* result, const PropertyKeyValue& pair, Function function) |
75 void ldraw::Object::handle(SetPropertyResult* result, const PropertyKeyValue& pair, Function function) |
137 { |
76 { |
138 if (pair.key == property) |
77 if (pair.key == property) |
139 { |
78 { |
140 function(pair.value.value<ldraw::PropertyType_t<property>>()); |
79 function(pair.value.value<ldraw::PropertyType<property>>()); |
141 *result = SetPropertyResult::Success; |
80 *result = SetPropertyResult::Success; |
142 } |
81 } |
143 } |
82 } |
144 |
83 |
145 class ldraw::ColoredObject : public Object |
84 class ldraw::ColoredObject : public Object |
151 Color colorIndex = ldraw::mainColor; |
90 Color colorIndex = ldraw::mainColor; |
152 protected: |
91 protected: |
153 void setProperty(SetPropertyResult* result, const PropertyKeyValue& pair) override; |
92 void setProperty(SetPropertyResult* result, const PropertyKeyValue& pair) override; |
154 }; |
93 }; |
155 |
94 |
156 template<int N> |
|
157 class ldraw::PolygonObject : public ColoredObject |
|
158 { |
|
159 public: |
|
160 PolygonObject(const std::array<glm::vec3, N>& points, const Color color) : |
|
161 ColoredObject{color}, |
|
162 points{points} {} |
|
163 int numPoints() const override |
|
164 { |
|
165 return N; |
|
166 } |
|
167 const glm::vec3& getPoint(int index) const override |
|
168 { |
|
169 Q_ASSERT(index >= 0 and index < N); |
|
170 return this->points[index]; |
|
171 } |
|
172 QVariant getProperty(const Property id) const override |
|
173 { |
|
174 switch (id) |
|
175 { |
|
176 case Property::Point0: |
|
177 return QVariant::fromValue(points[0]); |
|
178 case Property::Point1: |
|
179 return QVariant::fromValue(points[1]); |
|
180 case Property::Point2: |
|
181 if (N >= 3) |
|
182 { |
|
183 return QVariant::fromValue(points[2]); |
|
184 } |
|
185 break; |
|
186 case Property::Point3: |
|
187 if (N >= 4) |
|
188 { |
|
189 return QVariant::fromValue(points[3]); |
|
190 } |
|
191 break; |
|
192 default: |
|
193 break; |
|
194 } |
|
195 return ColoredObject::getProperty(id); |
|
196 } |
|
197 void setProperty(SetPropertyResult* result, const PropertyKeyValue& pair) |
|
198 { |
|
199 LDRAW_OBJECT_HANDLE_SET_PROPERTY(Point0, {points[0] = value;}) |
|
200 LDRAW_OBJECT_HANDLE_SET_PROPERTY(Point1, {points[1] = value;}) |
|
201 if constexpr (N >= 3) |
|
202 { |
|
203 LDRAW_OBJECT_HANDLE_SET_PROPERTY(Point2, {points[2] = value;}) |
|
204 } |
|
205 if constexpr (N >= 4) |
|
206 { |
|
207 LDRAW_OBJECT_HANDLE_SET_PROPERTY(Point3, {points[2] = value;}) |
|
208 } |
|
209 ColoredObject::setProperty(result, pair); |
|
210 } |
|
211 std::array<std::enable_if_t<(N > 0 and N <= 4), glm::vec3>, N> points; |
|
212 }; |
|
213 |
|
214 /** |
95 /** |
215 * @brief Represents an empty line. |
96 * @brief Represents an empty line. |
216 */ |
97 */ |
217 class ldraw::Empty : public Object |
98 class ldraw::Empty : public Object |
218 { |
99 { |