opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
thin_plate_spline_body_center_of_mass_scaling_step.h
Go to the documentation of this file.
1#pragma once
2
9
11#include <OpenSim/Simulation/SimbodyEngine/Body.h>
12#include <SimTKcommon/SmallMatrix.h>
13
14#include <format>
15#include <string>
16#include <vector>
17
18namespace OpenSim { class Model; }
19
20namespace opyn
21{
22 // A `ScalingStep` that applies the Thin-Plate Spline (TPS) warp the centers
23 // of mass of the given bodies (opensim-creator#1147).
26
27 OpenSim_DECLARE_LIST_PROPERTY(bodies, std::string, "Query paths (e.g. `/bodyset/*`) that the engine should use to find bodies in the source model that should be warped by this scaling step.");
28
29 public:
31 ToggleableThinPlateSplineScalingStep{"Apply Thin-Plate Spline (TPS) to Body Centers of Mass"}
32 {
33 setDescription("Warps the locations of body centers of mass in the model using the Thin-Plate Spline (TPS) warping algorithm.");
34 constructProperty_bodies();
35 }
36 private:
37 std::vector<ScalingStepValidationMessage> implValidate(
38 ScalingCache& cache,
39 const ScalingParameters& params,
40 const OpenSim::Model& sourceModel) const final
41 {
42 // Get base class validation messages.
43 auto messages = ToggleableThinPlateSplineScalingStep::implValidate(cache, params, sourceModel);
44
45 // Ensure every entry in `bodies` can be found in the source model.
46 for (int i = 0; i < getProperty_bodies().size(); ++i) {
47 if (not FindComponent<OpenSim::Body>(sourceModel, get_bodies(i))) {
48 messages.emplace_back(
50 std::format("{}: Cannot find a Body in 'bodies' in the source model (or it isn't a Body)", get_bodies(i))
51 );
52 }
53 }
54
55 return messages;
56 }
57
59 ScalingCache& scalingCache,
60 const ScalingParameters& parameters,
61 const OpenSim::Model& sourceModel,
62 OpenSim::Model& resultModel) const final
63 {
64 const auto commonParams = calcTPSScalingStepCommonParams(parameters, sourceModel, resultModel);
65
66 // Warp each specified center of mass, ensuring that the CoM is correctly
67 // transformed into the TPS warp's coordinate system.
68 for (int i = 0; i < getProperty_bodies().size(); ++i) {
69
70 // Find the CoM in the source model.
71 const auto* sourceBody = FindComponent<OpenSim::Body>(sourceModel, get_bodies(i));
72 OSC_ASSERT_ALWAYS(sourceBody && "could not find a body in the source model");
73
74 // Find the CoM in the result model (i.e. the one that's midway through warping).
75 const auto* resultBody = FindComponent<OpenSim::Body>(resultModel, get_bodies(i));
76 OSC_ASSERT_ALWAYS(resultBody && "could not find a body in the result model");
77
78 // Warp the CoM, while accounting for different frames etc. between the TPS
79 // landmarks and the CoM.
80 const SimTK::Vec3 warpedLocation = scalingCache.lookupTPSWarpedRigidPoint(
81 sourceModel,
82 resultModel,
83 sourceBody->get_mass_center(),
84 resultBody->get_mass_center(),
85 *sourceBody,
86 *resultBody,
87 *commonParams.sourceLandmarksFrame,
88 *commonParams.resultLandmarksFrame,
89 commonParams.tpsInputs,
90 commonParams.compensateForFrameChanges
91 );
92
93 // Update the body with the new CoM
94 auto* resultBodyMut = FindComponentMut<OpenSim::Body>(resultModel, get_bodies(i));
95 OSC_ASSERT_ALWAYS(resultBodyMut && "could not find a corresponding body in the result model");
96 resultBodyMut->set_mass_center(warpedLocation);
97 }
98 InitializeModel(resultModel);
99 InitializeState(resultModel);
100 }
101 };
102}
#define OSC_ASSERT_ALWAYS(expr)
Definition assertions.h:20
Definition scaling_cache.h:31
SimTK::Vec3 lookupTPSWarpedRigidPoint(const OpenSim::Model &sourceModel, const OpenSim::Model &resultModel, const SimTK::Vec3 &sourceLocation, const SimTK::Vec3 &resultLocation, const OpenSim::Frame &sourceParentFrame, const OpenSim::Frame &resultParentFrame, const OpenSim::Frame &sourceLandmarksFrame, const OpenSim::Frame &resultLandmarksFrame, const ThinPlateSplineCommonInputs &tpsInputs, bool compensateForFrameChanges)
Definition scaling_cache.h:83
Definition scaling_parameters.h:14
virtual std::vector< ScalingStepValidationMessage > implValidate(ScalingCache &, const ScalingParameters &, const OpenSim::Model &) const
Definition scaling_step.h:92
virtual void implApplyScalingStep(ScalingCache &, const ScalingParameters &, const OpenSim::Model &, OpenSim::Model &) const
Definition scaling_step.h:103
Definition thin_plate_spline_body_center_of_mass_scaling_step.h:24
std::vector< ScalingStepValidationMessage > implValidate(ScalingCache &, const ScalingParameters &, const OpenSim::Model &sourceModel) const override
Definition thin_plate_spline_scaling_step.h:72
Definition toggleable_thin_plate_spline_scaling_step.h:14
CommonParameters calcTPSScalingStepCommonParams(const ScalingParameters &parameters, const OpenSim::Model &sourceModel, const OpenSim::Model &resultModel) const
Definition toggleable_thin_plate_spline_scaling_step.h:32
Definition static_component_registries.h:3
Definition component_registry.h:14
void InitializeModel(OpenSim::Model &)
SimTK::State & InitializeState(OpenSim::Model &)