+
+ // get nodes to check UV
+ list< const SMDS_MeshNode* > uvCheckNodes;
+ itN = elem->nodesIterator();
+ while ( itN->more() ) {
+ node = static_cast<const SMDS_MeshNode*>( itN->next() );
+ if ( uvMap.find( node ) == uvMap.end() )
+ uvCheckNodes.push_back( node );
+ // add nodes of elems sharing node
+// SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator();
+// while ( eIt->more() ) {
+// const SMDS_MeshElement* e = eIt->next();
+// if ( e != elem && e->GetType() == SMDSAbs_Face ) {
+// SMDS_ElemIteratorPtr nIt = e->nodesIterator();
+// while ( nIt->more() ) {
+// const SMDS_MeshNode* n =
+// static_cast<const SMDS_MeshNode*>( nIt->next() );
+// if ( uvMap.find( n ) == uvMap.end() )
+// uvCheckNodes.push_back( n );
+// }
+// }
+// }
+ }
+ // check UV on face
+ list< const SMDS_MeshNode* >::iterator n = uvCheckNodes.begin();
+ for ( ; n != uvCheckNodes.end(); ++n )
+ {
+ node = *n;
+ gp_XY uv( 0, 0 );
+ const SMDS_PositionPtr& pos = node->GetPosition();
+ posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
+ // get existing UV
+ switch ( posType ) {
+ case SMDS_TOP_FACE: {
+ SMDS_FacePosition* fPos = ( SMDS_FacePosition* ) pos.get();
+ uv.SetCoord( fPos->GetUParameter(), fPos->GetVParameter() );
+ break;
+ }
+ case SMDS_TOP_EDGE: {
+ TopoDS_Shape S = aMesh->IndexToShape( pos->GetShapeId() );
+ Handle(Geom2d_Curve) pcurve;
+ if ( !S.IsNull() && S.ShapeType() == TopAbs_EDGE )
+ pcurve = BRep_Tool::CurveOnSurface( TopoDS::Edge( S ), face, f,l );
+ if ( !pcurve.IsNull() ) {
+ double u = (( SMDS_EdgePosition* ) pos.get() )->GetUParameter();
+ uv = pcurve->Value( u ).XY();
+ }
+ break;
+ }
+ case SMDS_TOP_VERTEX: {
+ TopoDS_Shape S = aMesh->IndexToShape( pos->GetShapeId() );
+ if ( !S.IsNull() && S.ShapeType() == TopAbs_VERTEX )
+ uv = BRep_Tool::Parameters( TopoDS::Vertex( S ), face ).XY();
+ break;
+ }
+ default:;
+ }
+ // check existing UV
+ bool project = true;
+ gp_Pnt pNode ( node->X(), node->Y(), node->Z() );
+ double dist1 = DBL_MAX, dist2 = 0;
+ if ( posType != SMDS_TOP_3DSPACE ) {
+ dist1 = pNode.SquareDistance( surface->Value( uv.X(), uv.Y() ));
+ project = dist1 > fToler2;
+ }
+ if ( project ) { // compute new UV
+ gp_XY newUV;
+ if ( !getClosestUV( projector, pNode, newUV )) {
+ MESSAGE("Node Projection Failed " << node);
+ }
+ else {
+ if ( isUPeriodic )
+ newUV.SetX( ElCLib::InPeriod( newUV.X(), u1, u2 ));
+ if ( isVPeriodic )
+ newUV.SetY( ElCLib::InPeriod( newUV.Y(), v1, v2 ));
+ // check new UV
+ if ( posType != SMDS_TOP_3DSPACE )
+ dist2 = pNode.SquareDistance( surface->Value( newUV.X(), newUV.Y() ));
+ if ( dist2 < dist1 )
+ uv = newUV;
+ }
+ }
+ // store UV in the map
+ listUV.push_back( uv );
+ uvMap.insert( make_pair( node, &listUV.back() ));
+ }
+ } // loop on not yet smoothed elements
+
+ if ( !faceSubMesh || nbElemOnFace != faceSubMesh->NbElements() )
+ checkBoundaryNodes = true;
+
+ // fix nodes on mesh boundary
+
+ if ( checkBoundaryNodes )
+ {
+ typedef pair<const SMDS_MeshNode*, const SMDS_MeshNode*> TLink;
+ map< TLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
+ map< TLink, int >::iterator link_nb;
+ // put all elements links to linkNbMap
+ list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
+ for ( ; elemIt != elemsOnFace.end(); ++elemIt )
+ {
+ // put elem nodes in array
+ vector< const SMDS_MeshNode* > nodes;
+ nodes.reserve( (*elemIt)->NbNodes() + 1 );
+ SMDS_ElemIteratorPtr itN = (*elemIt)->nodesIterator();
+ while ( itN->more() )
+ nodes.push_back( static_cast<const SMDS_MeshNode*>( itN->next() ));
+ nodes.push_back( nodes.front() );
+ // loop on elem links: insert them in linkNbMap
+ for ( int iN = 1; iN < nodes.size(); ++iN ) {
+ TLink link;
+ if ( nodes[ iN-1 ]->GetID() < nodes[ iN ]->GetID() )
+ link = make_pair( nodes[ iN-1 ], nodes[ iN ] );
+ else
+ link = make_pair( nodes[ iN ], nodes[ iN-1 ] );
+ link_nb = linkNbMap.find( link );
+ if ( link_nb == linkNbMap.end() )
+ linkNbMap.insert( make_pair ( link, 1 ));
+ else
+ link_nb->second++;
+ }
+ }
+ // remove nodes that are in links encountered only once from setMovableNodes
+ for ( link_nb = linkNbMap.begin(); link_nb != linkNbMap.end(); ++link_nb ) {
+ if ( link_nb->second == 1 ) {
+ setMovableNodes.erase( link_nb->first.first );
+ setMovableNodes.erase( link_nb->first.second );
+ }