+ return error( COMPERR_BAD_INPUT_MESH,
+ "Source elements don't cover totally the geometrical face" );
+
+ if ( helper.HasSeam() )
+ {
+ // links on seam edges are shared by two faces, so no edges were created on them
+ // by the previous detection of 2D mesh boundary
+ for ( size_t iE = 0; iE < edges.size(); ++iE )
+ {
+ if ( !helper.IsRealSeam( edges[iE] )) continue;
+ const TopoDS_Edge& seamEdge = edges[iE];
+ // to find nodes lying on the seamEdge we check nodes of mesh faces sharing a node on one
+ // of its vertices; after finding another node on seamEdge we continue the same way
+ // until finding all nodes.
+ TopoDS_Vertex seamVertex = helper.IthVertex( 0, seamEdge );
+ const SMDS_MeshNode* vertNode = SMESH_Algo::VertexNode( seamVertex, tgtMesh );
+ set< const SMDS_MeshNode* > checkedNodes; checkedNodes.insert( vertNode );
+ set< const SMDS_MeshElement* > checkedFaces;
+ // as a face can have more than one node on the seamEdge, there is a difficulty in selecting
+ // one of those nodes to treat next; so we simply find all nodes on the seamEdge and
+ // then sort them by U on edge
+ typedef list< pair< double, const SMDS_MeshNode* > > TUNodeList;
+ TUNodeList nodesOnSeam;
+ double u = helper.GetNodeU( seamEdge, vertNode );
+ nodesOnSeam.push_back( make_pair( u, vertNode ));
+ TUNodeList::iterator u2nIt = nodesOnSeam.begin();
+ for ( ; u2nIt != nodesOnSeam.end(); ++u2nIt )
+ {
+ const SMDS_MeshNode* startNode = (*u2nIt).second;
+ SMDS_ElemIteratorPtr faceIt = startNode->GetInverseElementIterator( SMDSAbs_Face );
+ while ( faceIt->more() )
+ {
+ const SMDS_MeshElement* face = faceIt->next();
+ if ( !checkedFaces.insert( face ).second ) continue;
+ for ( int i = 0, nbNodes = face->NbCornerNodes(); i < nbNodes; ++i )
+ {
+ const SMDS_MeshNode* n = face->GetNode( i );
+ if ( n == startNode || !checkedNodes.insert( n ).second ) continue;
+ if ( helper.CheckNodeU( seamEdge, n, u=0, projTol, /*force=*/true ))
+ nodesOnSeam.push_back( make_pair( u, n ));
+ }
+ }
+ }
+ // sort the found nodes by U on the seamEdge; most probably they are in a good order,
+ // so we can use the hint to spead-up map filling
+ map< double, const SMDS_MeshNode* > u2nodeMap;
+ for ( u2nIt = nodesOnSeam.begin(); u2nIt != nodesOnSeam.end(); ++u2nIt )
+ u2nodeMap.insert( u2nodeMap.end(), *u2nIt );
+
+ // create edges
+ {
+ SMESH_MesherHelper seamHelper( theMesh );
+ seamHelper.SetSubShape( edges[ iE ]);
+ seamHelper.SetElementsOnShape( true );
+
+ if ( (*checkedFaces.begin())->IsQuadratic() )
+ for ( set< const SMDS_MeshElement* >::iterator fIt = checkedFaces.begin();
+ fIt != checkedFaces.end(); ++fIt )
+ seamHelper.AddTLinks( static_cast<const SMDS_MeshFace*>( *fIt ));
+
+ map< double, const SMDS_MeshNode* >::iterator n1, n2, u2nEnd = u2nodeMap.end();
+ for ( n2 = u2nodeMap.begin(), n1 = n2++; n2 != u2nEnd; ++n1, ++n2 )
+ {
+ const SMDS_MeshNode* node1 = n1->second;
+ const SMDS_MeshNode* node2 = n2->second;
+ seamHelper.AddEdge( node1, node2 );
+ if ( node2->getshapeId() == helper.GetSubShapeID() )
+ {
+ tgtFaceSM->RemoveNode( node2, /*isNodeDeleted=*/false );
+ tgtMesh->SetNodeOnEdge( const_cast<SMDS_MeshNode*>( node2 ), seamEdge, n2->first );
+ }
+ }
+ }
+ } // loop on edges to find seam ones
+ } // if ( helper.HasSeam() )