Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/BeamAdapter/component/engine/WireRestShape.inl
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ bool WireRestShape<DataTypes>::initTopology()
l_topology->addEdge(i, i + 1);
}

prev_length = length;
prev_edges = nbrVisuEdges;
prev_length += length;
prev_edges += nbrVisuEdges;
startPtId = 1; // Assume the last point of mat[n] == first point of mat[n+1]
}

Expand Down Expand Up @@ -315,12 +315,23 @@ void WireRestShape<DataTypes>::getRestTransformOnX(Transform &global_H_local, co
}

const type::vector<Real>& keyPts = d_keyPoints.getValue();
// Walk all sections preceding the one that owns x_used and accumulate their tip transforms.
// Each section composes its local rest geometry with this predecessor frame, so chained non-straight
// sections (Spire after Spire, Mesh after Spire, ...) stay tangent-continuous instead of being placed
// along the world X axis at keyPts[i].
Transform predecessor = Transform::identity();
for (sofa::Size i = 1; i < keyPts.size(); ++i)
{
if (x_used <= keyPts[i])
{
return l_sectionMaterials.get(i - 1)->getRestTransformOnX(global_H_local, x_used, keyPts[i - 1]);
return l_sectionMaterials.get(i - 1)->getRestTransformOnX(
global_H_local, x_used, keyPts[i - 1], predecessor);
}

Transform tip;
l_sectionMaterials.get(i - 1)->getRestTransformOnX(
tip, keyPts[i], keyPts[i - 1], predecessor);
predecessor = tip;
}

msg_error() << " problem in getRestTransformOnX : x_curv " << x_used << " is not between keyPoints" << d_keyPoints.getValue();
Expand Down
10 changes: 8 additions & 2 deletions src/BeamAdapter/component/model/BaseRodSectionMaterial.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,18 @@ class BaseRodSectionMaterial : public core::objectmodel::BaseComponent
/// Returns the Young modulus, Poisson's and massDensity coefficient of this section
void getMechanicalParameters(Real& youngModulus, Real& cPoisson, Real& massDensity) const;

/// This function is called to get the rest position of the beam depending on the current curved abscisse given in parameter
virtual void getRestTransformOnX(Transform& global_H_local, const Real x_used, const Real x_start)
/// This function is called to get the rest position of the beam depending on the current curved abscisse given in parameter.
/// @param predecessor_H_sectionStart locates this section's starting frame wrt world. Pass Transform::identity()
/// for the first section. Subsequent sections receive the accumulated tip transform of all preceding sections so
/// each section composes its local rest geometry with the actual end-frame of the predecessor instead of assuming
/// the wire so far ran straight along world +X.
virtual void getRestTransformOnX(Transform& global_H_local, const Real x_used, const Real x_start,
const Transform& predecessor_H_sectionStart)
{
SOFA_UNUSED(global_H_local);
SOFA_UNUSED(x_used);
SOFA_UNUSED(x_start);
SOFA_UNUSED(predecessor_H_sectionStart);
}

protected:
Expand Down
7 changes: 5 additions & 2 deletions src/BeamAdapter/component/model/RodMeshSection.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,11 @@ class RodMeshSection : public BaseRodSectionMaterial<DataTypes>
/// Default Constructor
RodMeshSection();

/// Override method to get the rest position of the beam. In this implementation, it will interpolate along the loaded mesh geometry
void getRestTransformOnX(Transform& global_H_local, const Real x_used, const Real x_start) override;
/// Override method to get the rest position of the beam. The mesh-interpolated rest transform is expressed in the
/// section's local frame (origin at the section start, +X = predecessor tip tangent) and composed with
/// @p predecessor_H_sectionStart to obtain the world rest transform.
void getRestTransformOnX(Transform& global_H_local, const Real x_used, const Real x_start,
const Transform& predecessor_H_sectionStart) override;

protected:
/// Internal method to init the section. Called by @sa BaseRodSectionMaterial::init() method
Expand Down
12 changes: 6 additions & 6 deletions src/BeamAdapter/component/model/RodMeshSection.inl
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ bool RodMeshSection<DataTypes>::initSection()


template <class DataTypes>
void RodMeshSection<DataTypes>::getRestTransformOnX(Transform& global_H_local, const Real x_used, const Real x_start)
void RodMeshSection<DataTypes>::getRestTransformOnX(Transform& global_H_local, const Real x_used, const Real x_start,
const Transform& predecessor_H_sectionStart)
{
Real abs_curr = x_used - x_start;
abs_curr = abs_curr /(this->d_length.getValue()) * m_absOfGeometry;
Expand Down Expand Up @@ -97,11 +98,10 @@ void RodMeshSection<DataTypes>::getRestTransformOnX(Transform& global_H_local, c
p.getOrientation() = slerp;
}

type::Vec3 PosEndCurve = p.getCenter();
Quat ExtremityQuat = p.getOrientation();
type::Vec3 ExtremityPos = PosEndCurve + type::Vec3(x_start, 0, 0);

global_H_local.set(ExtremityPos, ExtremityQuat);
// p is expressed in the section-local frame (origin at section start, +X = predecessor tip tangent).
Transform sectionStart_H_local;
sectionStart_H_local.set(p.getCenter(), p.getOrientation());
global_H_local = predecessor_H_sectionStart * sectionStart_H_local;
}


