Skip to content

Commit

Permalink
Revert "Temporarily remove EdgeEl so that the branch can be merged to…
Browse files Browse the repository at this point in the history
… main (#802)"

This reverts commit 2ba887a.
  • Loading branch information
adamkewley committed Nov 20, 2023
1 parent 2ba887a commit 049df19
Show file tree
Hide file tree
Showing 12 changed files with 414 additions and 24 deletions.
2 changes: 2 additions & 0 deletions src/OpenSimCreator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ add_library(OpenSimCreator STATIC
ModelGraph/CommittableModelGraphActions.hpp
ModelGraph/CrossrefDescriptor.hpp
ModelGraph/CrossrefDirection.hpp
ModelGraph/EdgeEl.cpp
ModelGraph/EdgeEl.hpp
ModelGraph/GroundEl.cpp
ModelGraph/GroundEl.hpp
ModelGraph/ISceneElLookup.hpp
Expand Down
31 changes: 31 additions & 0 deletions src/OpenSimCreator/ModelGraph/CommittableModelGraphActions.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "CommittableModelGraphActions.hpp"

#include <OpenSimCreator/ModelGraph/BodyEl.hpp>
#include <OpenSimCreator/ModelGraph/EdgeEl.hpp>
#include <OpenSimCreator/ModelGraph/JointEl.hpp>
#include <OpenSimCreator/ModelGraph/MeshEl.hpp>
#include <OpenSimCreator/ModelGraph/ModelGraph.hpp>
Expand Down Expand Up @@ -465,3 +466,33 @@ bool osc::AddStationAtLocation(

return AddStationAtLocation(cmg, *el, loc);
}

bool osc::CreateEdgeBetween(
CommittableModelGraph& cmg,
UID firstSideID,
UID secondSideID)
{
ModelGraph& mg = cmg.updScratch();

auto const* const firstSideEl = mg.tryGetElByID(firstSideID);
if (!firstSideEl || !CanAttachEdgeTo(*firstSideEl))
{
return false;
}

auto const* const secondSideEl = mg.tryGetElByID(secondSideID);
if (!secondSideEl || !CanAttachEdgeTo(*secondSideEl))
{
return false;
}

auto const& edge = mg.emplaceEl<EdgeEl>(
UID{},
EdgeEl::Class().generateName(),
firstSideID,
secondSideID
);
SelectOnly(mg, edge);
cmg.commitScratch("added edge " + edge.getLabel());
return true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,10 @@ namespace osc
UID elID,
Vec3 const& loc
);

bool CreateEdgeBetween(
CommittableModelGraph&,
UID firstSideID,
UID secondSideID
);
}
66 changes: 66 additions & 0 deletions src/OpenSimCreator/ModelGraph/EdgeEl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "EdgeEl.hpp"

#include <OpenSimCreator/ModelGraph/ISceneElLookup.hpp>
#include <OpenSimCreator/ModelGraph/SceneEl.hpp>
#include <OpenSimCreator/ModelGraph/SceneElClass.hpp>

#include <IconsFontAwesome5.h>
#include <oscar/Maths/AABB.hpp>
#include <oscar/Maths/MathHelpers.hpp>
#include <oscar/Maths/Transform.hpp>
#include <oscar/Maths/Vec3.hpp>

#include <iostream>
#include <utility>

std::pair<osc::Vec3, osc::Vec3> osc::EdgeEl::getEdgeLineInGround(ISceneElLookup const& lookup) const
{
SceneEl const* first = lookup.find(m_FirstAttachmentID);
SceneEl const* second = lookup.find(m_SecondAttachmentID);
if (first && second)
{
return {first->getPos(lookup), second->getPos(lookup)};
}
else
{
return {Vec3{}, Vec3{}};
}
}

osc::SceneElClass osc::EdgeEl::CreateClass()
{
return SceneElClass
{
"Edge",
"Edges",
"Edge(s)",
ICON_FA_ARROWS_ALT,
"An edge between the centers of two other scene elements",
};
}

osc::Transform osc::EdgeEl::implGetXform(ISceneElLookup const& lookup) const
{
SceneEl const* first = lookup.find(m_FirstAttachmentID);
SceneEl const* second = lookup.find(m_FirstAttachmentID);
if (first && second)
{
Vec3 const pos = osc::Midpoint(first->getPos(lookup), second->getPos(lookup));
return Transform{.position = pos};
}
else
{
return Identity<Transform>();
}
}

std::ostream& osc::EdgeEl::implWriteToStream(std::ostream& out) const
{
return out << "Edge(id = " << m_ID << ", lhs = " << m_FirstAttachmentID << ", rhs = " << m_SecondAttachmentID << ')';
}

osc::AABB osc::EdgeEl::implCalcBounds(ISceneElLookup const& lookup) const
{
auto const p = getEdgeLineInGround(lookup);
return BoundingAABBOf(std::to_array({p.first, p.second}));
}
118 changes: 118 additions & 0 deletions src/OpenSimCreator/ModelGraph/EdgeEl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#pragma once

#include <OpenSimCreator/ModelGraph/CrossrefDescriptor.hpp>
#include <OpenSimCreator/ModelGraph/SceneElClass.hpp>
#include <OpenSimCreator/ModelGraph/SceneElCRTP.hpp>
#include <OpenSimCreator/ModelGraph/SceneElFlags.hpp>

#include <oscar/Maths/AABB.hpp>
#include <oscar/Maths/Transform.hpp>
#include <oscar/Maths/Vec3.hpp>
#include <oscar/Utils/CStringView.hpp>
#include <oscar/Utils/UID.hpp>

#include <iosfwd>
#include <stdexcept>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

namespace osc { class ISceneElLookup; }

namespace osc
{
class EdgeEl final : public SceneElCRTP<EdgeEl> {
public:
EdgeEl(
UID id_,
std::string_view label_,
UID firstAttachmentID_,
UID secondAttachmentID_) :

m_ID{id_},
m_Label{label_},
m_FirstAttachmentID{firstAttachmentID_},
m_SecondAttachmentID{secondAttachmentID_}
{
}

std::pair<Vec3, Vec3> getEdgeLineInGround(ISceneElLookup const&) const;

UID getFirstAttachmentID() const
{
return m_FirstAttachmentID;
}

UID getSecondAttachmentID() const
{
return m_SecondAttachmentID;
}
private:
friend class SceneElCRTP<EdgeEl>;
static SceneElClass CreateClass();

std::vector<CrossrefDescriptor> implGetCrossReferences() const final
{
return
{
{m_FirstAttachmentID, "First Point", CrossrefDirection::ToParent},
{m_SecondAttachmentID, "Second Point", CrossrefDirection::ToParent},
};
}

void implSetCrossReferenceConnecteeID(int i, UID newAttachmentID) final
{
switch (i) {
case 0:
m_FirstAttachmentID = newAttachmentID;
return;
case 1:
m_SecondAttachmentID = newAttachmentID;
return;
default:
throw std::runtime_error{"invalid index passed when looking up a cross refernece"};
}
}

SceneElFlags implGetFlags() const final
{
return
SceneElFlags::CanChangeLabel |
SceneElFlags::CanDelete |
SceneElFlags::CanSelect |
SceneElFlags::HasPhysicalSize;
}

UID implGetID() const final
{
return m_ID;
}

std::ostream& implWriteToStream(std::ostream&) const final;

CStringView implGetLabel() const
{
return m_Label;
}

void implSetLabel(std::string_view newLabel) final
{
m_Label = newLabel;
}

Transform implGetXform(ISceneElLookup const&) const final;

void implSetXform(ISceneElLookup const&, Transform const&) final
{
// do nothing: transform is defined by both attachments
}

AABB implCalcBounds(ISceneElLookup const&) const final;

UID m_ID;
std::string m_Label;
UID m_FirstAttachmentID;
UID m_SecondAttachmentID;
};
}
44 changes: 25 additions & 19 deletions src/OpenSimCreator/ModelGraph/ModelGraphHelpers.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "ModelGraphHelpers.hpp"

#include <OpenSimCreator/ModelGraph/BodyEl.hpp>
#include <OpenSimCreator/ModelGraph/EdgeEl.hpp>
#include <OpenSimCreator/ModelGraph/JointEl.hpp>
#include <OpenSimCreator/ModelGraph/MeshEl.hpp>
#include <OpenSimCreator/ModelGraph/ModelGraph.hpp>
Expand Down Expand Up @@ -193,25 +194,29 @@ std::string osc::GetContextMenuSubHeaderText(
std::visit(Overload
{
[&ss](GroundEl const&)
{
ss << "(scene origin)";
},
[&ss, &mg](MeshEl const& m)
{
ss << '(' << m.getClass().getName() << ", " << m.getPath().filename().string() << ", attached to " << getLabel(mg, m.getParentID()) << ')';
},
[&ss](BodyEl const& b)
{
ss << '(' << b.getClass().getName() << ')';
},
[&ss, &mg](JointEl const& j)
{
ss << '(' << j.getSpecificTypeName() << ", " << getLabel(mg, j.getChildID()) << " --> " << getLabel(mg, j.getParentID()) << ')';
},
[&ss, &mg](StationEl const& s)
{
ss << '(' << s.getClass().getName() << ", attached to " << getLabel(mg, s.getParentID()) << ')';
},
{
ss << "(scene origin)";
},
[&ss, &mg](MeshEl const& m)
{
ss << '(' << m.getClass().getName() << ", " << m.getPath().filename().string() << ", attached to " << getLabel(mg, m.getParentID()) << ')';
},
[&ss](BodyEl const& b)
{
ss << '(' << b.getClass().getName() << ')';
},
[&ss, &mg](JointEl const& j)
{
ss << '(' << j.getSpecificTypeName() << ", " << getLabel(mg, j.getChildID()) << " --> " << getLabel(mg, j.getParentID()) << ')';
},
[&ss, &mg](StationEl const& s)
{
ss << '(' << s.getClass().getName() << ", attached to " << getLabel(mg, s.getParentID()) << ')';
},
[&ss, &mg](EdgeEl const& e)
{
ss << '(' << e.getClass().getName() << ", " << getLabel(mg, e.getFirstAttachmentID()) << " --> " << getLabel(mg, e.getSecondAttachmentID()) << ')';
}
}, e.toVariant());
return std::move(ss).str();
}
Expand Down Expand Up @@ -279,6 +284,7 @@ osc::UID osc::GetStationAttachmentParent(ModelGraph const& mg, SceneEl const& el
[](BodyEl const& bodyEl) { return bodyEl.getID(); },
[](JointEl const&) { return ModelGraphIDs::Ground(); },
[](StationEl const&) { return ModelGraphIDs::Ground(); },
[](EdgeEl const&) { return ModelGraphIDs::Ground(); },
}, el.toVariant());
}

