@@ -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
206218template <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