Expand Down
7 changes: 5 additions & 2 deletions src/BeamAdapter/component/model/RodSpireSection.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@ class RodSpireSection : public BaseRodSectionMaterial<DataTypes>
/// Default Constructor
RodSpireSection();

/// Override method to get the rest position of the beam. In this implementation, it will compute the current position given the spire parameters
void getRestTransformOnX(Transform& global_H_local, const Real x_used, const Real x_start) override;
/// Override method to get the rest position of the beam. The spire is computed in the section's local frame
/// (origin at the section start, +X aligned with the predecessor tip tangent) and composed with
/// @p predecessor_H_sectionStart to obtain the world rest transform.
void getRestTransformOnX(Transform& global_H_local, const Real x_used, const Real x_start,
const Transform& predecessor_H_sectionStart) override;

protected:
/// Internal method to init the section. Called by @sa BaseRodSectionMaterial::init() method
Expand Down
10 changes: 6 additions & 4 deletions src/BeamAdapter/component/model/RodSpireSection.inl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ bool RodSpireSection<DataTypes>::initSection()


template <class DataTypes>
void RodSpireSection<DataTypes>::getRestTransformOnX(Transform& global_H_local, const Real x_used, const Real x_start)
void RodSpireSection<DataTypes>::getRestTransformOnX(Transform& global_H_local, const Real x_used, const Real x_start,
const Transform& predecessor_H_sectionStart)
{
Real projetedLength = d_spireDiameter.getValue() * M_PI;
Real lengthSpire = sqrt(d_spireHeight.getValue() * d_spireHeight.getValue() + projetedLength * projetedLength);
Expand All @@ -73,12 +74,13 @@ void RodSpireSection<DataTypes>::getRestTransformOnX(Transform& global_H_local,
Qtheta.axisToQuat(type::Vec3(0, 1, 0), theta);
Quat newSpireQuat = Qtheta * Qphi;

// computation of the position
// computation of the position in the section-local frame (origin at section start, +X = predecessor tip tangent)
Real radius = d_spireDiameter.getValue() / 2.0;
type::Vec3 PosEndCurve(radius * sin(theta), numSpire * d_spireHeight.getValue(), radius * (cos(theta) - 1));
type::Vec3 SpirePos = PosEndCurve + type::Vec3(x_start, 0, 0);

global_H_local.set(SpirePos, newSpireQuat);
Transform sectionStart_H_local;
sectionStart_H_local.set(PosEndCurve, newSpireQuat);
global_H_local = predecessor_H_sectionStart * sectionStart_H_local;
}

} // namespace beamadapter
7 changes: 5 additions & 2 deletions src/BeamAdapter/component/model/RodStraightSection.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,11 @@ class RodStraightSection : public BaseRodSectionMaterial<DataTypes>
/// Default Constructor
RodStraightSection();

/// Override method to get the rest position of the beam. In this implementation, it will basically returns Vec3(x_start + x_used, 0 0)
void getRestTransformOnX(Transform& global_H_local, const Real x_used, const Real x_start) override;
/// Override method to get the rest position of the beam. The local rest position along the section's own +X axis
/// is composed with @p predecessor_H_sectionStart so the section continues tangent to the predecessor's tip frame
/// rather than assuming a world-X anchored start.
void getRestTransformOnX(Transform& global_H_local, const Real x_used, const Real x_start,
const Transform& predecessor_H_sectionStart) override;

protected:
/// Internal method to init the section. Called by @sa BaseRodSectionMaterial::init() method
Expand Down
7 changes: 5 additions & 2 deletions src/BeamAdapter/component/model/RodStraightSection.inl
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,12 @@ bool RodStraightSection<DataTypes>::initSection()


template <class DataTypes>
void RodStraightSection<DataTypes>::getRestTransformOnX(Transform& global_H_local, const Real x_used, const Real x_start)
void RodStraightSection<DataTypes>::getRestTransformOnX(Transform& global_H_local, const Real x_used, const Real x_start,
const Transform& predecessor_H_sectionStart)
{
global_H_local.set(type::Vec3(x_start + x_used, 0.0, 0.0), Quat());
Transform sectionStart_H_local;
sectionStart_H_local.set(type::Vec3(x_used - x_start, 0.0, 0.0), Quat());
global_H_local = predecessor_H_sectionStart * sectionStart_H_local;
}


Expand Down