Expand Down
17 changes: 17 additions & 0 deletions src/OpenSimCreator/ModelGraph/SceneElHelpers.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "SceneElHelpers.hpp"

#include <OpenSimCreator/ModelGraph/BodyEl.hpp>
#include <OpenSimCreator/ModelGraph/EdgeEl.hpp>
#include <OpenSimCreator/ModelGraph/GroundEl.hpp>
#include <OpenSimCreator/ModelGraph/JointEl.hpp>
#include <OpenSimCreator/ModelGraph/MeshEl.hpp>
Expand All @@ -24,6 +25,7 @@ bool osc::CanAttachMeshTo(SceneEl const& e)
[](BodyEl const&) { return true; },
[](JointEl const&) { return true; },
[](StationEl const&) { return false; },
[](EdgeEl const&) { return false; },
}, e.toVariant());
}

Expand All @@ -36,9 +38,23 @@ bool osc::CanAttachStationTo(SceneEl const& e)
[](BodyEl const&) { return true; },
[](JointEl const&) { return false; },
[](StationEl const&) { return false; },
[](EdgeEl const&) { return false; },
}, e.toVariant());
}

bool osc::CanAttachEdgeTo(SceneEl const& el)
{
return std::visit(Overload
{
[](GroundEl const&) { return true; },
[](MeshEl const&) { return true; },
[](BodyEl const&) { return true; },
[](JointEl const&) { return true; },
[](StationEl const&) { return true; },
[](EdgeEl const&) { return false; },
}, el.toVariant());
}

