Skip to content

Commit 49d15c7

Browse files
[mapping] BeamProjectionDifferenceMultiMapping: new feature and refactoring (#212)
* [mapping] BeamProjectionDifferenceMultiMapping: add projections output, filter and refactoring * adds description
1 parent c65c36f commit 49d15c7

2 files changed

Lines changed: 33 additions & 22 deletions

File tree

src/BeamAdapter/component/mapping/BeamProjectionDifferenceMultiMapping.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ class SOFA_BEAMADAPTER_API BeamProjectionDifferenceMultiMapping : public sofa::c
164164
sofa::Data<bool> d_updateProjectionOrientation;
165165
sofa::Data<bool> d_draw;
166166
sofa::Data<Real> d_drawSize;
167+
sofa::Data<vector<In1Coord>> d_projections;
168+
sofa::Data<SReal> d_filter;
167169

168170
sofa::SingleLink<BeamProjectionDifferenceMultiMapping<TIn1, TIn2, TOut>, sofa::core::topology::BaseMeshTopology, sofa::BaseLink::FLAG_STOREPATH | sofa::BaseLink::FLAG_STRONGLINK> l_in2Topology;
169171
sofa::SingleLink<BeamProjectionDifferenceMultiMapping<TIn1, TIn2, TOut>, BeamInterpolation<TIn2>, sofa::BaseLink::FLAG_STOREPATH | sofa::BaseLink::FLAG_STRONGLINK> l_interpolation;

src/BeamAdapter/component/mapping/BeamProjectionDifferenceMultiMapping.inl

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ BeamProjectionDifferenceMultiMapping<TIn1, TIn2, TOut>::BeamProjectionDifference
5555
, d_updateProjectionOrientation(initData(&d_updateProjectionOrientation, false, "updateProjectionOrientation", "Update the projection on the beam at each time step even when direction[0]=1."))
5656
, d_draw(initData(&d_draw, "draw", "Draw projection points and directions"))
5757
, d_drawSize(initData(&d_drawSize, Real(3), "drawSize", ""))
58+
, d_projections(initData(&d_projections, "projections", "Computed projection points."))
59+
, d_filter(initData(&d_filter, Real(1e-2), "filter", "When updating the projection at each time step, use this parameter to filter small changes: "
60+
"If the projection is on the same edge as the previous step, and the weight (in [0, 1]) is smaller than the value of 'filter', skip."))
5861
, l_in2Topology(initLink("topologyInput2", "link to input2's topology container (beams to project on)"))
5962
, l_interpolation(initLink("interpolationInput2", "link to input2's interpolation component (BeamInterpolation)"))
6063
, m_fromModel1(NULL)
@@ -124,6 +127,10 @@ void BeamProjectionDifferenceMultiMapping<TIn1, TIn2, TOut>::init()
124127
msg_warning() << "Wrong size for directions, [" << directions << "]. The size should be " << OutCoord::total_size << ".";
125128
directions.resize(OutCoord::total_size);
126129
}
130+
131+
auto projections = sofa::helper::getWriteAccessor(d_projections);
132+
const auto& indices = sofa::helper::getReadAccessor(d_indices);
133+
projections.resize(indices.size());
127134
}
128135

129136

