29 OpenSim_DECLARE_LIST_PROPERTY(bodies, std::string,
"Absolute paths (e.g. `/bodyset/femur`) to `Body` components in the model");
30 OpenSim_DECLARE_PROPERTY( scale_factors, SimTK::Vec3,
"The manual scale factors that should be applied to the specified bodies");
31 OpenSim_DECLARE_PROPERTY( preserve_masses,
bool,
"If enabled, the masses of the bodies will not be scaled (inertial properties will still be scaled)");
36 setDescription(
"Applies a manually-specified scaling factor to the given body segments in the model.");
37 constructProperty_bodies();
38 constructProperty_scale_factors(SimTK::Vec3{1.0});
39 constructProperty_preserve_masses(
false);
46 const OpenSim::Model& sourceModel)
const final
48 std::vector<ScalingStepValidationMessage> messages;
51 for (
int i = 0; i < getProperty_bodies().size(); ++i) {
52 const auto* body = FindComponent<OpenSim::Body>(sourceModel, get_bodies(i));
54 messages.emplace_back(
56 std::format(
"{}: Cannot find a `Body` in 'bodies' in the source model (or it isn't a `Body`).", get_bodies(i))
61 const std::optional<double> blendingFactor = parameters.lookup<
double>(
"blending_factor");
62 OSC_ASSERT_ALWAYS(blendingFactor &&
"blending_factor was not set by the warping engine");
75 const OpenSim::Model&,
76 OpenSim::Model&
model)
const final
78 const std::optional<double> blendingFactor = parameters.lookup<
double>(
"blending_factor");
79 OSC_ASSERT_ALWAYS(blendingFactor &&
"blending_factor was not set by the warping engine");
81 const SimTK::Vec3 scaleFactors = {
82 osc::lerp(1.0, get_scale_factors()[0], *blendingFactor),
83 osc::lerp(1.0, get_scale_factors()[1], *blendingFactor),
84 osc::lerp(1.0, get_scale_factors()[2], *blendingFactor),
87 OpenSim::ScaleSet scaleSet;
88 for (
int i = 0; i < getProperty_bodies().size(); ++i) {
89 const auto* body = FindComponent<OpenSim::Body>(
model, get_bodies(i));
91 auto msg = std::format(
"{}: Cannot find a `Body` in 'bodies' in the source model (or it isn't a `Body`).", get_bodies(i));
92 throw std::runtime_error{std::move(msg)};
95 auto scale = std::make_unique<OpenSim::Scale>();
96 scale->setSegmentName(body->getName());
97 scale->setScaleFactors(scaleFactors);
98 scale->setApply(
true);
99 scaleSet.adoptAndAppend(scale.release());
101 model.scale(
model.updWorkingState(), scaleSet, get_preserve_masses());
Definition manually_scale_body_segments_scaling_step.h:26
std::vector< ScalingStepValidationMessage > implValidate(ScalingCache &, const ScalingParameters ¶meters, const OpenSim::Model &sourceModel) const final
Definition manually_scale_body_segments_scaling_step.h:43
ManuallyScaleBodySegmentsScalingStep()
Definition manually_scale_body_segments_scaling_step.h:33
void implApplyScalingStep(ScalingCache &, const ScalingParameters ¶meters, const OpenSim::Model &, OpenSim::Model &model) const final
Definition manually_scale_body_segments_scaling_step.h:72
void implForEachScalingParameterDeclaration(const std::function< void(const ScalingParameterDeclaration &)> &callback) const final
Definition manually_scale_body_segments_scaling_step.h:67