29 #ifndef NEMOSYS_NUCMESHJSON_H_ 30 #define NEMOSYS_NUCMESHJSON_H_ 32 #include <jsoncons/json.hpp> 40 #include <type_traits> 57 template <
typename R,
typename... Args>
64 template <
typename R,
typename... Args>
71 template <
typename T,
typename R,
typename... Args>
85 template <
typename T,
typename R,
typename... Args>
86 void setter_helper(T &obj, R (T::*setter)(Args...),
const jsoncons::json &json,
87 jsoncons::string_view key,
bool checkContains) {
88 if (json.contains(key)) {
89 (obj.*setter)(json.at(key)
90 .as<
typename std::decay<
92 }
else if (checkContains) {
93 throw jsoncons::convert_error(jsoncons::convert_errc::conversion_failed,
94 "Not a NEM::NUCMESH::ShapeBase");
100 const jsoncons::json &json,
101 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
104 inline std::unique_ptr<NEM::NUCMESH::ShapeBase>
as_shape(
105 const jsoncons::json &json,
106 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
109 template <
typename T>
110 typename std::enable_if<std::is_base_of<NEM::NUCMESH::ShapeBase, T>::value,
113 const jsoncons::json &json, T &shape,
114 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
116 bool checkRequired) {}
121 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>> &,
123 if (json.contains(
"Center")) {
124 auto centerSize = json.at(
"Center").array_value().size();
125 if (centerSize == 3) {
126 shape.
setCenter(json.at(
"Center").as<std::array<double, 3>>());
127 }
else if (centerSize == 5) {
128 auto center = json.at(
"Center").as<std::array<double, 5>>();
130 {center[0], center[1], center[2]}, {center[3], center[4]}));
138 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
140 bool checkRequired) {
143 modify_helper(json, dynamic_cast<NEM::NUCMESH::ShapeBase &>(shape),
144 savedShapes, checkRequired);
148 std::unique_ptr<NEM::NUCMESH::ShapeBase>
149 construct_helper<NEM::NUCMESH::Circles>(
150 const jsoncons::json &json,
151 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
154 std::unique_ptr<NEM::NUCMESH::ShapeBase> out{shape};
162 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
164 bool checkRequired) {
166 "Number of Sides", checkRequired);
169 modify_helper(json, dynamic_cast<NEM::NUCMESH::ShapeBase &>(shape),
170 savedShapes, checkRequired);
174 std::unique_ptr<NEM::NUCMESH::ShapeBase>
175 construct_helper<NEM::NUCMESH::CirclesAndPolys>(
176 const jsoncons::json &json,
177 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
180 std::unique_ptr<NEM::NUCMESH::ShapeBase> out{shape};
188 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
190 bool checkRequired) {
191 if (json.contains(arrayShapes) && json.at(arrayShapes).is_array()) {
193 for (
auto &shapeJson : json.at(arrayShapes).array_range()) {
200 }
else if (checkRequired) {
201 throw jsoncons::convert_error(jsoncons::convert_errc::conversion_failed,
202 "Not a NEM::NUCMESH::ShapesArray");
204 modify_helper(json, dynamic_cast<NEM::NUCMESH::ShapeBase &>(shape),
205 savedShapes, checkRequired);
211 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
213 bool checkRequired) {
217 "Start Angle", checkRequired);
219 "End Angle", checkRequired);
221 "Rotate with Array",
false);
222 if (json.contains(arrayPattern)) {
223 auto patternIdJson = json.at(arrayPattern).array_value();
224 if (!patternIdJson.empty()) {
225 auto patternIdIter = patternIdJson.begin();
226 const auto patternIdEnd = patternIdJson.end();
229 shape.
setPattern(patternIdx, patternIdIter->as<std::size_t>());
231 if (patternIdIter == patternIdEnd) {
232 patternIdIter = patternIdJson.begin();
236 }
else if (checkRequired) {
237 throw jsoncons::convert_error(jsoncons::convert_errc::conversion_failed,
238 "Not a NEM::NUCMESH::PolarArray");
240 modify_helper(json, dynamic_cast<NEM::NUCMESH::ShapesArray &>(shape),
241 savedShapes, checkRequired);
245 std::unique_ptr<NEM::NUCMESH::ShapeBase>
246 construct_helper<NEM::NUCMESH::PolarArray>(
247 const jsoncons::json &json,
248 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
251 json.at(
"Pattern").array_value().size(), {}, {}, {}};
252 std::unique_ptr<NEM::NUCMESH::ShapeBase> out{shape};
260 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
262 bool checkRequired) {
264 "Grid Distance", checkRequired);
265 if (json.contains(arrayPattern)) {
267 auto y = gridSize[1] - 1;
268 for (
auto &patternRow : json.at(arrayPattern).array_range()) {
270 for (
auto &patternJson : patternRow.array_range()) {
271 shape.
setPattern(x, y, patternJson.as<std::size_t>());
276 }
else if (checkRequired) {
277 throw jsoncons::convert_error(jsoncons::convert_errc::conversion_failed,
278 "Not a NEM::NUCMESH::RectangularArray");
280 modify_helper(json, dynamic_cast<NEM::NUCMESH::ShapesArray &>(shape),
281 savedShapes, checkRequired);
285 std::unique_ptr<NEM::NUCMESH::ShapeBase>
286 construct_helper<NEM::NUCMESH::RectangularArray>(
287 const jsoncons::json &json,
288 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
290 auto patternJson = json.at(
"Pattern").array_value();
292 {patternJson[0].size(), patternJson.size()}, {}};
293 std::unique_ptr<NEM::NUCMESH::ShapeBase> out{shape};
301 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
303 bool checkRequired) {
305 "Grid Distance", checkRequired);
306 if (json.contains(arrayPattern)) {
308 for (
auto &patternRow : json.at(arrayPattern).array_range()) {
310 for (
auto &patternJson : patternRow.array_range()) {
316 }
else if (checkRequired) {
317 throw jsoncons::convert_error(jsoncons::convert_errc::conversion_failed,
318 "Not a NEM::NUCMESH::HexagonalArray");
320 modify_helper(json, dynamic_cast<NEM::NUCMESH::ShapesArray &>(shape),
321 savedShapes, checkRequired);
325 std::unique_ptr<NEM::NUCMESH::ShapeBase>
326 construct_helper<NEM::NUCMESH::HexagonalArray>(
327 const jsoncons::json &json,
328 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
331 json.at(
"Pattern").array_value()[0].size(), {}};
332 std::unique_ptr<NEM::NUCMESH::ShapeBase> out{shape};
337 template <
typename T>
339 const jsoncons::json &json,
const T *
const aliasShape,
340 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
342 auto output =
new T{*aliasShape};
344 return std::unique_ptr<NEM::NUCMESH::ShapeBase>{output};
349 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
351 if (
auto circles = dynamic_cast<const NEM::NUCMESH::Circles *>(aliasShape)) {
353 }
else if (
auto circlesAndPolys =
354 dynamic_cast<const NEM::NUCMESH::CirclesAndPolys *>(
357 }
else if (
auto polar =
358 dynamic_cast<const NEM::NUCMESH::PolarArray *>(aliasShape)) {
360 }
else if (
auto rect = dynamic_cast<const NEM::NUCMESH::RectangularArray *>(
363 }
else if (
auto hex = dynamic_cast<const NEM::NUCMESH::HexagonalArray *>(
367 throw jsoncons::convert_error(jsoncons::convert_errc::conversion_failed,
368 "Not a NEM::NUCMESH::ShapeBase");
371 inline std::unique_ptr<NEM::NUCMESH::ShapeBase>
as_shape(
372 const jsoncons::json &json,
373 const std::map<std::string, std::unique_ptr<NEM::NUCMESH::ShapeBase>>
375 if (json.is_null()) {
378 static constexpr
auto loadSavedStr =
"Saved Object";
379 if (json.contains(loadSavedStr)) {
380 auto findIter = savedShapes.find(json.at(loadSavedStr).as_string());
381 if (findIter != savedShapes.end() && findIter->second) {
385 static constexpr
auto typeStr =
"Type";
386 if (json.contains(typeStr)) {
387 auto jsonType = json.at(typeStr).as_string_view();
388 if (jsonType ==
"Circles") {
389 return construct_helper<NEM::NUCMESH::Circles>(json, savedShapes);
390 }
else if (jsonType ==
"Circles And Polys") {
391 return construct_helper<NEM::NUCMESH::CirclesAndPolys>(json, savedShapes);
392 }
else if (jsonType ==
"Polar Array") {
393 return construct_helper<NEM::NUCMESH::PolarArray>(json, savedShapes);
394 }
else if (jsonType ==
"Rectangular Array") {
395 return construct_helper<NEM::NUCMESH::RectangularArray>(json,
397 }
else if (jsonType ==
"Hexagonal Array") {
398 return construct_helper<NEM::NUCMESH::HexagonalArray>(json, savedShapes);
401 throw jsoncons::convert_error(jsoncons::convert_errc::conversion_failed,
402 "Not a NEM::NUCMESH::ShapeBase");
412 (getOpts, setOpts,
"NucMesh Options"),
414 [](
const jsoncons::string_view &x) {
419 (
QUAD,
"Q"), (STRUCT,
"S"))
425 template <
typename Json>
428 using allocator_type =
typename Json::allocator_type;
429 using char_type =
typename Json::char_type;
430 using string_view_type =
typename Json::string_view_type;
431 static constexpr
auto meshingTypeStr =
"Type";
432 static constexpr
auto elemsStr =
"Number of Elems";
433 static bool is(
const Json &ajson) noexcept {
434 if (!ajson.is_object())
return false;
435 if (!ajson.contains(meshingTypeStr))
return false;
438 static value_type as(
const Json &ajson) {
442 throw convert_error(convert_errc::conversion_failed,
443 "Not a NEM::NUCMESH::RingMeshOption");
445 ajson.at(meshingTypeStr).template as<RingMeshOption::MeshingType>();
446 switch (meshingType) {
447 case RingMeshOption::MeshingType::TRI:
448 return RingMeshOption::ApplyTriMesh();
450 return RingMeshOption::ApplyQuadMesh();
451 case RingMeshOption::MeshingType::STRUCT:
452 if (ajson.contains(elemsStr)) {
453 return RingMeshOption::ApplyStructuredMesh(
456 decltype(RingMeshOption::ApplyStructuredMesh)>>::type>());
459 throw convert_error(convert_errc::conversion_failed,
460 "Not a NEM::NUCMESH::RingMeshOption");
465 :
public std::true_type {};
467 template <
typename Json>
470 using allocator_type =
typename Json::allocator_type;
471 using char_type =
typename Json::char_type;
472 using string_view_type =
typename Json::string_view_type;
473 static constexpr
auto radiusStr =
"Radius";
474 static constexpr
auto meshTypeStr =
"Mesh";
475 static constexpr
auto materialStr =
"Material";
476 static constexpr
auto sidesetStr =
"Sideset";
477 static bool is(
const Json &ajson) noexcept {
478 return ajson.is_object() && ajson.contains(radiusStr) &&
479 ajson.contains(meshTypeStr);
481 static value_type as(
const Json &ajson) {
483 throw convert_error(convert_errc::conversion_failed,
484 "Not a NEM::NUCMESH::Ring");
486 ajson.at(radiusStr).template as<decltype(value_type::radius)>(),
487 ajson.at(meshTypeStr).template as<decltype(value_type::meshType)>());
488 if (ajson.contains(materialStr)) {
489 jsoncons::json_traits_helper<Json>::set_udt_member(ajson, materialStr,
492 if (ajson.contains(sidesetStr)) {
493 jsoncons::json_traits_helper<Json>::set_udt_member(ajson, sidesetStr,
501 :
public std::true_type {};
503 template <
typename Json>
506 using allocator_type =
typename Json::allocator_type;
507 using char_type =
typename Json::char_type;
508 using string_view_type =
typename Json::string_view_type;
509 static constexpr
auto radiusStr =
510 json_type_traits<Json, NEM::NUCMESH::Ring>::radiusStr;
511 static constexpr
auto meshTypeStr =
512 json_type_traits<Json, NEM::NUCMESH::Ring>::meshTypeStr;
513 static constexpr
auto materialStr =
514 json_type_traits<Json, NEM::NUCMESH::Ring>::materialStr;
515 static constexpr
auto sidesetStr =
516 json_type_traits<Json, NEM::NUCMESH::Ring>::sidesetStr;
517 static constexpr
auto shapeTypeStr =
"Shape Type";
518 static constexpr
auto rotationStr =
"Rotation";
519 static bool is(
const Json &ajson) noexcept {
520 return ajson.template is<NEM::NUCMESH::Ring>() &&
521 ajson.contains(meshTypeStr);
523 static value_type as(
const Json &ajson) {
525 throw convert_error(convert_errc::conversion_failed,
526 "Not a NEM::NUCMESH::PolyRing");
528 ajson.at(shapeTypeStr).template as<decltype(value_type::shapeType)>(),
529 ajson.at(radiusStr).template as<decltype(value_type::radius)>(),
530 ajson.at(meshTypeStr).template as<decltype(value_type::meshType)>());
531 if (ajson.contains(rotationStr)) {
532 jsoncons::json_traits_helper<Json>::set_udt_member(ajson, rotationStr,
535 if (ajson.contains(materialStr)) {
536 jsoncons::json_traits_helper<Json>::set_udt_member(ajson, materialStr,
539 if (ajson.contains(sidesetStr)) {
540 jsoncons::json_traits_helper<Json>::set_udt_member(ajson, sidesetStr,
548 :
public std::true_type {};
554 constexpr
static auto savedObjectStr =
"Saved Objects";
555 constexpr
static auto savedObjectNameStr =
"Name";
556 constexpr
static auto extrudeStr =
"Extrude";
557 static bool is(
const Json &ajson) noexcept {
561 if (ajson.contains(savedObjectStr) && !ajson.at(savedObjectStr).is_array())
565 static value_type as(
const Json &ajson) {
569 throw convert_error(convert_errc::conversion_failed,
570 "Not a NEM::DRV::NucMeshDriver::Opts");
571 std::map<std::string, std::unique_ptr<ShapeBase>> savedObjects;
572 if (ajson.contains(savedObjectStr)) {
573 auto &savedObjectsJson = ajson.at(savedObjectStr);
574 for (
auto &savedObjectJson : savedObjectsJson.array_range()) {
575 if (savedObjectJson.contains(savedObjectNameStr)) {
576 savedObjects.emplace(
577 savedObjectJson.at(savedObjectNameStr).as_string_view(),
580 throw convert_error(convert_errc::conversion_failed,
581 "Not a NEM::DRV::NucMeshDriver");
587 aval.geometryAndMesh.emplace_back(
JSON::as_shape(shape, savedObjects));
589 if (ajson.contains(extrudeStr)) {
590 json_traits_helper<Json>::set_udt_member(ajson, extrudeStr,
598 :
public std::true_type {};
601 #endif // NEMOSYS_NUCMESHJSON_H_
void setEndAngle(double endAngle)
typename std::tuple_element< 0, typename function_traits< T >::argument_types >::type first_argument_type
const std::array< std::size_t, 2 > & getGridDims() const
void setPatternRowCol(int row, int col, std::size_t patternKey)
void setRings(std::vector< Ring > rings)
std::size_t getNumPatternShapes() const
std::enable_if< std::is_base_of< NEM::NUCMESH::ShapeBase, T >::value, void >::type modify_helper(const jsoncons::json &json, T &shape, const std::map< std::string, std::unique_ptr< NEM::NUCMESH::ShapeBase >> &savedShapes, bool checkRequired)
std::tuple< Args... > argument_types
Arrange a series of other ShapeBase objects along a circular arc.
void setGridDistance(const std::array< double, 2 > &gridDistance)
std::unique_ptr< NEM::NUCMESH::ShapeBase > construct_from_alias_helper(const jsoncons::json &json, const T *const aliasShape, const std::map< std::string, std::unique_ptr< NEM::NUCMESH::ShapeBase >> &savedShapes)
void setRotateWithArray(bool rotateWithArray)
static constexpr auto shapeType
void setNumSides(int numSides)
static std::array< double, 3 > getRotatedPoint(const std::array< double, 3 > ¢er, const std::array< double, 2 > &rotation)
void setPatternShape(std::size_t idx, const std::shared_ptr< ShapeBase > &shape)
#define NEM_JSON_N_GETTER_SETTER_NAME_TRAITS_FINAL(ValueType, ParentType, NumMandatoryParams,...)
Abstract base class for types that create NEM::GEO::GeoManager.
std::unique_ptr< NEM::NUCMESH::ShapeBase > construct_helper(const jsoncons::json &json, const std::map< std::string, std::unique_ptr< NEM::NUCMESH::ShapeBase >> &savedShapes)
std::unique_ptr< NEM::NUCMESH::ShapeBase > as_shape(const jsoncons::json &json, const std::map< std::string, std::unique_ptr< NEM::NUCMESH::ShapeBase >> &savedShapes)
void setGridDistance(double gridDistance)
static constexpr auto arrayShapes
static constexpr auto arrayPattern
void setCenter(const std::array< double, 3 > ¢er)
void setRings(std::vector< PolyRing > rings)
static constexpr const char * programType
std::unique_ptr< NEM::NUCMESH::ShapeBase > construct_from_alias(const jsoncons::json &json, const NEM::NUCMESH::ShapeBase *const aliasShape, const std::map< std::string, std::unique_ptr< NEM::NUCMESH::ShapeBase >> &savedShapes)
NEM::SRV::NucMeshConf Opts
void setRadius(double radius)
void setter_helper(T &obj, R(T::*setter)(Args...), const jsoncons::json &json, jsoncons::string_view key, bool checkContains)
A set of concentric circles and polygons and the faces they enclose.
static constexpr auto programType
std::tuple< Args... > argument_types
void setPattern(std::size_t x, std::size_t y, std::size_t patternKey)
The shape at [x, y] will be translated by [(x - (getGridDims()[0] - 1) / 2) * getGridDistance()[0]...
Abstract base class representing a set of other ShapeBase objects, with a transformation applied to e...
Class to create 2d geometry from polygons and circles and mesh it.
void setStartAngle(double startAngle)
static constexpr auto meshFiles
std::size_t getNumSubshapes() const
#define NEM_JSON_RDONLY_OVERRIDE(X)
std::tuple< Args... > argument_types
A set of concentric circles and the faces they enclose.
void setPattern(std::size_t idx, std::size_t patternKey)