@@ -134,8 +141,9 @@ void BeamProjectionDifferenceMultiMapping<TIn1, TIn2, TOut>::computeProjection(c
134141
auto interpolation = l_interpolation.get();
135142
auto edges = l_in2Topology.get()->getEdges();
136143

137-
// for each point of P of xFrom
144+
// for each point P of xFrom
138145
const auto& indices = sofa::helper::getReadAccessor(d_indices);
146+
const auto& filter = sofa::helper::getReadAccessor(d_filter);
139147
m_mappedPoints.resize(indices.size());
140148

141149
for (unsigned int i=0; i<indices.size(); i++)
@@ -155,16 +163,17 @@ void BeamProjectionDifferenceMultiMapping<TIn1, TIn2, TOut>::computeProjection(c
155163
OutDeriv dirAxe = Out::coordDifference(Q2, Q1);
156164
Real normAxe = In1::getDPos(dirAxe).norm();
157165

158-
if (std::abs(normAxe)<std::numeric_limits<SReal>::epsilon()) // edge is degenerated, continue with next edge
166+
SReal epsilon = std::numeric_limits<SReal>::epsilon();
167+
if (std::abs(normAxe)<epsilon) // edge is degenerated, continue with next edge
159168
continue;
160169

161170
dirAxe /= normAxe;
162171

163172
Real r = In1::getDPos(In1::coordDifference(P, Q1)) * In1::getDPos(dirAxe);
164173
Real alpha = r / normAxe;
165-
alpha = (std::abs(alpha)<1e-2)? std::abs(alpha): alpha;
174+
alpha = (std::abs(alpha)<1e-2)? std::abs(alpha): alpha; // avoid jumps between two edges when the projection is near the boundary
166175

167-
if (alpha < 0 || alpha > 1) // not on the edge, continue with next edge
176+
if (alpha < 0 - epsilon || alpha > 1 + epsilon) // not on the edge, continue with next edge
168177
continue;
169178

170179
In1Coord proj;
@@ -198,16 +207,19 @@ void BeamProjectionDifferenceMultiMapping<TIn1, TIn2, TOut>::computeProjection(c
198207
{
199208
mp.interpolatedTransform = m_mappedPoints[i].interpolatedTransform;
200209
}
201-
m_mappedPoints[i] = mp;
210+
211+
// When updating the projection at each time step, filter small changes
212+
if (m_mappedPoints[i].edgeIndex != mp.edgeIndex || std::abs(m_mappedPoints[i].alpha - mp.alpha) > filter)
213+
m_mappedPoints[i] = mp;
202214
}
203215
}
204216

205217

206218
template <class TIn1, class TIn2, class TOut>
207-
void BeamProjectionDifferenceMultiMapping<TIn1, TIn2, TOut>::apply( const sofa::core::MechanicalParams* mparams,
208-
const sofa::type::vector<OutDataVecCoord*>& dataVecOutPos,
209-
const sofa::type::vector<const In1DataVecCoord*>& dataVecIn1Pos ,
210-
const sofa::type::vector<const In2DataVecCoord*>& dataVecIn2Pos)
219+
void BeamProjectionDifferenceMultiMapping<TIn1, TIn2, TOut>::apply(const sofa::core::MechanicalParams* mparams,
220+
const sofa::type::vector<OutDataVecCoord*>& dataVecOutPos,
221+
const sofa::type::vector<const In1DataVecCoord*>& dataVecIn1Pos,
222+
const sofa::type::vector<const In2DataVecCoord*>& dataVecIn2Pos)
211223
{
212224
SOFA_UNUSED(mparams);
213225

@@ -222,6 +234,7 @@ void BeamProjectionDifferenceMultiMapping<TIn1, TIn2, TOut>::apply( const sofa::
222234
OutVecCoord& out = *dataVecOutPos[0]->beginEdit();
223235
const auto& directions = sofa::helper::getReadAccessor(d_directions);
224236
auto interpolation = l_interpolation.get();
237+
auto projections = sofa::helper::getWriteAccessor(d_projections);
225238

226239
if (m_mappedPoints.empty() || !directions[0])
227240
{
@@ -243,26 +256,22 @@ void BeamProjectionDifferenceMultiMapping<TIn1, TIn2, TOut>::apply( const sofa::
243256
MappedPoint& mp = m_mappedPoints[i];
244257
if (mp.onBeam)
245258
{
246-
Transform interpolatedTransform;
247-
interpolation->InterpolateTransformUsingSpline(interpolatedTransform,
259+
Transform R0_H_projection; // projection of the constraint on the beam
260+
interpolation->InterpolateTransformUsingSpline(R0_H_projection,
248261
mp.alpha,
249262
Transform(in2[mp.pi1].getCenter(), in2[mp.pi1].getOrientation()),
250263
Transform(in2[mp.pi2].getCenter(), in2[mp.pi2].getOrientation()),
251264
interpolation->getLength(mp.edgeIndex));
252265

253-
In1Coord projection;
254-
projection.getCenter() = interpolatedTransform.getOrigin();
255-
projection.getOrientation() = interpolatedTransform.getOrientation();
256-
257-
In1Coord p;
258-
for (size_t j=0; j<In1Coord::total_size; j++)
259-
{
260-
p[j] = in1[indices[i]][j] - projection[j];
261-
}
266+
Transform R0_H_constraint(in1[indices[i]].getCenter(), in1[indices[i]].getOrientation());
267+
In1Coord projection(R0_H_projection.getOrigin(), R0_H_projection.getOrientation());
268+
projections[i] = projection;
262269

270+
Transform constraint_H_projection;
271+
constraint_H_projection = R0_H_projection.inversed() * R0_H_constraint;
263272
In1Coord v;
264-
v.getCenter() = mp.interpolatedTransform.getRotationMatrix().transposed() * Out::getCPos(p);
265-
v.getOrientation() = p.getOrientation() * Out::getCRot(p);
273+
v.getCenter() = constraint_H_projection.getOrigin();
274+
v.getOrientation() = constraint_H_projection.getOrientation();
266275

267276
for (size_t j=0; j<In1Coord::total_size; j++)
268277
{

0 commit comments

Comments
 (0)