X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Prism_3D.cxx;h=8b7347d7b9702cc27cd8b02b523e7da47039e776;hp=04cc3aebe9e85e0b65293a7ad8669548b5853a7b;hb=3da8fefe9c957f4538e9eacf013ce678df4d6c91;hpb=0c5188fd2cf587b6c74c6adce920158f7edd4419 diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index 04cc3aebe..8b7347d7b 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.cxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -62,6 +62,7 @@ #include #include +#include using namespace std; @@ -71,8 +72,7 @@ using namespace std; #ifdef _DEBUG_ #define DBGOUT(msg) //cout << msg << endl; #define SHOWYXZ(msg, xyz) \ - // { gp_Pnt p (xyz); \ - // cout << msg << " ("<< p.X() << "; " <= columns.size() ) + if ( xColumn < 0 || xColumn >= (int) columns.size() ) { // select a column for X dir double maxDist = 0; - for ( int i = 0; i < columns.size(); ++i ) + for ( size_t i = 0; i < columns.size(); ++i ) { double dist = ( O - gpXYZ((*columns[ i ])[ z ])).SquareModulus(); if ( dist > maxDist ) @@ -408,8 +408,8 @@ namespace { if ( nbQuads > 0 ) toRemove = helper->IsStructured( faceSm ); else - toRemove = quadAlgo->CheckNbEdges( *helper->GetMesh(), - faceSm->GetSubShape() ); + toRemove = ( quadAlgo->CheckNbEdges( *helper->GetMesh(), + faceSm->GetSubShape() ) != NULL ); nbRemoved += toRemove; if ( toRemove ) smIt = notQuadSubMesh.erase( smIt ); @@ -455,9 +455,9 @@ namespace { std::advance( edgeIt, nbEdges-1 ); TopoDS_Edge prevE = *edgeIt; // bool isPrevStraight = SMESH_Algo::IsStraight( prevE ); - int iPrev = nbEdges - 1; + // int iPrev = nbEdges - 1; - int iUnite = -1; // the first of united EDGEs + // int iUnite = -1; // the first of united EDGEs // analyse angles between EDGEs int nbCorners = 0; @@ -525,7 +525,7 @@ namespace { void pointsToPython(const std::vector& p) { #ifdef _DEBUG_ - for ( int i = SMESH_Block::ID_V000; i < p.size(); ++i ) + for ( size_t i = SMESH_Block::ID_V000; i < p.size(); ++i ) { cout << "mesh.AddNode( " << p[i].X() << ", "<< p[i].Y() << ", "<< p[i].Z() << ") # " << i <<" " ; SMESH_Block::DumpShapeID( i, cout ) << endl; @@ -905,7 +905,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh return error( err ); } } - return true; + return error( COMPERR_OK ); } //================================================================================ @@ -934,6 +934,7 @@ bool StdMeshers_Prism_3D::getWallFaces( Prism_3D::TPrismTopo & thePrism, list< TopoDS_Edge >::iterator edge = thePrism.myBottomEdges.begin(); std::list< int >::iterator nbE = thePrism.myNbEdgesInWires.begin(); + std::list< int > nbQuadsPerWire; int iE = 0; double f,l; while ( edge != thePrism.myBottomEdges.end() ) @@ -977,6 +978,8 @@ bool StdMeshers_Prism_3D::getWallFaces( Prism_3D::TPrismTopo & thePrism, { iE = 0; ++nbE; + int nbQuadPrev = std::accumulate( nbQuadsPerWire.begin(), nbQuadsPerWire.end(), 0 ); + nbQuadsPerWire.push_back( thePrism.myWallQuads.size() - nbQuadPrev ); } } @@ -988,12 +991,14 @@ bool StdMeshers_Prism_3D::getWallFaces( Prism_3D::TPrismTopo & thePrism, // that is not so evident in case of several WIREs in the bottom FACE thePrism.myRightQuadIndex.clear(); for ( size_t i = 0; i < thePrism.myWallQuads.size(); ++i ) - thePrism.myRightQuadIndex.push_back( i+1 ); - list< int >::iterator nbEinW = thePrism.myNbEdgesInWires.begin(); - for ( int iLeft = 0; nbEinW != thePrism.myNbEdgesInWires.end(); ++nbEinW ) { - thePrism.myRightQuadIndex[ iLeft + *nbEinW - 1 ] = iLeft; // 1st EDGE index of a current WIRE - iLeft += *nbEinW; + thePrism.myRightQuadIndex.push_back( i+1 ); // OK for all but the last EDGE of a WIRE + } + list< int >::iterator nbQinW = nbQuadsPerWire.begin(); + for ( int iLeft = 0; nbQinW != nbQuadsPerWire.end(); ++nbQinW ) + { + thePrism.myRightQuadIndex[ iLeft + *nbQinW - 1 ] = iLeft; // for the last EDGE of a WIRE + iLeft += *nbQinW; } while ( totalNbFaces - faceMap.Extent() > 2 ) @@ -1073,7 +1078,7 @@ bool StdMeshers_Prism_3D::getWallFaces( Prism_3D::TPrismTopo & thePrism, { // now only top and bottom FACEs are not in the faceMap faceMap.Add( thePrism.myBottom ); - for ( TopExp_Explorer f( thePrism.myShape3D, TopAbs_FACE );f.More(); f.Next() ) + for ( TopExp_Explorer f( thePrism.myShape3D, TopAbs_FACE ); f.More(); f.Next() ) if ( !faceMap.Contains( f.Current() )) { thePrism.myTop = TopoDS::Face( f.Current() ); break; @@ -1287,6 +1292,7 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism) if ( !smDS ) return toSM( error(COMPERR_BAD_INPUT_MESH, "Null submesh")); // loop on bottom mesh faces + vector< const TNodeColumn* > columns; SMDS_ElemIteratorPtr faceIt = smDS->GetElements(); while ( faceIt->more() ) { @@ -1296,7 +1302,7 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism) // find node columns for each node int nbNodes = face->NbCornerNodes(); - vector< const TNodeColumn* > columns( nbNodes ); + columns.resize( nbNodes ); for ( int i = 0; i < nbNodes; ++i ) { const SMDS_MeshNode* n = face->GetNode( i ); @@ -1313,7 +1319,8 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism) } } // create prisms - AddPrisms( columns, myHelper ); + if ( !AddPrisms( columns, myHelper )) + return toSM( error("Different 'vertical' discretization")); } // loop on bottom mesh faces @@ -1811,17 +1818,20 @@ bool StdMeshers_Prism_3D::Evaluate(SMESH_Mesh& theMesh, */ //================================================================================ -void StdMeshers_Prism_3D::AddPrisms( vector & columns, +bool StdMeshers_Prism_3D::AddPrisms( vector & columns, SMESH_MesherHelper* helper) { - int nbNodes = columns.size(); - int nbZ = columns[0]->size(); - if ( nbZ < 2 ) return; + size_t nbNodes = columns.size(); + size_t nbZ = columns[0]->size(); + if ( nbZ < 2 ) return false; + for ( size_t i = 1; i < nbNodes; ++i ) + if ( columns[i]->size() != nbZ ) + return false; // find out orientation bool isForward = true; SMDS_VolumeTool vTool; - int z = 1; + size_t z = 1; switch ( nbNodes ) { case 3: { SMDS_VolumeOfNodes tmpPenta ( (*columns[0])[z-1], // bottom @@ -1907,7 +1917,7 @@ void StdMeshers_Prism_3D::AddPrisms( vector & columns, vector nodes( 2*nbNodes + 4*nbNodes); for ( z = 1; z < nbZ; ++z ) { - for ( int i = 0; i < nbNodes; ++i ) { + for ( size_t i = 0; i < nbNodes; ++i ) { nodes[ i ] = (*columns[ i ])[z+iBase1]; // bottom or top nodes[ 2*nbNodes-i-1 ] = (*columns[ i ])[z+iBase2]; // top or bottom // side @@ -1921,6 +1931,8 @@ void StdMeshers_Prism_3D::AddPrisms( vector & columns, } } // switch ( nbNodes ) + + return true; } //================================================================================ @@ -1976,7 +1988,7 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top( const gp_Trsf & bottomToTopTrsf n2nMapPtr = & TProjction2dAlgo::instance( this )->GetNodesMap(); } - if ( !n2nMapPtr || n2nMapPtr->size() < botSMDS->NbNodes() ) + if ( !n2nMapPtr || (int) n2nMapPtr->size() < botSMDS->NbNodes() ) { // associate top and bottom faces NSProjUtils::TShapeShapeMap shape2ShapeMap; @@ -2500,17 +2512,20 @@ namespace // utils used by StdMeshers_Prism_3D::IsApplicable() } EdgeWithNeighbors() {} }; - struct PrismSide + // PrismSide contains all FACEs linking a bottom EDGE with a top one. + struct PrismSide { - TopoDS_Face _face; - TopTools_IndexedMapOfShape *_faces; // pointer because its copy constructor is private - TopoDS_Edge _topEdge; - vector< EdgeWithNeighbors >*_edges; - int _iBotEdge; - vector< bool > _isCheckedEdge; + TopoDS_Face _face; // a currently treated upper FACE + TopTools_IndexedMapOfShape *_faces; // all FACEs (pointer because of a private copy constructor) + TopoDS_Edge _topEdge; // a current top EDGE + vector< EdgeWithNeighbors >*_edges; // all EDGEs of _face + int _iBotEdge; // index of _topEdge within _edges + vector< bool > _isCheckedEdge; // mark EDGEs whose two owner FACEs found int _nbCheckedEdges; // nb of EDGEs whose location is defined - PrismSide *_leftSide; + PrismSide *_leftSide; // neighbor sides PrismSide *_rightSide; + void SetExcluded() { _leftSide = _rightSide = NULL; } + bool IsExcluded() const { return !_leftSide; } const TopoDS_Edge& Edge( int i ) const { return (*_edges)[ i ]._edge; @@ -2549,7 +2564,7 @@ namespace // utils used by StdMeshers_Prism_3D::IsApplicable() for ( iE = 0; iE < *nbE; ++e, ++iE ) if ( SMESH_Algo::isDegenerated( *e )) { - ee.erase( e ); + e = --ee.erase( e ); --(*nbE); --iE; } @@ -2572,16 +2587,34 @@ namespace // utils used by StdMeshers_Prism_3D::IsApplicable() /*! * \brief Return another faces sharing an edge */ - const TopoDS_Shape & getAnotherFace( const TopoDS_Face& face, - const TopoDS_Edge& edge, - TopTools_IndexedDataMapOfShapeListOfShape& facesOfEdge) + const TopoDS_Face & getAnotherFace( const TopoDS_Face& face, + const TopoDS_Edge& edge, + TopTools_IndexedDataMapOfShapeListOfShape& facesOfEdge) { TopTools_ListIteratorOfListOfShape faceIt( facesOfEdge.FindFromKey( edge )); for ( ; faceIt.More(); faceIt.Next() ) if ( !face.IsSame( faceIt.Value() )) - return faceIt.Value(); + return TopoDS::Face( faceIt.Value() ); return face; } + + //-------------------------------------------------------------------------------- + /*! + * \brief Return number of faces sharing given edges + */ + int nbAdjacentFaces( const std::vector< EdgeWithNeighbors >& edges, + const TopTools_IndexedDataMapOfShapeListOfShape& facesOfEdge ) + { + TopTools_MapOfShape adjFaces; + + for ( size_t i = 0; i < edges.size(); ++i ) + { + TopTools_ListIteratorOfListOfShape faceIt( facesOfEdge.FindFromKey( edges[i]._edge )); + for ( ; faceIt.More(); faceIt.Next() ) + adjFaces.Add( faceIt.Value() ); + } + return adjFaces.Extent(); + } } //================================================================================ @@ -2647,11 +2680,13 @@ bool StdMeshers_Prism_3D::IsApplicable(const TopoDS_Shape & shape, bool toCheckA typedef vector< EdgeWithNeighbors > TEdgeWithNeighborsVec; vector< TEdgeWithNeighborsVec > faceEdgesVec( allFaces.Extent() + 1 ); - TopTools_IndexedMapOfShape* facesOfSide = new TopTools_IndexedMapOfShape[ faceEdgesVec.size() ]; + const size_t nbEdgesMax = facesOfEdge.Extent() * 2; // there can be seam EDGEs + TopTools_IndexedMapOfShape* facesOfSide = new TopTools_IndexedMapOfShape[ nbEdgesMax ]; SMESHUtils::ArrayDeleter delFacesOfSide( facesOfSide ); // try to use each face as a bottom one bool prismDetected = false; + vector< PrismSide > sides; for ( int iF = 1; iF < allFaces.Extent() && !prismDetected; ++iF ) { const TopoDS_Face& botF = TopoDS::Face( allFaces( iF )); @@ -2664,11 +2699,12 @@ bool StdMeshers_Prism_3D::IsApplicable(const TopoDS_Shape & shape, bool toCheckA continue; // all faces are adjacent to botF - no top FACE // init data of side FACEs - vector< PrismSide > sides( botEdges.size() ); - for ( int iS = 0; iS < botEdges.size(); ++iS ) + sides.clear(); + sides.resize( botEdges.size() ); + for ( size_t iS = 0; iS < botEdges.size(); ++iS ) { - sides[ iS ]._topEdge = botEdges[ iS ]._edge; - sides[ iS ]._face = botF; + sides[ iS ]._topEdge = botEdges[ iS ]._edge; + sides[ iS ]._face = botF; sides[ iS ]._leftSide = & sides[ botEdges[ iS ]._iR ]; sides[ iS ]._rightSide = & sides[ botEdges[ iS ]._iL ]; sides[ iS ]._faces = & facesOfSide[ iS ]; @@ -2700,8 +2736,8 @@ bool StdMeshers_Prism_3D::IsApplicable(const TopoDS_Shape & shape, bool toCheckA if ( side._isCheckedEdge[ iE ] ) continue; const TopoDS_Edge& vertE = side.Edge( iE ); const TopoDS_Shape& neighborF = getAnotherFace( side._face, vertE, facesOfEdge ); - bool isEdgeShared = adjSide->IsSideFace( neighborF ); - if ( isEdgeShared ) + bool isEdgeShared = adjSide->IsSideFace( neighborF ); + if ( isEdgeShared ) // vertE is shared with adjSide { isAdvanced = true; side._isCheckedEdge[ iE ] = true; @@ -2780,6 +2816,10 @@ bool StdMeshers_Prism_3D::IsApplicable(const TopoDS_Shape & shape, bool toCheckA side._isCheckedEdge[ side._iBotEdge ] = true; side._nbCheckedEdges = 1; // bottom EDGE is known } + else // probably a triangular top face found + { + side._face.Nullify(); + } side._topEdge.Nullify(); isOK = ( !side._edges->empty() || side._faces->Extent() > 1 ); @@ -2812,7 +2852,7 @@ bool StdMeshers_Prism_3D::IsApplicable(const TopoDS_Shape & shape, bool toCheckA const TopoDS_Shape& topFace = sides[0]._faces->FindKey( nbFaces ); size_t iS; for ( iS = 1; iS < sides.size(); ++iS ) - if ( !sides[ iS ]._faces->Contains( topFace )) + if ( ! sides[ iS ]._faces->Contains( topFace )) break; prismDetected = ( iS == sides.size() ); } @@ -3286,7 +3326,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, if ( nbUnitePerEdge[ iE ] < 0 ) continue; // look for already united faces - for ( int i = iE; i < iE + nbExraFaces; ++i ) + for ( size_t i = iE; i < iE + nbExraFaces; ++i ) { if ( nbUnitePerEdge[ i ] > 0 ) // a side including nbUnitePerEdge[i]+1 edge nbExraFaces += nbUnitePerEdge[ i ]; @@ -3325,7 +3365,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, else if ( nbExraFaces > 1 ) // unite { double u0 = 0, sumLen = 0; - for ( int i = iE; i < iE + nbExraFaces; ++i ) + for ( size_t i = iE; i < iE + nbExraFaces; ++i ) sumLen += edgeLength[ i ]; vector< TSideFace* > components( nbExraFaces ); @@ -3476,10 +3516,8 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, } } -// #define SHOWYXZ(msg, xyz) { \ -// gp_Pnt p (xyz); \ -// cout << msg << " ("<< p.X() << "; " < & double tol2; { Bnd_B3d bndBox; - for ( int i = 0; i < columns.size(); ++i ) + for ( size_t i = 0; i < columns.size(); ++i ) bndBox.Add( gpXYZ( columns[i]->front() )); tol2 = bndBox.SquareExtent() * 1e-5; } @@ -3594,7 +3632,7 @@ bool StdMeshers_PrismAsBlock::GetLayersTransformation(vector & //t.SetScaleFactor( distZ/dist0 ); - it does not work properly, wrong base point // check a transformation - for ( int i = 0; i < columns.size(); ++i ) + for ( size_t i = 0; i < columns.size(); ++i ) { gp_Pnt p0 = gpXYZ( (*columns[i])[0] ); gp_Pnt pz = gpXYZ( (*columns[i])[z] ); @@ -3798,7 +3836,7 @@ StdMeshers_PrismAsBlock::TSideFace::TSideFace( const TSideFace& other ): myComponents ( other.myComponents.size() ), myHelper ( *other.myHelper.GetMesh() ) { - for (int i = 0 ; i < myComponents.size(); ++i ) + for ( size_t i = 0 ; i < myComponents.size(); ++i ) myComponents[ i ] = new TSideFace( *other.myComponents[ i ]); } @@ -3810,7 +3848,7 @@ StdMeshers_PrismAsBlock::TSideFace::TSideFace( const TSideFace& other ): StdMeshers_PrismAsBlock::TSideFace::~TSideFace() { - for (int i = 0 ; i < myComponents.size(); ++i ) + for ( size_t i = 0 ; i < myComponents.size(); ++i ) if ( myComponents[ i ] ) delete myComponents[ i ]; } @@ -3910,7 +3948,7 @@ StdMeshers_PrismAsBlock::TSideFace::GetComponent(const double U,double & localU) if ( myComponents.empty() ) return const_cast( this ); - int i; + size_t i; for ( i = 0; i < myComponents.size(); ++i ) if ( U < myParams[ i ].second ) break; @@ -4349,9 +4387,9 @@ gp_Pnt StdMeshers_PrismAsBlock::TVerticalEdgeAdaptor::Value(const Standard_Real void StdMeshers_PrismAsBlock::TVerticalEdgeAdaptor::dumpNodes(int nbNodes) const { #ifdef _DEBUG_ - for ( int i = 0; i < nbNodes && i < myNodeColumn->size(); ++i ) + for ( int i = 0; i < nbNodes && i < (int)myNodeColumn->size(); ++i ) cout << (*myNodeColumn)[i]->GetID() << " "; - if ( nbNodes < myNodeColumn->size() ) + if ( nbNodes < (int) myNodeColumn->size() ) cout << myNodeColumn->back()->GetID(); #endif }