opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
manually_scale_body_segments_scaling_step.h
Go to the documentation of this file.
1#pragma once
2
8
11#include <OpenSim/Simulation/Model/Model.h>
12#include <OpenSim/Simulation/SimbodyEngine/Body.h>
13#include <OpenSim/Common/ScaleSet.h>
14#include <SimTKcommon/SmallMatrix.h>
15
16#include <memory>
17#include <optional>
18#include <stdexcept>
19#include <sstream>
20#include <string>
21#include <vector>
22
23namespace opyn
24{
25 // A `ScalingStep` that scales body segments by the chosen (potentially, non-uniform) scale factors
27 OpenSim_DECLARE_CONCRETE_OBJECT(ManuallyScaleBodySegmentsScalingStep, ScalingStep)
28
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)");
32 public:
34 ScalingStep{"Manually Scale Body Segments"}
35 {
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);
40 }
41
42 private:
43 std::vector<ScalingStepValidationMessage> implValidate(
45 const ScalingParameters& parameters,
46 const OpenSim::Model& sourceModel) const final
47 {
48 std::vector<ScalingStepValidationMessage> messages;
49
50 // Ensure every entry in `wrap_cylinders` can be found in the source model.
51 for (int i = 0; i < getProperty_bodies().size(); ++i) {
52 const auto* body = FindComponent<OpenSim::Body>(sourceModel, get_bodies(i));
53 if (not body) {
54 std::stringstream msg;
55 msg << get_bodies(i) << ": Cannot find a `Body` in 'bodies' in the source model (or it isn't a `Body`).";
56 messages.emplace_back(ScalingStepValidationState::Error, std::move(msg).str());
57 }
58 }
59
60 const std::optional<double> blendingFactor = parameters.lookup<double>("blending_factor");
61 OSC_ASSERT_ALWAYS(blendingFactor && "blending_factor was not set by the warping engine");
62
63 return messages;
64 }
65
66 void implForEachScalingParameterDeclaration(const std::function<void(const ScalingParameterDeclaration&)>& callback) const final
67 {
68 callback(ScalingParameterDeclaration{"blending_factor", 1.0});
69 }
70
73 const ScalingParameters& parameters,
74 const OpenSim::Model&,
75 OpenSim::Model& model) const final
76 {
77 const std::optional<double> blendingFactor = parameters.lookup<double>("blending_factor");
78 OSC_ASSERT_ALWAYS(blendingFactor && "blending_factor was not set by the warping engine");
79
80 const SimTK::Vec3 scaleFactors = {
81 osc::lerp(1.0, get_scale_factors()[0], *blendingFactor),
82 osc::lerp(1.0, get_scale_factors()[1], *blendingFactor),
83 osc::lerp(1.0, get_scale_factors()[2], *blendingFactor),
84 };
85
86 OpenSim::ScaleSet scaleSet;
87 for (int i = 0; i < getProperty_bodies().size(); ++i) {
88 const auto* body = FindComponent<OpenSim::Body>(model, get_bodies(i));
89 if (not body) {
90 std::stringstream msg;
91 msg << get_bodies(i) << ": Cannot find a `Body` in 'bodies' in the source model (or it isn't a `Body`).";
92 throw std::runtime_error{std::move(msg).str()};
93 }
94
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());
100 }
101 model.scale(model.updWorkingState(), scaleSet, get_preserve_masses());
104 }
105 };
106}
#define OSC_ASSERT_ALWAYS(expr)
Definition assertions.h:20
Definition manually_scale_body_segments_scaling_step.h:26
std::vector< ScalingStepValidationMessage > implValidate(ScalingCache &, const ScalingParameters &parameters, 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 &parameters, const OpenSim::Model &, OpenSim::Model &model) const final
Definition manually_scale_body_segments_scaling_step.h:71
void implForEachScalingParameterDeclaration(const std::function< void(const ScalingParameterDeclaration &)> &callback) const final
Definition manually_scale_body_segments_scaling_step.h:66
Definition scaling_cache.h:30
Definition scaling_parameter_declaration.h:16
Definition scaling_parameters.h:14
Definition scaling_step.h:25
Definition component_registry.h:14
void InitializeModel(OpenSim::Model &)
SimTK::State & InitializeState(OpenSim::Model &)
constexpr auto lerp(const Rgba< T > &x, const Rgba< T > &y, TInterpolant t)
Definition rgba.h:230