opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
model_warper_v3_document.h
Go to the documentation of this file.
1#pragma once
2
8
9#include <OpenSim/Common/Component.h>
10#include <OpenSim/Common/Property.h>
11
12#include <filesystem>
13#include <format>
14#include <memory>
15#include <stdexcept>
16#include <string>
17#include <utility>
18
19namespace opyn
20{
21 // Top-level document that describes a sequence of `ScalingStep`s that can be applied to
22 // the source model in order to yield a scaled model.
24 public OpenSim::Component,
26 OpenSim_DECLARE_CONCRETE_OBJECT(ModelWarperV3Document, OpenSim::Component)
27
28 OpenSim_DECLARE_LIST_PROPERTY(scaling_parameter_overrides, ScalingParameterOverride, "A sequence of `ScalingParameterOverride`s that should be used in place of the default values used by the `ScalingStep`s.");
29 public:
31 {
32 constructProperties();
33 finalizeFromProperties();
34 finalizeConnections(*this);
35 }
36
38 explicit ModelWarperV3Document(const std::filesystem::path& source) :
39 Component{source.string(), false} // Associate `Component` with `source`.
40 {
41 constructProperties();
42 updateFromXMLDocument();
43 finalizeFromProperties();
44 finalizeConnections(*this);
45 }
46
47 bool hasScalingSteps() const
48 {
49 if (getNumImmediateSubcomponents() == 0) {
50 return false;
51 }
52 const auto lst = getComponentList<ScalingStep>();
53 return lst.begin() != lst.end();
54 }
55
56 size_t getNumScalingSteps() const
57 {
58 if (getNumImmediateSubcomponents() == 0) {
59 return 0;
60 }
61 const auto lst = getComponentList<ScalingStep>();
62 return std::distance(lst.begin(), lst.end());
63 }
64
66 {
67 return getComponentList<ScalingStep>();
68 }
69
70 void addScalingStep(std::unique_ptr<ScalingStep> step)
71 {
72 addComponent(step.release());
73 clearConnections();
74 finalizeConnections(*this);
75 finalizeFromProperties();
76 }
77
79 {
80 if (not step.hasOwner()) {
81 return false;
82 }
83 if (&step.getOwner() != this) {
84 return false;
85 }
86
87 removeComponent(&step);
88 clearConnections();
89 finalizeConnections(*this);
90 finalizeFromProperties();
91 return true;
92 }
93
95 {
96 if (not hasScalingSteps()) {
97 return false;
98 }
99 for (const ScalingStep& step : iterateScalingSteps()) {
100 bool called = false;
101 step.forEachScalingParameterDeclaration([&called](const ScalingParameterDeclaration&) { called = true; });
102 if (called) {
103 return true;
104 }
105 }
106 return false;
107 }
108
110 {
112 }
113
115 {
117 if (getNumImmediateSubcomponents() == 0) {
118 return rv;
119 }
120
121 // Get/merge values from the scaling steps
122 for (const ScalingStep& step : iterateScalingSteps()) {
123 step.forEachScalingParameterDeclaration([&step, &rv](const ScalingParameterDeclaration& decl)
124 {
125 const auto [it, inserted] = rv.try_emplace(decl.name(), decl.default_value());
126 if (not inserted and it->second != decl.default_value()) {
127 auto msg = std::format("{}: declares a scaling parameter ({}) that has the same name as another scaling parameter, but they differ: the engine cannot figure out how to rectify this difference. The parameter should have a different name, or a disambiguating prefix added to it",
128 step.getAbsolutePathString(),
129 decl.name()
130 );
131 throw std::runtime_error{std::move(msg)};
132 }
133 });
134 }
135
136 // Apply overrides to the effective scaling parameters
137 {
138 const OpenSim::Property<ScalingParameterOverride>& overrides = getProperty_scaling_parameter_overrides();
139 for (int i = 0; i < overrides.size(); ++i) {
140 const ScalingParameterOverride& o = overrides.getValue(i);
141 rv.insert_or_assign(o.get_parameter_name(), o.get_parameter_value());
142 }
143 }
144
145 return rv;
146 }
147
148 bool setScalingParameterOverride(const std::string& scalingParamName, ScalingParameterValue newValue)
149 {
150 mutateScalingParammeterOverridesWithNewOverride(scalingParamName, newValue);
151 finalizeFromProperties();
152 return true;
153 }
154
155 void saveTo(const std::filesystem::path& p) const
156 {
157 print(p.string());
158 }
159
160 private:
161 void constructProperties()
162 {
163 constructProperty_scaling_parameter_overrides();
164 }
165
166 void mutateScalingParammeterOverridesWithNewOverride(const std::string& scalingParamName, ScalingParameterValue newValue)
167 {
168 // First, try to find an existing override with the same name and overwrite it
169 const OpenSim::Property<ScalingParameterOverride>& overrides = getProperty_scaling_parameter_overrides();
170 for (int i = 0; i < overrides.size(); ++i) {
171 const ScalingParameterOverride& o = overrides.getValue(i);
172 if (o.get_parameter_name() == scalingParamName) {
173 updProperty_scaling_parameter_overrides().updValue(i).set_parameter_value(newValue);
174 return; // found and overwritten
175 }
176 }
177
178 // Otherwise, add a new override
179 int idx = updProperty_scaling_parameter_overrides().appendValue(ScalingParameterOverride{scalingParamName, newValue});
180 updProperty_scaling_parameter_overrides().updValue(idx).set_parameter_name(scalingParamName);
181 updProperty_scaling_parameter_overrides().updValue(idx).set_parameter_value(newValue);
182 }
183
184 const OpenSim::Component& implGetComponent() const final
185 {
186 return *this;
187 }
188
189 bool implCanUpdComponent() const final
190 {
191 return true;
192 }
193
194 OpenSim::Component& implUpdComponent() final
195 {
196 throw std::runtime_error{ "component updating not implemented for this IComponentAccessor" };
197 }
198 };
199}
Definition open_sim_helpers.h:55
Definition model_warper_v3_document.h:25
bool removeScalingStep(ScalingStep &step)
Definition model_warper_v3_document.h:78
const OpenSim::Component & implGetComponent() const final
Definition model_warper_v3_document.h:184
bool hasScalingSteps() const
Definition model_warper_v3_document.h:47
ModelWarperV3Document(const std::filesystem::path &source)
Constructs a ModelWarperV3Document by loading its contents from source.
Definition model_warper_v3_document.h:38
void addScalingStep(std::unique_ptr< ScalingStep > step)
Definition model_warper_v3_document.h:70
size_t getNumScalingParameters() const
Definition model_warper_v3_document.h:109
auto iterateScalingSteps() const
Definition model_warper_v3_document.h:65
size_t getNumScalingSteps() const
Definition model_warper_v3_document.h:56
bool implCanUpdComponent() const final
Definition model_warper_v3_document.h:189
ModelWarperV3Document()
Definition model_warper_v3_document.h:30
bool hasScalingParameters() const
Definition model_warper_v3_document.h:94
ScalingParameters getEffectiveScalingParameters() const
Definition model_warper_v3_document.h:114
bool setScalingParameterOverride(const std::string &scalingParamName, ScalingParameterValue newValue)
Definition model_warper_v3_document.h:148
void saveTo(const std::filesystem::path &p) const
Definition model_warper_v3_document.h:155
OpenSim::Component & implUpdComponent() final
Definition model_warper_v3_document.h:194
Definition scaling_parameter_declaration.h:16
const ScalingParameterValue & default_value() const
Definition scaling_parameter_declaration.h:24
const std::string & name() const
Definition scaling_parameter_declaration.h:23
Definition scaling_parameter_override.h:14
Definition scaling_parameters.h:14
auto insert_or_assign(const std::string &name, const ScalingParameterValue &value)
Definition scaling_parameters.h:35
auto try_emplace(const std::string &name, const ScalingParameterValue &value)
Definition scaling_parameters.h:30
size_t size() const
Definition scaling_parameters.h:26
Definition scaling_step.h:25
Definition versioned_component_accessor.h:8
Definition component_registry.h:14
double ScalingParameterValue
Definition scaling_parameter_value.h:9