Zivid C++ API  2.4.2+1a2e8cfb-1
Defining the Future of 3D Machine Vision
Settings.h
Go to the documentation of this file.
1 
2 
3 /*******************************************************************************
4 
5  * This file is part of the Zivid 3D Camera API
6 
7  *
8 
9  * Copyright 2015-2021 (C) Zivid AS
10 
11  * All rights reserved.
12 
13  *
14 
15  * Zivid Software License, v1.0
16 
17  *
18 
19  * Redistribution and use in source and binary forms, with or without
20 
21  * modification, are permitted provided that the following conditions are met:
22 
23  *
24 
25  * 1. Redistributions of source code must retain the above copyright notice,
26 
27  * this list of conditions and the following disclaimer.
28 
29  *
30 
31  * 2. Redistributions in binary form must reproduce the above copyright notice,
32 
33  * this list of conditions and the following disclaimer in the documentation
34 
35  * and/or other materials provided with the distribution.
36 
37  *
38 
39  * 3. Neither the name of Zivid AS nor the names of its contributors may be used
40 
41  * to endorse or promote products derived from this software without specific
42 
43  * prior written permission.
44 
45  *
46 
47  * 4. This software, with or without modification, must not be used with any
48 
49  * other 3D camera than from Zivid AS.
50 
51  *
52 
53  * 5. Any software provided in binary form under this license must not be
54 
55  * reverse engineered, decompiled, modified and/or disassembled.
56 
57  *
58 
59  * THIS SOFTWARE IS PROVIDED BY ZIVID AS "AS IS" AND ANY EXPRESS OR IMPLIED
60 
61  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
62 
63  * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
64 
65  * DISCLAIMED. IN NO EVENT SHALL ZIVID AS OR CONTRIBUTORS BE LIABLE FOR ANY
66 
67  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68 
69  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70 
71  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
72 
73  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
74 
75  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76 
77  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78 
79  *
80 
81  * Contact: Zivid Customer Success Team <customersuccess@zivid.com>
82 
83  * Info: http://www.zivid.com
84 
85  ******************************************************************************/
86 
87 
88 
89 #pragma once
90 
91 #include <array>
92 #include <chrono>
93 #include <cmath>
94 #include <ctime>
95 #include <iomanip>
96 #include <memory>
97 #include <set>
98 #include <sstream>
99 #include <string>
100 #include <tuple>
101 #include <utility>
102 #include <vector>
103 
106 #include "Zivid/DataModel/Traits.h"
107 #include "Zivid/Detail/CoreExport.h"
108 #include "Zivid/Detail/TypeTraits.h"
109 #include "Zivid/Range.h"
110 
111 #ifdef _MSC_VER
112 # pragma warning(push)
113 # pragma warning(disable : 4251) // "X needs to have dll-interface to be used by clients of class Y."
114 #endif
115 
116 namespace Zivid
117 {
120  {
121  public:
123  static constexpr DataModel::NodeType nodeType = DataModel::NodeType::group;
124 
126  static constexpr const char *path{ "" };
127 
129  static constexpr const char *name{ "Settings" };
130 
132  static constexpr const char *description{
133  R"description(Settings used when capturing with a Zivid camera)description"
134  };
135 
136  static constexpr size_t version{ 8 };
137 
138 #ifndef NO_DOC
139  template<size_t>
140  struct Version;
141 
142  using LatestVersion = Zivid::Settings;
143 
144  // Short identifier. This value is not guaranteed to be universally unique
145  // Todo(ZIVID-2808): Move this to internal DataModelExt header
146  static constexpr std::array<uint8_t, 3> binaryId{ 's', 'e', 't' };
147 
148 #endif
149 
152  {
153  public:
155  static constexpr DataModel::NodeType nodeType = DataModel::NodeType::group;
156 
158  static constexpr const char *path{ "Acquisition" };
159 
161  static constexpr const char *name{ "Acquisition" };
162 
164  static constexpr const char *description{ R"description(Settings for a single acquisition)description" };
165 
170  {
171  public:
174 
176  static constexpr const char *path{ "Acquisition/Aperture" };
177 
179  static constexpr const char *name{ "Aperture" };
180 
182  static constexpr const char *description{
183  R"description(Aperture setting for the camera. Specified as an f-number (the ratio of lens focal length to
184 the effective aperture diameter).
185 )description"
186  };
187 
189  using ValueType = double;
190 
192  static constexpr Range<double> validRange()
193  {
194  return { 1.4, 32.0 };
195  }
196 
198  Aperture() = default;
199 
201  explicit constexpr Aperture(double value)
202  : m_opt{ verifyValue(value) }
203  {}
204 
209  double value() const;
210 
212  bool hasValue() const;
213 
215  void reset();
216 
218  std::string toString() const;
219 
221  bool operator==(const Aperture &other) const
222  {
223  return m_opt == other.m_opt;
224  }
225 
227  bool operator!=(const Aperture &other) const
228  {
229  return m_opt != other.m_opt;
230  }
231 
233  bool operator<(const Aperture &other) const
234  {
235  return m_opt < other.m_opt;
236  }
237 
239  bool operator>(const Aperture &other) const
240  {
241  return m_opt > other.m_opt;
242  }
243 
245  friend std::ostream &operator<<(std::ostream &stream, const Aperture &value)
246  {
247  return stream << value.toString();
248  }
249 
250  private:
251  void setFromString(const std::string &value);
252 
253  constexpr ValueType static verifyValue(const ValueType &value)
254  {
255  return validRange().isInRange(value)
256  ? value
257  : throw std::out_of_range{ "Aperture{ " + std::to_string(value) + " } is not in range ["
258  + std::to_string(validRange().min()) + ", "
259  + std::to_string(validRange().max()) + "]" };
260  }
261 
262  Zivid::DataModel::Detail::Optional<double> m_opt;
263 
264  friend struct DataModel::Detail::Befriend<Aperture>;
265  };
266 
281  {
282  public:
285 
287  static constexpr const char *path{ "Acquisition/Brightness" };
288 
290  static constexpr const char *name{ "Brightness" };
291 
293  static constexpr const char *description{
294  R"description(Brightness controls the light output from the projector.
295 
296 Brightness above 1.0 may be needed when the distance between the camera and the scene is large,
297 or in case of high levels of ambient lighting. Brightness above 1.0 is supported on Zivid One
298 Plus and Zivid Two.
299 
300 When brightness is above 1.0 the duty cycle of the camera (the percentage of time the camera
301 can capture) will be reduced. For Zivid One Plus the duty cycle in boost mode is 50%. For Zivid
302 Two the duty cycle is reduced linearly from 100% at brightness 1.0, to 50% at brightness 1.8.
303 The duty cycle is calculated over a 10 second period. This limitation is enforced automatically
304 by the camera. Calling capture when the duty cycle limit has been reached will cause the camera
305 to first wait (sleep) for a duration of time to cool down, before capture will start.
306 )description"
307  };
308 
310  using ValueType = double;
311 
313  static constexpr Range<double> validRange()
314  {
315  return { 0, 1.8 };
316  }
317 
319  Brightness() = default;
320 
322  explicit constexpr Brightness(double value)
323  : m_opt{ verifyValue(value) }
324  {}
325 
330  double value() const;
331 
333  bool hasValue() const;
334 
336  void reset();
337 
339  std::string toString() const;
340 
342  bool operator==(const Brightness &other) const
343  {
344  return m_opt == other.m_opt;
345  }
346 
348  bool operator!=(const Brightness &other) const
349  {
350  return m_opt != other.m_opt;
351  }
352 
354  bool operator<(const Brightness &other) const
355  {
356  return m_opt < other.m_opt;
357  }
358 
360  bool operator>(const Brightness &other) const
361  {
362  return m_opt > other.m_opt;
363  }
364 
366  friend std::ostream &operator<<(std::ostream &stream, const Brightness &value)
367  {
368  return stream << value.toString();
369  }
370 
371  private:
372  void setFromString(const std::string &value);
373 
374  constexpr ValueType static verifyValue(const ValueType &value)
375  {
376  return validRange().isInRange(value)
377  ? value
378  : throw std::out_of_range{ "Brightness{ " + std::to_string(value)
379  + " } is not in range [" + std::to_string(validRange().min())
380  + ", " + std::to_string(validRange().max()) + "]" };
381  }
382 
383  Zivid::DataModel::Detail::Optional<double> m_opt;
384 
385  friend struct DataModel::Detail::Befriend<Brightness>;
386  };
387 
390  {
391  public:
394 
396  static constexpr const char *path{ "Acquisition/ExposureTime" };
397 
399  static constexpr const char *name{ "ExposureTime" };
400 
402  static constexpr const char *description{
403  R"description(Exposure time for each single image in the measurement. Affects frame rate.)description"
404  };
405 
407  using ValueType = std::chrono::microseconds;
408 
411  {
412  return { std::chrono::microseconds{ 1677 }, std::chrono::microseconds{ 100000 } };
413  }
414 
416  ExposureTime() = default;
417 
419  explicit constexpr ExposureTime(std::chrono::microseconds value)
420  : m_opt{ verifyValue(value) }
421  {}
422 
427  std::chrono::microseconds value() const;
428 
430  bool hasValue() const;
431 
433  void reset();
434 
436  std::string toString() const;
437 
439  bool operator==(const ExposureTime &other) const
440  {
441  return m_opt == other.m_opt;
442  }
443 
445  bool operator!=(const ExposureTime &other) const
446  {
447  return m_opt != other.m_opt;
448  }
449 
451  bool operator<(const ExposureTime &other) const
452  {
453  return m_opt < other.m_opt;
454  }
455 
457  bool operator>(const ExposureTime &other) const
458  {
459  return m_opt > other.m_opt;
460  }
461 
463  friend std::ostream &operator<<(std::ostream &stream, const ExposureTime &value)
464  {
465  return stream << value.toString();
466  }
467 
468  private:
469  void setFromString(const std::string &value);
470 
471  constexpr ValueType static verifyValue(const ValueType &value)
472  {
473  return validRange().isInRange(value)
474  ? value
475  : throw std::out_of_range{ "ExposureTime{ " + std::to_string(value.count())
476  + " } is not in range ["
477  + std::to_string(validRange().min().count()) + ", "
478  + std::to_string(validRange().max().count()) + "]" };
479  }
480 
481  Zivid::DataModel::Detail::Optional<std::chrono::microseconds> m_opt;
482 
483  friend struct DataModel::Detail::Befriend<ExposureTime>;
484  };
485 
488  {
489  public:
492 
494  static constexpr const char *path{ "Acquisition/Gain" };
495 
497  static constexpr const char *name{ "Gain" };
498 
500  static constexpr const char *description{ R"description(Analog gain in the camera)description" };
501 
503  using ValueType = double;
504 
506  static constexpr Range<double> validRange()
507  {
508  return { 1, 16 };
509  }
510 
512  Gain() = default;
513 
515  explicit constexpr Gain(double value)
516  : m_opt{ verifyValue(value) }
517  {}
518 
523  double value() const;
524 
526  bool hasValue() const;
527 
529  void reset();
530 
532  std::string toString() const;
533 
535  bool operator==(const Gain &other) const
536  {
537  return m_opt == other.m_opt;
538  }
539 
541  bool operator!=(const Gain &other) const
542  {
543  return m_opt != other.m_opt;
544  }
545 
547  bool operator<(const Gain &other) const
548  {
549  return m_opt < other.m_opt;
550  }
551 
553  bool operator>(const Gain &other) const
554  {
555  return m_opt > other.m_opt;
556  }
557 
559  friend std::ostream &operator<<(std::ostream &stream, const Gain &value)
560  {
561  return stream << value.toString();
562  }
563 
564  private:
565  void setFromString(const std::string &value);
566 
567  constexpr ValueType static verifyValue(const ValueType &value)
568  {
569  return validRange().isInRange(value)
570  ? value
571  : throw std::out_of_range{ "Gain{ " + std::to_string(value) + " } is not in range ["
572  + std::to_string(validRange().min()) + ", "
573  + std::to_string(validRange().max()) + "]" };
574  }
575 
576  Zivid::DataModel::Detail::Optional<double> m_opt;
577 
578  friend struct DataModel::Detail::Befriend<Gain>;
579  };
580 
585 
588 
603 #ifndef NO_DOC
604  template<typename... Args,
605  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
606  typename std::enable_if<
607  Zivid::Detail::TypeTraits::AllArgsAreInTuple<Descendants,
608  typename std::decay<Args>::type...>::value,
609  int>::type = 0>
610 #else
611  template<typename... Args>
612 #endif
613  explicit Acquisition(Args &&...args)
614  {
615  using namespace Zivid::Detail::TypeTraits;
616 
617  static_assert(AllArgsDecayedAreUnique<Args...>::value,
618  "Found duplicate types among the arguments passed to Acquisition(...). "
619  "Types should be listed at most once.");
620 
621  set(std::forward<Args>(args)...);
622  }
623 
637 #ifndef NO_DOC
638  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
639 #else
640  template<typename... Args>
641 #endif
642  void set(Args &&...args)
643  {
644  using namespace Zivid::Detail::TypeTraits;
645 
646  using AllArgsAreDescendantNodes = AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
647  static_assert(AllArgsAreDescendantNodes::value,
648  "All arguments passed to set(...) must be descendant nodes.");
649 
650  static_assert(AllArgsDecayedAreUnique<Args...>::value,
651  "Found duplicate types among the arguments passed to set(...). "
652  "Types should be listed at most once.");
653 
654  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
655  }
656 
671 #ifndef NO_DOC
672  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
673 #else
674  template<typename... Args>
675 #endif
676  Acquisition copyWith(Args &&...args) const
677  {
678  using namespace Zivid::Detail::TypeTraits;
679 
680  using AllArgsAreDescendantNodes = AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
681  static_assert(AllArgsAreDescendantNodes::value,
682  "All arguments passed to copyWith(...) must be descendant nodes.");
683 
684  static_assert(AllArgsDecayedAreUnique<Args...>::value,
685  "Found duplicate types among the arguments passed to copyWith(...). "
686  "Types should be listed at most once.");
687 
688  auto copy{ *this };
689  copy.set(std::forward<Args>(args)...);
690  return copy;
691  }
692 
694  const Aperture &aperture() const
695  {
696  return m_aperture;
697  }
698 
701  {
702  return m_aperture;
703  }
704 
706  Acquisition &set(const Aperture &value)
707  {
708  m_aperture = value;
709  return *this;
710  }
711 
713  const Brightness &brightness() const
714  {
715  return m_brightness;
716  }
717 
720  {
721  return m_brightness;
722  }
723 
725  Acquisition &set(const Brightness &value)
726  {
727  m_brightness = value;
728  return *this;
729  }
730 
732  const ExposureTime &exposureTime() const
733  {
734  return m_exposureTime;
735  }
736 
739  {
740  return m_exposureTime;
741  }
742 
744  Acquisition &set(const ExposureTime &value)
745  {
746  m_exposureTime = value;
747  return *this;
748  }
749 
751  const Gain &gain() const
752  {
753  return m_gain;
754  }
755 
758  {
759  return m_gain;
760  }
761 
763  Acquisition &set(const Gain &value)
764  {
765  m_gain = value;
766  return *this;
767  }
768 
769  template<typename T,
770  typename std::enable_if<std::is_same<T, Settings::Acquisition::Aperture>::value, int>::type = 0>
772  {
773  return m_aperture;
774  }
775 
776  template<typename T,
777  typename std::enable_if<std::is_same<T, Settings::Acquisition::Brightness>::value, int>::type = 0>
779  {
780  return m_brightness;
781  }
782 
783  template<
784  typename T,
785  typename std::enable_if<std::is_same<T, Settings::Acquisition::ExposureTime>::value, int>::type = 0>
787  {
788  return m_exposureTime;
789  }
790 
791  template<typename T,
792  typename std::enable_if<std::is_same<T, Settings::Acquisition::Gain>::value, int>::type = 0>
794  {
795  return m_gain;
796  }
797 
798  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
800  {
801  return m_aperture;
802  }
803 
804  template<size_t i, typename std::enable_if<i == 1, int>::type = 0>
806  {
807  return m_brightness;
808  }
809 
810  template<size_t i, typename std::enable_if<i == 2, int>::type = 0>
812  {
813  return m_exposureTime;
814  }
815 
816  template<size_t i, typename std::enable_if<i == 3, int>::type = 0>
818  {
819  return m_gain;
820  }
821 
823  template<typename F>
824  void forEach(const F &f) const
825  {
826  f(m_aperture);
827  f(m_brightness);
828  f(m_exposureTime);
829  f(m_gain);
830  }
831 
833  template<typename F>
834  void forEach(const F &f)
835  {
836  f(m_aperture);
837  f(m_brightness);
838  f(m_exposureTime);
839  f(m_gain);
840  }
841 
843  bool operator==(const Acquisition &other) const;
844 
846  bool operator!=(const Acquisition &other) const;
847 
849  std::string toString() const;
850 
852  friend std::ostream &operator<<(std::ostream &stream, const Acquisition &value)
853  {
854  return stream << value.toString();
855  }
856 
857  private:
858  void setFromString(const std::string &value);
859 
860  void setFromString(const std::string &fullPath, const std::string &value);
861 
862  std::string getString(const std::string &fullPath) const;
863 
864  Aperture m_aperture;
865  Brightness m_brightness;
866  ExposureTime m_exposureTime;
867  Gain m_gain;
868 
869  friend struct DataModel::Detail::Befriend<Acquisition>;
870  };
871 
874  {
875  public:
878 
880  static constexpr const char *path{ "Acquisitions" };
881 
883  static constexpr const char *name{ "Acquisitions" };
884 
886  static constexpr const char *description{ R"description(List of Acquisition objects)description" };
887 
889  using ValueType = std::vector<Settings::Acquisition>;
890 
893  {
894  return { 0, std::numeric_limits<ValueType::size_type>::max() };
895  }
896 
898  Acquisitions() = default;
899 
901  explicit Acquisitions(std::vector<Settings::Acquisition> value)
902  : m_value{ std::move(value) }
903  {}
904 
906  explicit Acquisitions(std::initializer_list<Settings::Acquisition> value)
907  : Acquisitions{ ValueType{ value } }
908  {}
909 
911  const std::vector<Settings::Acquisition> &value() const;
912 
914  std::string toString() const;
915 
917  std::size_t size() const noexcept;
918 
920  bool isEmpty() const noexcept;
921 
927  template<typename... Args>
928  void emplaceBack(Args &&...args)
929  {
930  m_value.emplace_back(std::forward<Args>(args)...);
931  }
932 
938  Settings::Acquisition &at(std::size_t pos);
939 
945  const Settings::Acquisition &at(std::size_t pos) const;
946 
953 
959  const Settings::Acquisition &operator[](std::size_t pos) const;
960 
962  template<typename F>
963  void forEach(const F &f)
964  {
965  for(auto &child : m_value)
966  {
967  f(child);
968  }
969  }
970 
972  template<typename F>
973  void forEach(const F &f) const
974  {
975  for(const auto &child : m_value)
976  {
977  f(child);
978  }
979  }
980 
982  bool operator==(const Acquisitions &other) const
983  {
984  return m_value == other.m_value;
985  }
986 
988  bool operator!=(const Acquisitions &other) const
989  {
990  return m_value != other.m_value;
991  }
992 
994  friend std::ostream &operator<<(std::ostream &stream, const Acquisitions &value)
995  {
996  return stream << value.toString();
997  }
998 
999  private:
1000  void setFromString(const std::string &value);
1001 
1002  std::vector<Settings::Acquisition> m_value{};
1003 
1004  friend struct DataModel::Detail::Befriend<Acquisitions>;
1005  };
1006 
1009  {
1010  public:
1013 
1015  static constexpr const char *path{ "Experimental" };
1016 
1018  static constexpr const char *name{ "Experimental" };
1019 
1021  static constexpr const char *description{
1022  R"description(Experimental features. These settings may be changed, renamed, moved or deleted in the future.)description"
1023  };
1024 
1035  {
1036  public:
1039 
1041  static constexpr const char *path{ "Experimental/Engine" };
1042 
1044  static constexpr const char *name{ "Engine" };
1045 
1047  static constexpr const char *description{ R"description(Set the Zivid Vision Engine to use.
1048 
1049 The Phase Engine is the current default Zivid Vision Engine.
1050 
1051 The Stripe Engine uses anti-reflection technology to suppress interreflection artifacts
1052 and improve data quality on shiny objects like cylinders and chrome-plated parts.
1053 Additional acquisition and processing time are required for the Stripe Engine.
1054 The Stripe Engine is currently experimental, and may be changed and improved in the future.
1055 )description" };
1056 
1058  enum class ValueType
1059  {
1060  phase,
1061  stripe
1062  };
1063  static const Engine phase;
1064  static const Engine stripe;
1065 
1067  static std::set<ValueType> validValues()
1068  {
1069  return { ValueType::phase, ValueType::stripe };
1070  }
1071 
1073  Engine() = default;
1074 
1076  explicit constexpr Engine(ValueType value)
1077  : m_opt{ verifyValue(value) }
1078  {}
1079 
1084  ValueType value() const;
1085 
1087  bool hasValue() const;
1088 
1090  void reset();
1091 
1093  std::string toString() const;
1094 
1096  friend std::ostream &operator<<(std::ostream &stream, const Engine::ValueType &value)
1097  {
1098  return stream << Engine{ value }.toString();
1099  }
1100 
1102  bool operator==(const Engine &other) const
1103  {
1104  return m_opt == other.m_opt;
1105  }
1106 
1108  bool operator!=(const Engine &other) const
1109  {
1110  return m_opt != other.m_opt;
1111  }
1112 
1114  friend std::ostream &operator<<(std::ostream &stream, const Engine &value)
1115  {
1116  return stream << value.toString();
1117  }
1118 
1119  private:
1120  void setFromString(const std::string &value);
1121 
1122  constexpr ValueType static verifyValue(const ValueType &value)
1123  {
1124  return value == ValueType::phase || value == ValueType::stripe
1125  ? value
1126  : throw std::invalid_argument{
1127  "Invalid value: Engine{ "
1128  + std::to_string(static_cast<std::underlying_type<ValueType>::type>(value)) + " }"
1129  };
1130  }
1131 
1132  Zivid::DataModel::Detail::Optional<ValueType> m_opt;
1133 
1134  friend struct DataModel::Detail::Befriend<Engine>;
1135  };
1136 
1137  using Descendants = std::tuple<Settings::Experimental::Engine>;
1138 
1141 
1153 #ifndef NO_DOC
1154  template<typename... Args,
1155  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
1156  typename std::enable_if<
1157  Zivid::Detail::TypeTraits::AllArgsAreInTuple<Descendants,
1158  typename std::decay<Args>::type...>::value,
1159  int>::type = 0>
1160 #else
1161  template<typename... Args>
1162 #endif
1163  explicit Experimental(Args &&...args)
1164  {
1165  using namespace Zivid::Detail::TypeTraits;
1166 
1167  static_assert(AllArgsDecayedAreUnique<Args...>::value,
1168  "Found duplicate types among the arguments passed to Experimental(...). "
1169  "Types should be listed at most once.");
1170 
1171  set(std::forward<Args>(args)...);
1172  }
1173 
1184 #ifndef NO_DOC
1185  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
1186 #else
1187  template<typename... Args>
1188 #endif
1189  void set(Args &&...args)
1190  {
1191  using namespace Zivid::Detail::TypeTraits;
1192 
1193  using AllArgsAreDescendantNodes = AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
1194  static_assert(AllArgsAreDescendantNodes::value,
1195  "All arguments passed to set(...) must be descendant nodes.");
1196 
1197  static_assert(AllArgsDecayedAreUnique<Args...>::value,
1198  "Found duplicate types among the arguments passed to set(...). "
1199  "Types should be listed at most once.");
1200 
1201  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
1202  }
1203 
1215 #ifndef NO_DOC
1216  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
1217 #else
1218  template<typename... Args>
1219 #endif
1220  Experimental copyWith(Args &&...args) const
1221  {
1222  using namespace Zivid::Detail::TypeTraits;
1223 
1224  using AllArgsAreDescendantNodes = AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
1225  static_assert(AllArgsAreDescendantNodes::value,
1226  "All arguments passed to copyWith(...) must be descendant nodes.");
1227 
1228  static_assert(AllArgsDecayedAreUnique<Args...>::value,
1229  "Found duplicate types among the arguments passed to copyWith(...). "
1230  "Types should be listed at most once.");
1231 
1232  auto copy{ *this };
1233  copy.set(std::forward<Args>(args)...);
1234  return copy;
1235  }
1236 
1238  const Engine &engine() const
1239  {
1240  return m_engine;
1241  }
1242 
1245  {
1246  return m_engine;
1247  }
1248 
1250  Experimental &set(const Engine &value)
1251  {
1252  m_engine = value;
1253  return *this;
1254  }
1255 
1256  template<typename T,
1257  typename std::enable_if<std::is_same<T, Settings::Experimental::Engine>::value, int>::type = 0>
1259  {
1260  return m_engine;
1261  }
1262 
1263  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
1265  {
1266  return m_engine;
1267  }
1268 
1270  template<typename F>
1271  void forEach(const F &f) const
1272  {
1273  f(m_engine);
1274  }
1275 
1277  template<typename F>
1278  void forEach(const F &f)
1279  {
1280  f(m_engine);
1281  }
1282 
1284  bool operator==(const Experimental &other) const;
1285 
1287  bool operator!=(const Experimental &other) const;
1288 
1290  std::string toString() const;
1291 
1293  friend std::ostream &operator<<(std::ostream &stream, const Experimental &value)
1294  {
1295  return stream << value.toString();
1296  }
1297 
1298  private:
1299  void setFromString(const std::string &value);
1300 
1301  void setFromString(const std::string &fullPath, const std::string &value);
1302 
1303  std::string getString(const std::string &fullPath) const;
1304 
1305  Engine m_engine;
1306 
1307  friend struct DataModel::Detail::Befriend<Experimental>;
1308  };
1309 
1312  {
1313  public:
1316 
1318  static constexpr const char *path{ "Processing" };
1319 
1321  static constexpr const char *name{ "Processing" };
1322 
1324  static constexpr const char *description{
1325  R"description(Settings related to processing of a capture, including filters and color balance)description"
1326  };
1327 
1330  {
1331  public:
1334 
1336  static constexpr const char *path{ "Processing/Color" };
1337 
1339  static constexpr const char *name{ "Color" };
1340 
1342  static constexpr const char *description{ R"description(Color settings)description" };
1343 
1346  {
1347  public:
1350 
1352  static constexpr const char *path{ "Processing/Color/Balance" };
1353 
1355  static constexpr const char *name{ "Balance" };
1356 
1358  static constexpr const char *description{ R"description(Color balance settings)description" };
1359 
1362  {
1363  public:
1366 
1368  static constexpr const char *path{ "Processing/Color/Balance/Blue" };
1369 
1371  static constexpr const char *name{ "Blue" };
1372 
1374  static constexpr const char *description{
1375  R"description(Digital gain applied to blue channel)description"
1376  };
1377 
1379  using ValueType = double;
1380 
1382  static constexpr Range<double> validRange()
1383  {
1384  return { 1.0, 8.0 };
1385  }
1386 
1388  Blue() = default;
1389 
1391  explicit constexpr Blue(double value)
1392  : m_opt{ verifyValue(value) }
1393  {}
1394 
1399  double value() const;
1400 
1402  bool hasValue() const;
1403 
1405  void reset();
1406 
1408  std::string toString() const;
1409 
1411  bool operator==(const Blue &other) const
1412  {
1413  return m_opt == other.m_opt;
1414  }
1415 
1417  bool operator!=(const Blue &other) const
1418  {
1419  return m_opt != other.m_opt;
1420  }
1421 
1423  bool operator<(const Blue &other) const
1424  {
1425  return m_opt < other.m_opt;
1426  }
1427 
1429  bool operator>(const Blue &other) const
1430  {
1431  return m_opt > other.m_opt;
1432  }
1433 
1435  friend std::ostream &operator<<(std::ostream &stream, const Blue &value)
1436  {
1437  return stream << value.toString();
1438  }
1439 
1440  private:
1441  void setFromString(const std::string &value);
1442 
1443  constexpr ValueType static verifyValue(const ValueType &value)
1444  {
1445  return validRange().isInRange(value)
1446  ? value
1447  : throw std::out_of_range{ "Blue{ " + std::to_string(value)
1448  + " } is not in range ["
1449  + std::to_string(validRange().min()) + ", "
1450  + std::to_string(validRange().max()) + "]" };
1451  }
1452 
1453  Zivid::DataModel::Detail::Optional<double> m_opt;
1454 
1455  friend struct DataModel::Detail::Befriend<Blue>;
1456  };
1457 
1460  {
1461  public:
1464 
1466  static constexpr const char *path{ "Processing/Color/Balance/Green" };
1467 
1469  static constexpr const char *name{ "Green" };
1470 
1472  static constexpr const char *description{
1473  R"description(Digital gain applied to green channel)description"
1474  };
1475 
1477  using ValueType = double;
1478 
1480  static constexpr Range<double> validRange()
1481  {
1482  return { 1.0, 8.0 };
1483  }
1484 
1486  Green() = default;
1487 
1489  explicit constexpr Green(double value)
1490  : m_opt{ verifyValue(value) }
1491  {}
1492 
1497  double value() const;
1498 
1500  bool hasValue() const;
1501 
1503  void reset();
1504 
1506  std::string toString() const;
1507 
1509  bool operator==(const Green &other) const
1510  {
1511  return m_opt == other.m_opt;
1512  }
1513 
1515  bool operator!=(const Green &other) const
1516  {
1517  return m_opt != other.m_opt;
1518  }
1519 
1521  bool operator<(const Green &other) const
1522  {
1523  return m_opt < other.m_opt;
1524  }
1525 
1527  bool operator>(const Green &other) const
1528  {
1529  return m_opt > other.m_opt;
1530  }
1531 
1533  friend std::ostream &operator<<(std::ostream &stream, const Green &value)
1534  {
1535  return stream << value.toString();
1536  }
1537 
1538  private:
1539  void setFromString(const std::string &value);
1540 
1541  constexpr ValueType static verifyValue(const ValueType &value)
1542  {
1543  return validRange().isInRange(value)
1544  ? value
1545  : throw std::out_of_range{ "Green{ " + std::to_string(value)
1546  + " } is not in range ["
1547  + std::to_string(validRange().min()) + ", "
1548  + std::to_string(validRange().max()) + "]" };
1549  }
1550 
1551  Zivid::DataModel::Detail::Optional<double> m_opt;
1552 
1553  friend struct DataModel::Detail::Befriend<Green>;
1554  };
1555 
1558  {
1559  public:
1562 
1564  static constexpr const char *path{ "Processing/Color/Balance/Red" };
1565 
1567  static constexpr const char *name{ "Red" };
1568 
1570  static constexpr const char *description{
1571  R"description(Digital gain applied to red channel)description"
1572  };
1573 
1575  using ValueType = double;
1576 
1578  static constexpr Range<double> validRange()
1579  {
1580  return { 1.0, 8.0 };
1581  }
1582 
1584  Red() = default;
1585 
1587  explicit constexpr Red(double value)
1588  : m_opt{ verifyValue(value) }
1589  {}
1590 
1595  double value() const;
1596 
1598  bool hasValue() const;
1599 
1601  void reset();
1602 
1604  std::string toString() const;
1605 
1607  bool operator==(const Red &other) const
1608  {
1609  return m_opt == other.m_opt;
1610  }
1611 
1613  bool operator!=(const Red &other) const
1614  {
1615  return m_opt != other.m_opt;
1616  }
1617 
1619  bool operator<(const Red &other) const
1620  {
1621  return m_opt < other.m_opt;
1622  }
1623 
1625  bool operator>(const Red &other) const
1626  {
1627  return m_opt > other.m_opt;
1628  }
1629 
1631  friend std::ostream &operator<<(std::ostream &stream, const Red &value)
1632  {
1633  return stream << value.toString();
1634  }
1635 
1636  private:
1637  void setFromString(const std::string &value);
1638 
1639  constexpr ValueType static verifyValue(const ValueType &value)
1640  {
1641  return validRange().isInRange(value)
1642  ? value
1643  : throw std::out_of_range{ "Red{ " + std::to_string(value)
1644  + " } is not in range ["
1645  + std::to_string(validRange().min()) + ", "
1646  + std::to_string(validRange().max()) + "]" };
1647  }
1648 
1649  Zivid::DataModel::Detail::Optional<double> m_opt;
1650 
1651  friend struct DataModel::Detail::Befriend<Red>;
1652  };
1653 
1657 
1660 
1674 #ifndef NO_DOC
1675  template<typename... Args,
1676  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
1677  typename std::enable_if<Zivid::Detail::TypeTraits::AllArgsAreInTuple<
1678  Descendants,
1679  typename std::decay<Args>::type...>::value,
1680  int>::type = 0>
1681 #else
1682  template<typename... Args>
1683 #endif
1684  explicit Balance(Args &&...args)
1685  {
1686  using namespace Zivid::Detail::TypeTraits;
1687 
1688  static_assert(AllArgsDecayedAreUnique<Args...>::value,
1689  "Found duplicate types among the arguments passed to Balance(...). "
1690  "Types should be listed at most once.");
1691 
1692  set(std::forward<Args>(args)...);
1693  }
1694 
1707 #ifndef NO_DOC
1708  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
1709 #else
1710  template<typename... Args>
1711 #endif
1712  void set(Args &&...args)
1713  {
1714  using namespace Zivid::Detail::TypeTraits;
1715 
1716  using AllArgsAreDescendantNodes =
1717  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
1718  static_assert(AllArgsAreDescendantNodes::value,
1719  "All arguments passed to set(...) must be descendant nodes.");
1720 
1721  static_assert(AllArgsDecayedAreUnique<Args...>::value,
1722  "Found duplicate types among the arguments passed to set(...). "
1723  "Types should be listed at most once.");
1724 
1725  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
1726  }
1727 
1741 #ifndef NO_DOC
1742  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
1743 #else
1744  template<typename... Args>
1745 #endif
1746  Balance copyWith(Args &&...args) const
1747  {
1748  using namespace Zivid::Detail::TypeTraits;
1749 
1750  using AllArgsAreDescendantNodes =
1751  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
1752  static_assert(AllArgsAreDescendantNodes::value,
1753  "All arguments passed to copyWith(...) must be descendant nodes.");
1754 
1755  static_assert(AllArgsDecayedAreUnique<Args...>::value,
1756  "Found duplicate types among the arguments passed to copyWith(...). "
1757  "Types should be listed at most once.");
1758 
1759  auto copy{ *this };
1760  copy.set(std::forward<Args>(args)...);
1761  return copy;
1762  }
1763 
1765  const Blue &blue() const
1766  {
1767  return m_blue;
1768  }
1769 
1772  {
1773  return m_blue;
1774  }
1775 
1777  Balance &set(const Blue &value)
1778  {
1779  m_blue = value;
1780  return *this;
1781  }
1782 
1784  const Green &green() const
1785  {
1786  return m_green;
1787  }
1788 
1791  {
1792  return m_green;
1793  }
1794 
1796  Balance &set(const Green &value)
1797  {
1798  m_green = value;
1799  return *this;
1800  }
1801 
1803  const Red &red() const
1804  {
1805  return m_red;
1806  }
1807 
1810  {
1811  return m_red;
1812  }
1813 
1815  Balance &set(const Red &value)
1816  {
1817  m_red = value;
1818  return *this;
1819  }
1820 
1821  template<typename T,
1822  typename std::enable_if<std::is_same<T, Settings::Processing::Color::Balance::Blue>::value,
1823  int>::type = 0>
1825  {
1826  return m_blue;
1827  }
1828 
1829  template<
1830  typename T,
1831  typename std::enable_if<std::is_same<T, Settings::Processing::Color::Balance::Green>::value,
1832  int>::type = 0>
1834  {
1835  return m_green;
1836  }
1837 
1838  template<typename T,
1839  typename std::enable_if<std::is_same<T, Settings::Processing::Color::Balance::Red>::value,
1840  int>::type = 0>
1842  {
1843  return m_red;
1844  }
1845 
1846  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
1848  {
1849  return m_blue;
1850  }
1851 
1852  template<size_t i, typename std::enable_if<i == 1, int>::type = 0>
1854  {
1855  return m_green;
1856  }
1857 
1858  template<size_t i, typename std::enable_if<i == 2, int>::type = 0>
1860  {
1861  return m_red;
1862  }
1863 
1865  template<typename F>
1866  void forEach(const F &f) const
1867  {
1868  f(m_blue);
1869  f(m_green);
1870  f(m_red);
1871  }
1872 
1874  template<typename F>
1875  void forEach(const F &f)
1876  {
1877  f(m_blue);
1878  f(m_green);
1879  f(m_red);
1880  }
1881 
1883  bool operator==(const Balance &other) const;
1884 
1886  bool operator!=(const Balance &other) const;
1887 
1889  std::string toString() const;
1890 
1892  friend std::ostream &operator<<(std::ostream &stream, const Balance &value)
1893  {
1894  return stream << value.toString();
1895  }
1896 
1897  private:
1898  void setFromString(const std::string &value);
1899 
1900  void setFromString(const std::string &fullPath, const std::string &value);
1901 
1902  std::string getString(const std::string &fullPath) const;
1903 
1904  Blue m_blue;
1905  Green m_green;
1906  Red m_red;
1907 
1908  friend struct DataModel::Detail::Befriend<Balance>;
1909  };
1910 
1913  {
1914  public:
1917 
1919  static constexpr const char *path{ "Processing/Color/Experimental" };
1920 
1922  static constexpr const char *name{ "Experimental" };
1923 
1925  static constexpr const char *description{
1926  R"description(Experimental color settings. These may be renamed, moved or deleted in the future.)description"
1927  };
1928 
1931  {
1932  public:
1935 
1937  static constexpr const char *path{ "Processing/Color/Experimental/ToneMapping" };
1938 
1940  static constexpr const char *name{ "ToneMapping" };
1941 
1943  static constexpr const char *description{ R"description(Tonemapping settings.)description" };
1944 
1955  {
1956  public:
1959 
1961  static constexpr const char *path{ "Processing/Color/Experimental/ToneMapping/Enabled" };
1962 
1964  static constexpr const char *name{ "Enabled" };
1965 
1967  static constexpr const char *description{
1968  R"description(This setting controls when tone mapping of colors is performed. Tone mapping will normalize
1969 the captured color image to the full available output range by applying a gain factor to the
1970 colors. For single-captures this can be used do brighten dark images. For HDR captures this
1971 is required to map high-dynamic-range colors to the more limited dynamic range output.
1972 
1973 This setting has two possible values. `Always` will perform tone-mapping for all captures.
1974 `HdrOnly` will perform tone mapping for HDR captures but not for single-captures. It is not
1975 possible to disable tone mapping for HDR captures.
1976 )description"
1977  };
1978 
1980  enum class ValueType
1981  {
1982  always,
1983  hdrOnly
1984  };
1985  static const Enabled always;
1986  static const Enabled hdrOnly;
1987 
1989  static std::set<ValueType> validValues()
1990  {
1991  return { ValueType::always, ValueType::hdrOnly };
1992  }
1993 
1995  Enabled() = default;
1996 
1998  explicit constexpr Enabled(ValueType value)
1999  : m_opt{ verifyValue(value) }
2000  {}
2001 
2006  ValueType value() const;
2007 
2009  bool hasValue() const;
2010 
2012  void reset();
2013 
2015  std::string toString() const;
2016 
2018  friend std::ostream &operator<<(std::ostream &stream, const Enabled::ValueType &value)
2019  {
2020  return stream << Enabled{ value }.toString();
2021  }
2022 
2024  bool operator==(const Enabled &other) const
2025  {
2026  return m_opt == other.m_opt;
2027  }
2028 
2030  bool operator!=(const Enabled &other) const
2031  {
2032  return m_opt != other.m_opt;
2033  }
2034 
2036  friend std::ostream &operator<<(std::ostream &stream, const Enabled &value)
2037  {
2038  return stream << value.toString();
2039  }
2040 
2041  private:
2042  void setFromString(const std::string &value);
2043 
2044  constexpr ValueType static verifyValue(const ValueType &value)
2045  {
2046  return value == ValueType::always || value == ValueType::hdrOnly
2047  ? value
2048  : throw std::invalid_argument{
2049  "Invalid value: Enabled{ "
2050  + std::to_string(
2051  static_cast<std::underlying_type<ValueType>::type>(value))
2052  + " }"
2053  };
2054  }
2055 
2056  Zivid::DataModel::Detail::Optional<ValueType> m_opt;
2057 
2058  friend struct DataModel::Detail::Befriend<Enabled>;
2059  };
2060 
2061  using Descendants = std::tuple<Settings::Processing::Color::Experimental::ToneMapping::Enabled>;
2062 
2065 
2077 #ifndef NO_DOC
2078  template<typename... Args,
2079  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
2080  typename std::enable_if<Zivid::Detail::TypeTraits::AllArgsAreInTuple<
2081  Descendants,
2082  typename std::decay<Args>::type...>::value,
2083  int>::type = 0>
2084 #else
2085  template<typename... Args>
2086 #endif
2087  explicit ToneMapping(Args &&...args)
2088  {
2089  using namespace Zivid::Detail::TypeTraits;
2090 
2091  static_assert(AllArgsDecayedAreUnique<Args...>::value,
2092  "Found duplicate types among the arguments passed to ToneMapping(...). "
2093  "Types should be listed at most once.");
2094 
2095  set(std::forward<Args>(args)...);
2096  }
2097 
2108 #ifndef NO_DOC
2109  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
2110 #else
2111  template<typename... Args>
2112 #endif
2113  void set(Args &&...args)
2114  {
2115  using namespace Zivid::Detail::TypeTraits;
2116 
2117  using AllArgsAreDescendantNodes =
2118  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
2119  static_assert(AllArgsAreDescendantNodes::value,
2120  "All arguments passed to set(...) must be descendant nodes.");
2121 
2122  static_assert(AllArgsDecayedAreUnique<Args...>::value,
2123  "Found duplicate types among the arguments passed to set(...). "
2124  "Types should be listed at most once.");
2125 
2126  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
2127  }
2128 
2140 #ifndef NO_DOC
2141  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
2142 #else
2143  template<typename... Args>
2144 #endif
2145  ToneMapping copyWith(Args &&...args) const
2146  {
2147  using namespace Zivid::Detail::TypeTraits;
2148 
2149  using AllArgsAreDescendantNodes =
2150  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
2151  static_assert(AllArgsAreDescendantNodes::value,
2152  "All arguments passed to copyWith(...) must be descendant nodes.");
2153 
2154  static_assert(AllArgsDecayedAreUnique<Args...>::value,
2155  "Found duplicate types among the arguments passed to copyWith(...). "
2156  "Types should be listed at most once.");
2157 
2158  auto copy{ *this };
2159  copy.set(std::forward<Args>(args)...);
2160  return copy;
2161  }
2162 
2164  const Enabled &isEnabled() const
2165  {
2166  return m_enabled;
2167  }
2168 
2171  {
2172  return m_enabled;
2173  }
2174 
2176  ToneMapping &set(const Enabled &value)
2177  {
2178  m_enabled = value;
2179  return *this;
2180  }
2181 
2182  template<
2183  typename T,
2184  typename std::enable_if<
2185  std::is_same<T, Settings::Processing::Color::Experimental::ToneMapping::Enabled>::value,
2186  int>::type = 0>
2188  {
2189  return m_enabled;
2190  }
2191 
2192  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
2194  {
2195  return m_enabled;
2196  }
2197 
2199  template<typename F>
2200  void forEach(const F &f) const
2201  {
2202  f(m_enabled);
2203  }
2204 
2206  template<typename F>
2207  void forEach(const F &f)
2208  {
2209  f(m_enabled);
2210  }
2211 
2213  bool operator==(const ToneMapping &other) const;
2214 
2216  bool operator!=(const ToneMapping &other) const;
2217 
2219  std::string toString() const;
2220 
2222  friend std::ostream &operator<<(std::ostream &stream, const ToneMapping &value)
2223  {
2224  return stream << value.toString();
2225  }
2226 
2227  private:
2228  void setFromString(const std::string &value);
2229 
2230  void setFromString(const std::string &fullPath, const std::string &value);
2231 
2232  std::string getString(const std::string &fullPath) const;
2233 
2234  Enabled m_enabled;
2235 
2236  friend struct DataModel::Detail::Befriend<ToneMapping>;
2237  };
2238 
2241 
2244 
2257 #ifndef NO_DOC
2258  template<typename... Args,
2259  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
2260  typename std::enable_if<Zivid::Detail::TypeTraits::AllArgsAreInTuple<
2261  Descendants,
2262  typename std::decay<Args>::type...>::value,
2263  int>::type = 0>
2264 #else
2265  template<typename... Args>
2266 #endif
2267  explicit Experimental(Args &&...args)
2268  {
2269  using namespace Zivid::Detail::TypeTraits;
2270 
2271  static_assert(AllArgsDecayedAreUnique<Args...>::value,
2272  "Found duplicate types among the arguments passed to Experimental(...). "
2273  "Types should be listed at most once.");
2274 
2275  set(std::forward<Args>(args)...);
2276  }
2277 
2289 #ifndef NO_DOC
2290  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
2291 #else
2292  template<typename... Args>
2293 #endif
2294  void set(Args &&...args)
2295  {
2296  using namespace Zivid::Detail::TypeTraits;
2297 
2298  using AllArgsAreDescendantNodes =
2299  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
2300  static_assert(AllArgsAreDescendantNodes::value,
2301  "All arguments passed to set(...) must be descendant nodes.");
2302 
2303  static_assert(AllArgsDecayedAreUnique<Args...>::value,
2304  "Found duplicate types among the arguments passed to set(...). "
2305  "Types should be listed at most once.");
2306 
2307  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
2308  }
2309 
2322 #ifndef NO_DOC
2323  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
2324 #else
2325  template<typename... Args>
2326 #endif
2327  Experimental copyWith(Args &&...args) const
2328  {
2329  using namespace Zivid::Detail::TypeTraits;
2330 
2331  using AllArgsAreDescendantNodes =
2332  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
2333  static_assert(AllArgsAreDescendantNodes::value,
2334  "All arguments passed to copyWith(...) must be descendant nodes.");
2335 
2336  static_assert(AllArgsDecayedAreUnique<Args...>::value,
2337  "Found duplicate types among the arguments passed to copyWith(...). "
2338  "Types should be listed at most once.");
2339 
2340  auto copy{ *this };
2341  copy.set(std::forward<Args>(args)...);
2342  return copy;
2343  }
2344 
2346  const ToneMapping &toneMapping() const
2347  {
2348  return m_toneMapping;
2349  }
2350 
2353  {
2354  return m_toneMapping;
2355  }
2356 
2359  {
2360  m_toneMapping = value;
2361  return *this;
2362  }
2363 
2366  {
2367  m_toneMapping.set(value);
2368  return *this;
2369  }
2370 
2371  template<typename T,
2372  typename std::enable_if<
2373  std::is_same<T, Settings::Processing::Color::Experimental::ToneMapping>::value,
2374  int>::type = 0>
2376  {
2377  return m_toneMapping;
2378  }
2379 
2380  template<
2381  typename T,
2382  typename std::enable_if<
2383  std::is_same<T, Settings::Processing::Color::Experimental::ToneMapping::Enabled>::value,
2384  int>::type = 0>
2386  {
2388  }
2389 
2390  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
2392  {
2393  return m_toneMapping;
2394  }
2395 
2397  template<typename F>
2398  void forEach(const F &f) const
2399  {
2400  f(m_toneMapping);
2401  }
2402 
2404  template<typename F>
2405  void forEach(const F &f)
2406  {
2407  f(m_toneMapping);
2408  }
2409 
2411  bool operator==(const Experimental &other) const;
2412 
2414  bool operator!=(const Experimental &other) const;
2415 
2417  std::string toString() const;
2418 
2420  friend std::ostream &operator<<(std::ostream &stream, const Experimental &value)
2421  {
2422  return stream << value.toString();
2423  }
2424 
2425  private:
2426  void setFromString(const std::string &value);
2427 
2428  void setFromString(const std::string &fullPath, const std::string &value);
2429 
2430  std::string getString(const std::string &fullPath) const;
2431 
2432  ToneMapping m_toneMapping;
2433 
2434  friend struct DataModel::Detail::Befriend<Experimental>;
2435  };
2436 
2441  {
2442  public:
2445 
2447  static constexpr const char *path{ "Processing/Color/Gamma" };
2448 
2450  static constexpr const char *name{ "Gamma" };
2451 
2453  static constexpr const char *description{
2454  R"description(Gamma applied to the color values. Gamma less than 1 makes the colors brighter, while gamma
2455 greater than 1 makes the colors darker.
2456 )description"
2457  };
2458 
2460  using ValueType = double;
2461 
2463  static constexpr Range<double> validRange()
2464  {
2465  return { 0.25, 1.5 };
2466  }
2467 
2469  Gamma() = default;
2470 
2472  explicit constexpr Gamma(double value)
2473  : m_opt{ verifyValue(value) }
2474  {}
2475 
2480  double value() const;
2481 
2483  bool hasValue() const;
2484 
2486  void reset();
2487 
2489  std::string toString() const;
2490 
2492  bool operator==(const Gamma &other) const
2493  {
2494  return m_opt == other.m_opt;
2495  }
2496 
2498  bool operator!=(const Gamma &other) const
2499  {
2500  return m_opt != other.m_opt;
2501  }
2502 
2504  bool operator<(const Gamma &other) const
2505  {
2506  return m_opt < other.m_opt;
2507  }
2508 
2510  bool operator>(const Gamma &other) const
2511  {
2512  return m_opt > other.m_opt;
2513  }
2514 
2516  friend std::ostream &operator<<(std::ostream &stream, const Gamma &value)
2517  {
2518  return stream << value.toString();
2519  }
2520 
2521  private:
2522  void setFromString(const std::string &value);
2523 
2524  constexpr ValueType static verifyValue(const ValueType &value)
2525  {
2526  return validRange().isInRange(value)
2527  ? value
2528  : throw std::out_of_range{ "Gamma{ " + std::to_string(value) + " } is not in range ["
2529  + std::to_string(validRange().min()) + ", "
2530  + std::to_string(validRange().max()) + "]" };
2531  }
2532 
2533  Zivid::DataModel::Detail::Optional<double> m_opt;
2534 
2535  friend struct DataModel::Detail::Befriend<Gamma>;
2536  };
2537 
2546 
2549 
2568 #ifndef NO_DOC
2569  template<typename... Args,
2570  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
2571  typename std::enable_if<
2572  Zivid::Detail::TypeTraits::AllArgsAreInTuple<Descendants,
2573  typename std::decay<Args>::type...>::value,
2574  int>::type = 0>
2575 #else
2576  template<typename... Args>
2577 #endif
2578  explicit Color(Args &&...args)
2579  {
2580  using namespace Zivid::Detail::TypeTraits;
2581 
2582  static_assert(AllArgsDecayedAreUnique<Args...>::value,
2583  "Found duplicate types among the arguments passed to Color(...). "
2584  "Types should be listed at most once.");
2585 
2586  set(std::forward<Args>(args)...);
2587  }
2588 
2606 #ifndef NO_DOC
2607  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
2608 #else
2609  template<typename... Args>
2610 #endif
2611  void set(Args &&...args)
2612  {
2613  using namespace Zivid::Detail::TypeTraits;
2614 
2615  using AllArgsAreDescendantNodes =
2616  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
2617  static_assert(AllArgsAreDescendantNodes::value,
2618  "All arguments passed to set(...) must be descendant nodes.");
2619 
2620  static_assert(AllArgsDecayedAreUnique<Args...>::value,
2621  "Found duplicate types among the arguments passed to set(...). "
2622  "Types should be listed at most once.");
2623 
2624  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
2625  }
2626 
2645 #ifndef NO_DOC
2646  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
2647 #else
2648  template<typename... Args>
2649 #endif
2650  Color copyWith(Args &&...args) const
2651  {
2652  using namespace Zivid::Detail::TypeTraits;
2653 
2654  using AllArgsAreDescendantNodes =
2655  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
2656  static_assert(AllArgsAreDescendantNodes::value,
2657  "All arguments passed to copyWith(...) must be descendant nodes.");
2658 
2659  static_assert(AllArgsDecayedAreUnique<Args...>::value,
2660  "Found duplicate types among the arguments passed to copyWith(...). "
2661  "Types should be listed at most once.");
2662 
2663  auto copy{ *this };
2664  copy.set(std::forward<Args>(args)...);
2665  return copy;
2666  }
2667 
2669  const Balance &balance() const
2670  {
2671  return m_balance;
2672  }
2673 
2676  {
2677  return m_balance;
2678  }
2679 
2681  Color &set(const Balance &value)
2682  {
2683  m_balance = value;
2684  return *this;
2685  }
2686 
2688  Color &set(const Balance::Blue &value)
2689  {
2690  m_balance.set(value);
2691  return *this;
2692  }
2693 
2695  Color &set(const Balance::Green &value)
2696  {
2697  m_balance.set(value);
2698  return *this;
2699  }
2700 
2702  Color &set(const Balance::Red &value)
2703  {
2704  m_balance.set(value);
2705  return *this;
2706  }
2707 
2710  {
2711  return m_experimental;
2712  }
2713 
2716  {
2717  return m_experimental;
2718  }
2719 
2721  Color &set(const Experimental &value)
2722  {
2723  m_experimental = value;
2724  return *this;
2725  }
2726 
2729  {
2730  m_experimental.set(value);
2731  return *this;
2732  }
2733 
2736  {
2737  m_experimental.set(value);
2738  return *this;
2739  }
2740 
2742  const Gamma &gamma() const
2743  {
2744  return m_gamma;
2745  }
2746 
2749  {
2750  return m_gamma;
2751  }
2752 
2754  Color &set(const Gamma &value)
2755  {
2756  m_gamma = value;
2757  return *this;
2758  }
2759 
2760  template<typename T,
2761  typename std::enable_if<std::is_same<T, Settings::Processing::Color::Balance>::value,
2762  int>::type = 0>
2764  {
2765  return m_balance;
2766  }
2767 
2768  template<typename T,
2769  typename std::enable_if<std::is_same<T, Settings::Processing::Color::Balance::Blue>::value,
2770  int>::type = 0>
2772  {
2773  return m_balance.get<Settings::Processing::Color::Balance::Blue>();
2774  }
2775 
2776  template<typename T,
2777  typename std::enable_if<std::is_same<T, Settings::Processing::Color::Balance::Green>::value,
2778  int>::type = 0>
2780  {
2781  return m_balance.get<Settings::Processing::Color::Balance::Green>();
2782  }
2783 
2784  template<typename T,
2785  typename std::enable_if<std::is_same<T, Settings::Processing::Color::Balance::Red>::value,
2786  int>::type = 0>
2788  {
2789  return m_balance.get<Settings::Processing::Color::Balance::Red>();
2790  }
2791 
2792  template<typename T,
2793  typename std::enable_if<std::is_same<T, Settings::Processing::Color::Experimental>::value,
2794  int>::type = 0>
2796  {
2797  return m_experimental;
2798  }
2799 
2800  template<typename T,
2801  typename std::enable_if<
2802  std::is_same<T, Settings::Processing::Color::Experimental::ToneMapping>::value,
2803  int>::type = 0>
2805  {
2807  }
2808 
2809  template<typename T,
2810  typename std::enable_if<
2811  std::is_same<T, Settings::Processing::Color::Experimental::ToneMapping::Enabled>::value,
2812  int>::type = 0>
2814  {
2816  }
2817 
2818  template<
2819  typename T,
2820  typename std::enable_if<std::is_same<T, Settings::Processing::Color::Gamma>::value, int>::type = 0>
2822  {
2823  return m_gamma;
2824  }
2825 
2826  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
2828  {
2829  return m_balance;
2830  }
2831 
2832  template<size_t i, typename std::enable_if<i == 1, int>::type = 0>
2834  {
2835  return m_experimental;
2836  }
2837 
2838  template<size_t i, typename std::enable_if<i == 2, int>::type = 0>
2840  {
2841  return m_gamma;
2842  }
2843 
2845  template<typename F>
2846  void forEach(const F &f) const
2847  {
2848  f(m_balance);
2849  f(m_experimental);
2850  f(m_gamma);
2851  }
2852 
2854  template<typename F>
2855  void forEach(const F &f)
2856  {
2857  f(m_balance);
2858  f(m_experimental);
2859  f(m_gamma);
2860  }
2861 
2863  bool operator==(const Color &other) const;
2864 
2866  bool operator!=(const Color &other) const;
2867 
2869  std::string toString() const;
2870 
2872  friend std::ostream &operator<<(std::ostream &stream, const Color &value)
2873  {
2874  return stream << value.toString();
2875  }
2876 
2877  private:
2878  void setFromString(const std::string &value);
2879 
2880  void setFromString(const std::string &fullPath, const std::string &value);
2881 
2882  std::string getString(const std::string &fullPath) const;
2883 
2884  Balance m_balance;
2885  Experimental m_experimental;
2886  Gamma m_gamma;
2887 
2888  friend struct DataModel::Detail::Befriend<Color>;
2889  };
2890 
2893  {
2894  public:
2897 
2899  static constexpr const char *path{ "Processing/Filters" };
2900 
2902  static constexpr const char *name{ "Filters" };
2903 
2905  static constexpr const char *description{ R"description(Filters)description" };
2906 
2909  {
2910  public:
2913 
2915  static constexpr const char *path{ "Processing/Filters/Experimental" };
2916 
2918  static constexpr const char *name{ "Experimental" };
2919 
2921  static constexpr const char *description{
2922  R"description(Experimental filters. These may be renamed, moved or deleted in the future.)description"
2923  };
2924 
2931  {
2932  public:
2935 
2937  static constexpr const char *path{ "Processing/Filters/Experimental/ContrastDistortion" };
2938 
2940  static constexpr const char *name{ "ContrastDistortion" };
2941 
2943  static constexpr const char *description{
2944  R"description(Corrects artifacts that appear when imaging scenes with large texture gradients
2945 or high contrast. These artifacts are caused by blurring in the lens. The filter
2946 works best when aperture values are chosen such that the camera has quite good focus.
2947 The filter also supports removing the points that experience a large correction.
2948 )description"
2949  };
2950 
2953  {
2954  public:
2957 
2959  static constexpr const char *path{
2960  "Processing/Filters/Experimental/ContrastDistortion/Correction"
2961  };
2962 
2964  static constexpr const char *name{ "Correction" };
2965 
2967  static constexpr const char *description{ R"description(Correction)description" };
2968 
2971  {
2972  public:
2975 
2977  static constexpr const char *path{
2978  "Processing/Filters/Experimental/ContrastDistortion/Correction/Enabled"
2979  };
2980 
2982  static constexpr const char *name{ "Enabled" };
2983 
2985  static constexpr const char *description{ R"description(Enabled)description" };
2986 
2988  using ValueType = bool;
2989  static const Enabled yes;
2990  static const Enabled no;
2991 
2993  static std::set<bool> validValues()
2994  {
2995  return { false, true };
2996  }
2997 
2999  Enabled() = default;
3000 
3002  explicit constexpr Enabled(bool value)
3003  : m_opt{ value }
3004  {}
3005 
3010  bool value() const;
3011 
3013  bool hasValue() const;
3014 
3016  void reset();
3017 
3019  std::string toString() const;
3020 
3022  bool operator==(const Enabled &other) const
3023  {
3024  return m_opt == other.m_opt;
3025  }
3026 
3028  bool operator!=(const Enabled &other) const
3029  {
3030  return m_opt != other.m_opt;
3031  }
3032 
3034  friend std::ostream &operator<<(std::ostream &stream, const Enabled &value)
3035  {
3036  return stream << value.toString();
3037  }
3038 
3039  private:
3040  void setFromString(const std::string &value);
3041 
3042  Zivid::DataModel::Detail::Optional<bool> m_opt;
3043 
3044  friend struct DataModel::Detail::Befriend<Enabled>;
3045  };
3046 
3049  {
3050  public:
3053 
3055  static constexpr const char *path{
3056  "Processing/Filters/Experimental/ContrastDistortion/Correction/Strength"
3057  };
3058 
3060  static constexpr const char *name{ "Strength" };
3061 
3063  static constexpr const char *description{
3064  R"description(Higher values gives more correction.)description"
3065  };
3066 
3068  using ValueType = double;
3069 
3071  static constexpr Range<double> validRange()
3072  {
3073  return { 0.0, 1.0 };
3074  }
3075 
3077  Strength() = default;
3078 
3080  explicit constexpr Strength(double value)
3081  : m_opt{ verifyValue(value) }
3082  {}
3083 
3088  double value() const;
3089 
3091  bool hasValue() const;
3092 
3094  void reset();
3095 
3097  std::string toString() const;
3098 
3100  bool operator==(const Strength &other) const
3101  {
3102  return m_opt == other.m_opt;
3103  }
3104 
3106  bool operator!=(const Strength &other) const
3107  {
3108  return m_opt != other.m_opt;
3109  }
3110 
3112  bool operator<(const Strength &other) const
3113  {
3114  return m_opt < other.m_opt;
3115  }
3116 
3118  bool operator>(const Strength &other) const
3119  {
3120  return m_opt > other.m_opt;
3121  }
3122 
3124  friend std::ostream &operator<<(std::ostream &stream, const Strength &value)
3125  {
3126  return stream << value.toString();
3127  }
3128 
3129  private:
3130  void setFromString(const std::string &value);
3131 
3132  constexpr ValueType static verifyValue(const ValueType &value)
3133  {
3134  return validRange().isInRange(value)
3135  ? value
3136  : throw std::out_of_range{ "Strength{ " + std::to_string(value)
3137  + " } is not in range ["
3138  + std::to_string(validRange().min()) + ", "
3139  + std::to_string(validRange().max()) + "]" };
3140  }
3141 
3142  Zivid::DataModel::Detail::Optional<double> m_opt;
3143 
3144  friend struct DataModel::Detail::Befriend<Strength>;
3145  };
3146 
3147  using Descendants = std::tuple<
3150 
3153 
3166 #ifndef NO_DOC
3167  template<typename... Args,
3168  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
3169  typename std::enable_if<Zivid::Detail::TypeTraits::AllArgsAreInTuple<
3170  Descendants,
3171  typename std::decay<Args>::type...>::value,
3172  int>::type = 0>
3173 #else
3174  template<typename... Args>
3175 #endif
3176  explicit Correction(Args &&...args)
3177  {
3178  using namespace Zivid::Detail::TypeTraits;
3179 
3180  static_assert(AllArgsDecayedAreUnique<Args...>::value,
3181  "Found duplicate types among the arguments passed to Correction(...). "
3182  "Types should be listed at most once.");
3183 
3184  set(std::forward<Args>(args)...);
3185  }
3186 
3198 #ifndef NO_DOC
3199  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
3200 #else
3201  template<typename... Args>
3202 #endif
3203  void set(Args &&...args)
3204  {
3205  using namespace Zivid::Detail::TypeTraits;
3206 
3207  using AllArgsAreDescendantNodes =
3208  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
3209  static_assert(AllArgsAreDescendantNodes::value,
3210  "All arguments passed to set(...) must be descendant nodes.");
3211 
3212  static_assert(AllArgsDecayedAreUnique<Args...>::value,
3213  "Found duplicate types among the arguments passed to set(...). "
3214  "Types should be listed at most once.");
3215 
3216  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
3217  }
3218 
3231 #ifndef NO_DOC
3232  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
3233 #else
3234  template<typename... Args>
3235 #endif
3236  Correction copyWith(Args &&...args) const
3237  {
3238  using namespace Zivid::Detail::TypeTraits;
3239 
3240  using AllArgsAreDescendantNodes =
3241  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
3242  static_assert(AllArgsAreDescendantNodes::value,
3243  "All arguments passed to copyWith(...) must be descendant nodes.");
3244 
3245  static_assert(AllArgsDecayedAreUnique<Args...>::value,
3246  "Found duplicate types among the arguments passed to copyWith(...). "
3247  "Types should be listed at most once.");
3248 
3249  auto copy{ *this };
3250  copy.set(std::forward<Args>(args)...);
3251  return copy;
3252  }
3253 
3255  const Enabled &isEnabled() const
3256  {
3257  return m_enabled;
3258  }
3259 
3262  {
3263  return m_enabled;
3264  }
3265 
3267  Correction &set(const Enabled &value)
3268  {
3269  m_enabled = value;
3270  return *this;
3271  }
3272 
3274  const Strength &strength() const
3275  {
3276  return m_strength;
3277  }
3278 
3281  {
3282  return m_strength;
3283  }
3284 
3286  Correction &set(const Strength &value)
3287  {
3288  m_strength = value;
3289  return *this;
3290  }
3291 
3292  template<typename T,
3293  typename std::enable_if<
3294  std::is_same<T,
3295  Settings::Processing::Filters::Experimental::ContrastDistortion::
3296  Correction::Enabled>::value,
3297  int>::type = 0>
3299  get() const
3300  {
3301  return m_enabled;
3302  }
3303 
3304  template<typename T,
3305  typename std::enable_if<
3306  std::is_same<T,
3307  Settings::Processing::Filters::Experimental::ContrastDistortion::
3308  Correction::Strength>::value,
3309  int>::type = 0>
3311  &
3312  get() const
3313  {
3314  return m_strength;
3315  }
3316 
3317  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
3319  get() const
3320  {
3321  return m_enabled;
3322  }
3323 
3324  template<size_t i, typename std::enable_if<i == 1, int>::type = 0>
3326  &
3327  get() const
3328  {
3329  return m_strength;
3330  }
3331 
3333  template<typename F>
3334  void forEach(const F &f) const
3335  {
3336  f(m_enabled);
3337  f(m_strength);
3338  }
3339 
3341  template<typename F>
3342  void forEach(const F &f)
3343  {
3344  f(m_enabled);
3345  f(m_strength);
3346  }
3347 
3349  bool operator==(const Correction &other) const;
3350 
3352  bool operator!=(const Correction &other) const;
3353 
3355  std::string toString() const;
3356 
3358  friend std::ostream &operator<<(std::ostream &stream, const Correction &value)
3359  {
3360  return stream << value.toString();
3361  }
3362 
3363  private:
3364  void setFromString(const std::string &value);
3365 
3366  void setFromString(const std::string &fullPath, const std::string &value);
3367 
3368  std::string getString(const std::string &fullPath) const;
3369 
3370  Enabled m_enabled;
3371  Strength m_strength;
3372 
3373  friend struct DataModel::Detail::Befriend<Correction>;
3374  };
3375 
3378  {
3379  public:
3382 
3384  static constexpr const char *path{
3385  "Processing/Filters/Experimental/ContrastDistortion/Removal"
3386  };
3387 
3389  static constexpr const char *name{ "Removal" };
3390 
3392  static constexpr const char *description{ R"description(Removal)description" };
3393 
3396  {
3397  public:
3400 
3402  static constexpr const char *path{
3403  "Processing/Filters/Experimental/ContrastDistortion/Removal/Enabled"
3404  };
3405 
3407  static constexpr const char *name{ "Enabled" };
3408 
3410  static constexpr const char *description{ R"description(Enabled)description" };
3411 
3413  using ValueType = bool;
3414  static const Enabled yes;
3415  static const Enabled no;
3416 
3418  static std::set<bool> validValues()
3419  {
3420  return { false, true };
3421  }
3422 
3424  Enabled() = default;
3425 
3427  explicit constexpr Enabled(bool value)
3428  : m_opt{ value }
3429  {}
3430 
3435  bool value() const;
3436 
3438  bool hasValue() const;
3439 
3441  void reset();
3442 
3444  std::string toString() const;
3445 
3447  bool operator==(const Enabled &other) const
3448  {
3449  return m_opt == other.m_opt;
3450  }
3451 
3453  bool operator!=(const Enabled &other) const
3454  {
3455  return m_opt != other.m_opt;
3456  }
3457 
3459  friend std::ostream &operator<<(std::ostream &stream, const Enabled &value)
3460  {
3461  return stream << value.toString();
3462  }
3463 
3464  private:
3465  void setFromString(const std::string &value);
3466 
3467  Zivid::DataModel::Detail::Optional<bool> m_opt;
3468 
3469  friend struct DataModel::Detail::Befriend<Enabled>;
3470  };
3471 
3474  {
3475  public:
3478 
3480  static constexpr const char *path{
3481  "Processing/Filters/Experimental/ContrastDistortion/Removal/Threshold"
3482  };
3483 
3485  static constexpr const char *name{ "Threshold" };
3486 
3488  static constexpr const char *description{
3489  R"description(Higher values remove more points.)description"
3490  };
3491 
3493  using ValueType = double;
3494 
3496  static constexpr Range<double> validRange()
3497  {
3498  return { 0.0, 1.0 };
3499  }
3500 
3502  Threshold() = default;
3503 
3505  explicit constexpr Threshold(double value)
3506  : m_opt{ verifyValue(value) }
3507  {}
3508 
3513  double value() const;
3514 
3516  bool hasValue() const;
3517 
3519  void reset();
3520 
3522  std::string toString() const;
3523 
3525  bool operator==(const Threshold &other) const
3526  {
3527  return m_opt == other.m_opt;
3528  }
3529 
3531  bool operator!=(const Threshold &other) const
3532  {
3533  return m_opt != other.m_opt;
3534  }
3535 
3537  bool operator<(const Threshold &other) const
3538  {
3539  return m_opt < other.m_opt;
3540  }
3541 
3543  bool operator>(const Threshold &other) const
3544  {
3545  return m_opt > other.m_opt;
3546  }
3547 
3549  friend std::ostream &operator<<(std::ostream &stream, const Threshold &value)
3550  {
3551  return stream << value.toString();
3552  }
3553 
3554  private:
3555  void setFromString(const std::string &value);
3556 
3557  constexpr ValueType static verifyValue(const ValueType &value)
3558  {
3559  return validRange().isInRange(value)
3560  ? value
3561  : throw std::out_of_range{ "Threshold{ " + std::to_string(value)
3562  + " } is not in range ["
3563  + std::to_string(validRange().min()) + ", "
3564  + std::to_string(validRange().max()) + "]" };
3565  }
3566 
3567  Zivid::DataModel::Detail::Optional<double> m_opt;
3568 
3569  friend struct DataModel::Detail::Befriend<Threshold>;
3570  };
3571 
3572  using Descendants = std::tuple<
3575 
3578 
3591 #ifndef NO_DOC
3592  template<typename... Args,
3593  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
3594  typename std::enable_if<Zivid::Detail::TypeTraits::AllArgsAreInTuple<
3595  Descendants,
3596  typename std::decay<Args>::type...>::value,
3597  int>::type = 0>
3598 #else
3599  template<typename... Args>
3600 #endif
3601  explicit Removal(Args &&...args)
3602  {
3603  using namespace Zivid::Detail::TypeTraits;
3604 
3605  static_assert(AllArgsDecayedAreUnique<Args...>::value,
3606  "Found duplicate types among the arguments passed to Removal(...). "
3607  "Types should be listed at most once.");
3608 
3609  set(std::forward<Args>(args)...);
3610  }
3611 
3623 #ifndef NO_DOC
3624  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
3625 #else
3626  template<typename... Args>
3627 #endif
3628  void set(Args &&...args)
3629  {
3630  using namespace Zivid::Detail::TypeTraits;
3631 
3632  using AllArgsAreDescendantNodes =
3633  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
3634  static_assert(AllArgsAreDescendantNodes::value,
3635  "All arguments passed to set(...) must be descendant nodes.");
3636 
3637  static_assert(AllArgsDecayedAreUnique<Args...>::value,
3638  "Found duplicate types among the arguments passed to set(...). "
3639  "Types should be listed at most once.");
3640 
3641  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
3642  }
3643 
3656 #ifndef NO_DOC
3657  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
3658 #else
3659  template<typename... Args>
3660 #endif
3661  Removal copyWith(Args &&...args) const
3662  {
3663  using namespace Zivid::Detail::TypeTraits;
3664 
3665  using AllArgsAreDescendantNodes =
3666  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
3667  static_assert(AllArgsAreDescendantNodes::value,
3668  "All arguments passed to copyWith(...) must be descendant nodes.");
3669 
3670  static_assert(AllArgsDecayedAreUnique<Args...>::value,
3671  "Found duplicate types among the arguments passed to copyWith(...). "
3672  "Types should be listed at most once.");
3673 
3674  auto copy{ *this };
3675  copy.set(std::forward<Args>(args)...);
3676  return copy;
3677  }
3678 
3680  const Enabled &isEnabled() const
3681  {
3682  return m_enabled;
3683  }
3684 
3687  {
3688  return m_enabled;
3689  }
3690 
3692  Removal &set(const Enabled &value)
3693  {
3694  m_enabled = value;
3695  return *this;
3696  }
3697 
3699  const Threshold &threshold() const
3700  {
3701  return m_threshold;
3702  }
3703 
3706  {
3707  return m_threshold;
3708  }
3709 
3711  Removal &set(const Threshold &value)
3712  {
3713  m_threshold = value;
3714  return *this;
3715  }
3716 
3717  template<
3718  typename T,
3719  typename std::enable_if<std::is_same<T,
3720  Settings::Processing::Filters::Experimental::
3721  ContrastDistortion::Removal::Enabled>::value,
3722  int>::type = 0>
3724  get() const
3725  {
3726  return m_enabled;
3727  }
3728 
3729  template<
3730  typename T,
3731  typename std::enable_if<std::is_same<T,
3732  Settings::Processing::Filters::Experimental::
3733  ContrastDistortion::Removal::Threshold>::value,
3734  int>::type = 0>
3736  get() const
3737  {
3738  return m_threshold;
3739  }
3740 
3741  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
3743  get() const
3744  {
3745  return m_enabled;
3746  }
3747 
3748  template<size_t i, typename std::enable_if<i == 1, int>::type = 0>
3750  get() const
3751  {
3752  return m_threshold;
3753  }
3754 
3756  template<typename F>
3757  void forEach(const F &f) const
3758  {
3759  f(m_enabled);
3760  f(m_threshold);
3761  }
3762 
3764  template<typename F>
3765  void forEach(const F &f)
3766  {
3767  f(m_enabled);
3768  f(m_threshold);
3769  }
3770 
3772  bool operator==(const Removal &other) const;
3773 
3775  bool operator!=(const Removal &other) const;
3776 
3778  std::string toString() const;
3779 
3781  friend std::ostream &operator<<(std::ostream &stream, const Removal &value)
3782  {
3783  return stream << value.toString();
3784  }
3785 
3786  private:
3787  void setFromString(const std::string &value);
3788 
3789  void setFromString(const std::string &fullPath, const std::string &value);
3790 
3791  std::string getString(const std::string &fullPath) const;
3792 
3793  Enabled m_enabled;
3794  Threshold m_threshold;
3795 
3796  friend struct DataModel::Detail::Befriend<Removal>;
3797  };
3798 
3799  using Descendants = std::tuple<
3806 
3809 
3826 #ifndef NO_DOC
3827  template<typename... Args,
3828  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
3829  typename std::enable_if<Zivid::Detail::TypeTraits::AllArgsAreInTuple<
3830  Descendants,
3831  typename std::decay<Args>::type...>::value,
3832  int>::type = 0>
3833 #else
3834  template<typename... Args>
3835 #endif
3836  explicit ContrastDistortion(Args &&...args)
3837  {
3838  using namespace Zivid::Detail::TypeTraits;
3839 
3840  static_assert(
3841  AllArgsDecayedAreUnique<Args...>::value,
3842  "Found duplicate types among the arguments passed to ContrastDistortion(...). "
3843  "Types should be listed at most once.");
3844 
3845  set(std::forward<Args>(args)...);
3846  }
3847 
3863 #ifndef NO_DOC
3864  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
3865 #else
3866  template<typename... Args>
3867 #endif
3868  void set(Args &&...args)
3869  {
3870  using namespace Zivid::Detail::TypeTraits;
3871 
3872  using AllArgsAreDescendantNodes =
3873  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
3874  static_assert(AllArgsAreDescendantNodes::value,
3875  "All arguments passed to set(...) must be descendant nodes.");
3876 
3877  static_assert(AllArgsDecayedAreUnique<Args...>::value,
3878  "Found duplicate types among the arguments passed to set(...). "
3879  "Types should be listed at most once.");
3880 
3881  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
3882  }
3883 
3900 #ifndef NO_DOC
3901  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
3902 #else
3903  template<typename... Args>
3904 #endif
3905  ContrastDistortion copyWith(Args &&...args) const
3906  {
3907  using namespace Zivid::Detail::TypeTraits;
3908 
3909  using AllArgsAreDescendantNodes =
3910  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
3911  static_assert(AllArgsAreDescendantNodes::value,
3912  "All arguments passed to copyWith(...) must be descendant nodes.");
3913 
3914  static_assert(AllArgsDecayedAreUnique<Args...>::value,
3915  "Found duplicate types among the arguments passed to copyWith(...). "
3916  "Types should be listed at most once.");
3917 
3918  auto copy{ *this };
3919  copy.set(std::forward<Args>(args)...);
3920  return copy;
3921  }
3922 
3924  const Correction &correction() const
3925  {
3926  return m_correction;
3927  }
3928 
3931  {
3932  return m_correction;
3933  }
3934 
3937  {
3938  m_correction = value;
3939  return *this;
3940  }
3941 
3944  {
3945  m_correction.set(value);
3946  return *this;
3947  }
3948 
3951  {
3952  m_correction.set(value);
3953  return *this;
3954  }
3955 
3957  const Removal &removal() const
3958  {
3959  return m_removal;
3960  }
3961 
3964  {
3965  return m_removal;
3966  }
3967 
3970  {
3971  m_removal = value;
3972  return *this;
3973  }
3974 
3977  {
3978  m_removal.set(value);
3979  return *this;
3980  }
3981 
3984  {
3985  m_removal.set(value);
3986  return *this;
3987  }
3988 
3989  template<typename T,
3990  typename std::enable_if<std::is_same<T,
3991  Settings::Processing::Filters::Experimental::
3992  ContrastDistortion::Correction>::value,
3993  int>::type = 0>
3995  {
3996  return m_correction;
3997  }
3998 
3999  template<
4000  typename T,
4001  typename std::enable_if<std::is_same<T,
4002  Settings::Processing::Filters::Experimental::
4003  ContrastDistortion::Correction::Enabled>::value,
4004  int>::type = 0>
4006  get() const
4007  {
4008  return m_correction.get<
4010  }
4011 
4012  template<
4013  typename T,
4014  typename std::enable_if<std::is_same<T,
4015  Settings::Processing::Filters::Experimental::
4016  ContrastDistortion::Correction::Strength>::value,
4017  int>::type = 0>
4019  get() const
4020  {
4021  return m_correction.get<Settings::Processing::Filters::Experimental::ContrastDistortion::
4022  Correction::Strength>();
4023  }
4024 
4025  template<typename T,
4026  typename std::enable_if<std::is_same<T,
4027  Settings::Processing::Filters::Experimental::
4028  ContrastDistortion::Removal>::value,
4029  int>::type = 0>
4031  {
4032  return m_removal;
4033  }
4034 
4035  template<typename T,
4036  typename std::enable_if<std::is_same<T,
4037  Settings::Processing::Filters::Experimental::
4038  ContrastDistortion::Removal::Enabled>::value,
4039  int>::type = 0>
4041  const
4042  {
4043  return m_removal.get<
4045  }
4046 
4047  template<
4048  typename T,
4049  typename std::enable_if<std::is_same<T,
4050  Settings::Processing::Filters::Experimental::
4051  ContrastDistortion::Removal::Threshold>::value,
4052  int>::type = 0>
4054  const
4055  {
4056  return m_removal.get<
4058  }
4059 
4060  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
4062  {
4063  return m_correction;
4064  }
4065 
4066  template<size_t i, typename std::enable_if<i == 1, int>::type = 0>
4068  {
4069  return m_removal;
4070  }
4071 
4073  template<typename F>
4074  void forEach(const F &f) const
4075  {
4076  f(m_correction);
4077  f(m_removal);
4078  }
4079 
4081  template<typename F>
4082  void forEach(const F &f)
4083  {
4084  f(m_correction);
4085  f(m_removal);
4086  }
4087 
4089  bool operator==(const ContrastDistortion &other) const;
4090 
4092  bool operator!=(const ContrastDistortion &other) const;
4093 
4095  std::string toString() const;
4096 
4098  friend std::ostream &operator<<(std::ostream &stream, const ContrastDistortion &value)
4099  {
4100  return stream << value.toString();
4101  }
4102 
4103  private:
4104  void setFromString(const std::string &value);
4105 
4106  void setFromString(const std::string &fullPath, const std::string &value);
4107 
4108  std::string getString(const std::string &fullPath) const;
4109 
4110  Correction m_correction;
4111  Removal m_removal;
4112 
4113  friend struct DataModel::Detail::Befriend<ContrastDistortion>;
4114  };
4115 
4116  using Descendants = std::tuple<
4124 
4127 
4145 #ifndef NO_DOC
4146  template<typename... Args,
4147  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
4148  typename std::enable_if<Zivid::Detail::TypeTraits::AllArgsAreInTuple<
4149  Descendants,
4150  typename std::decay<Args>::type...>::value,
4151  int>::type = 0>
4152 #else
4153  template<typename... Args>
4154 #endif
4155  explicit Experimental(Args &&...args)
4156  {
4157  using namespace Zivid::Detail::TypeTraits;
4158 
4159  static_assert(AllArgsDecayedAreUnique<Args...>::value,
4160  "Found duplicate types among the arguments passed to Experimental(...). "
4161  "Types should be listed at most once.");
4162 
4163  set(std::forward<Args>(args)...);
4164  }
4165 
4182 #ifndef NO_DOC
4183  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
4184 #else
4185  template<typename... Args>
4186 #endif
4187  void set(Args &&...args)
4188  {
4189  using namespace Zivid::Detail::TypeTraits;
4190 
4191  using AllArgsAreDescendantNodes =
4192  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
4193  static_assert(AllArgsAreDescendantNodes::value,
4194  "All arguments passed to set(...) must be descendant nodes.");
4195 
4196  static_assert(AllArgsDecayedAreUnique<Args...>::value,
4197  "Found duplicate types among the arguments passed to set(...). "
4198  "Types should be listed at most once.");
4199 
4200  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
4201  }
4202 
4220 #ifndef NO_DOC
4221  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
4222 #else
4223  template<typename... Args>
4224 #endif
4225  Experimental copyWith(Args &&...args) const
4226  {
4227  using namespace Zivid::Detail::TypeTraits;
4228 
4229  using AllArgsAreDescendantNodes =
4230  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
4231  static_assert(AllArgsAreDescendantNodes::value,
4232  "All arguments passed to copyWith(...) must be descendant nodes.");
4233 
4234  static_assert(AllArgsDecayedAreUnique<Args...>::value,
4235  "Found duplicate types among the arguments passed to copyWith(...). "
4236  "Types should be listed at most once.");
4237 
4238  auto copy{ *this };
4239  copy.set(std::forward<Args>(args)...);
4240  return copy;
4241  }
4242 
4245  {
4246  return m_contrastDistortion;
4247  }
4248 
4251  {
4252  return m_contrastDistortion;
4253  }
4254 
4257  {
4258  m_contrastDistortion = value;
4259  return *this;
4260  }
4261 
4264  {
4265  m_contrastDistortion.set(value);
4266  return *this;
4267  }
4268 
4271  {
4272  m_contrastDistortion.set(value);
4273  return *this;
4274  }
4275 
4278  {
4279  m_contrastDistortion.set(value);
4280  return *this;
4281  }
4282 
4285  {
4286  m_contrastDistortion.set(value);
4287  return *this;
4288  }
4289 
4292  {
4293  m_contrastDistortion.set(value);
4294  return *this;
4295  }
4296 
4299  {
4300  m_contrastDistortion.set(value);
4301  return *this;
4302  }
4303 
4304  template<
4305  typename T,
4306  typename std::enable_if<
4307  std::is_same<T, Settings::Processing::Filters::Experimental::ContrastDistortion>::value,
4308  int>::type = 0>
4310  {
4311  return m_contrastDistortion;
4312  }
4313 
4314  template<typename T,
4315  typename std::enable_if<std::is_same<T,
4316  Settings::Processing::Filters::Experimental::
4317  ContrastDistortion::Correction>::value,
4318  int>::type = 0>
4320  {
4321  return m_contrastDistortion
4323  }
4324 
4325  template<typename T,
4326  typename std::enable_if<std::is_same<T,
4327  Settings::Processing::Filters::Experimental::
4328  ContrastDistortion::Correction::Enabled>::value,
4329  int>::type = 0>
4331  const
4332  {
4333  return m_contrastDistortion.get<
4335  }
4336 
4337  template<typename T,
4338  typename std::enable_if<std::is_same<T,
4339  Settings::Processing::Filters::Experimental::
4340  ContrastDistortion::Correction::Strength>::value,
4341  int>::type = 0>
4343  const
4344  {
4345  return m_contrastDistortion.get<
4347  }
4348 
4349  template<
4350  typename T,
4351  typename std::enable_if<
4352  std::is_same<T, Settings::Processing::Filters::Experimental::ContrastDistortion::Removal>::
4353  value,
4354  int>::type = 0>
4356  {
4357  return m_contrastDistortion
4359  }
4360 
4361  template<typename T,
4362  typename std::enable_if<std::is_same<T,
4363  Settings::Processing::Filters::Experimental::
4364  ContrastDistortion::Removal::Enabled>::value,
4365  int>::type = 0>
4367  {
4368  return m_contrastDistortion
4370  }
4371 
4372  template<typename T,
4373  typename std::enable_if<std::is_same<T,
4374  Settings::Processing::Filters::Experimental::
4375  ContrastDistortion::Removal::Threshold>::value,
4376  int>::type = 0>
4378  const
4379  {
4380  return m_contrastDistortion
4382  }
4383 
4384  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
4386  {
4387  return m_contrastDistortion;
4388  }
4389 
4391  template<typename F>
4392  void forEach(const F &f) const
4393  {
4394  f(m_contrastDistortion);
4395  }
4396 
4398  template<typename F>
4399  void forEach(const F &f)
4400  {
4401  f(m_contrastDistortion);
4402  }
4403 
4405  bool operator==(const Experimental &other) const;
4406 
4408  bool operator!=(const Experimental &other) const;
4409 
4411  std::string toString() const;
4412 
4414  friend std::ostream &operator<<(std::ostream &stream, const Experimental &value)
4415  {
4416  return stream << value.toString();
4417  }
4418 
4419  private:
4420  void setFromString(const std::string &value);
4421 
4422  void setFromString(const std::string &fullPath, const std::string &value);
4423 
4424  std::string getString(const std::string &fullPath) const;
4425 
4426  ContrastDistortion m_contrastDistortion;
4427 
4428  friend struct DataModel::Detail::Befriend<Experimental>;
4429  };
4430 
4433  {
4434  public:
4437 
4439  static constexpr const char *path{ "Processing/Filters/Noise" };
4440 
4442  static constexpr const char *name{ "Noise" };
4443 
4445  static constexpr const char *description{
4446  R"description(Contains a filter that removes points with low signal-to-noise ratio (SNR))description"
4447  };
4448 
4451  {
4452  public:
4455 
4457  static constexpr const char *path{ "Processing/Filters/Noise/Removal" };
4458 
4460  static constexpr const char *name{ "Removal" };
4461 
4463  static constexpr const char *description{
4464  R"description(Discard points with signal-to-noise ratio (SNR) values below a threshold)description"
4465  };
4466 
4469  {
4470  public:
4473 
4475  static constexpr const char *path{ "Processing/Filters/Noise/Removal/Enabled" };
4476 
4478  static constexpr const char *name{ "Enabled" };
4479 
4481  static constexpr const char *description{
4482  R"description(Enable or disable the SNR filter)description"
4483  };
4484 
4486  using ValueType = bool;
4487  static const Enabled yes;
4488  static const Enabled no;
4489 
4491  static std::set<bool> validValues()
4492  {
4493  return { false, true };
4494  }
4495 
4497  Enabled() = default;
4498 
4500  explicit constexpr Enabled(bool value)
4501  : m_opt{ value }
4502  {}
4503 
4508  bool value() const;
4509 
4511  bool hasValue() const;
4512 
4514  void reset();
4515 
4517  std::string toString() const;
4518 
4520  bool operator==(const Enabled &other) const
4521  {
4522  return m_opt == other.m_opt;
4523  }
4524 
4526  bool operator!=(const Enabled &other) const
4527  {
4528  return m_opt != other.m_opt;
4529  }
4530 
4532  friend std::ostream &operator<<(std::ostream &stream, const Enabled &value)
4533  {
4534  return stream << value.toString();
4535  }
4536 
4537  private:
4538  void setFromString(const std::string &value);
4539 
4540  Zivid::DataModel::Detail::Optional<bool> m_opt;
4541 
4542  friend struct DataModel::Detail::Befriend<Enabled>;
4543  };
4544 
4547  {
4548  public:
4551 
4553  static constexpr const char *path{ "Processing/Filters/Noise/Removal/Threshold" };
4554 
4556  static constexpr const char *name{ "Threshold" };
4557 
4559  static constexpr const char *description{
4560  R"description(Discard points with signal-to-noise ratio (SNR) below the given value)description"
4561  };
4562 
4564  using ValueType = double;
4565 
4567  static constexpr Range<double> validRange()
4568  {
4569  return { 0.0, 100.0 };
4570  }
4571 
4573  Threshold() = default;
4574 
4576  explicit constexpr Threshold(double value)
4577  : m_opt{ verifyValue(value) }
4578  {}
4579 
4584  double value() const;
4585 
4587  bool hasValue() const;
4588 
4590  void reset();
4591 
4593  std::string toString() const;
4594 
4596  bool operator==(const Threshold &other) const
4597  {
4598  return m_opt == other.m_opt;
4599  }
4600 
4602  bool operator!=(const Threshold &other) const
4603  {
4604  return m_opt != other.m_opt;
4605  }
4606 
4608  bool operator<(const Threshold &other) const
4609  {
4610  return m_opt < other.m_opt;
4611  }
4612 
4614  bool operator>(const Threshold &other) const
4615  {
4616  return m_opt > other.m_opt;
4617  }
4618 
4620  friend std::ostream &operator<<(std::ostream &stream, const Threshold &value)
4621  {
4622  return stream << value.toString();
4623  }
4624 
4625  private:
4626  void setFromString(const std::string &value);
4627 
4628  constexpr ValueType static verifyValue(const ValueType &value)
4629  {
4630  return validRange().isInRange(value)
4631  ? value
4632  : throw std::out_of_range{ "Threshold{ " + std::to_string(value)
4633  + " } is not in range ["
4634  + std::to_string(validRange().min()) + ", "
4635  + std::to_string(validRange().max()) + "]" };
4636  }
4637 
4638  Zivid::DataModel::Detail::Optional<double> m_opt;
4639 
4640  friend struct DataModel::Detail::Befriend<Threshold>;
4641  };
4642 
4645 
4648 
4661 #ifndef NO_DOC
4662  template<typename... Args,
4663  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
4664  typename std::enable_if<Zivid::Detail::TypeTraits::AllArgsAreInTuple<
4665  Descendants,
4666  typename std::decay<Args>::type...>::value,
4667  int>::type = 0>
4668 #else
4669  template<typename... Args>
4670 #endif
4671  explicit Removal(Args &&...args)
4672  {
4673  using namespace Zivid::Detail::TypeTraits;
4674 
4675  static_assert(AllArgsDecayedAreUnique<Args...>::value,
4676  "Found duplicate types among the arguments passed to Removal(...). "
4677  "Types should be listed at most once.");
4678 
4679  set(std::forward<Args>(args)...);
4680  }
4681 
4693 #ifndef NO_DOC
4694  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
4695 #else
4696  template<typename... Args>
4697 #endif
4698  void set(Args &&...args)
4699  {
4700  using namespace Zivid::Detail::TypeTraits;
4701 
4702  using AllArgsAreDescendantNodes =
4703  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
4704  static_assert(AllArgsAreDescendantNodes::value,
4705  "All arguments passed to set(...) must be descendant nodes.");
4706 
4707  static_assert(AllArgsDecayedAreUnique<Args...>::value,
4708  "Found duplicate types among the arguments passed to set(...). "
4709  "Types should be listed at most once.");
4710 
4711  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
4712  }
4713 
4726 #ifndef NO_DOC
4727  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
4728 #else
4729  template<typename... Args>
4730 #endif
4731  Removal copyWith(Args &&...args) const
4732  {
4733  using namespace Zivid::Detail::TypeTraits;
4734 
4735  using AllArgsAreDescendantNodes =
4736  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
4737  static_assert(AllArgsAreDescendantNodes::value,
4738  "All arguments passed to copyWith(...) must be descendant nodes.");
4739 
4740  static_assert(AllArgsDecayedAreUnique<Args...>::value,
4741  "Found duplicate types among the arguments passed to copyWith(...). "
4742  "Types should be listed at most once.");
4743 
4744  auto copy{ *this };
4745  copy.set(std::forward<Args>(args)...);
4746  return copy;
4747  }
4748 
4750  const Enabled &isEnabled() const
4751  {
4752  return m_enabled;
4753  }
4754 
4757  {
4758  return m_enabled;
4759  }
4760 
4762  Removal &set(const Enabled &value)
4763  {
4764  m_enabled = value;
4765  return *this;
4766  }
4767 
4769  const Threshold &threshold() const
4770  {
4771  return m_threshold;
4772  }
4773 
4776  {
4777  return m_threshold;
4778  }
4779 
4781  Removal &set(const Threshold &value)
4782  {
4783  m_threshold = value;
4784  return *this;
4785  }
4786 
4787  template<typename T,
4788  typename std::enable_if<
4789  std::is_same<T, Settings::Processing::Filters::Noise::Removal::Enabled>::value,
4790  int>::type = 0>
4792  {
4793  return m_enabled;
4794  }
4795 
4796  template<typename T,
4797  typename std::enable_if<
4798  std::is_same<T, Settings::Processing::Filters::Noise::Removal::Threshold>::value,
4799  int>::type = 0>
4801  {
4802  return m_threshold;
4803  }
4804 
4805  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
4807  {
4808  return m_enabled;
4809  }
4810 
4811  template<size_t i, typename std::enable_if<i == 1, int>::type = 0>
4813  {
4814  return m_threshold;
4815  }
4816 
4818  template<typename F>
4819  void forEach(const F &f) const
4820  {
4821  f(m_enabled);
4822  f(m_threshold);
4823  }
4824 
4826  template<typename F>
4827  void forEach(const F &f)
4828  {
4829  f(m_enabled);
4830  f(m_threshold);
4831  }
4832 
4834  bool operator==(const Removal &other) const;
4835 
4837  bool operator!=(const Removal &other) const;
4838 
4840  std::string toString() const;
4841 
4843  friend std::ostream &operator<<(std::ostream &stream, const Removal &value)
4844  {
4845  return stream << value.toString();
4846  }
4847 
4848  private:
4849  void setFromString(const std::string &value);
4850 
4851  void setFromString(const std::string &fullPath, const std::string &value);
4852 
4853  std::string getString(const std::string &fullPath) const;
4854 
4855  Enabled m_enabled;
4856  Threshold m_threshold;
4857 
4858  friend struct DataModel::Detail::Befriend<Removal>;
4859  };
4860 
4864 
4867 
4881 #ifndef NO_DOC
4882  template<typename... Args,
4883  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
4884  typename std::enable_if<Zivid::Detail::TypeTraits::AllArgsAreInTuple<
4885  Descendants,
4886  typename std::decay<Args>::type...>::value,
4887  int>::type = 0>
4888 #else
4889  template<typename... Args>
4890 #endif
4891  explicit Noise(Args &&...args)
4892  {
4893  using namespace Zivid::Detail::TypeTraits;
4894 
4895  static_assert(AllArgsDecayedAreUnique<Args...>::value,
4896  "Found duplicate types among the arguments passed to Noise(...). "
4897  "Types should be listed at most once.");
4898 
4899  set(std::forward<Args>(args)...);
4900  }
4901 
4914 #ifndef NO_DOC
4915  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
4916 #else
4917  template<typename... Args>
4918 #endif
4919  void set(Args &&...args)
4920  {
4921  using namespace Zivid::Detail::TypeTraits;
4922 
4923  using AllArgsAreDescendantNodes =
4924  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
4925  static_assert(AllArgsAreDescendantNodes::value,
4926  "All arguments passed to set(...) must be descendant nodes.");
4927 
4928  static_assert(AllArgsDecayedAreUnique<Args...>::value,
4929  "Found duplicate types among the arguments passed to set(...). "
4930  "Types should be listed at most once.");
4931 
4932  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
4933  }
4934 
4948 #ifndef NO_DOC
4949  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
4950 #else
4951  template<typename... Args>
4952 #endif
4953  Noise copyWith(Args &&...args) const
4954  {
4955  using namespace Zivid::Detail::TypeTraits;
4956 
4957  using AllArgsAreDescendantNodes =
4958  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
4959  static_assert(AllArgsAreDescendantNodes::value,
4960  "All arguments passed to copyWith(...) must be descendant nodes.");
4961 
4962  static_assert(AllArgsDecayedAreUnique<Args...>::value,
4963  "Found duplicate types among the arguments passed to copyWith(...). "
4964  "Types should be listed at most once.");
4965 
4966  auto copy{ *this };
4967  copy.set(std::forward<Args>(args)...);
4968  return copy;
4969  }
4970 
4972  const Removal &removal() const
4973  {
4974  return m_removal;
4975  }
4976 
4979  {
4980  return m_removal;
4981  }
4982 
4984  Noise &set(const Removal &value)
4985  {
4986  m_removal = value;
4987  return *this;
4988  }
4989 
4991  Noise &set(const Removal::Enabled &value)
4992  {
4993  m_removal.set(value);
4994  return *this;
4995  }
4996 
4999  {
5000  m_removal.set(value);
5001  return *this;
5002  }
5003 
5004  template<
5005  typename T,
5006  typename std::enable_if<std::is_same<T, Settings::Processing::Filters::Noise::Removal>::value,
5007  int>::type = 0>
5009  {
5010  return m_removal;
5011  }
5012 
5013  template<typename T,
5014  typename std::enable_if<
5015  std::is_same<T, Settings::Processing::Filters::Noise::Removal::Enabled>::value,
5016  int>::type = 0>
5018  {
5020  }
5021 
5022  template<typename T,
5023  typename std::enable_if<
5024  std::is_same<T, Settings::Processing::Filters::Noise::Removal::Threshold>::value,
5025  int>::type = 0>
5027  {
5029  }
5030 
5031  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
5033  {
5034  return m_removal;
5035  }
5036 
5038  template<typename F>
5039  void forEach(const F &f) const
5040  {
5041  f(m_removal);
5042  }
5043 
5045  template<typename F>
5046  void forEach(const F &f)
5047  {
5048  f(m_removal);
5049  }
5050 
5052  bool operator==(const Noise &other) const;
5053 
5055  bool operator!=(const Noise &other) const;
5056 
5058  std::string toString() const;
5059 
5061  friend std::ostream &operator<<(std::ostream &stream, const Noise &value)
5062  {
5063  return stream << value.toString();
5064  }
5065 
5066  private:
5067  void setFromString(const std::string &value);
5068 
5069  void setFromString(const std::string &fullPath, const std::string &value);
5070 
5071  std::string getString(const std::string &fullPath) const;
5072 
5073  Removal m_removal;
5074 
5075  friend struct DataModel::Detail::Befriend<Noise>;
5076  };
5077 
5080  {
5081  public:
5084 
5086  static constexpr const char *path{ "Processing/Filters/Outlier" };
5087 
5089  static constexpr const char *name{ "Outlier" };
5090 
5092  static constexpr const char *description{
5093  R"description(Contains a filter that removes points with large Euclidean distance to neighboring points)description"
5094  };
5095 
5098  {
5099  public:
5102 
5104  static constexpr const char *path{ "Processing/Filters/Outlier/Removal" };
5105 
5107  static constexpr const char *name{ "Removal" };
5108 
5110  static constexpr const char *description{
5111  R"description(Discard point if Euclidean distance to neighboring points is above a threshold)description"
5112  };
5113 
5116  {
5117  public:
5120 
5122  static constexpr const char *path{ "Processing/Filters/Outlier/Removal/Enabled" };
5123 
5125  static constexpr const char *name{ "Enabled" };
5126 
5128  static constexpr const char *description{
5129  R"description(Enable or disable the outlier filter)description"
5130  };
5131 
5133  using ValueType = bool;
5134  static const Enabled yes;
5135  static const Enabled no;
5136 
5138  static std::set<bool> validValues()
5139  {
5140  return { false, true };
5141  }
5142 
5144  Enabled() = default;
5145 
5147  explicit constexpr Enabled(bool value)
5148  : m_opt{ value }
5149  {}
5150 
5155  bool value() const;
5156 
5158  bool hasValue() const;
5159 
5161  void reset();
5162 
5164  std::string toString() const;
5165 
5167  bool operator==(const Enabled &other) const
5168  {
5169  return m_opt == other.m_opt;
5170  }
5171 
5173  bool operator!=(const Enabled &other) const
5174  {
5175  return m_opt != other.m_opt;
5176  }
5177 
5179  friend std::ostream &operator<<(std::ostream &stream, const Enabled &value)
5180  {
5181  return stream << value.toString();
5182  }
5183 
5184  private:
5185  void setFromString(const std::string &value);
5186 
5187  Zivid::DataModel::Detail::Optional<bool> m_opt;
5188 
5189  friend struct DataModel::Detail::Befriend<Enabled>;
5190  };
5191 
5194  {
5195  public:
5198 
5200  static constexpr const char *path{ "Processing/Filters/Outlier/Removal/Threshold" };
5201 
5203  static constexpr const char *name{ "Threshold" };
5204 
5206  static constexpr const char *description{
5207  R"description(Discard point if Euclidean distance to neighboring points is above the given value)description"
5208  };
5209 
5211  using ValueType = double;
5212 
5214  static constexpr Range<double> validRange()
5215  {
5216  return { 0.0, 100.0 };
5217  }
5218 
5220  Threshold() = default;
5221 
5223  explicit constexpr Threshold(double value)
5224  : m_opt{ verifyValue(value) }
5225  {}
5226 
5231  double value() const;
5232 
5234  bool hasValue() const;
5235 
5237  void reset();
5238 
5240  std::string toString() const;
5241 
5243  bool operator==(const Threshold &other) const
5244  {
5245  return m_opt == other.m_opt;
5246  }
5247 
5249  bool operator!=(const Threshold &other) const
5250  {
5251  return m_opt != other.m_opt;
5252  }
5253 
5255  bool operator<(const Threshold &other) const
5256  {
5257  return m_opt < other.m_opt;
5258  }
5259 
5261  bool operator>(const Threshold &other) const
5262  {
5263  return m_opt > other.m_opt;
5264  }
5265 
5267  friend std::ostream &operator<<(std::ostream &stream, const Threshold &value)
5268  {
5269  return stream << value.toString();
5270  }
5271 
5272  private:
5273  void setFromString(const std::string &value);
5274 
5275  constexpr ValueType static verifyValue(const ValueType &value)
5276  {
5277  return validRange().isInRange(value)
5278  ? value
5279  : throw std::out_of_range{ "Threshold{ " + std::to_string(value)
5280  + " } is not in range ["
5281  + std::to_string(validRange().min()) + ", "
5282  + std::to_string(validRange().max()) + "]" };
5283  }
5284 
5285  Zivid::DataModel::Detail::Optional<double> m_opt;
5286 
5287  friend struct DataModel::Detail::Befriend<Threshold>;
5288  };
5289 
5292 
5295 
5308 #ifndef NO_DOC
5309  template<typename... Args,
5310  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
5311  typename std::enable_if<Zivid::Detail::TypeTraits::AllArgsAreInTuple<
5312  Descendants,
5313  typename std::decay<Args>::type...>::value,
5314  int>::type = 0>
5315 #else
5316  template<typename... Args>
5317 #endif
5318  explicit Removal(Args &&...args)
5319  {
5320  using namespace Zivid::Detail::TypeTraits;
5321 
5322  static_assert(AllArgsDecayedAreUnique<Args...>::value,
5323  "Found duplicate types among the arguments passed to Removal(...). "
5324  "Types should be listed at most once.");
5325 
5326  set(std::forward<Args>(args)...);
5327  }
5328 
5340 #ifndef NO_DOC
5341  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
5342 #else
5343  template<typename... Args>
5344 #endif
5345  void set(Args &&...args)
5346  {
5347  using namespace Zivid::Detail::TypeTraits;
5348 
5349  using AllArgsAreDescendantNodes =
5350  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
5351  static_assert(AllArgsAreDescendantNodes::value,
5352  "All arguments passed to set(...) must be descendant nodes.");
5353 
5354  static_assert(AllArgsDecayedAreUnique<Args...>::value,
5355  "Found duplicate types among the arguments passed to set(...). "
5356  "Types should be listed at most once.");
5357 
5358  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
5359  }
5360 
5373 #ifndef NO_DOC
5374  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
5375 #else
5376  template<typename... Args>
5377 #endif
5378  Removal copyWith(Args &&...args) const
5379  {
5380  using namespace Zivid::Detail::TypeTraits;
5381 
5382  using AllArgsAreDescendantNodes =
5383  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
5384  static_assert(AllArgsAreDescendantNodes::value,
5385  "All arguments passed to copyWith(...) must be descendant nodes.");
5386 
5387  static_assert(AllArgsDecayedAreUnique<Args...>::value,
5388  "Found duplicate types among the arguments passed to copyWith(...). "
5389  "Types should be listed at most once.");
5390 
5391  auto copy{ *this };
5392  copy.set(std::forward<Args>(args)...);
5393  return copy;
5394  }
5395 
5397  const Enabled &isEnabled() const
5398  {
5399  return m_enabled;
5400  }
5401 
5404  {
5405  return m_enabled;
5406  }
5407 
5409  Removal &set(const Enabled &value)
5410  {
5411  m_enabled = value;
5412  return *this;
5413  }
5414 
5416  const Threshold &threshold() const
5417  {
5418  return m_threshold;
5419  }
5420 
5423  {
5424  return m_threshold;
5425  }
5426 
5428  Removal &set(const Threshold &value)
5429  {
5430  m_threshold = value;
5431  return *this;
5432  }
5433 
5434  template<typename T,
5435  typename std::enable_if<
5436  std::is_same<T, Settings::Processing::Filters::Outlier::Removal::Enabled>::value,
5437  int>::type = 0>
5439  {
5440  return m_enabled;
5441  }
5442 
5443  template<typename T,
5444  typename std::enable_if<
5445  std::is_same<T, Settings::Processing::Filters::Outlier::Removal::Threshold>::value,
5446  int>::type = 0>
5448  {
5449  return m_threshold;
5450  }
5451 
5452  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
5454  {
5455  return m_enabled;
5456  }
5457 
5458  template<size_t i, typename std::enable_if<i == 1, int>::type = 0>
5460  {
5461  return m_threshold;
5462  }
5463 
5465  template<typename F>
5466  void forEach(const F &f) const
5467  {
5468  f(m_enabled);
5469  f(m_threshold);
5470  }
5471 
5473  template<typename F>
5474  void forEach(const F &f)
5475  {
5476  f(m_enabled);
5477  f(m_threshold);
5478  }
5479 
5481  bool operator==(const Removal &other) const;
5482 
5484  bool operator!=(const Removal &other) const;
5485 
5487  std::string toString() const;
5488 
5490  friend std::ostream &operator<<(std::ostream &stream, const Removal &value)
5491  {
5492  return stream << value.toString();
5493  }
5494 
5495  private:
5496  void setFromString(const std::string &value);
5497 
5498  void setFromString(const std::string &fullPath, const std::string &value);
5499 
5500  std::string getString(const std::string &fullPath) const;
5501 
5502  Enabled m_enabled;
5503  Threshold m_threshold;
5504 
5505  friend struct DataModel::Detail::Befriend<Removal>;
5506  };
5507 
5511 
5514 
5528 #ifndef NO_DOC
5529  template<typename... Args,
5530  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
5531  typename std::enable_if<Zivid::Detail::TypeTraits::AllArgsAreInTuple<
5532  Descendants,
5533  typename std::decay<Args>::type...>::value,
5534  int>::type = 0>
5535 #else
5536  template<typename... Args>
5537 #endif
5538  explicit Outlier(Args &&...args)
5539  {
5540  using namespace Zivid::Detail::TypeTraits;
5541 
5542  static_assert(AllArgsDecayedAreUnique<Args...>::value,
5543  "Found duplicate types among the arguments passed to Outlier(...). "
5544  "Types should be listed at most once.");
5545 
5546  set(std::forward<Args>(args)...);
5547  }
5548 
5561 #ifndef NO_DOC
5562  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
5563 #else
5564  template<typename... Args>
5565 #endif
5566  void set(Args &&...args)
5567  {
5568  using namespace Zivid::Detail::TypeTraits;
5569 
5570  using AllArgsAreDescendantNodes =
5571  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
5572  static_assert(AllArgsAreDescendantNodes::value,
5573  "All arguments passed to set(...) must be descendant nodes.");
5574 
5575  static_assert(AllArgsDecayedAreUnique<Args...>::value,
5576  "Found duplicate types among the arguments passed to set(...). "
5577  "Types should be listed at most once.");
5578 
5579  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
5580  }
5581 
5595 #ifndef NO_DOC
5596  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
5597 #else
5598  template<typename... Args>
5599 #endif
5600  Outlier copyWith(Args &&...args) const
5601  {
5602  using namespace Zivid::Detail::TypeTraits;
5603 
5604  using AllArgsAreDescendantNodes =
5605  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
5606  static_assert(AllArgsAreDescendantNodes::value,
5607  "All arguments passed to copyWith(...) must be descendant nodes.");
5608 
5609  static_assert(AllArgsDecayedAreUnique<Args...>::value,
5610  "Found duplicate types among the arguments passed to copyWith(...). "
5611  "Types should be listed at most once.");
5612 
5613  auto copy{ *this };
5614  copy.set(std::forward<Args>(args)...);
5615  return copy;
5616  }
5617 
5619  const Removal &removal() const
5620  {
5621  return m_removal;
5622  }
5623 
5626  {
5627  return m_removal;
5628  }
5629 
5631  Outlier &set(const Removal &value)
5632  {
5633  m_removal = value;
5634  return *this;
5635  }
5636 
5639  {
5640  m_removal.set(value);
5641  return *this;
5642  }
5643 
5646  {
5647  m_removal.set(value);
5648  return *this;
5649  }
5650 
5651  template<
5652  typename T,
5653  typename std::enable_if<std::is_same<T, Settings::Processing::Filters::Outlier::Removal>::value,
5654  int>::type = 0>
5656  {
5657  return m_removal;
5658  }
5659 
5660  template<typename T,
5661  typename std::enable_if<
5662  std::is_same<T, Settings::Processing::Filters::Outlier::Removal::Enabled>::value,
5663  int>::type = 0>
5665  {
5667  }
5668 
5669  template<typename T,
5670  typename std::enable_if<
5671  std::is_same<T, Settings::Processing::Filters::Outlier::Removal::Threshold>::value,
5672  int>::type = 0>
5674  {
5676  }
5677 
5678  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
5680  {
5681  return m_removal;
5682  }
5683 
5685  template<typename F>
5686  void forEach(const F &f) const
5687  {
5688  f(m_removal);
5689  }
5690 
5692  template<typename F>
5693  void forEach(const F &f)
5694  {
5695  f(m_removal);
5696  }
5697 
5699  bool operator==(const Outlier &other) const;
5700 
5702  bool operator!=(const Outlier &other) const;
5703 
5705  std::string toString() const;
5706 
5708  friend std::ostream &operator<<(std::ostream &stream, const Outlier &value)
5709  {
5710  return stream << value.toString();
5711  }
5712 
5713  private:
5714  void setFromString(const std::string &value);
5715 
5716  void setFromString(const std::string &fullPath, const std::string &value);
5717 
5718  std::string getString(const std::string &fullPath) const;
5719 
5720  Removal m_removal;
5721 
5722  friend struct DataModel::Detail::Befriend<Outlier>;
5723  };
5724 
5727  {
5728  public:
5731 
5733  static constexpr const char *path{ "Processing/Filters/Reflection" };
5734 
5736  static constexpr const char *name{ "Reflection" };
5737 
5739  static constexpr const char *description{
5740  R"description(Contains a filter that removes points likely introduced by reflections (useful for shiny materials))description"
5741  };
5742 
5745  {
5746  public:
5749 
5751  static constexpr const char *path{ "Processing/Filters/Reflection/Removal" };
5752 
5754  static constexpr const char *name{ "Removal" };
5755 
5757  static constexpr const char *description{
5758  R"description(Discard points likely introduced by reflections (useful for shiny materials))description"
5759  };
5760 
5763  {
5764  public:
5767 
5769  static constexpr const char *path{ "Processing/Filters/Reflection/Removal/Enabled" };
5770 
5772  static constexpr const char *name{ "Enabled" };
5773 
5775  static constexpr const char *description{
5776  R"description(Enable or disable the reflection filter. Note that this filter is computationally intensive and may affect the frame rate)description"
5777  };
5778 
5780  using ValueType = bool;
5781  static const Enabled yes;
5782  static const Enabled no;
5783 
5785  static std::set<bool> validValues()
5786  {
5787  return { false, true };
5788  }
5789 
5791  Enabled() = default;
5792 
5794  explicit constexpr Enabled(bool value)
5795  : m_opt{ value }
5796  {}
5797 
5802  bool value() const;
5803 
5805  bool hasValue() const;
5806 
5808  void reset();
5809 
5811  std::string toString() const;
5812 
5814  bool operator==(const Enabled &other) const
5815  {
5816  return m_opt == other.m_opt;
5817  }
5818 
5820  bool operator!=(const Enabled &other) const
5821  {
5822  return m_opt != other.m_opt;
5823  }
5824 
5826  friend std::ostream &operator<<(std::ostream &stream, const Enabled &value)
5827  {
5828  return stream << value.toString();
5829  }
5830 
5831  private:
5832  void setFromString(const std::string &value);
5833 
5834  Zivid::DataModel::Detail::Optional<bool> m_opt;
5835 
5836  friend struct DataModel::Detail::Befriend<Enabled>;
5837  };
5838 
5839  using Descendants = std::tuple<Settings::Processing::Filters::Reflection::Removal::Enabled>;
5840 
5843 
5855 #ifndef NO_DOC
5856  template<typename... Args,
5857  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
5858  typename std::enable_if<Zivid::Detail::TypeTraits::AllArgsAreInTuple<
5859  Descendants,
5860  typename std::decay<Args>::type...>::value,
5861  int>::type = 0>
5862 #else
5863  template<typename... Args>
5864 #endif
5865  explicit Removal(Args &&...args)
5866  {
5867  using namespace Zivid::Detail::TypeTraits;
5868 
5869  static_assert(AllArgsDecayedAreUnique<Args...>::value,
5870  "Found duplicate types among the arguments passed to Removal(...). "
5871  "Types should be listed at most once.");
5872 
5873  set(std::forward<Args>(args)...);
5874  }
5875 
5886 #ifndef NO_DOC
5887  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
5888 #else
5889  template<typename... Args>
5890 #endif
5891  void set(Args &&...args)
5892  {
5893  using namespace Zivid::Detail::TypeTraits;
5894 
5895  using AllArgsAreDescendantNodes =
5896  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
5897  static_assert(AllArgsAreDescendantNodes::value,
5898  "All arguments passed to set(...) must be descendant nodes.");
5899 
5900  static_assert(AllArgsDecayedAreUnique<Args...>::value,
5901  "Found duplicate types among the arguments passed to set(...). "
5902  "Types should be listed at most once.");
5903 
5904  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
5905  }
5906 
5918 #ifndef NO_DOC
5919  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
5920 #else
5921  template<typename... Args>
5922 #endif
5923  Removal copyWith(Args &&...args) const
5924  {
5925  using namespace Zivid::Detail::TypeTraits;
5926 
5927  using AllArgsAreDescendantNodes =
5928  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
5929  static_assert(AllArgsAreDescendantNodes::value,
5930  "All arguments passed to copyWith(...) must be descendant nodes.");
5931 
5932  static_assert(AllArgsDecayedAreUnique<Args...>::value,
5933  "Found duplicate types among the arguments passed to copyWith(...). "
5934  "Types should be listed at most once.");
5935 
5936  auto copy{ *this };
5937  copy.set(std::forward<Args>(args)...);
5938  return copy;
5939  }
5940 
5942  const Enabled &isEnabled() const
5943  {
5944  return m_enabled;
5945  }
5946 
5949  {
5950  return m_enabled;
5951  }
5952 
5954  Removal &set(const Enabled &value)
5955  {
5956  m_enabled = value;
5957  return *this;
5958  }
5959 
5960  template<
5961  typename T,
5962  typename std::enable_if<
5963  std::is_same<T, Settings::Processing::Filters::Reflection::Removal::Enabled>::value,
5964  int>::type = 0>
5966  {
5967  return m_enabled;
5968  }
5969 
5970  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
5972  {
5973  return m_enabled;
5974  }
5975 
5977  template<typename F>
5978  void forEach(const F &f) const
5979  {
5980  f(m_enabled);
5981  }
5982 
5984  template<typename F>
5985  void forEach(const F &f)
5986  {
5987  f(m_enabled);
5988  }
5989 
5991  bool operator==(const Removal &other) const;
5992 
5994  bool operator!=(const Removal &other) const;
5995 
5997  std::string toString() const;
5998 
6000  friend std::ostream &operator<<(std::ostream &stream, const Removal &value)
6001  {
6002  return stream << value.toString();
6003  }
6004 
6005  private:
6006  void setFromString(const std::string &value);
6007 
6008  void setFromString(const std::string &fullPath, const std::string &value);
6009 
6010  std::string getString(const std::string &fullPath) const;
6011 
6012  Enabled m_enabled;
6013 
6014  friend struct DataModel::Detail::Befriend<Removal>;
6015  };
6016 
6019 
6022 
6035 #ifndef NO_DOC
6036  template<typename... Args,
6037  typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0,
6038  typename std::enable_if<Zivid::Detail::TypeTraits::AllArgsAreInTuple<
6039  Descendants,
6040  typename std::decay<Args>::type...>::value,
6041  int>::type = 0>
6042 #else
6043  template<typename... Args>
6044 #endif
6045  explicit Reflection(Args &&...args)
6046  {
6047  using namespace Zivid::Detail::TypeTraits;
6048 
6049  static_assert(AllArgsDecayedAreUnique<Args...>::value,
6050  "Found duplicate types among the arguments passed to Reflection(...). "
6051  "Types should be listed at most once.");
6052 
6053  set(std::forward<Args>(args)...);
6054  }
6055 
6067 #ifndef NO_DOC
6068  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 2, int>::type = 0>
6069 #else
6070  template<typename... Args>
6071 #endif
6072  void set(Args &&...args)
6073  {
6074  using namespace Zivid::Detail::TypeTraits;
6075 
6076  using AllArgsAreDescendantNodes =
6077  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
6078  static_assert(AllArgsAreDescendantNodes::value,
6079  "All arguments passed to set(...) must be descendant nodes.");
6080 
6081  static_assert(AllArgsDecayedAreUnique<Args...>::value,
6082  "Found duplicate types among the arguments passed to set(...). "
6083  "Types should be listed at most once.");
6084 
6085  Zivid::DataModel::Detail::invokeSetWithEachArgument(*this, std::forward<Args>(args)...);
6086  }
6087 
6100 #ifndef NO_DOC
6101  template<typename... Args, typename std::enable_if<sizeof...(Args) >= 1, int>::type = 0>
6102 #else
6103  template<typename... Args>
6104 #endif
6105  Reflection copyWith(Args &&...args) const
6106  {
6107  using namespace Zivid::Detail::TypeTraits;
6108 
6109  using AllArgsAreDescendantNodes =
6110  AllArgsAreInTuple<Descendants, typename std::decay<Args>::type...>;
6111  static_assert(AllArgsAreDescendantNodes::value,
6112  "All arguments passed to copyWith(...) must be descendant nodes.");
6113 
6114  static_assert(AllArgsDecayedAreUnique<Args...>::value,
6115  "Found duplicate types among the arguments passed to copyWith(...). "
6116  "Types should be listed at most once.");
6117 
6118  auto copy{ *this };
6119  copy.set(std::forward<Args>(args)...);
6120  return copy;
6121  }
6122 
6124  const Removal &removal() const
6125  {
6126  return m_removal;
6127  }
6128 
6131  {
6132  return m_removal;
6133  }
6134 
6136  Reflection &set(const Removal &value)
6137  {
6138  m_removal = value;
6139  return *this;
6140  }
6141 
6144  {
6145  m_removal.set(value);
6146  return *this;
6147  }
6148 
6149  template<typename T,
6150  typename std::enable_if<
6151  std::is_same<T, Settings::Processing::Filters::Reflection::Removal>::value,
6152  int>::type = 0>
6154  {
6155  return m_removal;
6156  }
6157 
6158  template<typename T,
6159  typename std::enable_if<
6160  std::is_same<T, Settings::Processing::Filters::Reflection::Removal::Enabled>::value,
6161  int>::type = 0>
6163  {
6165  }
6166 
6167  template<size_t i, typename std::enable_if<i == 0, int>::type = 0>
6169  {
6170  return m_removal;
6171  }
6172 
6174  template<typename F>
6175  void forEach(const F &f) const
6176  {
6177  f(m_removal);
6178  }
6179 
6181  template<typename F>
6182  void forEach(const F &f)
6183  {
6184  f(m_removal);
6185  }
6186 
6188  bool operator==(const Reflection &other) const;
6189 
6191  bool operator!=(const Reflection &other) const;
6192 
6194  std::string toString() const;
6195 
6197  friend std::ostream &operator<<(std::ostream &stream, const Reflection &value)
6198  {
6199  return stream << value.toString();
6200  }
6201 
6202  private:
6203  void setFromString(const std::string &value);
6204 
6205  void setFromString(const std::string &fullPath, const std::string &value);
6206 
6207  std::string getString(const std::string &fullPath) const;
6208 
6209  Removal m_removal;
6210 
6211  friend struct DataModel::Detail::Befriend<Reflection>;
6212  };
6213 
6216  {
6217  public:
6220 
6222  static constexpr const char *path{ "Processing/Filters/Smoothing" };
6223 
6225  static constexpr const char *name{ "Smoothing" };
6226 
6228  static constexpr const char *description{ R"description(Smoothing filters)description" };
6229 
6232  {
6233  public:
6236 
6238  static constexpr const char *path{ "Processing/Filters/Smoothing/Gaussian" };
6239 
6241  static constexpr const char *name{ "Gaussian" };
6242 
6244  static constexpr const char *description{
6245  R"description(Gaussian smoothing of the point cloud)description"
6246  };
6247 
6250  {
6251  public:
6254 
6256  static constexpr const char *path{ "Processing/Filters/Smoothing/Gaussian/Enabled" };
6257 
6259  static constexpr const char *name{ "Enabled" };
6260 
6262  static constexpr const char *description{
6263  R"description(Enable or disable the smoothing filter)description"
6264  };
6265 
6267  using ValueType = bool;
6268  static const Enabled yes;
6269  static const Enabled no;
6270 
6272  static std::set<bool> validValues()
6273  {
6274  return { false, true };
6275  }
6276 
6278  Enabled() = default;
6279 
6281  explicit constexpr Enabled(bool value)
6282  : m_opt{ value }
6283  {}
6284 
6289  bool value() const;
6290 
6292  bool hasValue() const;
6293 
6295  void reset();
6296 
6298  std::string toString() const;
6299 
6301  bool operator==(const Enabled &other) const
6302  {
6303  return m_opt == other.m_opt;
6304  }
6305 
6307  bool operator!=(const Enabled &other) const
6308  {
6309  return m_opt != other.m_opt;
6310  }
6311 
6313  friend std::ostream &operator<<(std::ostream &stream, const Enabled &value)
6314  {
6315  return stream << value.toString();
6316  }
6317 
6318  private:
6319  void setFromString(const std::string &value);
6320 
6321  Zivid::DataModel::Detail::Optional<bool> m_opt;
6322 
6323  friend struct DataModel::Detail::Befriend<Enabled>;
6324  };
6325 
6328  {
6329  public:
6332 
6334  static constexpr const char *path{ "Processing/Filters/Smoothing/Gaussian/Sigma" };
6335 
6337  static constexpr const char *name{ "Sigma" };
6338 
6340  static constexpr const char *description{
6341  R"description(Higher values result in smoother point clouds (Standard deviation of the filter coefficients))description"
6342  };
6343 
6345  using ValueType = double;
6346 
6348  static constexpr Range<double> validRange()
6349  {
6350  return { 0.5, 5 };
6351  }
6352 
6354  Sigma() = default;
6355 
6357  explicit constexpr Sigma(double value)
6358  : m_opt{ verifyValue(value) }
6359  {}
6360 
6365  double value() const;
6366 
6368  bo