Skip to content

Commit

Permalink
Stub out parts of the ComponentWarpingStrategy implementaions
Browse files Browse the repository at this point in the history
  • Loading branch information
adamkewley committed Jul 3, 2024
1 parent 13a3733 commit 44b359e
Showing 1 changed file with 155 additions and 12 deletions.
167 changes: 155 additions & 12 deletions src/OpenSimCreator/Documents/ModelWarper/ModelWarperConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <concepts>
#include <filesystem>
#include <sstream>
#include <stdexcept>
#include <string>
#include <string_view>
#include <typeinfo>
#include <unordered_set>
Expand Down Expand Up @@ -47,8 +49,19 @@ namespace osc::mow
State _state = State::None;
};

// an abstract interface to something that is capable of warping one specific component in
// the model
// additional warping parameters that are provided at runtime by the caller (usually, these are
// less "static" than the parameters provided via the `ModelWarperConfiguration`)
class RuntimeWarpParameters final {
public:
RuntimeWarpParameters() = default;
explicit RuntimeWarpParameters(float blendFactor) : m_BlendFactor{blendFactor} {}

float getBlendFactor() const { return m_BlendFactor; }
private:
float m_BlendFactor = 1.0f;
};

// an interface to an object that is capable of warping one specific component in the input model
//
// a `ComponentWarpingStrategy` produces this after matching the component, validating it against,
// the rest of the model, etc.
Expand All @@ -62,23 +75,60 @@ namespace osc::mow
public:
virtual ~IComponentWarper() noexcept = default;

void warpInPlace(const WarpableModel& model, const OpenSim::Component& source, OpenSim::Component& targetCopy)
void warpInPlace(
const RuntimeWarpParameters& warpParameters,
const WarpableModel& sourceModel,
const OpenSim::Component& sourceComponent,
OpenSim::Model& targetModel,
OpenSim::Component& targetComponent)
{
implWarpInPlace(model, source, targetCopy);
implWarpInPlace(warpParameters, sourceModel, sourceComponent, targetModel, targetComponent);
}
private:
virtual void implWarpInPlace(const WarpableModel&, const OpenSim::Component& source, OpenSim::Component& targetCopy) = 0;
virtual void implWarpInPlace(
const RuntimeWarpParameters& warpParameters,
const WarpableModel& sourceModel,
const OpenSim::Component& sourceComponent,
OpenSim::Model& targetModel,
OpenSim::Component& targetComponent
) = 0;
};

// concrete implementation of an `IComponentWarper` that does nothing
//
// (handy as a stand-in during development)
class IdentityComponentWarper : public IComponentWarper {
private:
void implWarpInPlace(const WarpableModel&, const OpenSim::Component&, OpenSim::Component&) override
void implWarpInPlace(
const RuntimeWarpParameters&,
const WarpableModel&,
const OpenSim::Component&,
OpenSim::Model&,
OpenSim::Component&) override
{}
};

// concrete implementation of an `IComponentWarper` that throws an exception
// when used
class ExceptionThrowingComponentWarper : public IComponentWarper {
public:
explicit ExceptionThrowingComponentWarper(std::string message) :
m_Message{std::move(message)}
{}
private:
void implWarpInPlace(
const RuntimeWarpParameters&,
const WarpableModel&,
const OpenSim::Component&,
OpenSim::Model&,
OpenSim::Component&) override
{
throw std::runtime_error{m_Message};
}

std::string m_Message;
};

// abstract interface to a component that is capable of warping `n` other
// components (`StrategyTargets`) during a model warp
class ComponentWarpingStrategy :
Expand Down Expand Up @@ -212,6 +262,7 @@ namespace osc::mow

std::vector<WarpDetail> implWarpDetails() const override
{
// TODO: similar steps to `ThinPlateSplineStationWarpingStrategy`
return {};
}

Expand All @@ -234,12 +285,21 @@ namespace osc::mow

std::vector<WarpDetail> implWarpDetails() const override
{
return {};
return {
WarpDetail{"description", "this warping strategy will always produce an error: you probably need to configure a better strategy for this component"},
};
}

std::unique_ptr<IComponentWarper> implCreateWarper(const WarpableModel&, const OpenSim::Component&) override
{
return std::make_unique<IdentityComponentWarper>();
return std::make_unique<ExceptionThrowingComponentWarper>("ProduceErrorStationWarpingStrategy: TODO: configuration-customizable error message");
}

std::vector<ValidationCheckResult> implValidate(const WarpableModel&) const
{
return {
ValidationCheckResult{"this warping strategy always produces an error (TODO: configuration-customizable error message)", ValidationCheckState::Error},
};
}
};

Expand All @@ -256,13 +316,22 @@ namespace osc::mow

std::vector<WarpDetail> implWarpDetails() const override
{
return {};
return {
WarpDetail{"description", "this warping strategy will leave the frame untouched"},
};
}

