opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
thin_plate_spline_meshes_scaling_step.h
Go to the documentation of this file.
1#pragma once
2
10
11#include <OpenSim/Simulation/Model/Geometry.h>
12
13#include <memory>
14#include <sstream>
15#include <string>
16#include <utility>
17#include <vector>
18
19namespace opyn
20{
21 // A `ScalingStep` that warps `OpenSim::Mesh`es in the source model by using
22 // the Thin-Plate Spline (TPS) warping algorithm on landmark pairs loaded from
23 // associated files.
26
27 OpenSim_DECLARE_LIST_PROPERTY(meshes, std::string, "Component path(s), relative to the model, that locates mesh(es) that should be scaled by this scaling step (e.g. `/bodyset/torso/torso_geom_4`)");
28
29 public:
31 ToggleableThinPlateSplineScalingStep{"Apply Thin-Plate Spline (TPS) to Meshes"}
32 {
33 setDescription("Warps mesh(es) in the source model by applying a Thin-Plate Spline (TPS) warp to each vertex in the souce mesh(es).");
34 constructProperty_meshes();
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 at least one mesh is specified.
46 if (getProperty_meshes().empty()) {
47 messages.emplace_back(ScalingStepValidationState::Error, "No mesh(es) given (e.g. `/bodyset/torso/torso_geom`).");
48 }
49
50 // Ensure all specified meshes can be found in the source model.
51 for (int i = 0; i < getProperty_meshes().size(); ++i) {
52 const auto* mesh = FindComponent<OpenSim::Mesh>(sourceModel, get_meshes(i));
53 if (not mesh) {
54 std::stringstream msg;
55 msg << get_meshes(i) << ": Cannot find entry in 'meshes' in the source model (or it isn't a Mesh).";
56 messages.emplace_back(ScalingStepValidationState::Error, std::move(msg).str());
57 }
58 }
59
60 return messages;
61 }
62
64 ScalingCache& scalingCache,
65 const ScalingParameters& parameters,
66 const OpenSim::Model& sourceModel,
67 OpenSim::Model& resultModel) const final
68 {
69 const auto commonParams = calcTPSScalingStepCommonParams(parameters, sourceModel, resultModel);
70
71 // Warp each mesh specified by the `meshes` property.
72 for (int i = 0; i < getProperty_meshes().size(); ++i) {
73 const auto* sourceMesh = FindComponent<OpenSim::Mesh>(sourceModel, get_meshes(i));
74 OSC_ASSERT_ALWAYS(sourceMesh && "could not find a mesh in the source model");
75
76 // Find the input mesh and use it produce the warped mesh.
77 const auto* resultMesh = FindComponent<OpenSim::Mesh>(resultModel, get_meshes(i));
78 OSC_ASSERT_ALWAYS(resultMesh && "could not find a mesh in the model");
79
80 std::unique_ptr<InMemoryMesh> warpedMesh = scalingCache.lookupTPSMeshWarp(
81 sourceModel,
82 resultModel,
83 *sourceMesh,
84 *resultMesh,
85 *commonParams.sourceLandmarksFrame,
86 *commonParams.resultLandmarksFrame,
87 commonParams.tpsInputs,
88 commonParams.compensateForFrameChanges
89 );
90 OSC_ASSERT_ALWAYS(warpedMesh && "warping a mesh in the model failed");
91
92 // Overwrite the mesh in the result model with the warped mesh.
93 auto* resultMeshMut = FindComponentMut<OpenSim::Mesh>(resultModel, get_meshes(i));
94 OSC_ASSERT_ALWAYS(resultMesh && "could not find a corresponding mesh in the result model");
95 OverwriteGeometry(resultModel, *resultMeshMut, std::move(warpedMesh));
96 OSC_ASSERT_ALWAYS(FindComponent<InMemoryMesh>(resultModel, get_meshes(i)) != nullptr);
97 }
98 InitializeModel(resultModel);
99 InitializeState(resultModel);
100 }
101 };
102}
#define OSC_ASSERT_ALWAYS(expr)
Definition assertions.h:20
Definition scaling_cache.h:30
Definition scaling_parameters.h:14
virtual std::vector< ScalingStepValidationMessage > implValidate(ScalingCache &, const ScalingParameters &, const OpenSim::Model &) const
Definition scaling_step.h:92
Definition thin_plate_spline_meshes_scaling_step.h:24
ThinPlateSplineMeshesScalingStep()
Definition thin_plate_spline_meshes_scaling_step.h:30
void implApplyScalingStep(ScalingCache &scalingCache, const ScalingParameters &parameters, const OpenSim::Model &sourceModel, OpenSim::Model &resultModel) const final
Definition thin_plate_spline_meshes_scaling_step.h:63
std::vector< ScalingStepValidationMessage > implValidate(ScalingCache &cache, const ScalingParameters &params, const OpenSim::Model &sourceModel) const final
Definition thin_plate_spline_meshes_scaling_step.h:37
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 component_registry.h:14
void InitializeModel(OpenSim::Model &)
bool empty(const OpenSim::Set< T, C > &s)
Definition open_sim_helpers.h:149
SimTK::State & InitializeState(OpenSim::Model &)
void OverwriteGeometry(OpenSim::Model &, OpenSim::Geometry &oldGeometry, std::unique_ptr< OpenSim::Geometry > newGeometry)