@@ -24,6 +24,7 @@ namespace po = boost::program_options;
2424namespace std {
2525 istream& operator >>(istream& in, set<int >& ints);
2626 istream& operator >>(istream& in, set<string>& ints);
27+ istream& operator >>(istream& in, vector<double >& vs);
2728}
2829#endif
2930
@@ -43,7 +44,10 @@ namespace ifcopenshell {
4344 struct SettingBase {
4445 typedef T base_type;
4546
46- boost::optional<T> value;
47+ // boost program options does not seem to handle optional<vector> types, so in case
48+ // of vector settings we need to strip away the optional and detect argument presence
49+ // with !vector::empty()
50+ std::conditional_t <std::is_same_v<T, std::vector<double >>, T, boost::optional<T>> value;
4751
4852 SettingBase () {}
4953
@@ -59,24 +63,34 @@ namespace ifcopenshell {
5963 // @todo bool_switch doesn't work with optional unfortunately...
6064 value.emplace ();
6165 desc.add_options ()(Derived::name, apply_default (po::bool_switch (&*value)), Derived::description);
66+ } else if constexpr (std::is_same_v<T, std::vector<double >>) {
67+ desc.add_options ()(Derived::name, apply_default (po::value (&value)->multitoken ()), Derived::description);
6268 } else {
6369 desc.add_options ()(Derived::name, apply_default (po::value (&value)), Derived::description);
6470 }
6571 }
6672
6773 T get () const {
68- if (value) {
69- return value.get ();
70- }
71- if constexpr (HasDefault<Derived>()) {
72- return Derived::defaultvalue;
74+ if constexpr (std::is_same_v<T, std::vector<double >>) {
75+ return value;
76+ } else {
77+ if (value) {
78+ return value.get ();
79+ }
80+ if constexpr (HasDefault<Derived>()) {
81+ return Derived::defaultvalue;
82+ }
83+ throw std::runtime_error (" Setting not set" );
7384 }
74- throw std::runtime_error (" Setting not set" );
7585 }
7686
7787 bool has () const {
78- // @todo this is not reliable, better use vmap[...].defaulted()
79- return !!value;
88+ if constexpr (std::is_same_v<T, std::vector<double >>) {
89+ return !value.empty ();
90+ } else {
91+ // @todo this is not reliable, better use vmap[...].defaulted()
92+ return !!value;
93+ }
8094 }
8195 };
8296
@@ -354,12 +368,22 @@ namespace ifcopenshell {
354368 static constexpr const char * const description = " Indicates the parameter value for defining step size when evaluating piecewise curves." ;
355369 static constexpr double defaultvalue = 0.5 ; // ceiling of this value is used when PiecewiseStepMethod is MinSteps
356370 };
371+
372+ struct ModelOffset : public SettingBase <ModelOffset, std::vector<double >> {
373+ static constexpr const char * const name = " model-offset" ;
374+ static constexpr const char * const description = " Applies an arbitrary offset of form 'x,y,z' to all placements." ;
375+ };
376+
377+ struct ModelRotation : public SettingBase <ModelRotation, std::vector<double >> {
378+ static constexpr const char * const name = " model-rotation" ;
379+ static constexpr const char * const description = " Applies an arbitrary quaternion rotation of form 'x,y,z,w' to all placements." ;
380+ };
357381 }
358382
359383 template <typename settings_t >
360384 class IFC_GEOM_API SettingsContainer {
361385 public:
362- typedef boost::variant<bool , int , double , std::string, std::set<int >, std::set<std::string>, IteratorOutputOptions, PiecewiseStepMethod, OutputDimensionalityTypes> value_variant_t ;
386+ typedef boost::variant<bool , int , double , std::string, std::set<int >, std::set<std::string>, std::vector< double >, IteratorOutputOptions, PiecewiseStepMethod, OutputDimensionalityTypes> value_variant_t ;
363387 private:
364388 settings_t settings;
365389
@@ -446,7 +470,7 @@ namespace ifcopenshell {
446470 };
447471
448472 class IFC_GEOM_API Settings : public SettingsContainer<
449- std::tuple<MesherLinearDeflection, MesherAngularDeflection, ReorientShells, LengthUnit, PlaneUnit, Precision, OutputDimensionality, LayersetFirst, DisableBooleanResult, NoWireIntersectionCheck, NoWireIntersectionTolerance, PrecisionFactor, DebugBooleanOperations, BooleanAttempt2d, WeldVertices, UseWorldCoords, UseMaterialNames, ConvertBackUnits, ContextIds, ContextTypes, ContextIdentifiers, IteratorOutput, DisableOpeningSubtractions, ApplyDefaultMaterials, DontEmitNormals, GenerateUvs, ApplyLayerSets, UseElementHierarchy, ValidateQuantities, EdgeArrows, BuildingLocalPlacement, SiteLocalPlacement, ForceSpaceTransparency, CircleSegments, KeepBoundingBoxes, PiecewiseStepType, PiecewiseStepParam, NoParallelMapping>
473+ std::tuple<MesherLinearDeflection, MesherAngularDeflection, ReorientShells, LengthUnit, PlaneUnit, Precision, OutputDimensionality, LayersetFirst, DisableBooleanResult, NoWireIntersectionCheck, NoWireIntersectionTolerance, PrecisionFactor, DebugBooleanOperations, BooleanAttempt2d, WeldVertices, UseWorldCoords, UseMaterialNames, ConvertBackUnits, ContextIds, ContextTypes, ContextIdentifiers, IteratorOutput, DisableOpeningSubtractions, ApplyDefaultMaterials, DontEmitNormals, GenerateUvs, ApplyLayerSets, UseElementHierarchy, ValidateQuantities, EdgeArrows, BuildingLocalPlacement, SiteLocalPlacement, ForceSpaceTransparency, CircleSegments, KeepBoundingBoxes, PiecewiseStepType, PiecewiseStepParam, NoParallelMapping, ModelOffset, ModelRotation >
450474 >
451475 {};
452476}
0 commit comments