18#include <OpenSim/Simulation/Model/Model.h>
19#include <SimTKcommon/internal/Transform.h>
20#include <SimTKcommon/internal/Rotation.h>
21#include <SimTKcommon/SmallMatrix.h>
33 const OpenSim::Model& sourceModel,
34 const OpenSim::Model& resultModel,
35 const OpenSim::Mesh& sourceMesh,
36 const OpenSim::Mesh& resultMesh,
37 const OpenSim::Frame& sourceLandmarksFrame,
38 const OpenSim::Frame& resultLandmarksFrame,
40 bool compensateForFrameChanges)
46 const Transforms transforms = calculateTransforms(
49 sourceMesh.getFrame(),
50 resultMesh.getFrame(),
53 compensateForFrameChanges
59 resultModel.getWorkingState(),
64 auto vertices = resultOscMesh.
vertices();
65 for (
auto& vertex : vertices) {
66 vertex = transform_point(transforms.localToLandmarks, vertex);
68 static_assert(
alignof(
decltype(vertices.front())) ==
alignof(SimTK::fVec3));
69 static_assert(
sizeof(
decltype(vertices.front())) ==
sizeof(SimTK::fVec3));
70 auto* punned = std::launder(
reinterpret_cast<SimTK::fVec3*
>(vertices.data()));
72 for (
auto& vertex : vertices) {
73 vertex = transform_point(transforms.landmarksToLocal, vertex);
79 return std::make_unique<InMemoryMesh>(resultOscMesh);
83 const OpenSim::Model& sourceModel,
84 const OpenSim::Model& resultModel,
85 [[maybe_unused]]
const SimTK::Vec3& sourceLocation,
86 const SimTK::Vec3& resultLocation,
87 const OpenSim::Frame& sourceParentFrame,
88 const OpenSim::Frame& resultParentFrame,
89 const OpenSim::Frame& sourceLandmarksFrame,
90 const OpenSim::Frame& resultLandmarksFrame,
92 bool compensateForFrameChanges)
98 const Transforms transforms = calculateTransforms(
103 sourceLandmarksFrame,
104 resultLandmarksFrame,
105 compensateForFrameChanges
108 const auto resultLocationInLandmarkFrame = transform_point(transforms.localToLandmarks,
osc::to<osc::Vector3>(resultLocation));
120 const SimTK::Vec<3, float> x = coefficients.
a2.normalize();
121 const SimTK::Vec<3, float> y = coefficients.
a3.normalize();
122 const SimTK::Vec<3, float> z = coefficients.
a4.normalize();
123 const SimTK::Mat33 rotationMatrix{
128 const SimTK::Rotation rotation{rotationMatrix};
130 return SimTK::Transform{rotation, translation};
133 struct Transforms final {
138 Transforms calculateTransforms(
139 const OpenSim::Model& sourceModel,
140 const OpenSim::Model& resultModel,
141 const OpenSim::Frame& sourceFrame,
142 const OpenSim::Frame& resultFrame,
143 const OpenSim::Frame& sourceLandmarksFrame,
144 const OpenSim::Frame& resultLandmarksFrame,
145 bool compensateForFrameChanges)
const
147 const SimTK::Transform resultTransform = resultFrame.findTransformBetween(resultModel.getWorkingState(), resultLandmarksFrame);
149 if (compensateForFrameChanges) {
150 const SimTK::Transform sourceTransform = sourceFrame.findTransformBetween(sourceModel.getWorkingState(), sourceLandmarksFrame);
151 const SimTK::Transform frameWarpTransform = sourceTransform.invert() * resultTransform;
164 const TPSCoefficients3D<float>& lookupTPSCoefficients(
const ThinPlateSplineCommonInputs& tpsInputs)
171 TPSCoefficientSolverInputs3D<float> inputs;
172 inputs.landmarks.reserve(
osc::max(sourceLandmarks.size(), destinationLandmarks.size()));
173 TryPairingLandmarks(sourceLandmarks, destinationLandmarks, [&inputs, &tpsInputs](
const MaybeNamedLandmarkPair& p)
175 if (
auto landmark3d = p.tryGetPairedLocations()) {
176 landmark3d->source = tpsInputs.sourceLandmarksPrescale * landmark3d->source;
177 landmark3d->destination = tpsInputs.destinationLandmarksPrescale * landmark3d->destination;
178 inputs.landmarks.push_back(*landmark3d);
181 osc::log_warn(
"The landmarks %s could not be paired, might be missing in the source/destination?", p.name().c_str());
184 inputs.apply_affine_translation = tpsInputs.applyAffineTranslation;
185 inputs.apply_affine_scale = tpsInputs.applyAffineScale;
186 inputs.apply_affine_rotation = tpsInputs.applyAffineRotation;
187 inputs.apply_non_affine_warp = tpsInputs.applyNonAffineWarp;
188 inputs.warping_penalty =
static_cast<float>(tpsInputs.warpingPenalty);
193 return m_CoefficientsTODO;
196 TPSCoefficients3D<float> m_CoefficientsTODO;
#define OSC_ASSERT_ALWAYS(expr)
Definition assertions.h:20
Definition scaling_cache.h:30
SimTK::Transform lookupTPSAffineTransformWithoutScaling(const ThinPlateSplineCommonInputs &tpsInputs)
Definition scaling_cache.h:113
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:82
std::unique_ptr< InMemoryMesh > lookupTPSMeshWarp(const OpenSim::Model &sourceModel, const OpenSim::Model &resultModel, const OpenSim::Mesh &sourceMesh, const OpenSim::Mesh &resultMesh, const OpenSim::Frame &sourceLandmarksFrame, const OpenSim::Frame &resultLandmarksFrame, const ThinPlateSplineCommonInputs &tpsInputs, bool compensateForFrameChanges)
Definition scaling_cache.h:32
void set_vertices(std::span< const Vector3 >)
void recalculate_normals()
std::vector< Vector3 > vertices() const
Definition component_registry.h:14
void tps3d_warp_points_in_place(const TPSCoefficients3D< float > &, std::span< SimTK::Vec< 3, float > >, float linear_interpolant)
TPSCoefficients3D< float > tps3d_solve_coefficients(const TPSCoefficientSolverInputs3D< float > &)
SimTK::Vec< 3, float > tps3d_warp_point(const TPSCoefficients3D< float > &, const SimTK::Vec< 3, float > &p)
void TryPairingLandmarks(std::vector< Landmark >, std::vector< Landmark >, const std::function< void(const MaybeNamedLandmarkPair &)> &consumer)
std::vector< Landmark > ReadLandmarksFromCSVIntoVectorOrThrow(const std::filesystem::path &)
osc::Mesh ToOscMesh(osc::SceneCache &, const OpenSim::Model &, const SimTK::State &, const OpenSim::Mesh &, const OpenSimDecorationOptions &, float fixupScaleFactor)
Vector3 transform_point(const Matrix4x4 &mat, const Vector3 &point)
Definition math_helpers.h:140
constexpr auto max(Angle< Rep1, Units1 > x, Angle< Rep2, Units2 > y) -> std::common_type_t< decltype(x), decltype(y)>
Definition angle.h:283
constexpr U to(T &&value)
Definition conversion.h:56
SimTK::Vec< 3, T > a1
Definition tps3d.h:138
SimTK::Vec< 3, T > a3
Definition tps3d.h:140
SimTK::Vec< 3, T > a4
Definition tps3d.h:141
SimTK::Vec< 3, T > a2
Definition tps3d.h:139