std::unique_ptr<IComponentWarper> implCreateWarper(const WarpableModel&, const OpenSim::Component&) override
{
return std::make_unique<IdentityComponentWarper>();
}

std::vector<ValidationCheckResult> implValidate(const WarpableModel&) const
{
return {
ValidationCheckResult{"this is an identity warp (i.e. it ignores warping this offset frame altogether)", ValidationCheckState::Warning},
};
}
};

// abstract interface to a component that is capable of warping `n`
Expand All @@ -282,8 +351,64 @@ namespace osc::mow
return std::make_unique<ThinPlateSplineStationWarpingStrategy>(*this);
}

std::vector<ValidationCheckResult> implValidate(const WarpableModel&) const
{
/*
* std::vector<ValidationCheckResult> rv;
// has a source landmarks file
{
std::stringstream ss;
ss << "has source landmarks file at " << recommendedSourceLandmarksFilepath().string();
rv.emplace_back(std::move(ss).str(), hasSourceLandmarksFilepath());
}
// has source landmarks
rv.emplace_back("source landmarks file contains landmarks", hasSourceLandmarks());
// has destination mesh file
{
std::stringstream ss;
ss << "has destination mesh file at " << recommendedDestinationMeshFilepath().string();
rv.emplace_back(std::move(ss).str(), hasDestinationMeshFilepath());
}
// has destination landmarks file
{
std::stringstream ss;
ss << "has destination landmarks file at " << recommendedDestinationLandmarksFilepath().string();
rv.emplace_back(std::move(ss).str(), hasDestinationLandmarksFilepath());
}
// has destination landmarks
rv.emplace_back("destination landmarks file contains landmarks", hasDestinationLandmarks());
// has at least a few paired landmarks
rv.emplace_back("at least three landmarks can be paired between source/destination", getNumFullyPairedLandmarks() >= 3);
// (warning): has no unpaired landmarks
rv.emplace_back("there are no unpaired landmarks", getNumUnpairedLandmarks() == 0 ? ValidationCheckState::Ok : ValidationCheckState::Warning);
*/
return {};
}

std::vector<WarpDetail> implWarpDetails() const override
{
/*
* std::vector<WarpDetail> rv;
rv.emplace_back("source mesh filepath", getSourceMeshAbsoluteFilepath().string());
rv.emplace_back("source landmarks expected filepath", recommendedSourceLandmarksFilepath().string());
rv.emplace_back("has source landmarks file?", hasSourceLandmarksFilepath() ? "yes" : "no");
rv.emplace_back("number of source landmarks", std::to_string(getNumSourceLandmarks()));
rv.emplace_back("destination mesh expected filepath", recommendedDestinationMeshFilepath().string());
rv.emplace_back("has destination mesh?", hasDestinationMeshFilepath() ? "yes" : "no");
rv.emplace_back("destination landmarks expected filepath", recommendedDestinationLandmarksFilepath().string());
rv.emplace_back("has destination landmarks file?", hasDestinationLandmarksFilepath() ? "yes" : "no");
rv.emplace_back("number of destination landmarks", std::to_string(getNumDestinationLandmarks()));
rv.emplace_back("number of paired landmarks", std::to_string(getNumFullyPairedLandmarks()));
rv.emplace_back("number of unpaired landmarks", std::to_string(getNumUnpairedLandmarks()));
return rv;
*/
return {};
}

Expand All @@ -305,12 +430,21 @@ namespace osc::mow

std::vector<WarpDetail> implWarpDetails() const override
{
return {};
return {
WarpDetail{"description", "this warping strategy will always produce an error: you probably need to configure a better strategy for this component"},
};
}

std::unique_ptr<IComponentWarper> implCreateWarper(const WarpableModel&, const OpenSim::Component&) override
{
return std::make_unique<IdentityComponentWarper>();
return std::make_unique<ExceptionThrowingComponentWarper>("ProduceErrorStationWarpingStrategy: TODO: configuration-customizable error message");
}

std::vector<ValidationCheckResult> implValidate(const WarpableModel&) const
{
return {
ValidationCheckResult{"this warping strategy always produces an error (TODO: configuration-customizable error message)", ValidationCheckState::Error},
};
}
};

Expand All @@ -326,13 +460,22 @@ namespace osc::mow

std::vector<WarpDetail> implWarpDetails() const override
{
return {};
return {
WarpDetail{"description", "this warping strategy will leave the station untouched"},
};
}

std::unique_ptr<IComponentWarper> implCreateWarper(const WarpableModel&, const OpenSim::Component&) override
{
return std::make_unique<IdentityComponentWarper>();
}

std::vector<ValidationCheckResult> implValidate(const WarpableModel&) const
{
return {
ValidationCheckResult{"this is an identity warp (i.e. it ignores warping this station altogether)", ValidationCheckState::Warning},
};
}
};

// top-level model warping configuration file
Expand Down

0 comments on commit 44b359e

Please sign in to comment.