| 19 | } |
| 20 | |
| 21 | MarkedContour3f resample( const MarkedContour3f & in, float minStep, Contour3f * normals ) |
| 22 | { |
| 23 | MR_TIMER; |
| 24 | assert( !normals || normals->size() == in.contour.size() ); |
| 25 | MarkedContour3f res; |
| 26 | if ( in.contour.empty() ) |
| 27 | return res; |
| 28 | |
| 29 | assert( in.firstLastMarked() ); |
| 30 | res.marks.autoResizeSet( res.contour.size() ); |
| 31 | res.contour.push_back( in.contour.front() ); |
| 32 | Contour3f resNormals; |
| 33 | if ( normals ) |
| 34 | resNormals.push_back( normals->front() ); |
| 35 | |
| 36 | for ( size_t i = 0; i + 1 < in.contour.size(); ) |
| 37 | { |
| 38 | auto i1 = i; //< will be next mark |
| 39 | float distance = 0; //< distance to next mark |
| 40 | for ( ++i1; i1 < in.contour.size(); ++i1 ) |
| 41 | { |
| 42 | distance += ( in.contour[i1 - 1] - in.contour[i1] ).length(); |
| 43 | if ( in.marks.test( i1 ) ) |
| 44 | break; |
| 45 | } |
| 46 | assert( in.marks.test( i1 ) ); |
| 47 | |
| 48 | const int numMidPoints = int( distance / minStep ); |
| 49 | if ( numMidPoints > 0 ) |
| 50 | { |
| 51 | const float step = distance / ( numMidPoints + 1 ); |
| 52 | float remDistance = step; //< till next sample point |
| 53 | auto i2 = i; |
| 54 | auto p = in.contour[i2]; |
| 55 | Vector3f n; |
| 56 | if ( normals ) |
| 57 | n = ( *normals )[i2]; |
| 58 | while ( i2 < i1 ) |
| 59 | { |
| 60 | auto segmLen = ( in.contour[i2 + 1] - p ).length(); |
| 61 | if ( segmLen <= remDistance ) |
| 62 | { |
| 63 | remDistance -= segmLen; |
| 64 | p = in.contour[++i2]; |
| 65 | if ( normals ) |
| 66 | n = ( *normals )[i2]; |
| 67 | continue; |
| 68 | } |
| 69 | const float a = remDistance / segmLen; |
| 70 | res.contour.push_back( p = ( 1 - a ) * p + a * in.contour[i2 + 1] ); |
| 71 | if ( normals ) |
| 72 | resNormals.push_back( n = ( ( 1 - a ) * n + a * ( *normals )[i2 + 1] ).normalized() ); |
| 73 | remDistance = step; |
| 74 | } |
| 75 | } |
| 76 | i = i1; |
| 77 | res.marks.autoResizeSet( res.contour.size() ); |
| 78 | res.contour.push_back( in.contour[i] ); |