std::array<osc::SceneElClass, std::variant_size_v<osc::SceneElVariant>> const& osc::GetSceneElClasses()
{
static auto const s_Classes = std::to_array(
Expand All @@ -48,6 +64,7 @@ std::array<osc::SceneElClass, std::variant_size_v<osc::SceneElVariant>> const& o
BodyEl::Class(),
JointEl::Class(),
StationEl::Class(),
EdgeEl::Class(),
});
return s_Classes;
}
Expand Down
3 changes: 3 additions & 0 deletions src/OpenSimCreator/ModelGraph/SceneElHelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ namespace osc
// returns `true` if a `StationEl` can be attached to the element
bool CanAttachStationTo(SceneEl const&);

// returns `true` if `EdgeEl` can be attached to `el`
bool CanAttachEdgeTo(SceneEl const&);

std::array<SceneElClass, std::variant_size_v<SceneElVariant>> const& GetSceneElClasses();

Vec3 AverageCenter(MeshEl const&);
Expand Down
7 changes: 5 additions & 2 deletions src/OpenSimCreator/ModelGraph/SceneElVariant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ namespace osc
class BodyEl;
class JointEl;
class StationEl;
class EdgeEl;

// a variant for storing a `const` reference to a `const` scene element
using ConstSceneElVariant = std::variant<
std::reference_wrapper<GroundEl const>,
std::reference_wrapper<MeshEl const>,
std::reference_wrapper<BodyEl const>,
std::reference_wrapper<JointEl const>,
std::reference_wrapper<StationEl const>
std::reference_wrapper<StationEl const>,
std::reference_wrapper<EdgeEl const>
>;

// a variant for storing a non-`const` reference to a non-`const` scene element
Expand All @@ -26,6 +28,7 @@ namespace osc
std::reference_wrapper<MeshEl>,
std::reference_wrapper<BodyEl>,
std::reference_wrapper<JointEl>,
std::reference_wrapper<StationEl>
std::reference_wrapper<StationEl>,
std::reference_wrapper<EdgeEl>
>;
}
Loading

0 comments on commit 049df19

Please sign in to comment.