139 {
141 *err = "v2 'segments' is not an array";
142 return false;
143 }
144
145 auto arrPtr = segmentsArr.
as_array();
146 if (!arrPtr) {
147 *err = "v2 'segments' array could not be read";
148 return false;
149 }
150
151 for (const auto& elem : *arrPtr) {
152 if (!elem) {
153 *err = "v2 segment is null";
154 return false;
155 }
156 fl::json segVal(elem);
157 if (!segVal.has_value() || !segVal.is_object()) {
158 *err = "v2 segment is not an object";
159 return false;
160 }
161
162
163 if (!segVal.contains("id") || !segVal["id"].has_value()) {
164 *err = "v2 segment missing 'id'";
165 return false;
166 }
167 auto idOpt = segVal["id"].as_string();
168 if (!idOpt) {
169 *err = "v2 segment 'id' is not a string";
170 return false;
171 }
172 string id = *idOpt;
173
174
175 if (!segVal.contains("x") || !segVal["x"].has_value() || !segVal["x"].is_array()) {
176 *err = "v2 segment '" + id + "' missing or invalid 'x' array";
177 return false;
178 }
180
181
182 if (!segVal.contains("y") || !segVal["y"].has_value() || !segVal["y"].is_array()) {
183 *err = "v2 segment '" + id + "' missing or invalid 'y' array";
184 return false;
185 }
187
188 string type =
"led_strip";
189 if (segVal.contains("type") && segVal["type"].has_value()) {
190 auto typeOpt = segVal["type"].as_string();
191 if (!typeOpt) { *err = "v2 segment '" + id + "' has invalid 'type'"; return false; }
193 }
194 const bool isWire =
type ==
"el_wire";
195 const bool isPanel =
type ==
"el_panel";
196 if (
type !=
"led_strip" && !isWire && !isPanel) {
197 *err =
"v2 segment '" +
id +
"' has unsupported type '" +
type +
"'";
198 return false;
199 }
200 if (x_array.
size() != y_array.
size()) {
201 *err = "v2 segment '" + id + "' has mismatched x/y lengths";
202 return false;
203 }
204 const size_t minVertices = isWire ? 2 : isPanel ? 3 : 0;
205 if ((isWire || isPanel) && x_array.
size() < minVertices) {
206 *err = "v2 segment '" + id + "' has too few vertices";
207 return false;
208 }
209 float thickness = 0.0f;
210 if (isWire) {
211 if (!segVal.contains("thickness") || !segVal["thickness"].has_value()) {
212 *err = "v2 el_wire segment '" + id + "' missing thickness";
213 return false;
214 }
215 auto thicknessOpt = segVal["thickness"].as_float();
216 if (!thicknessOpt || *thicknessOpt <= 0.0f) {
217 *err = "v2 el_wire segment '" + id + "' requires positive thickness";
218 return false;
219 }
220 thickness = static_cast<float>(*thicknessOpt);
221 } else if (segVal.contains("thickness")) {
222 *err = "v2 segment '" + id + "' thickness is only valid for el_wire";
223 return false;
224 }
225
226
227
228
229 float diameter = -1.0f;
230 if (segVal.contains("diameter") && segVal["diameter"].has_value()) {
231 auto diameterOpt = segVal["diameter"].as_float();
232 if (diameterOpt) {
233 diameter = static_cast<float>(*diameterOpt);
234 }
235 }
236
238 ScreenMap segment_map(isWire || isPanel ? 1 :
static_cast<u32
>(n), diameter);
239 if (isWire || isPanel) {
240 fl::vector<vec2f> vertices;
242 for (
size_t i = 0; i < n; i++) vertices.
push_back({x_array[i], y_array[i]});
244 }
245 if (!isWire && !isPanel) {
246 for (size_t i = 0; i < n; i++) {
247 segment_map.set(
static_cast<u16
>(i),
vec2f{x_array[i], y_array[i]});
248 }
249 }
250 (*segmentMaps)[id] =
fl::move(segment_map);
251 }
252 return true;
253}
bool has_value() const FL_NO_EXCEPT
bool is_array() const FL_NO_EXCEPT
const json_array * as_array() const FL_NO_EXCEPT
fl::size size() const FL_NO_EXCEPT
void reserve(fl::size n) FL_NO_EXCEPT
void push_back(const T &value) FL_NO_EXCEPT
constexpr remove_reference< T >::type && move(T &&t) FL_NO_EXCEPT
FL_DISABLE_WARNING_PUSH U constexpr common_type_t< T, U > min(T a, U b) FL_NO_EXCEPT
fl::vector< float > jsonArrayToFloatVector(const fl::json &jsonArray)