+//================================================================================
+/*!
+ * \brief Computes new UV using angle based smoothing technic
+ */
+//================================================================================
+
+gp_XY _SmoothNode::computeAngularPos(vector<gp_XY>& uv,
+ const gp_XY& uvToFix,
+ const double refSign)
+{
+ uv.push_back( uv.front() );
+
+ vector< gp_XY > edgeDir ( uv.size() );
+ vector< double > edgeSize( uv.size() );
+ for ( size_t i = 1; i < edgeDir.size(); ++i )
+ {
+ edgeDir [i-1] = uv[i] - uv[i-1];
+ edgeSize[i-1] = edgeDir[i-1].Modulus();
+ if ( edgeSize[i-1] < numeric_limits<double>::min() )
+ edgeDir[i-1].SetX( 100 );
+ else
+ edgeDir[i-1] /= edgeSize[i-1] * refSign;
+ }
+ edgeDir.back() = edgeDir.front();
+ edgeSize.back() = edgeSize.front();
+
+ gp_XY newPos(0,0);
+ int nbEdges = 0;
+ double sumSize = 0;
+ for ( size_t i = 1; i < edgeDir.size(); ++i )
+ {
+ if ( edgeDir[i-1].X() > 1. ) continue;
+ int i1 = i-1;
+ while ( edgeDir[i].X() > 1. && ++i < edgeDir.size() );
+ if ( i == edgeDir.size() ) break;
+ gp_XY p = uv[i];
+ gp_XY norm1( -edgeDir[i1].Y(), edgeDir[i1].X() );
+ gp_XY norm2( -edgeDir[i].Y(), edgeDir[i].X() );
+ gp_XY bisec = norm1 + norm2;
+ double bisecSize = bisec.Modulus();
+ if ( bisecSize < numeric_limits<double>::min() )
+ {
+ bisec = -edgeDir[i1] + edgeDir[i];
+ bisecSize = bisec.Modulus();
+ }
+ bisec /= bisecSize;
+
+ gp_XY dirToN = uvToFix - p;
+ double distToN = dirToN.Modulus();
+ if ( bisec * dirToN < 0 )
+ distToN = -distToN;
+
+ newPos += ( p + bisec * distToN ) * ( edgeSize[i1] + edgeSize[i] );
+ ++nbEdges;
+ sumSize += edgeSize[i1] + edgeSize[i];
+ }
+ newPos /= /*nbEdges * */sumSize;
+ return newPos;
+}
+