11#include <OpenSim/Simulation/Model/Frame.h>
12#include <OpenSim/Simulation/Model/Model.h>
33 OpenSim_DECLARE_PROPERTY(source_landmarks_file, std::string,
"Filesystem path, relative to the model's filesystem path, where a CSV containing the source landmarks can be loaded from (e.g. `Geometry/torso.landmarks.csv`)");
34 OpenSim_DECLARE_PROPERTY(destination_landmarks_file, std::string,
"Filesystem path, relative to the model's filesystem path, where a CSV containing the destination landmarks can be loaded from (e.g. `DestinationGeometry/torso.landmarks.csv`)");
35 OpenSim_DECLARE_PROPERTY(landmarks_frame, std::string,
"Component path (e.g. `/bodyset/somebody`) to the frame that the landmarks defined in both `source_landmarks_file` and `destination_landmarks_file` are expressed in.\n\nThe engine uses this to figure out how to transform the input to/from the coordinate system of the warp transform.");
36 OpenSim_DECLARE_PROPERTY(compensate_for_frame_changes,
bool,
"If `landmarks_frame` is different from the source data's frame, and previous scaling steps have caused the spatial transform between those two frames to change, compensate for it by inverse-applying the difference between the frames to the result, so that the effect of those frame changes is compensated for. This can be necessary to stop double-warping for occurring (e.g. when separately warping a frame followed by warping data within that frame)");
37 OpenSim_DECLARE_PROPERTY(source_landmarks_prescale,
double,
"Scaling factor that each source landmark point should be multiplied by before computing the TPS warp. This is sometimes necessary if (e.g.) the mesh is in different units (OpenSim works in meters).");
38 OpenSim_DECLARE_PROPERTY(destination_landmarks_prescale,
double,
"Scaling factor that each destination landmark point should be multiplied by before computing the TPS warp. This is sometimes necessary if (e.g.) the mesh is in different units (OpenSim works in meters).");
39 OpenSim_DECLARE_PROPERTY(warping_penalty,
double,
"A warping penalty that smooths out the warp. Explained in OPynSim's Thin-Plate Spline documentation.");
41 struct CommonParameters final {
43 const OpenSim::Frame* sourceLandmarksFrame =
nullptr;
44 const OpenSim::Frame* resultLandmarksFrame =
nullptr;
45 bool compensateForFrameChanges =
false;
54 constructProperty_source_landmarks_file({});
55 constructProperty_destination_landmarks_file({});
56 constructProperty_landmarks_frame(
"/ground");
57 constructProperty_compensate_for_frame_changes(
false);
58 constructProperty_source_landmarks_prescale(1.0);
59 constructProperty_destination_landmarks_prescale(1.0);
60 constructProperty_warping_penalty(0.0);
74 const OpenSim::Model& sourceModel)
const override
76 std::vector<ScalingStepValidationMessage> messages;
80 if (not modelFilesystemLocation) {
86 if (get_source_landmarks_file().
empty()) {
89 else if (
const auto sourceLandmarksPath = modelFilesystemLocation->parent_path() / get_source_landmarks_file();
90 not std::filesystem::exists(sourceLandmarksPath)) {
92 std::stringstream msg;
93 msg << sourceLandmarksPath.string() <<
": Cannot find source landmarks file on filesystem";
98 if (get_destination_landmarks_file().empty()) {
101 else if (
const auto destinationLandmarksPath = modelFilesystemLocation->parent_path() / get_destination_landmarks_file();
102 not std::filesystem::exists(destinationLandmarksPath)) {
104 std::stringstream msg;
105 msg << destinationLandmarksPath.string() <<
": Cannot find destination landmarks file on filesystem";
110 const auto* landmarksFrame = FindComponent<OpenSim::Frame>(sourceModel, get_landmarks_frame());
111 if (not landmarksFrame) {
112 std::stringstream msg;
113 msg << get_landmarks_frame() <<
": Cannot find this frame in the source model (or it isn't a Frame).";
124 const OpenSim::Model& sourceModel,
125 const OpenSim::Model& resultModel)
const
128 const std::optional<std::filesystem::path> modelFilesystemLocation =
TryFindInputFile(resultModel);
129 OSC_ASSERT_ALWAYS(modelFilesystemLocation &&
"The source model has no filesystem location");
132 const std::filesystem::path sourceLandmarksPath = modelFilesystemLocation->parent_path() / get_source_landmarks_file();
135 const std::filesystem::path destinationLandmarksPath = modelFilesystemLocation->parent_path() / get_destination_landmarks_file();
139 const auto* sourceLandmarksFrame = FindComponent<OpenSim::Frame>(sourceModel, get_landmarks_frame());
140 OSC_ASSERT_ALWAYS(sourceLandmarksFrame &&
"could not find the landmarks frame in the source model");
142 const auto* resultLandmarksFrame = FindComponent<OpenSim::Frame>(resultModel, get_landmarks_frame());
143 OSC_ASSERT_ALWAYS(resultLandmarksFrame &&
"could not find the landmarks frame in the model");
145 const std::optional<double> blendingFactor = parameters.
lookup<
double>(
"blending_factor");
146 OSC_ASSERT_ALWAYS(blendingFactor &&
"blending_factor was not set by the warping engine");
148 return CommonParameters{
151 destinationLandmarksPath,
152 get_source_landmarks_prescale(),
153 get_destination_landmarks_prescale(),
155 get_warping_penalty(),
157 .sourceLandmarksFrame = sourceLandmarksFrame,
158 .resultLandmarksFrame = resultLandmarksFrame,
159 .compensateForFrameChanges = get_compensate_for_frame_changes(),
#define OSC_ASSERT_ALWAYS(expr)
Definition assertions.h:20
Definition scaling_cache.h:30
Definition scaling_parameter_declaration.h:16
Definition scaling_parameters.h:14
std::optional< T > lookup(const std::string &key) const
Definition scaling_parameters.h:17
Definition scaling_step.h:25
osc::CStringView label() const
Definition scaling_step.h:41
Definition thin_plate_spline_scaling_step.h:28
std::vector< ScalingStepValidationMessage > implValidate(ScalingCache &, const ScalingParameters &, const OpenSim::Model &sourceModel) const override
Definition thin_plate_spline_scaling_step.h:71
CommonParameters calcTPSScalingStepCommonParams(const ScalingParameters ¶meters, const OpenSim::Model &sourceModel, const OpenSim::Model &resultModel) const
Definition thin_plate_spline_scaling_step.h:122
void implForEachScalingParameterDeclaration(const std::function< void(const ScalingParameterDeclaration &)> &callback) const override
Definition thin_plate_spline_scaling_step.h:64
ThinPlateSplineScalingStep(std::string_view label)
Definition thin_plate_spline_scaling_step.h:51
Definition component_registry.h:14
std::optional< std::filesystem::path > TryFindInputFile(const OpenSim::Model &)
bool empty(const OpenSim::Set< T, C > &s)
Definition open_sim_helpers.h:149