00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "StdMeshers_Import_1D2D.hxx"
00028
00029 #include "StdMeshers_Import_1D.hxx"
00030 #include "StdMeshers_ImportSource.hxx"
00031
00032 #include "SMDS_MeshElement.hxx"
00033 #include "SMDS_MeshNode.hxx"
00034 #include "SMESHDS_Group.hxx"
00035 #include "SMESHDS_Mesh.hxx"
00036 #include "SMESH_Comment.hxx"
00037 #include "SMESH_Gen.hxx"
00038 #include "SMESH_Group.hxx"
00039 #include "SMESH_Mesh.hxx"
00040 #include "SMESH_MesherHelper.hxx"
00041 #include "SMESH_subMesh.hxx"
00042
00043 #include "Utils_SALOME_Exception.hxx"
00044 #include "utilities.h"
00045
00046 #include <BRep_Builder.hxx>
00047 #include <BRep_Tool.hxx>
00048 #include <TopExp.hxx>
00049 #include <TopExp_Explorer.hxx>
00050 #include <TopoDS.hxx>
00051 #include <TopoDS_Compound.hxx>
00052 #include <TopoDS_Edge.hxx>
00053 #include <TopoDS_Vertex.hxx>
00054 #include <Precision.hxx>
00055
00056 #include <numeric>
00057
00058 using namespace std;
00059
00060
00064
00065
00066 StdMeshers_Import_1D2D::StdMeshers_Import_1D2D(int hypId, int studyId, SMESH_Gen * gen)
00067 :SMESH_2D_Algo(hypId, studyId, gen), _sourceHyp(0)
00068 {
00069 MESSAGE("StdMeshers_Import_1D2D::StdMeshers_Import_1D2D");
00070 _name = "Import_1D2D";
00071 _shapeType = (1 << TopAbs_FACE);
00072
00073 _compatibleHypothesis.push_back("ImportSource2D");
00074 _requireDescretBoundary = false;
00075 }
00076
00077
00081
00082
00083 bool StdMeshers_Import_1D2D::CheckHypothesis
00084 (SMESH_Mesh& aMesh,
00085 const TopoDS_Shape& aShape,
00086 SMESH_Hypothesis::Hypothesis_Status& aStatus)
00087 {
00088 _sourceHyp = 0;
00089
00090 const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
00091 if ( hyps.size() == 0 )
00092 {
00093 aStatus = SMESH_Hypothesis::HYP_MISSING;
00094 return false;
00095 }
00096
00097 if ( hyps.size() > 1 )
00098 {
00099 aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST;
00100 return false;
00101 }
00102
00103 const SMESHDS_Hypothesis *theHyp = hyps.front();
00104
00105 string hypName = theHyp->GetName();
00106
00107 if (hypName == _compatibleHypothesis.front())
00108 {
00109 _sourceHyp = (StdMeshers_ImportSource1D *)theHyp;
00110 aStatus = SMESH_Hypothesis::HYP_OK;
00111 return true;
00112 }
00113
00114 aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
00115 return true;
00116 }
00117
00118 namespace
00119 {
00123 struct TLink : public SMESH_OrientedLink
00124 {
00125 const SMDS_MeshNode* _medium;
00126 TLink( const SMDS_MeshNode* n1,
00127 const SMDS_MeshNode* n2,
00128 const SMDS_MeshNode* medium=0)
00129 : SMESH_OrientedLink( n1,n2 ), _medium( medium ) {}
00130 };
00131 }
00132
00133
00137
00138
00139 bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape)
00140 {
00141 if ( !_sourceHyp ) return false;
00142
00143 const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
00144 if ( srcGroups.empty() )
00145 return error("Invalid source groups");
00146
00147 SMESH_MesherHelper helper(theMesh);
00148 helper.SetSubShape(theShape);
00149 SMESHDS_Mesh* tgtMesh = theMesh.GetMeshDS();
00150
00151 const TopoDS_Face& geomFace = TopoDS::Face( theShape );
00152 const double faceTol = helper.MaxTolerance( geomFace );
00153 const int shapeID = tgtMesh->ShapeToIndex( geomFace );
00154 const bool toCheckOri = (helper.NbAncestors( geomFace, theMesh, TopAbs_SOLID ) == 1 );
00155
00156 Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace );
00157 const bool reverse =
00158 ( helper.GetSubShapeOri( tgtMesh->ShapeToMesh(), geomFace) == TopAbs_REVERSED );
00159 gp_Pnt p; gp_Vec du, dv;
00160
00161 set<int> subShapeIDs;
00162 subShapeIDs.insert( shapeID );
00163
00164
00165 list < SMESH_TNodeXYZ > vertexNodes;
00166 list < SMESH_TNodeXYZ >::iterator vNIt;
00167 TopExp_Explorer exp( theShape, TopAbs_VERTEX );
00168 for ( ; exp.More(); exp.Next() )
00169 {
00170 const TopoDS_Vertex& v = TopoDS::Vertex( exp.Current() );
00171 if ( !subShapeIDs.insert( tgtMesh->ShapeToIndex( v )).second )
00172 continue;
00173 const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh );
00174 if ( !n )
00175 {
00176 _gen->Compute(theMesh,v,true);
00177 n = SMESH_Algo::VertexNode( v, tgtMesh );
00178 if ( !n ) return false;
00179 }
00180 vertexNodes.push_back( SMESH_TNodeXYZ( n ));
00181 }
00182
00183
00184 map<TLink, int> linkCount;
00185 map<TLink, int>::iterator link2Nb;
00186 double minLinkLen2 = Precision::Infinite();
00187
00188
00189
00190
00191
00192 StdMeshers_Import_1D::TNodeNodeMap* n2n;
00193 StdMeshers_Import_1D::TElemElemMap* e2e;
00194 vector<const SMDS_MeshNode*> newNodes;
00195 for ( int iG = 0; iG < srcGroups.size(); ++iG )
00196 {
00197 const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
00198
00199 const int meshID = srcGroup->GetMesh()->GetPersistentId();
00200 const SMESH_Mesh* srcMesh = GetMeshByPersistentID( meshID );
00201 if ( !srcMesh ) continue;
00202 StdMeshers_Import_1D::getMaps( srcMesh, &theMesh, n2n, e2e );
00203
00204 SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
00205 SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0);
00206 gp_XY uv( Precision::Infinite(), Precision::Infinite() );
00207 while ( srcElems->more() )
00208 {
00209 const SMDS_MeshElement* face = srcElems->next();
00210
00211 newNodes.resize( face->NbNodes() );
00212 newNodes.back() = 0;
00213 int nbCreatedNodes = 0;
00214 SMDS_MeshElement::iterator node = face->begin_nodes();
00215 for ( unsigned i = 0; i < newNodes.size(); ++i, ++node )
00216 {
00217 TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
00218 if ( n2nIt->second )
00219 {
00220 if ( !subShapeIDs.count( n2nIt->second->getshapeId() ))
00221 break;
00222 }
00223 else
00224 {
00225
00226 for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt)
00227 if ( vNIt->SquareDistance( *node ) < 10 * faceTol * faceTol)
00228 {
00229 (*n2nIt).second = vNIt->_node;
00230 vertexNodes.erase( vNIt );
00231 break;
00232 }
00233 }
00234 if ( !n2nIt->second )
00235 {
00236
00237 tmpNode->setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
00238 if ( helper.CheckNodeUV( geomFace, tmpNode, uv, 10 * faceTol, true ))
00239 {
00240 SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
00241 n2nIt->second = newNode;
00242 tgtMesh->SetNodeOnFace( newNode, shapeID, uv.X(), uv.Y() );
00243 nbCreatedNodes++;
00244 }
00245 }
00246 if ( !(newNodes[i] = n2nIt->second ))
00247 break;
00248 }
00249 if ( !newNodes.back() )
00250 continue;
00251
00252
00253 SMDS_MeshElement * newFace = 0;
00254 if ( nbCreatedNodes == 0 &&
00255 tgtMesh->FindElement(newNodes, SMDSAbs_Face, false))
00256 continue;
00257
00258
00259 if ( toCheckOri )
00260 {
00261 int iNode = -1;
00262 gp_Vec geomNorm;
00263 do
00264 {
00265 uv = helper.GetNodeUV( geomFace, newNodes[++iNode] );
00266 surface->D1( uv.X(),uv.Y(), p, du,dv );
00267 geomNorm = reverse ? dv^du : du^dv;
00268 }
00269 while ( geomNorm.SquareMagnitude() < 1e-6 && iNode+1 < face->NbCornerNodes());
00270
00271 int iNext = helper.WrapIndex( iNode+1, face->NbCornerNodes() );
00272 int iPrev = helper.WrapIndex( iNode-1, face->NbCornerNodes() );
00273
00274 SMESH_TNodeXYZ prevNode( newNodes[iPrev] );
00275 SMESH_TNodeXYZ curNode ( newNodes[iNode] );
00276 SMESH_TNodeXYZ nextNode( newNodes[iNext] );
00277 gp_Vec n1n0( prevNode - curNode);
00278 gp_Vec n1n2( nextNode - curNode );
00279 gp_Vec meshNorm = n1n2 ^ n1n0;
00280
00281 if ( geomNorm * meshNorm < 0 )
00282 std::reverse( newNodes.begin(), newNodes.end() );
00283 }
00284
00285
00286 switch ( newNodes.size() )
00287 {
00288 case 3:
00289 newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2] );
00290 break;
00291 case 4:
00292 newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3] );
00293 break;
00294 case 6:
00295 newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2],
00296 newNodes[3], newNodes[4], newNodes[5]);
00297 break;
00298 case 8:
00299 newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3],
00300 newNodes[4], newNodes[5], newNodes[6], newNodes[7]);
00301 break;
00302 default: continue;
00303 }
00304 tgtMesh->SetMeshElementOnShape( newFace, shapeID );
00305 e2e->insert( make_pair( face, newFace ));
00306
00307
00308 int nbNodes = face->NbCornerNodes();
00309 const SMDS_MeshNode* medium = 0;
00310 for ( int i = 0; i < nbNodes; ++i )
00311 {
00312 const SMDS_MeshNode* n1 = newNodes[i];
00313 const SMDS_MeshNode* n2 = newNodes[ (i+1)%nbNodes ];
00314 if ( newFace->IsQuadratic() )
00315 medium = newNodes[i+nbNodes];
00316 link2Nb = linkCount.insert( make_pair( TLink( n1, n2, medium ), 0)).first;
00317 ++link2Nb->second;
00318 if ( link2Nb->second == 1 )
00319 {
00320
00321 double len2 = SMESH_TNodeXYZ( n1 ).SquareDistance( n2 );
00322 if ( len2 < minLinkLen2 )
00323 minLinkLen2 = len2;
00324 }
00325 }
00326 }
00327 helper.GetMeshDS()->RemoveNode(tmpNode);
00328 }
00329
00330
00331
00332
00333
00334
00335 vector< TopoDS_Edge > edges;
00336 for ( exp.Init( theShape, TopAbs_EDGE ); exp.More(); exp.Next() )
00337 if ( subShapeIDs.insert( tgtMesh->ShapeToIndex( exp.Current() )).second )
00338 edges.push_back( TopoDS::Edge( exp.Current() ));
00339
00340
00341
00342 const double projTol = 1e-3 * sqrt( minLinkLen2 );
00343
00344 bool isFaceMeshed = false;
00345 if ( SMESHDS_SubMesh* tgtSM = tgtMesh->MeshElements( theShape ))
00346 {
00347
00348
00349 subShapeIDs.erase( shapeID );
00350 double u, f, l;
00351 for ( link2Nb = linkCount.begin(); link2Nb != linkCount.end(); ++link2Nb)
00352 {
00353 const TLink& link = (*link2Nb).first;
00354 int nbFaces = link2Nb->second;
00355 if ( nbFaces == 1 )
00356 {
00357
00358 bool nodesOnBoundary = true;
00359 list< TopoDS_Shape > bndShapes;
00360 for ( int is1stN = 0; is1stN < 2 && nodesOnBoundary; ++is1stN )
00361 {
00362 const SMDS_MeshNode* n = is1stN ? link.node1() : link.node2();
00363 if ( !subShapeIDs.count( n->getshapeId() ))
00364 {
00365 for ( unsigned iE = 0; iE < edges.size(); ++iE )
00366 if ( helper.CheckNodeU( edges[iE], n, u=0, projTol, true ))
00367 {
00368 BRep_Tool::Range(edges[iE],f,l);
00369 if ( Abs(u-f) < 2 * faceTol || Abs(u-l) < 2 * faceTol )
00370
00371 return error("Source elements overlap one another");
00372 tgtSM->RemoveNode( n, false );
00373 tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)n, edges[iE], u );
00374 break;
00375 }
00376 nodesOnBoundary = subShapeIDs.count( n->getshapeId());
00377 }
00378 if ( nodesOnBoundary )
00379 {
00380 TopoDS_Shape s = helper.GetSubShapeByNode( n, tgtMesh );
00381 if ( s.ShapeType() == TopAbs_VERTEX )
00382 bndShapes.push_front( s );
00383 else
00384 bndShapes.push_back( s );
00385 }
00386 }
00387 if ( !nodesOnBoundary )
00388 break;
00389 if ( bndShapes.front().ShapeType() == TopAbs_EDGE &&
00390 bndShapes.front() != bndShapes.back() )
00391 break;
00392
00393
00394 if ( bndShapes.back().ShapeType() != TopAbs_EDGE )
00395 {
00396
00397 TopoDS_Shape geomEdge;
00398 PShapeIteratorPtr edgeIt = helper.GetAncestors( bndShapes.back(), theMesh, TopAbs_EDGE );
00399 while ( edgeIt->more() )
00400 {
00401 geomEdge = *(edgeIt->next());
00402 if ( !helper.IsSubShape( bndShapes.front(), geomEdge ))
00403 geomEdge.Nullify();
00404 }
00405 if ( geomEdge.IsNull() )
00406 break;
00407 bndShapes.push_back( geomEdge );
00408 }
00409
00410
00411 newNodes.resize(2);
00412 newNodes[0] = link.node1(), newNodes[1] = link.node2();
00413 const SMDS_MeshElement* edge = tgtMesh->FindElement( newNodes, SMDSAbs_Edge );
00414 if ( edge ) continue;
00415
00416 if ( link._reversed ) std::swap( newNodes[0], newNodes[1] );
00417 if ( link._medium )
00418 {
00419 newNodes.push_back( link._medium );
00420 edge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] );
00421
00422 TopoDS_Edge geomEdge = TopoDS::Edge(bndShapes.back());
00423 helper.CheckNodeU( geomEdge, link._medium, u, 10*faceTol, true );
00424 tgtSM->RemoveNode( link._medium, false );
00425 tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)link._medium, geomEdge, u );
00426 }
00427 else
00428 {
00429 edge = tgtMesh->AddEdge( newNodes[0], newNodes[1]);
00430 }
00431 if ( !edge )
00432 return false;
00433
00434 tgtMesh->SetMeshElementOnShape( edge, bndShapes.back() );
00435 }
00436 else if ( nbFaces > 2 )
00437 {
00438 return error( "Non-manifold source mesh");
00439 }
00440 }
00441 isFaceMeshed = ( link2Nb == linkCount.end() && !linkCount.empty());
00442 if ( isFaceMeshed )
00443 {
00444
00445
00446 SMESH_MeshEditor editor( &theMesh );
00447 set<int>::iterator subID = subShapeIDs.begin();
00448 for ( ; subID != subShapeIDs.end(); ++subID )
00449 {
00450 const TopoDS_Shape& s = tgtMesh->IndexToShape( *subID );
00451 if ( s.ShapeType() != TopAbs_VERTEX ) continue;
00452 const SMDS_MeshNode* n = SMESH_Algo::VertexNode( TopoDS::Vertex(s), tgtMesh );
00453 SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator(SMDSAbs_Edge);
00454 int nbEdges = 0;
00455 while ( eIt->more() )
00456 {
00457 const SMDS_MeshElement* edge = eIt->next();
00458 int sId = editor.FindShape( edge );
00459 nbEdges += subShapeIDs.count( sId );
00460 }
00461 if ( nbEdges < 2 )
00462 return false;
00463 if ( nbEdges > 2 )
00464 return error( "Source elements overlap one another");
00465 }
00466 }
00467 }
00468 if ( !isFaceMeshed )
00469 return error( "Source elements don't cover totally the geometrical face" );
00470
00471
00472 for ( unsigned iE = 0; iE < edges.size(); ++iE )
00473 theMesh.GetSubMesh( edges[iE] )->ComputeStateEngine(SMESH_subMesh::CHECK_COMPUTE_STATE);
00474
00475
00476
00477
00478
00479 vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
00480 for ( unsigned i = 0; i < srcMeshes.size(); ++i )
00481 StdMeshers_Import_1D::importMesh( srcMeshes[i], theMesh, _sourceHyp, theShape );
00482
00483 return true;
00484 }
00485
00486
00492
00493
00494 void StdMeshers_Import_1D2D::SetEventListener(SMESH_subMesh* subMesh)
00495 {
00496 if ( !_sourceHyp )
00497 {
00498 const TopoDS_Shape& tgtShape = subMesh->GetSubShape();
00499 SMESH_Mesh* tgtMesh = subMesh->GetFather();
00500 Hypothesis_Status aStatus;
00501 CheckHypothesis( *tgtMesh, tgtShape, aStatus );
00502 }
00503 StdMeshers_Import_1D::setEventListener( subMesh, _sourceHyp );
00504 }
00505 void StdMeshers_Import_1D2D::SubmeshRestored(SMESH_subMesh* subMesh)
00506 {
00507 SetEventListener(subMesh);
00508 }
00509
00510
00514
00515
00516 bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh & theMesh,
00517 const TopoDS_Shape & theShape,
00518 MapShapeNbElems& aResMap)
00519 {
00520 if ( !_sourceHyp ) return false;
00521
00522 const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
00523 if ( srcGroups.empty() )
00524 return error("Invalid source groups");
00525
00526 vector<int> aVec(SMDSEntity_Last,0);
00527
00528 bool toCopyMesh, toCopyGroups;
00529 _sourceHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups);
00530 if ( toCopyMesh )
00531 {
00532 vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
00533 for ( unsigned i = 0; i < srcMeshes.size(); ++i )
00534 {
00535 SMESH_subMesh* sm = StdMeshers_Import_1D::getSubMeshOfCopiedMesh( theMesh, *srcMeshes[i]);
00536 if ( !sm || aResMap.count( sm )) continue;
00537 const SMDS_MeshInfo& aMeshInfo = srcMeshes[i]->GetMeshDS()->GetMeshInfo();
00538 for (int i = 0; i < SMDSEntity_Last; i++)
00539 aVec[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
00540 }
00541 }
00542 else
00543 {
00544
00545 typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator;
00546
00547 SMESH_MesherHelper helper(theMesh);
00548 helper.SetSubShape(theShape);
00549
00550 const TopoDS_Face& geomFace = TopoDS::Face( theShape );
00551 const double faceTol = helper.MaxTolerance( geomFace );
00552
00553
00554 TopExp_Explorer exp( theShape, TopAbs_VERTEX );
00555 for ( ; exp.More(); exp.Next() )
00556 theMesh.GetSubMesh( exp.Current())->Evaluate( aResMap );
00557
00558
00559
00560 map<SMESH_TLink, int> linkCount;
00561 map<SMESH_TLink, int>::iterator link2Nb;
00562
00563
00564 set<const SMDS_MeshNode* > allNodes;
00565 gp_XY uv;
00566 for ( int iG = 0; iG < srcGroups.size(); ++iG )
00567 {
00568 const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
00569 SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
00570 SMDS_MeshNode *tmpNode =helper.AddNode(0,0,0);
00571 while ( srcElems->more() )
00572 {
00573 const SMDS_MeshElement* face = srcElems->next();
00574
00575
00576 gp_XYZ gc(0,0,0);
00577 gc = accumulate( TXyzIterator(face->nodesIterator()), TXyzIterator(), gc)/face->NbNodes();
00578 tmpNode->setXYZ( gc.X(), gc.Y(), gc.Z());
00579 if ( helper.CheckNodeUV( geomFace, tmpNode, uv, 10 * faceTol, true ))
00580 {
00581 ++aVec[ face->GetEntityType() ];
00582
00583
00584 int nbConers = face->NbCornerNodes();
00585 for ( int i = 0; i < face->NbNodes(); ++i )
00586 {
00587 const SMDS_MeshNode* n1 = face->GetNode(i);
00588 allNodes.insert( n1 );
00589 if ( i < nbConers )
00590 {
00591 const SMDS_MeshNode* n2 = face->GetNode( (i+1)%nbConers );
00592 link2Nb = linkCount.insert( make_pair( SMESH_TLink( n1, n2 ), 0)).first;
00593 if ( (*link2Nb).second )
00594 link2Nb->second += (link2Nb->second < 0 ) ? -1 : 1;
00595 else
00596 link2Nb->second += ( face->IsQuadratic() ) ? -1 : 1;
00597 }
00598 }
00599 }
00600 }
00601 helper.GetMeshDS()->RemoveNode(tmpNode);
00602 }
00603
00604 int nbNodes = allNodes.size();
00605 allNodes.clear();
00606
00607
00608
00609 double u;
00610 for ( exp.Init(theShape, TopAbs_EDGE); exp.More(); exp.Next() )
00611 {
00612 TopoDS_Edge geomEdge = TopoDS::Edge( exp.Current() );
00613 SMESH_subMesh* sm = theMesh.GetSubMesh( geomEdge );
00614 vector<int>& edgeVec = aResMap[sm];
00615 if ( edgeVec.empty() )
00616 {
00617 edgeVec.resize(SMDSEntity_Last,0);
00618 for ( link2Nb = linkCount.begin(); link2Nb != linkCount.end(); )
00619 {
00620 const SMESH_TLink& link = (*link2Nb).first;
00621 int nbFacesOfLink = Abs( link2Nb->second );
00622 bool eraseLink = ( nbFacesOfLink != 1 );
00623 if ( nbFacesOfLink == 1 )
00624 {
00625 if ( helper.CheckNodeU( geomEdge, link.node1(), u, 10*faceTol, true )&&
00626 helper.CheckNodeU( geomEdge, link.node2(), u, 10*faceTol, true ))
00627 {
00628 bool isQuadratic = ( link2Nb->second < 0 );
00629 ++edgeVec[ isQuadratic ? SMDSEntity_Quad_Edge : SMDSEntity_Edge ];
00630 ++edgeVec[ SMDSEntity_Node ];
00631 --nbNodes;
00632 eraseLink = true;
00633 }
00634 }
00635 if ( eraseLink )
00636 linkCount.erase(link2Nb++);
00637 else
00638 link2Nb++;
00639 }
00640 if ( edgeVec[ SMDSEntity_Node] > 0 )
00641 --edgeVec[ SMDSEntity_Node ];
00642 }
00643 else if ( !helper.IsSeamShape( geomEdge ) ||
00644 geomEdge.Orientation() == TopAbs_FORWARD )
00645 {
00646 nbNodes -= 1+edgeVec[ SMDSEntity_Node ];
00647 }
00648 }
00649
00650 aVec[SMDSEntity_Node] = nbNodes;
00651 }
00652
00653 SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
00654 aResMap.insert(make_pair(sm,aVec));
00655
00656 return true;
00657 }