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_Penta_3D.hxx"
00028
00029 #include "utilities.h"
00030 #include "Utils_ExceptHandlers.hxx"
00031
00032 #include "SMDS_EdgePosition.hxx"
00033 #include "SMDS_MeshElement.hxx"
00034 #include "SMDS_VolumeOfNodes.hxx"
00035 #include "SMDS_VolumeTool.hxx"
00036 #include "SMESHDS_SubMesh.hxx"
00037 #include "SMESH_Mesh.hxx"
00038 #include "SMESH_MesherHelper.hxx"
00039 #include "SMESH_subMesh.hxx"
00040 #include "SMESH_subMeshEventListener.hxx"
00041 #include "SMESH_Comment.hxx"
00042
00043 #include <BRep_Tool.hxx>
00044 #include <TopExp.hxx>
00045 #include <TopExp_Explorer.hxx>
00046 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
00047 #include <TopTools_IndexedMapOfShape.hxx>
00048 #include <TopTools_ListIteratorOfListOfShape.hxx>
00049 #include <TopTools_ListOfShape.hxx>
00050 #include <TopTools_SequenceOfShape.hxx>
00051 #include <TopTools_MapOfShape.hxx>
00052 #include <TopoDS.hxx>
00053 #include <TopoDS_Edge.hxx>
00054 #include <TopoDS_Shell.hxx>
00055 #include <TopoDS_Vertex.hxx>
00056 #include <gp_Pnt.hxx>
00057
00058 #include <stdio.h>
00059 #include <algorithm>
00060
00061 using namespace std;
00062
00063 typedef map < int, int, less<int> >::iterator \
00064 StdMeshers_IteratorOfDataMapOfIntegerInteger;
00065
00066 enum { NB_WALL_FACES = 4 };
00067
00068
00069
00070
00071
00072 StdMeshers_Penta_3D::StdMeshers_Penta_3D()
00073 : myErrorStatus(SMESH_ComputeError::New())
00074 {
00075 myTol3D=0.1;
00076 myWallNodesMaps.resize( SMESH_Block::NbFaces() );
00077 myShapeXYZ.resize( SMESH_Block::NbSubShapes() );
00078 myTool = 0;
00079 }
00080
00081
00082
00083
00084
00085
00086 StdMeshers_Penta_3D::~StdMeshers_Penta_3D()
00087 {
00088 }
00089
00090
00091
00092
00093
00094 bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh,
00095 const TopoDS_Shape& aShape)
00096 {
00097 MESSAGE("StdMeshers_Penta_3D::Compute()");
00098
00099 bool bOK=false;
00100
00101 myShape=aShape;
00102 SetMesh(aMesh);
00103
00104 CheckData();
00105 if (!myErrorStatus->IsOK()) {
00106 return bOK;
00107 }
00108
00109
00110 MakeBlock();
00111 if (!myErrorStatus->IsOK()) {
00112 return bOK;
00113 }
00114
00115 ClearMeshOnFxy1();
00116 if (!myErrorStatus->IsOK()) {
00117 return bOK;
00118 }
00119
00120
00121 SMESH_MesherHelper helper(aMesh);
00122 myTool = &helper;
00123 myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape);
00124
00125
00126 MakeNodes();
00127 if (!myErrorStatus->IsOK()) {
00128 return bOK;
00129 }
00130
00131 MakeConnectingMap();
00132
00133 MakeMeshOnFxy1();
00134 if (!myErrorStatus->IsOK()) {
00135 return bOK;
00136 }
00137
00138 MakeVolumeMesh();
00139
00140 return !bOK;
00141 }
00142
00143
00144
00145
00146
00147 void StdMeshers_Penta_3D::MakeNodes()
00148 {
00149 const int aNbSIDs=9;
00150 int i, j, k, ij, iNbN, aNodeID, aSize, iErr;
00151 double aX, aY, aZ;
00152 SMESH_Block::TShapeID aSID, aSIDs[aNbSIDs]={
00153 SMESH_Block::ID_V000, SMESH_Block::ID_V100,
00154 SMESH_Block::ID_V110, SMESH_Block::ID_V010,
00155 SMESH_Block::ID_Ex00, SMESH_Block::ID_E1y0,
00156 SMESH_Block::ID_Ex10, SMESH_Block::ID_E0y0,
00157 SMESH_Block::ID_Fxy0
00158 };
00159
00160 SMESH_Mesh* pMesh=GetMesh();
00161
00162
00163
00164
00165 myJSize=0;
00166 for (i=0; i<aNbSIDs; ++i) {
00167 const TopoDS_Shape& aS = myBlock.Shape(aSIDs[i]);
00168 SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS);
00169 ASSERT(aSubMesh);
00170 SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS();
00171 if(!myCreateQuadratic) {
00172 iNbN = aSM->NbNodes();
00173 }
00174 else {
00175 iNbN = 0;
00176 SMDS_NodeIteratorPtr itn = aSM->GetNodes();
00177 while(itn->more()) {
00178 const SMDS_MeshNode* aNode = itn->next();
00179 if(myTool->IsMedium(aNode))
00180 continue;
00181 iNbN++;
00182 }
00183 }
00184 myJSize += iNbN;
00185 }
00186
00187
00188
00189 myISize=2;
00190 {
00191 const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_E00z);
00192 SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS);
00193 ASSERT(aSubMesh);
00194 SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS();
00195 if(!myCreateQuadratic) {
00196 iNbN = aSM->NbNodes();
00197 }
00198 else {
00199 iNbN = 0;
00200 SMDS_NodeIteratorPtr itn = aSM->GetNodes();
00201 while(itn->more()) {
00202 const SMDS_MeshNode* aNode = itn->next();
00203 if(myTool->IsMedium(aNode))
00204 continue;
00205 iNbN++;
00206 }
00207 }
00208 myISize += iNbN;
00209 }
00210
00211
00212 aSize=myISize*myJSize;
00213 myTNodes.resize(aSize);
00214
00215 StdMeshers_TNode aTNode;
00216 gp_XYZ aCoords;
00217 gp_Pnt aP3D;
00218
00219
00220 i=0; j=0;
00221
00222 for (k=0; k<aNbSIDs; ++k) {
00223 aSID=aSIDs[k];
00224 const TopoDS_Shape& aS = myBlock.Shape(aSID);
00225 SMDS_NodeIteratorPtr ite = pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes();
00226 while(ite->more()) {
00227 const SMDS_MeshNode* aNode = ite->next();
00228 if(myTool->IsMedium(aNode))
00229 continue;
00230 aNodeID=aNode->GetID();
00231
00232 aTNode.SetNode(aNode);
00233 aTNode.SetShapeSupportID(aSID);
00234 aTNode.SetBaseNodeID(aNodeID);
00235
00236 if ( SMESH_Block::IsEdgeID (aSID)) {
00237 const SMDS_EdgePosition* epos =
00238 static_cast<const SMDS_EdgePosition*>(aNode->GetPosition());
00239 myBlock.ComputeParameters( epos->GetUParameter(), aS, aCoords );
00240 }
00241 else {
00242 aX=aNode->X();
00243 aY=aNode->Y();
00244 aZ=aNode->Z();
00245 aP3D.SetCoord(aX, aY, aZ);
00246 myBlock.ComputeParameters(aP3D, aS, aCoords);
00247 }
00248 iErr = myBlock.ErrorStatus();
00249 if (iErr) {
00250 MESSAGE("StdMeshers_Penta_3D::MakeNodes()," <<
00251 "SMESHBlock: ComputeParameters operation failed");
00252 myErrorStatus=myBlock.GetError();
00253 return;
00254 }
00255 aTNode.SetNormCoord(aCoords);
00256 ij=i*myJSize+j;
00257 myTNodes[ij]=aTNode;
00258 ++j;
00259 }
00260 }
00261
00262
00263 SMESH_Block::TShapeID wallFaceID[ NB_WALL_FACES ] = {
00264 SMESH_Block::ID_Fx0z, SMESH_Block::ID_Fx1z,
00265 SMESH_Block::ID_F0yz, SMESH_Block::ID_F1yz
00266 };
00267 SMESH_Block::TShapeID baseEdgeID[ NB_WALL_FACES ] = {
00268 SMESH_Block::ID_Ex00, SMESH_Block::ID_Ex10,
00269 SMESH_Block::ID_E0y0, SMESH_Block::ID_E1y0
00270 };
00271 for ( i = 0; i < NB_WALL_FACES ; ++i ) {
00272 int fIndex = SMESH_Block::ShapeIndex( wallFaceID[ i ]);
00273 bool ok = LoadIJNodes (myWallNodesMaps[ fIndex ],
00274 TopoDS::Face( myBlock.Shape( wallFaceID[ i ] )),
00275 TopoDS::Edge( myBlock.Shape( baseEdgeID[ i ] )),
00276 pMesh->GetMeshDS());
00277 if ( !ok ) {
00278 myErrorStatus->myName = COMPERR_BAD_INPUT_MESH;
00279 myErrorStatus->myComment = SMESH_Comment() <<
00280 "Can't find regular quadrangle mesh on a side face #" <<
00281 pMesh->GetMeshDS()->ShapeToIndex( myBlock.Shape( wallFaceID[ i ]));
00282 return;
00283 }
00284 }
00285
00286
00287 vector<const SMDS_MeshNode*> * verticEdgeNodes[ NB_WALL_FACES ];
00288 SMESH_Block::TShapeID verticEdgeID [ NB_WALL_FACES ];
00289 for ( i = 0; i < NB_WALL_FACES ; ++i ) {
00290
00291 SMESH_Block::TShapeID eID, vID = aSIDs[ i ];
00292 ShapeSupportID(false, vID, eID);
00293 verticEdgeID[ i ] = eID;
00294
00295 StdMeshers_TNode& aTNode = myTNodes[ i ];
00296 verticEdgeNodes[ i ] = 0;
00297 for ( j = 0; j < NB_WALL_FACES ; ++j ) {
00298 int fIndex = SMESH_Block::ShapeIndex( wallFaceID[ j ]);
00299 StdMeshers_IJNodeMap & ijNodes= myWallNodesMaps[ fIndex ];
00300 if ( ijNodes.begin()->second[0] == aTNode.Node() )
00301 verticEdgeNodes[ i ] = & ijNodes.begin()->second;
00302 else if ( ijNodes.rbegin()->second[0] == aTNode.Node() )
00303 verticEdgeNodes[ i ] = & ijNodes.rbegin()->second;
00304 if ( verticEdgeNodes[ i ] )
00305 break;
00306 }
00307 }
00308
00309
00310 SMESHDS_Mesh* aMesh = GetMesh()->GetMeshDS();
00311 for ( int id = SMESH_Block::ID_V000; id < SMESH_Block::ID_Shell; ++id ) {
00312 if ( SMESH_Block::IsVertexID( id )) {
00313 TopoDS_Shape V = myBlock.Shape( id );
00314 SMESHDS_SubMesh* sm = aMesh->MeshElements( V );
00315 const SMDS_MeshNode* n = sm->GetNodes()->next();
00316 myShapeXYZ[ id ].SetCoord( n->X(), n->Y(), n->Z() );
00317 }
00318 else
00319 myShapeXYZ[ id ].SetCoord( 0., 0., 0. );
00320 }
00321
00322
00323
00324 bool bIsUpperLayer;
00325 int iBNID;
00326 SMESH_Block::TShapeID aSSID, aBNSSID;
00327 StdMeshers_TNode aTN;
00328
00329
00330
00331 const TopoDS_Face& TopFace = TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy1));
00332 SMESHDS_Mesh* meshDS = pMesh->GetMeshDS();
00333 int topfaceID = meshDS->ShapeToIndex(TopFace);
00334 const TopoDS_Vertex& v001 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V001));
00335 SMDS_NodeIteratorPtr itn = pMesh->GetSubMeshContaining(v001)->GetSubMeshDS()->GetNodes();
00336 const SMDS_MeshNode* N = itn->next();
00337 gp_XY UV001 = myTool->GetNodeUV(TopFace,N);
00338 const TopoDS_Vertex& v101 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V101));
00339 itn = pMesh->GetSubMeshContaining(v101)->GetSubMeshDS()->GetNodes();
00340 N = itn->next();
00341 gp_XY UV101 = myTool->GetNodeUV(TopFace,N);
00342 const TopoDS_Vertex& v011 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V011));
00343 itn = pMesh->GetSubMeshContaining(v011)->GetSubMeshDS()->GetNodes();
00344 N = itn->next();
00345 gp_XY UV011 = myTool->GetNodeUV(TopFace,N);
00346 const TopoDS_Vertex& v111 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V111));
00347 itn = pMesh->GetSubMeshContaining(v111)->GetSubMeshDS()->GetNodes();
00348 N = itn->next();
00349 gp_XY UV111 = myTool->GetNodeUV(TopFace,N);
00350
00351 for (j=0; j<myJSize; ++j) {
00352
00353 const StdMeshers_TNode& aBN = myTNodes[j];
00354 aBNSSID = (SMESH_Block::TShapeID)aBN.ShapeSupportID();
00355 iBNID = aBN.BaseNodeID();
00356 const gp_XYZ& aBNXYZ = aBN.NormCoord();
00357 bool createNode = ( aBNSSID == SMESH_Block::ID_Fxy0 );
00358
00359
00360
00361 vector<const SMDS_MeshNode*>* nColumns[8];
00362 double ratio[ NB_WALL_FACES ];
00363 if ( createNode ) {
00364 for ( k = 0; k < NB_WALL_FACES ; ++k ) {
00365 ratio[ k ] = SetHorizEdgeXYZ (aBNXYZ, wallFaceID[ k ],
00366 nColumns[k*2], nColumns[k*2+1]);
00367 }
00368 }
00369
00370
00371 const SMDS_MeshNode* n = aBN.Node();
00372 myShapeXYZ[ SMESH_Block::ID_Fxy0 ].SetCoord( n->X(), n->Y(), n->Z() );
00373 myShapeXYZ[ SMESH_Block::ID_Fxy1 ].SetCoord( 0., 0., 0. );
00374
00375
00376 for (i=myISize-1; i>0; --i)
00377 {
00378 bIsUpperLayer = (i==(myISize-1));
00379 gp_XY UV_Ex01, UV_Ex11, UV_E0y1, UV_E1y1;
00380 if ( createNode )
00381 {
00382
00383 for ( k = 0; k < NB_WALL_FACES ; ++k ) {
00384
00385 const SMDS_MeshNode* n = (*verticEdgeNodes[ k ]) [ i ];
00386 myShapeXYZ[ verticEdgeID[ k ] ].SetCoord( n->X(), n->Y(), n->Z() );
00387
00388 n = (*nColumns[k*2]) [ i ];
00389 gp_XYZ xyz( n->X(), n->Y(), n->Z() );
00390 myShapeXYZ[ wallFaceID[ k ]] = ( 1. - ratio[ k ]) * xyz;
00391 gp_XY tmp1;
00392 if( bIsUpperLayer ) {
00393 tmp1 = myTool->GetNodeUV(TopFace,n);
00394 tmp1 = ( 1. - ratio[ k ]) * tmp1;
00395 }
00396
00397 n = (*nColumns[k*2+1]) [ i ];
00398 xyz.SetCoord( n->X(), n->Y(), n->Z() );
00399 myShapeXYZ[ wallFaceID[ k ]] += ratio[ k ] * xyz;
00400 if( bIsUpperLayer ) {
00401 gp_XY tmp2 = myTool->GetNodeUV(TopFace,n);
00402 tmp1 += ratio[ k ] * tmp2;
00403 if( k==0 )
00404 UV_Ex01 = tmp1;
00405 else if( k==1 )
00406 UV_Ex11 = tmp1;
00407 else if( k==2 )
00408 UV_E0y1 = tmp1;
00409 else
00410 UV_E1y1 = tmp1;
00411 }
00412 }
00413 }
00414
00415
00416 ij=i*myJSize+j;
00417
00418 aX=aBNXYZ.X();
00419 aY=aBNXYZ.Y();
00420
00421 aZ=(double)i/(double)(myISize-1);
00422 aCoords.SetCoord(aX, aY, aZ);
00423
00424
00425 ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID);
00426 if (!myErrorStatus->IsOK()) {
00427 MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
00428 return;
00429 }
00430
00431 aTN.SetShapeSupportID(aSSID);
00432 aTN.SetNormCoord(aCoords);
00433 aTN.SetBaseNodeID(iBNID);
00434
00435 if (aSSID!=SMESH_Block::ID_NONE){
00436
00437 const TopoDS_Shape& aS=myBlock.Shape((int)aSSID);
00438 FindNodeOnShape(aS, aCoords, i, aTN);
00439 }
00440 else{
00441
00442 CreateNode (bIsUpperLayer, aCoords, aTN);
00443
00444 if ( bIsUpperLayer ) {
00445 const SMDS_MeshNode* n = aTN.Node();
00446 myShapeXYZ[ SMESH_Block::ID_Fxy1 ].SetCoord( n->X(), n->Y(), n->Z() );
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 gp_Pnt2d aP;
00460 double u = aCoords.X(), v = aCoords.Y();
00461 double u1 = ( 1. - u ), v1 = ( 1. - v );
00462 aP.ChangeCoord() = UV_Ex01 * v1;
00463 aP.ChangeCoord() += UV_Ex11 * v;
00464 aP.ChangeCoord() += UV_E0y1 * u1;
00465 aP.ChangeCoord() += UV_E1y1 * u;
00466 aP.ChangeCoord() -= UV001 * u1 * v1;
00467 aP.ChangeCoord() -= UV101 * u * v1;
00468 aP.ChangeCoord() -= UV011 * u1 * v;
00469 aP.ChangeCoord() -= UV111 * u * v;
00470 meshDS->SetNodeOnFace((SMDS_MeshNode*)n, topfaceID, aP.X(), aP.Y());
00471 }
00472 }
00473 if (!myErrorStatus->IsOK()) {
00474 MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
00475 return;
00476 }
00477
00478 myTNodes[ij]=aTN;
00479 }
00480 }
00481 }
00482
00483
00484
00485
00486
00487
00488
00489 void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS,
00490 const gp_XYZ& aParams,
00491 const int z,
00492 StdMeshers_TNode& aTN)
00493 {
00494 double aX, aY, aZ, aD, aTol2, minD;
00495 gp_Pnt aP1, aP2;
00496
00497 SMESH_Mesh* pMesh = GetMesh();
00498 aTol2 = myTol3D*myTol3D;
00499 minD = 1.e100;
00500 SMDS_MeshNode* pNode = NULL;
00501
00502 if ( aS.ShapeType() == TopAbs_FACE ||
00503 aS.ShapeType() == TopAbs_EDGE ) {
00504
00505 int faceID;
00506 if ( aS.ShapeType() == TopAbs_FACE )
00507 faceID = myBlock.ShapeID( aS );
00508 else {
00509 gp_XYZ aCoord = aParams;
00510 if ( aCoord.Z() == 1. )
00511 aCoord.SetZ( 0.5 );
00512 else
00513 aCoord.SetX( 0.5 );
00514 faceID = SMESH_Block::GetShapeIDByParams( aCoord );
00515 }
00516 ASSERT( SMESH_Block::IsFaceID( faceID ));
00517 int fIndex = SMESH_Block::ShapeIndex( faceID );
00518 StdMeshers_IJNodeMap & ijNodes = myWallNodesMaps[ fIndex ];
00519
00520 const SMDS_MeshNode* baseNode = pMesh->GetMeshDS()->FindNode( aTN.BaseNodeID() );
00521 StdMeshers_IJNodeMap::const_iterator par_nVec = ijNodes.begin();
00522 for ( ; par_nVec != ijNodes.end(); par_nVec++ )
00523 if ( par_nVec->second[ 0 ] == baseNode ) {
00524 pNode = (SMDS_MeshNode*)par_nVec->second.at( z );
00525 aTN.SetNode(pNode);
00526 return;
00527 }
00528 }
00529
00530 myBlock.Point(aParams, aS, aP1);
00531
00532 SMDS_NodeIteratorPtr ite=
00533 pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes();
00534 while(ite->more()) {
00535 const SMDS_MeshNode* aNode = ite->next();
00536 if(myTool->IsMedium(aNode))
00537 continue;
00538 aX=aNode->X();
00539 aY=aNode->Y();
00540 aZ=aNode->Z();
00541 aP2.SetCoord(aX, aY, aZ);
00542 aD=(double)aP1.SquareDistance(aP2);
00543
00544 if (aD < minD) {
00545 pNode=(SMDS_MeshNode*)aNode;
00546 aTN.SetNode(pNode);
00547 minD = aD;
00548
00549 if (aD<aTol2)
00550 return;
00551 }
00552 }
00553
00554
00555
00556
00557
00558 }
00559
00560
00561
00562
00563
00564
00565
00566 double StdMeshers_Penta_3D::SetHorizEdgeXYZ(const gp_XYZ& aBaseNodeParams,
00567 const int aFaceID,
00568 vector<const SMDS_MeshNode*>*& aCol1,
00569 vector<const SMDS_MeshNode*>*& aCol2)
00570 {
00571
00572 enum { BASE = 0, TOP };
00573 vector< int > edgeVec;
00574 SMESH_Block::GetFaceEdgesIDs( aFaceID, edgeVec );
00575
00576 int coord = SMESH_Block::GetCoordIndOnEdge( edgeVec[ BASE ] );
00577 bool isForward = myBlock.IsForwadEdge( edgeVec[ BASE ] );
00578
00579 double param = aBaseNodeParams.Coord( coord );
00580 if ( !isForward)
00581 param = 1. - param;
00582
00583
00584 StdMeshers_IJNodeMap & ijNodes =
00585 myWallNodesMaps[ SMESH_Block::ShapeIndex( aFaceID )];
00586 StdMeshers_IJNodeMap::iterator par_nVec_1 = ijNodes.begin();
00587 while ( par_nVec_1->first < param )
00588 par_nVec_1++;
00589 StdMeshers_IJNodeMap::iterator par_nVec_2 = par_nVec_1;
00590
00591 double r = 0;
00592 if ( par_nVec_1 != ijNodes.begin() ) {
00593 par_nVec_1--;
00594 r = ( param - par_nVec_1->first ) / ( par_nVec_2->first - par_nVec_1->first );
00595 }
00596 aCol1 = & par_nVec_1->second;
00597 aCol2 = & par_nVec_2->second;
00598
00599
00600 if (1) {
00601
00602
00603 const SMDS_MeshNode* n1 = aCol1->back();
00604 const SMDS_MeshNode* n2 = aCol2->back();
00605 gp_XYZ xyz1( n1->X(), n1->Y(), n1->Z() );
00606 gp_XYZ xyz2( n2->X(), n2->Y(), n2->Z() );
00607 myShapeXYZ[ edgeVec[ 1 ] ] = ( 1. - r ) * xyz1 + r * xyz2;
00608 }
00609 else {
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 }
00622
00623
00624 myBlock.Block().EdgePoint( edgeVec[ BASE ],
00625 aBaseNodeParams,
00626 myShapeXYZ[ edgeVec[ BASE ]]);
00627 return r;
00628 }
00629
00630
00631
00632
00633
00634
00635 void StdMeshers_Penta_3D::MakeVolumeMesh()
00636 {
00637 int i, j, ij, ik, i1, i2, aSSID;
00638
00639 SMESH_Mesh* pMesh = GetMesh();
00640 SMESHDS_Mesh* meshDS = pMesh->GetMeshDS();
00641
00642 int shapeID = meshDS->ShapeToIndex( myShape );
00643
00644
00645 ik = myISize-1;
00646 for (i=1; i<ik; ++i){
00647 for (j=0; j<myJSize; ++j){
00648 ij=i*myJSize+j;
00649 const StdMeshers_TNode& aTN = myTNodes[ij];
00650 aSSID=aTN.ShapeSupportID();
00651 if (aSSID==SMESH_Block::ID_NONE) {
00652 SMDS_MeshNode* aNode = (SMDS_MeshNode*)aTN.Node();
00653 meshDS->SetNodeInVolume(aNode, shapeID);
00654 }
00655 }
00656 }
00657
00658
00659 int aID0, k , aJ[3];
00660 vector<const SMDS_MeshNode*> aN;
00661
00662 SMDS_ElemIteratorPtr itf, aItNodes;
00663
00664 const TopoDS_Face& aFxy0=
00665 TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0));
00666 SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0);
00667 SMESHDS_SubMesh *aSM0 = aSubMesh0->GetSubMeshDS();
00668
00669 itf = aSM0->GetElements();
00670 while(itf->more()) {
00671 const SMDS_MeshElement* pE0 = itf->next();
00672
00673 int nbFaceNodes = pE0->NbNodes();
00674 if(myCreateQuadratic)
00675 nbFaceNodes = nbFaceNodes/2;
00676 if ( aN.size() < nbFaceNodes * 2 )
00677 aN.resize( nbFaceNodes * 2 );
00678
00679 for ( k=0; k<nbFaceNodes; ++k ) {
00680 const SMDS_MeshNode* pNode = pE0->GetNode(k);
00681
00682
00683 aID0 = pNode->GetID();
00684 aJ[k] = GetIndexOnLayer(aID0);
00685 if (!myErrorStatus->IsOK()) {
00686 MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh");
00687 return;
00688 }
00689 }
00690
00691 bool forward = true;
00692 for (i=0; i<ik; ++i) {
00693 i1=i;
00694 i2=i+1;
00695 for(j=0; j<nbFaceNodes; ++j) {
00696 ij = i1*myJSize+aJ[j];
00697 const StdMeshers_TNode& aTN1 = myTNodes[ij];
00698 const SMDS_MeshNode* aN1 = aTN1.Node();
00699 aN[j]=aN1;
00700
00701 ij=i2*myJSize+aJ[j];
00702 const StdMeshers_TNode& aTN2 = myTNodes[ij];
00703 const SMDS_MeshNode* aN2 = aTN2.Node();
00704 aN[j+nbFaceNodes] = aN2;
00705 }
00706
00707 if ( i == 0 ) {
00708 SMDS_VolumeTool vTool;
00709 switch ( nbFaceNodes ) {
00710 case 3: {
00711 SMDS_VolumeOfNodes tmpVol (aN[0], aN[1], aN[2],
00712 aN[3], aN[4], aN[5]);
00713 vTool.Set( &tmpVol );
00714 break;
00715 }
00716 case 4: {
00717 SMDS_VolumeOfNodes tmpVol(aN[0], aN[1], aN[2], aN[3],
00718 aN[4], aN[5], aN[6], aN[7]);
00719 vTool.Set( &tmpVol );
00720 break;
00721 }
00722 default:
00723 continue;
00724 }
00725 forward = vTool.IsForward();
00726 }
00727
00728 SMDS_MeshVolume* aV = 0;
00729 switch ( nbFaceNodes ) {
00730 case 3:
00731 if ( forward ) {
00732
00733
00734 aV = myTool->AddVolume(aN[0], aN[1], aN[2], aN[3], aN[4], aN[5]);
00735 }
00736 else {
00737
00738
00739 aV = myTool->AddVolume(aN[0], aN[2], aN[1], aN[3], aN[5], aN[4]);
00740 }
00741 break;
00742 case 4:
00743 if ( forward ) {
00744
00745
00746 aV = myTool->AddVolume(aN[0], aN[1], aN[2], aN[3],
00747 aN[4], aN[5], aN[6], aN[7]);
00748 }
00749 else {
00750
00751
00752 aV = myTool->AddVolume(aN[0], aN[3], aN[2], aN[1],
00753 aN[4], aN[7], aN[6], aN[5]);
00754 }
00755 break;
00756 default:
00757 continue;
00758 }
00759 meshDS->SetMeshElementOnShape(aV, shapeID);
00760 }
00761 }
00762 }
00763
00764
00765
00766
00767
00768 void StdMeshers_Penta_3D::MakeMeshOnFxy1()
00769 {
00770 int aID0, aJ, aLevel, ij, aNbNodes, k;
00771
00772 SMDS_NodeIteratorPtr itn;
00773 SMDS_ElemIteratorPtr itf, aItNodes;
00774 SMDSAbs_ElementType aElementType;
00775
00776 const TopoDS_Face& aFxy0=
00777 TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0));
00778 const TopoDS_Face& aFxy1=
00779 TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy1));
00780
00781 SMESH_Mesh* pMesh = GetMesh();
00782 SMESHDS_Mesh * meshDS = pMesh->GetMeshDS();
00783
00784 SMESH_subMesh *aSubMesh1 = pMesh->GetSubMeshContaining(aFxy1);
00785 SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0);
00786 SMESHDS_SubMesh *aSM0 = aSubMesh0->GetSubMeshDS();
00787
00788
00789 aLevel = myISize-1;
00790 itn = aSM0->GetNodes();
00791 aNbNodes = aSM0->NbNodes();
00792
00793 myTool->SetSubShape( aFxy1 );
00794
00795
00796 vector<const SMDS_MeshNode*> aNodes1;
00797
00798 itf = aSM0->GetElements();
00799 while(itf->more()) {
00800 const SMDS_MeshElement* pE0 = itf->next();
00801 aElementType = pE0->GetType();
00802 if (!aElementType==SMDSAbs_Face) {
00803 continue;
00804 }
00805 aNbNodes = pE0->NbNodes();
00806 if(myCreateQuadratic)
00807 aNbNodes = aNbNodes/2;
00808 if ( aNodes1.size() < aNbNodes )
00809 aNodes1.resize( aNbNodes );
00810
00811 k = aNbNodes-1;
00812 aItNodes = pE0->nodesIterator();
00813 while (aItNodes->more()) {
00814 const SMDS_MeshNode* pNode =
00815 static_cast<const SMDS_MeshNode*> (aItNodes->next());
00816 if(myTool->IsMedium(pNode))
00817 continue;
00818 aID0 = pNode->GetID();
00819 aJ = GetIndexOnLayer(aID0);
00820 if (!myErrorStatus->IsOK()) {
00821 MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
00822 return;
00823 }
00824
00825 ij = aLevel*myJSize + aJ;
00826 const StdMeshers_TNode& aTN1 = myTNodes[ij];
00827 const SMDS_MeshNode* aN1 = aTN1.Node();
00828 aNodes1[k] = aN1;
00829 --k;
00830 }
00831 SMDS_MeshFace * face = 0;
00832 switch ( aNbNodes ) {
00833 case 3:
00834 face = myTool->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]);
00835 break;
00836 case 4:
00837 face = myTool->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]);
00838 break;
00839 default:
00840 continue;
00841 }
00842 meshDS->SetMeshElementOnShape(face, aFxy1);
00843 }
00844 myTool->SetSubShape( myShape );
00845
00846
00847 aSubMesh1->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
00848
00849
00850
00851 SMESH_subMesh* volSM = pMesh->GetSubMesh( myTool->GetSubShape() );
00852 volSM->SetEventListener( new SMESH_subMeshEventListener(true),
00853 SMESH_subMeshEventListenerData::MakeData( aSubMesh1 ),
00854 aSubMesh0 );
00855 }
00856
00857
00858
00859
00860
00861 void StdMeshers_Penta_3D::ClearMeshOnFxy1()
00862 {
00863 SMESH_subMesh* aSubMesh;
00864 SMESH_Mesh* pMesh=GetMesh();
00865
00866 const TopoDS_Shape& aFxy1=myBlock.Shape(SMESH_Block::ID_Fxy1);
00867 aSubMesh = pMesh->GetSubMeshContaining(aFxy1);
00868 if (aSubMesh)
00869 aSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN );
00870 }
00871
00872
00873
00874
00875
00876 int StdMeshers_Penta_3D::GetIndexOnLayer(const int aID)
00877 {
00878 int j=-1;
00879 StdMeshers_IteratorOfDataMapOfIntegerInteger aMapIt;
00880
00881 aMapIt=myConnectingMap.find(aID);
00882 if (aMapIt==myConnectingMap.end()) {
00883 myErrorStatus->myName = 200;
00884 myErrorStatus->myComment = "Internal error of StdMeshers_Penta_3D";
00885 return j;
00886 }
00887 j=(*aMapIt).second;
00888 return j;
00889 }
00890
00891
00892
00893
00894
00895 void StdMeshers_Penta_3D::MakeConnectingMap()
00896 {
00897 int j, aBNID;
00898
00899 for (j=0; j<myJSize; ++j) {
00900 const StdMeshers_TNode& aBN=myTNodes[j];
00901 aBNID=aBN.BaseNodeID();
00902 myConnectingMap[aBNID]=j;
00903 }
00904 }
00905
00906
00907
00908
00909
00910 void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer,
00911 const gp_XYZ& aParams,
00912 StdMeshers_TNode& aTN)
00913 {
00914 double aX, aY, aZ;
00915
00916 gp_Pnt aP;
00917
00918 SMDS_MeshNode* pNode=NULL;
00919 aTN.SetNode(pNode);
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930 if (bIsUpperLayer) {
00931 double u = aParams.X(), v = aParams.Y();
00932 double u1 = ( 1. - u ), v1 = ( 1. - v );
00933 aP.ChangeCoord() = myShapeXYZ[ SMESH_Block::ID_Ex01 ] * v1;
00934 aP.ChangeCoord() += myShapeXYZ[ SMESH_Block::ID_Ex11 ] * v;
00935 aP.ChangeCoord() += myShapeXYZ[ SMESH_Block::ID_E0y1 ] * u1;
00936 aP.ChangeCoord() += myShapeXYZ[ SMESH_Block::ID_E1y1 ] * u;
00937
00938 aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V001 ] * u1 * v1;
00939 aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V101 ] * u * v1;
00940 aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V011 ] * u1 * v;
00941 aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V111 ] * u * v;
00942 }
00943 else {
00944 SMESH_Block::ShellPoint( aParams, myShapeXYZ, aP.ChangeCoord() );
00945 }
00946
00947
00948
00949
00950
00951
00952
00953 aX=aP.X(); aY=aP.Y(); aZ=aP.Z();
00954
00955 SMESH_Mesh* pMesh = GetMesh();
00956 SMESHDS_Mesh* pMeshDS = pMesh->GetMeshDS();
00957
00958 pNode = pMeshDS->AddNode(aX, aY, aZ);
00959
00960 aTN.SetNode(pNode);
00961 }
00962
00963
00964
00965
00966
00967 void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer,
00968 const SMESH_Block::TShapeID aBNSSID,
00969 SMESH_Block::TShapeID& aSSID)
00970 {
00971 switch (aBNSSID) {
00972 case SMESH_Block::ID_V000:
00973 aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V001 : SMESH_Block::ID_E00z;
00974 break;
00975 case SMESH_Block::ID_V100:
00976 aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V101 : SMESH_Block::ID_E10z;
00977 break;
00978 case SMESH_Block::ID_V110:
00979 aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V111 : SMESH_Block::ID_E11z;
00980 break;
00981 case SMESH_Block::ID_V010:
00982 aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V011 : SMESH_Block::ID_E01z;
00983 break;
00984 case SMESH_Block::ID_Ex00:
00985 aSSID=(bIsUpperLayer) ? SMESH_Block::ID_Ex01 : SMESH_Block::ID_Fx0z;
00986 break;
00987 case SMESH_Block::ID_Ex10:
00988 aSSID=(bIsUpperLayer) ? SMESH_Block::ID_Ex11 : SMESH_Block::ID_Fx1z;
00989 break;
00990 case SMESH_Block::ID_E0y0:
00991 aSSID=(bIsUpperLayer) ? SMESH_Block::ID_E0y1 : SMESH_Block::ID_F0yz;
00992 break;
00993 case SMESH_Block::ID_E1y0:
00994 aSSID=(bIsUpperLayer) ? SMESH_Block::ID_E1y1 : SMESH_Block::ID_F1yz;
00995 break;
00996 case SMESH_Block::ID_Fxy0:
00997 aSSID=SMESH_Block::ID_NONE;
00998 break;
00999 default:
01000 aSSID=SMESH_Block::ID_NONE;
01001 myErrorStatus->myName=10;
01002 myErrorStatus->myComment = "Internal error of StdMeshers_Penta_3D";
01003 break;
01004 }
01005 return;
01006 }
01007
01008
01009
01010
01011 void StdMeshers_Penta_3D::MakeBlock()
01012 {
01013 bool bFound;
01014 int i, j, iNbEV, iNbE, iErr, iCnt, iNbNodes, iNbF;
01015
01016 TopoDS_Vertex aV000, aV001;
01017 TopoDS_Shape aFTr;
01018 TopTools_IndexedDataMapOfShapeListOfShape aMVES;
01019 TopTools_IndexedMapOfShape aME ,aMEV, aM;
01020 TopTools_ListIteratorOfListOfShape aIt;
01021
01022 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
01023
01024
01025 SMDSAbs_ElementType aElementType;
01026 SMESH_Mesh* pMesh=GetMesh();
01027
01028 iCnt = 0;
01029 iNbF = aM.Extent();
01030 for (i=1; i<=iNbF; ++i) {
01031 const TopoDS_Shape& aF = aM(i);
01032 SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aF);
01033 ASSERT(aSubMesh);
01034 SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS();
01035 SMDS_ElemIteratorPtr itf = aSM->GetElements();
01036 while(itf->more()) {
01037 const SMDS_MeshElement * pElement = itf->next();
01038 aElementType = pElement->GetType();
01039 if (aElementType==SMDSAbs_Face) {
01040 iNbNodes = pElement->NbNodes();
01041 if ( iNbNodes==3 || (pElement->IsQuadratic() && iNbNodes==6) ) {
01042 aFTr = aF;
01043 ++iCnt;
01044 if (iCnt>1) {
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054 break;
01055
01056 }
01057 break;
01058 }
01059 }
01060 }
01061 }
01062
01063
01064
01065
01066
01067
01068 if (iCnt != 1) {
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107 int isOK = 0;
01108
01109 int iNbF = aM.Extent();
01110 if (iNbF == 6) {
01111
01112 int nb_f1 = pMesh->GetSubMeshContaining(aM(1))->GetSubMeshDS()->NbElements();
01113 int nb_f2 = pMesh->GetSubMeshContaining(aM(2))->GetSubMeshDS()->NbElements();
01114 int nb_f3 = pMesh->GetSubMeshContaining(aM(3))->GetSubMeshDS()->NbElements();
01115 int nb_f4 = pMesh->GetSubMeshContaining(aM(4))->GetSubMeshDS()->NbElements();
01116 int nb_f5 = pMesh->GetSubMeshContaining(aM(5))->GetSubMeshDS()->NbElements();
01117 int nb_f6 = pMesh->GetSubMeshContaining(aM(6))->GetSubMeshDS()->NbElements();
01118
01119 int has_only_quad_f1 = 1;
01120 int has_only_quad_f2 = 1;
01121 int has_only_quad_f3 = 1;
01122 int has_only_quad_f4 = 1;
01123 int has_only_quad_f5 = 1;
01124 int has_only_quad_f6 = 1;
01125
01126 for (i=1; i<=iNbF; ++i) {
01127 int ok = 1;
01128 const TopoDS_Shape& aF = aM(i);
01129 SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aF);
01130 SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS();
01131 SMDS_ElemIteratorPtr itf = aSM->GetElements();
01132 while(itf->more()) {
01133 const SMDS_MeshElement * pElement = itf->next();
01134 aElementType = pElement->GetType();
01135 if (aElementType==SMDSAbs_Face) {
01136 iNbNodes = pElement->NbNodes();
01137 if ( iNbNodes!=4 ) {
01138 ok = 0;
01139 break ;
01140 }
01141 }
01142 }
01143 if (i==1) has_only_quad_f1 = ok ;
01144 if (i==2) has_only_quad_f2 = ok ;
01145 if (i==3) has_only_quad_f3 = ok ;
01146 if (i==4) has_only_quad_f4 = ok ;
01147 if (i==5) has_only_quad_f5 = ok ;
01148 if (i==6) has_only_quad_f6 = ok ;
01149 }
01150
01151 TopTools_IndexedMapOfShape aE;
01152 TopExp::MapShapes(myShape, TopAbs_EDGE, aE);
01153 int iNbE = aE.Extent();
01154 if (iNbE == 12) {
01155
01156 int nb_e01 = pMesh->GetSubMeshContaining(aE(1))->GetSubMeshDS()->NbElements();
01157 int nb_e02 = pMesh->GetSubMeshContaining(aE(2))->GetSubMeshDS()->NbElements();
01158 int nb_e03 = pMesh->GetSubMeshContaining(aE(3))->GetSubMeshDS()->NbElements();
01159 int nb_e04 = pMesh->GetSubMeshContaining(aE(4))->GetSubMeshDS()->NbElements();
01160 int nb_e05 = pMesh->GetSubMeshContaining(aE(5))->GetSubMeshDS()->NbElements();
01161 int nb_e06 = pMesh->GetSubMeshContaining(aE(6))->GetSubMeshDS()->NbElements();
01162 int nb_e07 = pMesh->GetSubMeshContaining(aE(7))->GetSubMeshDS()->NbElements();
01163 int nb_e08 = pMesh->GetSubMeshContaining(aE(8))->GetSubMeshDS()->NbElements();
01164 int nb_e09 = pMesh->GetSubMeshContaining(aE(9))->GetSubMeshDS()->NbElements();
01165 int nb_e10 = pMesh->GetSubMeshContaining(aE(10))->GetSubMeshDS()->NbElements();
01166 int nb_e11 = pMesh->GetSubMeshContaining(aE(11))->GetSubMeshDS()->NbElements();
01167 int nb_e12 = pMesh->GetSubMeshContaining(aE(12))->GetSubMeshDS()->NbElements();
01168
01169 int nb_ok = 0 ;
01170
01171 if ( (nb_e01==nb_e03) && (nb_e03==nb_e05) && (nb_e05==nb_e07) ) {
01172 if ( has_only_quad_f1 && has_only_quad_f2 && has_only_quad_f3 && has_only_quad_f4 ) {
01173 if ( (nb_e09==nb_e10) && (nb_e08==nb_e06) && (nb_e11==nb_e12) && (nb_e04==nb_e02) ) {
01174 if (nb_f5==nb_f6) {
01175 nb_ok += 1;
01176 aFTr = aM(5);
01177 }
01178 }
01179 }
01180 }
01181 if ( (nb_e02==nb_e04) && (nb_e04==nb_e06) && (nb_e06==nb_e08) ) {
01182 if ( has_only_quad_f1 && has_only_quad_f2 && has_only_quad_f5 && has_only_quad_f6 ) {
01183 if ( (nb_e01==nb_e03) && (nb_e10==nb_e12) && (nb_e05==nb_e07) && (nb_e09==nb_e11) ) {
01184 if (nb_f3==nb_f4) {
01185 nb_ok += 1;
01186 aFTr = aM(3);
01187 }
01188 }
01189 }
01190 }
01191 if ( (nb_e09==nb_e10) && (nb_e10==nb_e11) && (nb_e11==nb_e12) ) {
01192 if ( has_only_quad_f3 && has_only_quad_f4 && has_only_quad_f5 && has_only_quad_f6 ) {
01193 if ( (nb_e01==nb_e05) && (nb_e02==nb_e06) && (nb_e03==nb_e07) && (nb_e04==nb_e08) ) {
01194 if (nb_f1==nb_f2) {
01195 nb_ok += 1;
01196 aFTr = aM(1);
01197 }
01198 }
01199 }
01200 }
01201
01202 if ( nb_ok == 1 ) {
01203 isOK = 1;
01204 }
01205
01206 }
01207 }
01208 if (!isOK) {
01209 myErrorStatus->myName=5;
01210 myErrorStatus->myComment="Incorrect input mesh";
01211 return;
01212 }
01213 }
01214
01215
01216
01217
01218 TopExp::MapShapes(aFTr, TopAbs_EDGE, aME);
01219 TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMVES);
01220
01221
01222 iNbE = aME.Extent();
01223 if (iNbE!= NB_WALL_FACES ){
01224 MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
01225 myErrorStatus->myName=7;
01226 myErrorStatus->myComment=SMESH_Comment("Not a quadrilateral face #")
01227 <<pMesh->GetMeshDS()->ShapeToIndex( aFTr )<<": "<<iNbE<<" edges" ;
01228 return;
01229 }
01230 const TopoDS_Edge& aE1=TopoDS::Edge(aME(1));
01231 aV000=TopExp::FirstVertex(aE1);
01232
01233 const TopTools_ListOfShape& aLE=aMVES.FindFromKey(aV000);
01234 aIt.Initialize(aLE);
01235 for (; aIt.More(); aIt.Next()) {
01236 const TopoDS_Shape& aEx=aIt.Value();
01237 aMEV.Add(aEx);
01238 }
01239 iNbEV=aMEV.Extent();
01240 if (iNbEV!=3){
01241 MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
01242 myErrorStatus->myName=7;
01243 myErrorStatus->myComment=SMESH_Comment("3 edges must share vertex #")
01244 <<pMesh->GetMeshDS()->ShapeToIndex( aV000 )<<" but there are "<<iNbEV<<" edges";
01245 return;
01246 }
01247
01248
01249 bFound=false;
01250 for (j=1; j<=iNbEV; ++j) {
01251 const TopoDS_Shape& aEx=aMEV(j);
01252 if (!aME.Contains(aEx)) {
01253 TopoDS_Vertex aV[2];
01254
01255 const TopoDS_Edge& aE=TopoDS::Edge(aEx);
01256 TopExp::Vertices(aE, aV[0], aV[1]);
01257 for (i=0; i<2; ++i) {
01258 if (!aV[i].IsSame(aV000)) {
01259 aV001=aV[i];
01260 bFound=!bFound;
01261 break;
01262 }
01263 }
01264 }
01265 }
01266
01267 if (!bFound) {
01268 MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
01269 myErrorStatus->myName=8;
01270 myErrorStatus->myComment=SMESH_Comment("Can't find opposite vertex for vertex #")
01271 <<pMesh->GetMeshDS()->ShapeToIndex( aV000 );
01272 return;
01273 }
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283 aME.Clear();
01284 TopExp::MapShapes(myShape, TopAbs_SHELL, aME);
01285 iNbE=aME.Extent();
01286 if (iNbE!=1) {
01287 MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
01288 myErrorStatus->myName=9;
01289 myErrorStatus->myComment=SMESH_Comment("Unexpected nb of shells ")<<iNbE;
01290 return;
01291 }
01292
01293
01294 const TopoDS_Shell& aShell=TopoDS::Shell(aME(1));
01295 myBlock.Load(aShell, aV000, aV001);
01296 iErr = myBlock.ErrorStatus();
01297 if (iErr) {
01298 MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
01299 myErrorStatus=myBlock.GetError();
01300 return;
01301 }
01302 }
01303
01304
01305
01306
01307 void StdMeshers_Penta_3D::CheckData()
01308 {
01309 int i, iNb;
01310 int iNbEx[]={8, 12, 6};
01311
01312 TopAbs_ShapeEnum aST;
01313 TopAbs_ShapeEnum aSTEx[]={
01314 TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE
01315 };
01316 TopTools_IndexedMapOfShape aM;
01317
01318 if (myShape.IsNull()){
01319 MESSAGE("StdMeshers_Penta_3D::CheckData() ");
01320 myErrorStatus->myName=2;
01321 myErrorStatus->myComment="Null shape";
01322 return;
01323 }
01324
01325 aST=myShape.ShapeType();
01326 if (!(aST==TopAbs_SOLID || aST==TopAbs_SHELL)) {
01327 MESSAGE("StdMeshers_Penta_3D::CheckData() ");
01328 myErrorStatus->myName=3;
01329 myErrorStatus->myComment=SMESH_Comment("Wrong shape type (TopAbs_ShapeEnum) ")<<aST;
01330 return;
01331 }
01332
01333 for (i=0; i<3; ++i) {
01334 aM.Clear();
01335 TopExp::MapShapes(myShape, aSTEx[i], aM);
01336 iNb=aM.Extent();
01337 if (iNb!=iNbEx[i]){
01338 MESSAGE("StdMeshers_Penta_3D::CheckData() ");
01339 myErrorStatus->myName=4;
01340 myErrorStatus->myComment="Wrong number of subshapes of a block";
01341 return;
01342 }
01343 }
01344 }
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356 bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
01357 const TopoDS_Face& theFace,
01358 const TopoDS_Edge& theBaseEdge,
01359 SMESHDS_Mesh* theMesh)
01360 {
01361
01362 TopoDS_Vertex vfb, vlb, vft;
01363 TopoDS_Edge eFrw = TopoDS::Edge( theBaseEdge.Oriented( TopAbs_FORWARD ));
01364 TopExp::Vertices( eFrw, vfb, vlb );
01365
01366
01367 TopoDS_Edge e1, e2, eTop;
01368 bool rev1, CumOri = false;
01369 TopExp_Explorer exp( theFace, TopAbs_EDGE );
01370 int nbEdges = 0;
01371 for ( ; exp.More(); exp.Next() ) {
01372 if ( ++nbEdges > NB_WALL_FACES ) {
01373 return false;
01374 }
01375 TopoDS_Edge e = TopoDS::Edge( exp.Current() );
01376 if ( theBaseEdge.IsSame( e ))
01377 continue;
01378 TopoDS_Vertex vCommon;
01379 if ( !TopExp::CommonVertex( theBaseEdge, e, vCommon ))
01380 eTop = e;
01381 else if ( vCommon.IsSame( vfb )) {
01382 e1 = e;
01383 vft = TopExp::LastVertex( e1, CumOri );
01384 rev1 = vfb.IsSame( vft );
01385 if ( rev1 )
01386 vft = TopExp::FirstVertex( e1, CumOri );
01387 }
01388 else
01389 e2 = e;
01390 }
01391 if ( nbEdges < NB_WALL_FACES ) {
01392 return false;
01393 }
01394
01395
01396 SMESHDS_SubMesh* smFace = theMesh->MeshElements( theFace );
01397 SMESHDS_SubMesh* smb = theMesh->MeshElements( theBaseEdge );
01398 SMESHDS_SubMesh* smt = theMesh->MeshElements( eTop );
01399 SMESHDS_SubMesh* sm1 = theMesh->MeshElements( e1 );
01400 SMESHDS_SubMesh* sm2 = theMesh->MeshElements( e2 );
01401 SMESHDS_SubMesh* smVfb = theMesh->MeshElements( vfb );
01402 SMESHDS_SubMesh* smVlb = theMesh->MeshElements( vlb );
01403 SMESHDS_SubMesh* smVft = theMesh->MeshElements( vft );
01404 if (!smFace || !smb || !smt || !sm1 || !sm2 || !smVfb || !smVlb || !smVft ) {
01405 MESSAGE( "NULL submesh " <<smFace<<" "<<smb<<" "<<smt<<" "<<
01406 sm1<<" "<<sm2<<" "<<smVfb<<" "<<smVlb<<" "<<smVft);
01407 return false;
01408 }
01409 if ( smb->NbNodes() != smt->NbNodes() || sm1->NbNodes() != sm2->NbNodes() ) {
01410 MESSAGE(" Diff nb of nodes on opposite edges" );
01411 return false;
01412 }
01413 if (smVfb->NbNodes() != 1 || smVlb->NbNodes() != 1 || smVft->NbNodes() != 1) {
01414 MESSAGE("Empty submesh of vertex");
01415 return false;
01416 }
01417 if ( sm1->NbNodes() * smb->NbNodes() != smFace->NbNodes() ) {
01418
01419 if ( myCreateQuadratic ) {
01420 int n1 = sm1->NbNodes()/2;
01421 int n2 = smb->NbNodes()/2;
01422 int n3 = sm1->NbNodes() - n1;
01423 int n4 = smb->NbNodes() - n2;
01424 int nf = sm1->NbNodes()*smb->NbNodes() - n3*n4;
01425 if( nf != smFace->NbNodes() ) {
01426 MESSAGE( "Wrong nb face nodes: " <<
01427 sm1->NbNodes()<<" "<<smb->NbNodes()<<" "<<smFace->NbNodes());
01428 return false;
01429 }
01430 }
01431 else {
01432 MESSAGE( "Wrong nb face nodes: " <<
01433 sm1->NbNodes()<<" "<<smb->NbNodes()<<" "<<smFace->NbNodes());
01434 return false;
01435 }
01436 }
01437
01438 int vsize = sm1->NbNodes() + 2;
01439 int hsize = smb->NbNodes() + 2;
01440 if(myCreateQuadratic) {
01441 vsize = vsize - sm1->NbNodes()/2 -1;
01442 hsize = hsize - smb->NbNodes()/2 -1;
01443 }
01444
01445
01446
01447 set<const SMDS_MeshNode*> loadedNodes;
01448 const SMDS_MeshNode* nullNode = 0;
01449
01450 vector<const SMDS_MeshNode*> & nVecf = theIJNodes[ 0.];
01451 nVecf.resize( vsize, nullNode );
01452 loadedNodes.insert( nVecf[ 0 ] = smVfb->GetNodes()->next() );
01453
01454 vector<const SMDS_MeshNode*> & nVecl = theIJNodes[ 1.];
01455 nVecl.resize( vsize, nullNode );
01456 loadedNodes.insert( nVecl[ 0 ] = smVlb->GetNodes()->next() );
01457
01458 double f, l;
01459 BRep_Tool::Range( eFrw, f, l );
01460 double range = l - f;
01461 SMDS_NodeIteratorPtr nIt = smb->GetNodes();
01462 const SMDS_MeshNode* node;
01463 while ( nIt->more() ) {
01464 node = nIt->next();
01465 if(myTool->IsMedium(node))
01466 continue;
01467 const SMDS_EdgePosition* pos =
01468 dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition() );
01469 if ( !pos ) {
01470 return false;
01471 }
01472 double u = ( pos->GetUParameter() - f ) / range;
01473 vector<const SMDS_MeshNode*> & nVec = theIJNodes[ u ];
01474 nVec.resize( vsize, nullNode );
01475 loadedNodes.insert( nVec[ 0 ] = node );
01476 }
01477 if ( theIJNodes.size() != hsize ) {
01478 MESSAGE( "Wrong node positions on theBaseEdge" );
01479 return false;
01480 }
01481
01482
01483
01484 map< double, const SMDS_MeshNode*> sortedNodes;
01485 nIt = sm1->GetNodes();
01486 while ( nIt->more() ) {
01487 node = nIt->next();
01488 if(myTool->IsMedium(node))
01489 continue;
01490 const SMDS_EdgePosition* pos =
01491 dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition() );
01492 if ( !pos ) {
01493 return false;
01494 }
01495 sortedNodes.insert( make_pair( pos->GetUParameter(), node ));
01496 }
01497 loadedNodes.insert( nVecf[ vsize - 1 ] = smVft->GetNodes()->next() );
01498 map< double, const SMDS_MeshNode*>::iterator u_n = sortedNodes.begin();
01499 int row = rev1 ? vsize - 1 : 0;
01500 for ( ; u_n != sortedNodes.end(); u_n++ ) {
01501 if ( rev1 ) row--;
01502 else row++;
01503 loadedNodes.insert( nVecf[ row ] = u_n->second );
01504 }
01505
01506
01507
01508
01509 TIDSortedElemSet allFaces, foundFaces;
01510 SMDS_ElemIteratorPtr eIt = smFace->GetElements();
01511 while ( eIt->more() ) {
01512 const SMDS_MeshElement* e = eIt->next();
01513 if ( e->GetType() == SMDSAbs_Face )
01514 allFaces.insert( e );
01515 }
01516
01517
01518
01519
01520
01521
01522
01523 StdMeshers_IJNodeMap::iterator par_nVec_1 = theIJNodes.begin();
01524 StdMeshers_IJNodeMap::iterator par_nVec_2 = par_nVec_1;
01525
01526 int col = 0;
01527 for ( par_nVec_2++; par_nVec_2 != theIJNodes.end(); par_nVec_1++, par_nVec_2++ ) {
01528 col++;
01529 row = 0;
01530 const SMDS_MeshNode* n1 = par_nVec_1->second[ row ];
01531 const SMDS_MeshNode* n2 = par_nVec_2->second[ row ];
01532 const SMDS_MeshElement* face = 0;
01533 do {
01534
01535 face = SMESH_MeshEditor::FindFaceInSet( n1, n2, allFaces, foundFaces );
01536 if ( face ) {
01537 int nbFaceNodes = face->NbNodes();
01538 if ( (!myCreateQuadratic && nbFaceNodes>4) ||
01539 (myCreateQuadratic && nbFaceNodes>8) ) {
01540 MESSAGE(" Too many nodes in a face: " << nbFaceNodes );
01541 return false;
01542 }
01543
01544 bool found = false;
01545 const SMDS_MeshNode* n3 = 0;
01546 eIt = face->nodesIterator() ;
01547 while ( !found && eIt->more() ) {
01548 node = static_cast<const SMDS_MeshNode*>( eIt->next() );
01549 if(myTool->IsMedium(node))
01550 continue;
01551 found = loadedNodes.insert( node ).second;
01552 if ( !found && node != n1 && node != n2 )
01553 n3 = node;
01554 }
01555 if ( found ) {
01556 if ( ++row > vsize - 1 ) {
01557 MESSAGE( "Too many nodes in column "<< col <<": "<< row+1);
01558 return false;
01559 }
01560 par_nVec_2->second[ row ] = node;
01561 foundFaces.insert( face );
01562 n2 = node;
01563 if ( nbFaceNodes==4 || (myCreateQuadratic && nbFaceNodes==8) ) {
01564 n1 = par_nVec_1->second[ row ];
01565 }
01566 }
01567 else if ( (nbFaceNodes==3 || (myCreateQuadratic && nbFaceNodes==6) ) &&
01568 n3 == par_nVec_1->second[ row ] ) {
01569 n1 = n3;
01570 }
01571 else {
01572 MESSAGE( "Not quad mesh, column "<< col );
01573 return false;
01574 }
01575 }
01576 }
01577 while ( face && n1 && n2 );
01578
01579 if ( row < vsize - 1 ) {
01580 MESSAGE( "Too few nodes in column "<< col <<": "<< row+1);
01581 MESSAGE( "Base node 1: "<< par_nVec_1->second[0]);
01582 MESSAGE( "Base node 2: "<< par_nVec_2->second[0]);
01583 MESSAGE( "Current node 1: "<< n1);
01584 MESSAGE( "Current node 2: "<< n2);
01585 MESSAGE( "first base node: "<< theIJNodes.begin()->second[0]);
01586 MESSAGE( "last base node: "<< theIJNodes.rbegin()->second[0]);
01587 return false;
01588 }
01589 }
01590
01591 return true;
01592 }
01593
01595
01596
01597
01599
01600
01601
01602
01603
01604 StdMeshers_SMESHBlock::StdMeshers_SMESHBlock()
01605 {
01606 myErrorStatus=1;
01607 myIsEdgeForward.resize( SMESH_Block::NbEdges(), -1 );
01608 }
01609
01610
01611
01612
01613
01614
01615 bool StdMeshers_SMESHBlock::IsForwadEdge(const int theEdgeID)
01616 {
01617 int index = myTBlock.ShapeIndex( theEdgeID );
01618 if ( !myTBlock.IsEdgeID( theEdgeID ))
01619 return false;
01620
01621 if ( myIsEdgeForward[ index ] < 0 )
01622 myIsEdgeForward[ index ] =
01623 myTBlock.IsForwardEdge( TopoDS::Edge( Shape( theEdgeID )), myShapeIDMap );
01624
01625 return myIsEdgeForward[ index ];
01626 }
01627
01628
01629
01630
01631
01632 int StdMeshers_SMESHBlock::ErrorStatus() const
01633 {
01634 return myErrorStatus;
01635 }
01636
01637
01641
01642
01643 SMESH_ComputeErrorPtr StdMeshers_SMESHBlock::GetError() const
01644 {
01645 SMESH_ComputeErrorPtr err = SMESH_ComputeError::New();
01646 string & text = err->myComment;
01647 switch ( myErrorStatus ) {
01648 case 2:
01649 case 3: text = "Internal error of StdMeshers_Penta_3D"; break;
01650 case 4: text = "Can't compute normalized parameters of a point inside a block"; break;
01651 case 5: text = "Can't compute coordinates by normalized parameters inside a block"; break;
01652 case 6: text = "Can't detect block subshapes. Not a block?"; break;
01653 }
01654 if (!text.empty())
01655 err->myName = myErrorStatus;
01656 return err;
01657 }
01658
01659
01660
01661
01662
01663 void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell)
01664 {
01665 TopoDS_Vertex aV000, aV001;
01666
01667 Load(theShell, aV000, aV001);
01668 }
01669
01670
01671
01672
01673
01674 void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell,
01675 const TopoDS_Vertex& theV000,
01676 const TopoDS_Vertex& theV001)
01677 {
01678 myErrorStatus=0;
01679
01680 myShell=theShell;
01681
01682 bool bOk;
01683
01684 myShapeIDMap.Clear();
01685 bOk = myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap);
01686 if (!bOk) {
01687 myErrorStatus=6;
01688 return;
01689 }
01690 }
01691
01692
01693
01694
01695
01696 void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt,
01697 gp_XYZ& theXYZ)
01698 {
01699 ComputeParameters(thePnt, myShell, theXYZ);
01700 }
01701
01702
01703
01704
01705
01706 void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt,
01707 const TopoDS_Shape& theShape,
01708 gp_XYZ& theXYZ)
01709 {
01710 myErrorStatus=0;
01711
01712 int aID;
01713 bool bOk;
01714
01715 aID = ShapeID(theShape);
01716 if (myErrorStatus) {
01717 return;
01718 }
01719 bOk = myTBlock.ComputeParameters(thePnt, theXYZ, aID);
01720 if (!bOk) {
01721 myErrorStatus=4;
01722 return;
01723 }
01724 }
01725
01726
01727
01728
01729
01730
01731 void StdMeshers_SMESHBlock::ComputeParameters(const double& theU,
01732 const TopoDS_Shape& theShape,
01733 gp_XYZ& theXYZ)
01734 {
01735 myErrorStatus=0;
01736
01737 int aID;
01738 bool bOk=false;
01739
01740 aID = ShapeID(theShape);
01741 if (myErrorStatus) {
01742 return;
01743 }
01744 if ( SMESH_Block::IsEdgeID( aID ))
01745 bOk = myTBlock.EdgeParameters( aID, theU, theXYZ );
01746 if (!bOk) {
01747 myErrorStatus=4;
01748 return;
01749 }
01750 }
01751
01752
01753
01754
01755
01756 void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams, gp_Pnt& aP3D)
01757 {
01758 TopoDS_Shape aS;
01759
01760 Point(theParams, aS, aP3D);
01761 }
01762
01763
01764
01765
01766
01767 void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams,
01768 const TopoDS_Shape& theShape,
01769 gp_Pnt& aP3D)
01770 {
01771 myErrorStatus = 0;
01772
01773 int aID;
01774 bool bOk = false;
01775 gp_XYZ aXYZ(99.,99.,99.);
01776 aP3D.SetXYZ(aXYZ);
01777
01778 if (theShape.IsNull()) {
01779 bOk = myTBlock.ShellPoint(theParams, aXYZ);
01780 }
01781
01782 else {
01783 aID=ShapeID(theShape);
01784 if (myErrorStatus) {
01785 return;
01786 }
01787
01788 if (SMESH_Block::IsVertexID(aID)) {
01789 bOk = myTBlock.VertexPoint(aID, aXYZ);
01790 }
01791 else if (SMESH_Block::IsEdgeID(aID)) {
01792 bOk = myTBlock.EdgePoint(aID, theParams, aXYZ);
01793 }
01794
01795 else if (SMESH_Block::IsFaceID(aID)) {
01796 bOk = myTBlock.FacePoint(aID, theParams, aXYZ);
01797 }
01798 }
01799 if (!bOk) {
01800 myErrorStatus=5;
01801 return;
01802 }
01803 aP3D.SetXYZ(aXYZ);
01804 }
01805
01806
01807
01808
01809
01810 int StdMeshers_SMESHBlock::ShapeID(const TopoDS_Shape& theShape)
01811 {
01812 myErrorStatus=0;
01813
01814 int aID=-1;
01815 TopoDS_Shape aSF, aSR;
01816
01817 aSF=theShape;
01818 aSF.Orientation(TopAbs_FORWARD);
01819 aSR=theShape;
01820 aSR.Orientation(TopAbs_REVERSED);
01821
01822 if (myShapeIDMap.Contains(aSF)) {
01823 aID=myShapeIDMap.FindIndex(aSF);
01824 return aID;
01825 }
01826 if (myShapeIDMap.Contains(aSR)) {
01827 aID=myShapeIDMap.FindIndex(aSR);
01828 return aID;
01829 }
01830 myErrorStatus=2;
01831 return aID;
01832 }
01833
01834
01835
01836
01837
01838 const TopoDS_Shape& StdMeshers_SMESHBlock::Shape(const int theID)
01839 {
01840 myErrorStatus=0;
01841
01842 int aNb;
01843
01844 aNb=myShapeIDMap.Extent();
01845 if (theID<1 || theID>aNb) {
01846 myErrorStatus=3;
01847 return myEmptyShape;
01848 }
01849
01850 const TopoDS_Shape& aS=myShapeIDMap.FindKey(theID);
01851 return aS;
01852 }
01853
01854
01855
01856
01857
01858
01859 bool StdMeshers_Penta_3D::Evaluate(SMESH_Mesh& aMesh,
01860 const TopoDS_Shape& aShape,
01861 MapShapeNbElems& aResMap)
01862 {
01863 MESSAGE("StdMeshers_Penta_3D::Evaluate()");
01864
01865
01866 vector < SMESH_subMesh * >meshFaces;
01867 TopTools_SequenceOfShape aFaces;
01868 int NumBase = 0, i = 0;
01869 for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
01870 i++;
01871 aFaces.Append(exp.Current());
01872 SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
01873 meshFaces.push_back(aSubMesh);
01874 MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i]);
01875 if( anIt == aResMap.end() ) {
01876 NumBase = 0;
01877 break;
01878 }
01879 std::vector<int> aVec = (*anIt).second;
01880 int nbtri = Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]);
01881 int nbqua = Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
01882 if( nbtri>0 && nbqua==0 ) {
01883 NumBase = i;
01884 }
01885 }
01886
01887 if(NumBase==0) {
01888 std::vector<int> aResVec(SMDSEntity_Last);
01889 for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
01890 SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
01891 aResMap.insert(std::make_pair(sm,aResVec));
01892 myErrorStatus->myName = COMPERR_ALGO_FAILED;
01893 myErrorStatus->myComment = "Submesh can not be evaluated";
01894 return false;
01895 }
01896
01897
01898 int nb1d = 0;
01899 TopTools_MapOfShape Edges1;
01900 for (TopExp_Explorer exp(aFaces.Value(NumBase), TopAbs_EDGE); exp.More(); exp.Next()) {
01901 Edges1.Add(exp.Current());
01902 SMESH_subMesh *sm = aMesh.GetSubMesh(exp.Current());
01903 if( sm ) {
01904 MapShapeNbElemsItr anIt = aResMap.find(sm);
01905 if( anIt == aResMap.end() ) continue;
01906 std::vector<int> aVec = (*anIt).second;
01907 nb1d += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
01908 }
01909 }
01910
01911 int OppNum = 0;
01912 for(i=1; i<=6; i++) {
01913 if(i==NumBase) continue;
01914 bool IsOpposite = true;
01915 for(TopExp_Explorer exp(aFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) {
01916 if( Edges1.Contains(exp.Current()) ) {
01917 IsOpposite = false;
01918 break;
01919 }
01920 }
01921 if(IsOpposite) {
01922 OppNum = i;
01923 break;
01924 }
01925 }
01926
01927 int nb2d = 0;
01928 for(i=1; i<=6; i++) {
01929 if( i==OppNum || i==NumBase ) continue;
01930 MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] );
01931 if( anIt == aResMap.end() ) continue;
01932 std::vector<int> aVec = (*anIt).second;
01933 nb2d += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
01934 }
01935
01936 MapShapeNbElemsItr anIt = aResMap.find( meshFaces[NumBase-1] );
01937 std::vector<int> aVec = (*anIt).second;
01938 int nb2d_face0 = Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
01939 int nb0d_face0 = aVec[SMDSEntity_Node];
01940
01941 anIt = aResMap.find( meshFaces[OppNum-1] );
01942 for(i=SMDSEntity_Node; i<SMDSEntity_Last; i++)
01943 (*anIt).second[i] = aVec[i];
01944
01945 SMESH_MesherHelper aTool (aMesh);
01946 bool _quadraticMesh = aTool.IsQuadraticSubMesh(aShape);
01947
01948 std::vector<int> aResVec(SMDSEntity_Last);
01949 for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
01950 if(_quadraticMesh) {
01951 aResVec[SMDSEntity_Quad_Penta] = nb2d_face0 * ( nb2d/nb1d );
01952 aResVec[SMDSEntity_Node] = nb0d_face0 * ( 2*nb2d/nb1d - 1 );
01953 }
01954 else {
01955 aResVec[SMDSEntity_Node] = nb0d_face0 * ( nb2d/nb1d - 1 );
01956 aResVec[SMDSEntity_Penta] = nb2d_face0 * ( nb2d/nb1d );
01957 }
01958 SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
01959 aResMap.insert(std::make_pair(sm,aResVec));
01960
01961 return true;
01962 }
01963