RayZaler 0.1
The free opto-mechanical simulation framework
Element.h
1//
2// Copyright (c) 2024 Gonzalo José Carracedo Carballal
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU Lesser General Public License as
6// published by the Free Software Foundation, either version 3 of the
7// License, or (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU Lesser General Public License for more details.
13//
14// You should have received a copy of the GNU Lesser General Public
15// License along with this program. If not, see
16// <http://www.gnu.org/licenses/>
17//
18
19#ifndef _ELEMENT_H
20#define _ELEMENT_H
21
22#include "ReferenceFrame.h"
23#include "Helpers.h"
24#include "ElementMacros.h"
25#include <set>
26#include <list>
27#include <map>
28#include <variant>
29#include <GLHelpers.h>
30
31//
32// An optical element is something that:
33//
34// 1. Is defined on top of a reference frame
35// 2. May define additional axes and points on that reference frame
36// 3. May provide additional reference frames
37// 4. May include a method to draw an OpenGL representation
38// 5. Define several properties
39
40namespace RZ {
41 class OMModel;
42 class GenericCompositeModel;
43 class OpticalElement;
44 class Detector;
45 class OpticalPath;
46 struct ElementFactoryMeta;
48
49 enum PropertyValueType {
50 UndefinedValue,
51 IntegerValue,
52 RealValue,
53 BooleanValue,
54 StringValue
55 };
56
57 typedef std::variant<UndefinedProperty, int64_t, Real, bool, std::string> BasePropertyVariant;
58 class PropertyValue : public BasePropertyVariant {
59 // Cobolization of C++ will never end. I need this specific construct to
60 // inherit constructors from BasePropertyVariant
61 using BasePropertyVariant::BasePropertyVariant;
62
63 std::string m_description;
64 std::string m_context;
65 bool m_hidden = false;
66
67 public:
68 inline void
69 setHidden(bool hidden)
70 {
71 m_hidden = hidden;
72 }
73
74 bool
75 isHidden() const
76 {
77 return m_hidden;
78 }
79
80 inline void
81 setDescription(std::string const &desc)
82 {
83 m_description = desc;
84 }
85
86 inline void
87 setContext(std::string const &ctx)
88 {
89 m_context = ctx;
90 }
91
92 inline std::string
93 description() const
94 {
95 return m_description;
96 }
97
98 inline std::string
99 context() const
100 {
101 return m_context;
102 }
103
104 static inline PropertyValue
105 undefined()
106 {
107 return PropertyValue();
108 }
109
110 inline bool
111 isUndefined() const
112 {
113 return index() == 0;
114 }
115
116 inline PropertyValueType
117 type() const
118 {
119 return static_cast<PropertyValueType>(index());
120 }
121
122 template<typename T>
123 inline operator T() const
124 {
125 switch (index()) {
126 case 1:
127 return std::get<int64_t>(*this);
128 break;
129
130 case 2:
131 return std::get<Real>(*this);
132 break;
133
134 case 3:
135 return std::get<bool>(*this);
136 break;
137 }
138
139 return T();
140 }
141
142 inline int64_t asInteger() const { return std::get<int64_t>(*this); }
143 inline Real asReal() const { return std::get<Real>(*this); }
144 inline bool asBool() const { return std::get<bool>(*this); }
145 inline std::string asString() const { return std::get<std::string>(*this); }
146 };
147
148 template<>
149 inline PropertyValue::operator bool() const
150 {
151 std::string val;
152
153 switch (type()) {
154 case IntegerValue:
155 return std::get<int64_t>(*this) != 0;
156
157 case RealValue:
158 return std::get<Real>(*this) < -0.5
159 || std::get<Real>(*this) > 0.5;
160
161 case BooleanValue:
162 return std::get<bool>(*this);
163
164 case StringValue:
165 return val == "1" || iequals(val, "yes") || iequals(val, "true");
166 }
167
168 return false;
169 }
170
171 class ElementFactory;
172
173 class Element {
174 std::string m_className;
175 std::string m_name;
176 Element *m_parent = nullptr;
177 ReferenceFrame *m_parentFrame = nullptr;
178 GenericCompositeModel *m_parentModel = nullptr;
179 ElementFactory *m_factory = nullptr;
180 Vec3 m_bb1;
181 Vec3 m_bb2;
182 std::vector<GLfloat> m_bbLines;
183
184 std::list<Element *> m_children;
185 std::list<ReferenceFrame *> m_portList;
186 std::map<std::string, ReferenceFrame *> m_nameToPort;
187 std::vector<std::string> m_sortedProperties;
188 std::map<std::string, PropertyValue> m_properties;
189
190 // Representation state
191 bool m_selected = false;
192 bool m_visible = true;
193
194 // Default appearence
195 Real m_shiny = 64;
196 Real m_red = .25;
197 Real m_green = .25;
198 Real m_blue = .25;
199
200 Real m_specRed = .25;
201 Real m_specGreen = .25;
202 Real m_specBlue = .25;
203
204 void pushChild(Element *);
205 void registerProperties(const ElementFactoryMeta *meta);
206
207 protected:
208 void material(std::string const &role);
209 void refreshProperties();
210 void registerProperty(
211 std::string const &,
212 PropertyValue const &,
213 std::string const &);
214
215 // Takes ownership
216 ReferenceFrame *registerPort(std::string const &, ReferenceFrame *);
217
218 // Does not take ownership
219 bool addPort(std::string const &, ReferenceFrame *);
220
221 template <class T>
222 inline T *
223 registerPort(std::string const &name, T *frame)
224 {
225 auto ret = registerPort(name, static_cast<ReferenceFrame *>(frame));
226 return static_cast<T *>(ret);
227 }
228
229 virtual bool propertyChanged(std::string const &, PropertyValue const &);
230
231 void setBoundingBox(Vec3 const &p1, Vec3 const &p2);
232 void updatePropertyValue(std::string const &, PropertyValue const &);
233
234 Element(
236 std::string const &,
238 Element *parent = nullptr);
239
240 public:
241 virtual ~Element();
242
243 inline Real red() const { return m_red; }
244 inline Real green() const { return m_green; }
245 inline Real blue() const { return m_blue; }
246
248 factory() const
249 {
250 return m_factory;
251 }
252
253 inline GenericCompositeModel *
254 parentModel()
255 {
256 return m_parentModel;
257 }
258
259 void
260 setParentModel(GenericCompositeModel *model)
261 {
262 m_parentModel = model;
263 }
264
265 // Get name
266 std::string const &
267 name() const
268 {
269 return m_name;
270 }
271
272 // Determine whether it has a property
273 inline bool
274 hasProperty(std::string const &prop) const
275 {
276 return m_properties.find(prop) != m_properties.end();
277 }
278
279 inline PropertyValueType
280 queryPropertyType(std::string const &prop) const
281 {
282 auto it = m_properties.find(prop);
283
284 if (it == m_properties.end())
285 return UndefinedValue;
286
287 return it->second.type();
288 }
289
290 inline bool
291 propertyIsHidden(std::string const &prop) const
292 {
293 auto it = m_properties.find(prop);
294
295 if (it == m_properties.end())
296 return false;
297
298 return it->second.isHidden();
299 }
300
301 // Get parent frame
302 inline ReferenceFrame *
303 parentFrame() const
304 {
305 return m_parentFrame;
306 }
307
308 inline bool
309 visible() const
310 {
311 return m_visible;
312 }
313
314 // Refresh all reference frames depending on parent
315 void refreshFrames();
316
317 // Enumerate ports
318 std::set<std::string> ports() const;
319
320 // Enumerate properties
321 std::set<std::string> properties() const;
322
323 // Sorted properties
324 std::vector<std::string> sortedProperties() const;
325
326 // Get the reference frame of one of these ports
327 ReferenceFrame *getPortFrame(std::string const &) const;
328
329 // Plug a new element to this port
330 Element *plug(
331 std::string const &port,
332 std::string const &type,
333 std::string const &name = "");
334
335
336 template <class T>
337 inline T *
338 plug(
339 std::string const &port,
340 std::string const &type,
341 std::string const &name = "")
342 {
343 auto ret = plug(port, type, name);
344 return static_cast<T *>(ret);
345 }
346
347 // Set properties
348 bool set(std::string const &, PropertyValue const &);
349 void setDefaults();
350
351 // Get properties
352 PropertyValue get(std::string const &) const;
353 template <class T>
354 T
355 get(std::string const &name) const
356 {
357 return static_cast<T>(get(name));
358 }
359
360 // Representation methods
361 void setSelected(bool);
362 void setVisible(bool);
363 void boundingBox(Vec3 &p1, Vec3 &p2) const;
364
365 // Representation interface
366 virtual void enterOpenGL();
367 virtual void nativeMaterialOpenGL(std::string const &role);
368 virtual void renderOpenGL();
369
370 void calcBoundingBoxOpenGL();
371 void renderBoundingBoxOpenGL();
372
373 virtual OMModel *nestedModel() const;
374 virtual GenericCompositeModel *nestedCompositeModel() const;
375
376 // Other helper methods
377 Element *lookupElement(std::string const &name) const;
378 OpticalElement *lookupOpticalElement(std::string const &name) const;
379 Detector *lookupDetector(std::string const &name) const;
380 const OpticalPath *lookupOpticalPath(std::string const &name) const;
381 };
382
384 ElementFactoryMeta *parent; // Parent factory meta
385 std::string name; // Name of the element factory
386 std::string description; // Description
387 std::map<std::string, PropertyValue> properties; // Default properties
388 std::vector<std::string> sortedProperties; // Properties in addition order
389
390 PropertyValue *queryProperty(std::string const &);
391 };
392
394 std::list<ElementFactoryMeta> m_meta;
395 ElementFactoryMeta *m_metaData = nullptr;
396
397 protected:
398 void enterDecls(std::string const &, std::string const &);
399 PropertyValue &hiddenProperty(
400 std::string const &,
401 PropertyValue const &,
402 std::string const &);
403
404 void property(
405 std::string const &,
406 PropertyValue const &,
407 std::string const &);
408
409 public:
411
412 virtual Element *make(
413 std::string const &name,
414 ReferenceFrame *pFrame,
415 Element *parent = nullptr) = 0;
416
417 std::string name() const;
418 const ElementFactoryMeta *metaData() const;
419 PropertyValue *queryProperty(std::string const &);
420 };
421}
422
423#endif // _ELEMENT_H
Definition: Detector.h:116
Definition: Element.h:393
Definition: Element.h:173
Definition: GenericCompositeModel.h:120
Definition: OMModel.h:204
Definition: OpticalElement.h:87
Definition: Element.h:58
Definition: ReferenceFrame.h:59
Definition: Element.h:383
Definition: OpticalElement.h:54
Definition: Element.h:47
Definition: Vector.h:66