MCPcopy Create free account
hub / github.com/MeshInspector/MeshLib / bendContoursAlongCurve

Function bendContoursAlongCurve

source/MRMesh/MRAlignContoursToMesh.cpp:114–195  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

112}
113
114Expected<Mesh> bendContoursAlongCurve( const Contours2f& contours, const CurveFunc& curve, const BendContoursAlongCurveParams& params )
115{
116 MR_TIMER;
117 auto contoursMesh = PlanarTriangulation::triangulateContours( contours );
118 auto bbox = contoursMesh.computeBoundingBox();
119 if ( !bbox.valid() )
120 return unexpected( "Contours mesh is empty" );
121
122 if ( curve.totalLength <= 0.0f )
123 {
124 assert( !"invalid curve length" );
125 return unexpected( "Invalid curve length" );
126 }
127
128 const float cStartDepth = bbox.diagonal() * 0.05f; // use relative depth to avoid floating errors
129 addBaseToPlanarMesh( contoursMesh, -cStartDepth );
130 contoursMesh.invalidateCaches();
131 auto diagonal = bbox.size();
132 diagonal.z = cStartDepth;
133 const float pivotInBoxX = lerp( bbox.min.x, bbox.max.x, params.pivotBoxPoint.x );
134 const float pivotInBoxY = lerp( bbox.min.y, bbox.max.y, params.pivotBoxPoint.y );
135
136 const float plusOffset = std::abs( params.extrusion );
137 const float minusOffset = cStartDepth - std::abs( params.extrusion );
138
139 auto& contoursMeshPoints = contoursMesh.points;
140 VertId firstBottomVert( contoursMeshPoints.size() / 2 );
141
142 const auto components = MeshComponents::getAllComponents( contoursMesh );
143 const auto stretchMod = curve.totalLength / diagonal.x;
144 const auto startCurvePos = params.pivotCurveTime * curve.totalLength;
145 // independently for each component of contoursMesh
146 ParallelFor( components, [&]( size_t icomp )
147 {
148 const auto & compFaces = components[icomp];
149 const auto compCenter = contoursMesh.computeBoundingBox( &compFaces ).center();
150 float xInBox = compCenter.x - pivotInBoxX;
151 if ( params.stretch )
152 xInBox *= stretchMod;
153
154 float curveTime = startCurvePos + xInBox;
155 if ( params.periodicCurve )
156 curveTime = curveTime - std::floor( curveTime / curve.totalLength ) * curve.totalLength;
157 const auto pos = curve.func( curveTime );
158
159 const auto vecx = pos.dir;
160 const auto norm = pos.snorm;
161 const auto vecy = cross( vecx, -norm ).normalized();
162
163 auto rotQ = Quaternionf( Vector3f::plusX(), vecx );
164 // handle degenerated case
165 auto newY = rotQ( Vector3f::plusY() );
166 auto dotY = dot( newY, vecy );
167 if ( std::abs( std::abs( dotY ) - 1.0f ) < 10.0f * std::numeric_limits<float>::epsilon() )
168 {
169 if ( dotY < 0.0f )
170 rotQ = Quaternionf( vecx, PI_F ) * rotQ;
171 }

Callers 2

bendTextAlongCurveFunction · 0.85

Calls 15

triangulateContoursFunction · 0.85
addBaseToPlanarMeshFunction · 0.85
lerpFunction · 0.85
absFunction · 0.85
ParallelForFunction · 0.85
floorFunction · 0.85
getIncidentVertsFunction · 0.85
unexpectedFunction · 0.70
getAllComponentsFunction · 0.70
crossFunction · 0.70
dotFunction · 0.70
computeBoundingBoxMethod · 0.45

Tested by

no test coverage detected