1111#include " MRMeshComponents.h"
1212#include " MRParallelFor.h"
1313#include " MRRegionBoundary.h"
14+ #include < cmath>
1415
1516namespace MR
1617{
@@ -117,6 +118,12 @@ Expected<Mesh> bendContoursAlongCurve( const Contours2f& contours, const CurveFu
117118 if ( !bbox.valid () )
118119 return unexpected ( " Contours mesh is empty" );
119120
121+ if ( curve.totalLength <= 0 .0f )
122+ {
123+ assert ( !" invalid curve length" );
124+ return unexpected ( " Invalid curve length" );
125+ }
126+
120127 const float cStartDepth = bbox.diagonal () * 0 .05f ; // use relative depth to avoid floating errors
121128 addBaseToPlanarMesh ( contoursMesh, -cStartDepth );
122129 contoursMesh.invalidateCaches ();
@@ -132,19 +139,21 @@ Expected<Mesh> bendContoursAlongCurve( const Contours2f& contours, const CurveFu
132139 VertId firstBottomVert ( contoursMeshPoints.size () / 2 );
133140
134141 const auto components = MeshComponents::getAllComponents ( contoursMesh );
142+ const auto stretchMod = curve.totalLength / diagonal.x ;
143+ const auto startCurvePos = params.pivotCurveTime * curve.totalLength ;
135144 // independently for each component of contoursMesh
136145 ParallelFor ( components, [&]( size_t icomp )
137146 {
138147 const auto & compFaces = components[icomp];
139148 const auto compCenter = contoursMesh.computeBoundingBox ( &compFaces ).center ();
140- float xInBoxRelPivot = compCenter.x - pivotInBoxX;
149+ float xInBox = compCenter.x - pivotInBoxX;
141150 if ( params.stretch )
142- xInBoxRelPivot /= diagonal. x ;
151+ xInBox *= stretchMod ;
143152
144- float curveTime = params. pivotCurveTime + xInBoxRelPivot ;
153+ float curveTime = startCurvePos + xInBox ;
145154 if ( params.periodicCurve )
146- curveTime = curveTime - std::floor ( curveTime ) ;
147- const auto pos = curve ( curveTime );
155+ curveTime = curveTime - std::floor ( curveTime / curve. totalLength ) * curve. totalLength ;
156+ const auto pos = curve. func ( curveTime );
148157
149158 const auto vecx = pos.dir ;
150159 const auto norm = pos.snorm ;
@@ -188,19 +197,19 @@ Expected<Mesh> bendContoursAlongSurfacePath( const Contours2f& contours, const M
188197 const BendContoursAlongCurveParams& params )
189198{
190199 MR_TIMER;
191- return curveFromPoints ( meshPathCurvePoints ( mesh, start, path, end ), params. stretch )
200+ return curveFromPoints ( meshPathCurvePoints ( mesh, start, path, end ) )
192201 .and_then ( [&]( auto && curve ) { return bendContoursAlongCurve ( contours, curve, params ); } );
193202}
194203
195204Expected<Mesh> bendContoursAlongSurfacePath ( const Contours2f& contours, const Mesh& mesh, const SurfacePath& path,
196205 const BendContoursAlongCurveParams& params )
197206{
198207 MR_TIMER;
199- return curveFromPoints ( meshPathCurvePoints ( mesh, path ), params. stretch )
208+ return curveFromPoints ( meshPathCurvePoints ( mesh, path ) )
200209 .and_then ( [&]( auto && curve ) { return bendContoursAlongCurve ( contours, curve, params ); } );
201210}
202211
203- Expected<std::vector<float >> findPartialLens ( const CurvePoints& cp, bool unitLength, float * outCurveLen )
212+ Expected<std::vector<float >> findPartialLens ( const CurvePoints& cp, float * outCurveLen )
204213{
205214 MR_TIMER;
206215 if ( cp.size () < 2 )
@@ -220,13 +229,6 @@ Expected<std::vector<float>> findPartialLens( const CurvePoints& cp, bool unitLe
220229 if ( lens.back () <= 0 )
221230 return unexpected ( " curve has zero length" );
222231
223- if ( unitLength )
224- {
225- // to relative lengths
226- const auto factor = 1 / lens.back ();
227- for ( auto & l : lens )
228- l *= factor;
229- }
230232 return lens;
231233}
232234
@@ -265,30 +267,36 @@ CurvePoint getCurvePoint( const CurvePoints& cp, const std::vector<float> & lens
265267 return res;
266268}
267269
268- Expected<CurveFunc> curveFromPoints ( const CurvePoints& cp, bool unitLength, float * outCurveLen )
270+ Expected<CurveFunc> curveFromPoints ( const CurvePoints& cp, float * outCurveLen )
269271{
270272 MR_TIMER;
271- auto maybeLens = findPartialLens ( cp, unitLength, outCurveLen );
273+ auto maybeLens = findPartialLens ( cp, outCurveLen );
272274 if ( !maybeLens )
273275 return unexpected ( std::move ( maybeLens.error () ) );
274276
275- return [&cp, lens = std::move ( *maybeLens )]( float p )
277+ CurveFunc res;
278+ res.totalLength = maybeLens->back ();
279+ res.func = [&cp, lens = std::move ( *maybeLens )] ( float p )
276280 {
277281 return getCurvePoint ( cp, lens, p );
278282 };
283+ return res;
279284}
280285
281- Expected<CurveFunc> curveFromPoints ( CurvePoints&& cp, bool unitLength, float * outCurveLen )
286+ Expected<CurveFunc> curveFromPoints ( CurvePoints&& cp, float * outCurveLen )
282287{
283288 MR_TIMER;
284- auto maybeLens = findPartialLens ( cp, unitLength, outCurveLen );
289+ auto maybeLens = findPartialLens ( cp, outCurveLen );
285290 if ( !maybeLens )
286291 return unexpected ( std::move ( maybeLens.error () ) );
287292
288- return [cp = std::move ( cp ), lens = std::move ( *maybeLens )]( float p )
293+ CurveFunc res;
294+ res.totalLength = maybeLens->back ();
295+ res.func = [&cp, lens = std::move ( *maybeLens )] ( float p )
289296 {
290297 return getCurvePoint ( cp, lens, p );
291298 };
299+ return res;
292300}
293301
294302CurvePoints meshPathCurvePoints ( const Mesh& mesh, const MeshTriPoint & start, const SurfacePath& path, const MeshTriPoint & end )
0 commit comments