+//=======================================================================
+//function : correctTheValue
+//purpose : Given a boundaries of parametric space determine if the node coordinate (u,v) need correction
+// based on the reference coordinate (uref,vref)
+//=======================================================================
+void correctTheValue( Standard_Real Umax, Standard_Real Umin, Standard_Real Vmax, Standard_Real Vmin,
+ Standard_Real uref, Standard_Real vref, Standard_Real &u, Standard_Real &v )
+{
+ bool isUTobeCorrected = (std::fabs( uref - u ) >= 0.7 * std::fabs( Umax - Umin ));
+ bool isVTobeCorrected = (std::fabs( vref - v ) >= 0.7 * std::fabs( Vmax - Vmin ));
+ if ( isUTobeCorrected )
+ u = std::fabs(u-Umin) < 1e-7 ? Umax : Umin;
+ if ( isVTobeCorrected )
+ v = std::fabs(v-Vmin) < 1e-7 ? Vmax : Vmin;
+}
+
+//=======================================================================
+//function : averageByElement
+//purpose : Auxiliar function to treat properly nodes in periodic faces in the centroidal smoother
+//=======================================================================
+void averageByElement( const Handle(Geom_Surface)& theSurface, const SMDS_MeshNode* refNode, const SMDS_MeshElement* elem,
+ map< const SMDS_MeshNode*, gp_XY* >& theUVMap, SMESH::Controls::TSequenceOfXYZ& aNodePoints,
+ gp_XYZ& elemCenter )
+{
+ int nn = elem->NbNodes();
+ if(elem->IsQuadratic()) nn = nn/2;
+ int i=0;
+ SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+ Standard_Real Umin,Umax,Vmin,Vmax;
+ while ( i<nn )
+ {
+ const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>( itN->next() );
+ i++;
+ gp_XYZ aP( aNode->X(), aNode->Y(), aNode->Z() );
+ aNodePoints.push_back( aP );
+ if ( !theSurface.IsNull() ) // smooth in 2D
+ {
+ ASSERT( theUVMap.find( aNode ) != theUVMap.end() );
+ gp_XY* uv = theUVMap[ aNode ];
+
+ if ( theSurface->IsUPeriodic() || theSurface->IsVPeriodic() )
+ {
+ theSurface->Bounds( Umin, Umax, Vmin, Vmax );
+ Standard_Real u = uv->X();
+ Standard_Real v = uv->Y();
+ bool isSingularPoint = std::fabs(u - Umin) < 1e-7 || std::fabs(v - Vmin) < 1e-7 || std::fabs(u - Umax) < 1e-7 || std::fabs( v - Vmax ) < 1e-7;
+ if ( !isSingularPoint )
+ {
+ aP.SetCoord( uv->X(), uv->Y(), 0. );
+ }
+ else
+ {
+ gp_XY* refPoint = theUVMap[ refNode ];
+ Standard_Real uref = refPoint->X();
+ Standard_Real vref = refPoint->Y();
+ correctTheValue( Umax, Umin, Vmax, Vmin, uref, vref, u, v );
+ aP.SetCoord( u, v, 0. );
+ }
+ }
+ else
+ aP.SetCoord( uv->X(), uv->Y(), 0. );
+ }
+ elemCenter += aP;
+ }
+}
+