X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Prism_3D.cxx;h=627a3da2bf2101bbfcea5aab4fdb8c2bd556c095;hb=ff4dc09d85e5af2ffef91b85c91dec43e249d7cd;hp=0493e6c1b3c051bd9aceb5eb208a6448e2a6710d;hpb=6cf8eec1823ce62c9f061ef2fb05db6ee1cbc929;p=modules%2Fsmesh.git diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index 0493e6c1b..627a3da2b 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.cxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx @@ -1,23 +1,23 @@ -// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // SMESH SMESH : implementaion of SMESH idl descriptions @@ -385,7 +385,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh myHelper->IsQuadraticSubMesh( theShape ); - // Analyse mesh and geomerty to find block subshapes and submeshes + // Analyse mesh and geomerty to find block sub-shapes and submeshes if ( !myBlock.Init( myHelper, theShape )) return error( myBlock.GetError()); @@ -984,7 +984,7 @@ bool StdMeshers_Prism_3D::projectBottomToTop() //================================================================================ /*! - * \brief Set projection coordinates of a node to a face and it's subshapes + * \brief Set projection coordinates of a node to a face and it's sub-shapes * \param faceID - the face given by in-block ID * \param params - node normalized parameters * \retval bool - is a success @@ -1318,24 +1318,47 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, // Get ordered bottom edges list< TopoDS_Edge > orderedEdges; - list< int > nbVertexInWires; + list< int > nbEInW; SMESH_Block::GetOrderedEdges( TopoDS::Face( botSM->GetSubShape().Reversed() ), - V000, orderedEdges, nbVertexInWires ); -// if ( nbVertexInWires.size() != 1 ) + V000, orderedEdges, nbEInW ); +// if ( nbEInW.size() != 1 ) // RETURN_BAD_RESULT("Wrong prism geometry"); // Get Wall faces corresponding to the ordered bottom edges list< TopoDS_Face > wallFaces; - if ( !GetWallFaces( Mesh(), shape3D, botSM->GetSubShape(), orderedEdges, wallFaces)) + if ( !GetWallFaces( Mesh(), shape3D, botSM->GetSubShape(), orderedEdges, nbEInW, wallFaces)) return error(COMPERR_BAD_SHAPE, "Can't find side faces"); + // check that the found top and bottom faces are opposite + { + for (TopExp_Explorer edge(botSM->GetSubShape(), TopAbs_EDGE); edge.More(); edge.Next()) + if ( helper->IsSubShape( edge.Current(), topSM->GetSubShape() )) + return error(notQuadGeomSubMesh.empty() ? COMPERR_BAD_INPUT_MESH : COMPERR_BAD_SHAPE, + "Non-quadrilateral faces are not opposite"); + } + + // Protect from a distorted block (test 3D_mesh_HEXA3D/B7 on 32bit platform) + // check that all wall faces have an edge common with the top face + { + list< TopoDS_Face >::iterator faceIt = wallFaces.begin(); + for ( ; faceIt != wallFaces.end(); ++faceIt ) + { + bool hasCommon = false; + for (TopExp_Explorer edge(*faceIt, TopAbs_EDGE); !hasCommon && edge.More(); edge.Next()) + if ( helper->IsSubShape( edge.Current(), topSM->GetSubShape() )) + hasCommon = true; + if ( !hasCommon ) + return error(COMPERR_BAD_SHAPE); + } + } + // Find columns of wall nodes and calculate edges' lengths // -------------------------------------------------------- myParam2ColumnMaps.clear(); myParam2ColumnMaps.resize( orderedEdges.size() ); // total nb edges - int iE, nbEdges = nbVertexInWires.front(); // nb outer edges + int iE, nbEdges = nbEInW.front(); // nb outer edges vector< double > edgeLength( nbEdges ); map< double, int > len2edgeMap; @@ -1437,9 +1460,12 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, int nbSplit = i_nb->second; vector< double > params; splitParams( nbSplit, &myParam2ColumnMaps[ iE ], params ); - bool isForward = ( edgeIt->Orientation() == TopAbs_FORWARD ); + const bool isForward = + StdMeshers_PrismAsBlock::IsForwardEdge( myHelper->GetMeshDS(), + myParam2ColumnMaps[iE], + *edgeIt, SMESH_Block::ID_Fx0z ); for ( int i = 0; i < nbSplit; ++i ) { - double f = ( isForward ? params[ i ] : params[ nbSplit - i-1 ]); + double f = ( isForward ? params[ i ] : params[ nbSplit - i-1 ]); double l = ( isForward ? params[ i+1 ] : params[ nbSplit - i ]); TSideFace* comp = new TSideFace( myHelper, wallFaceIds[ iSide ], *faceIt, *edgeIt, @@ -1665,16 +1691,18 @@ bool StdMeshers_PrismAsBlock::GetLayersTransformation(vector & trsf) co list< TopoDS_Edge >::iterator edgeIt = orderedEdges.begin(); for ( int iE = 0; iE < nbEdgesInWires.front(); ++iE, ++edgeIt ) { - const TParam2ColumnMap& u2colMap = + if ( BRep_Tool::Degenerated( *edgeIt )) continue; + const TParam2ColumnMap* u2colMap = GetParam2ColumnMap( myHelper->GetMeshDS()->ShapeToIndex( *edgeIt ), isReverse ); + if ( !u2colMap ) return false; isReverse = ( edgeIt->Orientation() == TopAbs_REVERSED ); - double f = u2colMap.begin()->first, l = u2colMap.rbegin()->first; + double f = u2colMap->begin()->first, l = u2colMap->rbegin()->first; if ( isReverse ) swap ( f, l ); const int nbCol = 5; for ( int i = 0; i < nbCol; ++i ) { double u = f + i/double(nbCol) * ( l - f ); - const TNodeColumn* col = & getColumn( & u2colMap, u )->second; + const TNodeColumn* col = & getColumn( u2colMap, u )->second; if ( columns.empty() || col != columns.back() ) columns.push_back( col ); } @@ -1688,7 +1716,7 @@ bool StdMeshers_PrismAsBlock::GetLayersTransformation(vector & trsf) co Bnd_B3d bndBox; for ( int i = 0; i < columns.size(); ++i ) bndBox.Add( gpXYZ( columns[i]->front() )); - tol2 = bndBox.SquareExtent() * 4 * 1e-4; + tol2 = bndBox.SquareExtent() * 1e-5; } // Compute transformations @@ -1728,7 +1756,7 @@ bool StdMeshers_PrismAsBlock::GetLayersTransformation(vector & trsf) co * \param columnsMap - node columns map of side face * \param bottomEdge - the bootom edge * \param sideFaceID - side face in-block ID - * \retval bool - true if orientation coinside with in-block froward orientation + * \retval bool - true if orientation coinside with in-block forward orientation */ //================================================================================ @@ -1766,31 +1794,49 @@ bool StdMeshers_PrismAsBlock::IsForwardEdge(SMESHDS_Mesh* meshDS, */ //================================================================================ -bool StdMeshers_PrismAsBlock::GetWallFaces( SMESH_Mesh* mesh, - const TopoDS_Shape & mainShape, - const TopoDS_Shape & bottomFace, - const std::list< TopoDS_Edge >& bottomEdges, - std::list< TopoDS_Face >& wallFaces) +bool StdMeshers_PrismAsBlock::GetWallFaces( SMESH_Mesh* mesh, + const TopoDS_Shape & mainShape, + const TopoDS_Shape & bottomFace, + std::list< TopoDS_Edge >& bottomEdges, + std::list< int > & nbEInW, + std::list< TopoDS_Face >& wallFaces) { wallFaces.clear(); TopTools_IndexedMapOfShape faceMap; TopExp::MapShapes( mainShape, TopAbs_FACE, faceMap ); - list< TopoDS_Edge >::const_iterator edge = bottomEdges.begin(); - for ( ; edge != bottomEdges.end(); ++edge ) + list< TopoDS_Edge >::iterator edge = bottomEdges.begin(); + std::list< int >::iterator nbE = nbEInW.begin(); + int iE = 0; + while ( edge != bottomEdges.end() ) { - TopTools_ListIteratorOfListOfShape ancestIt = mesh->GetAncestors( *edge ); - for ( ; ancestIt.More(); ancestIt.Next() ) + ++iE; + if ( BRep_Tool::Degenerated( *edge )) + { + edge = bottomEdges.erase( edge ); + --iE; + --(*nbE); + } + else { - const TopoDS_Shape& ancestor = ancestIt.Value(); - if ( ancestor.ShapeType() == TopAbs_FACE && // face - !bottomFace.IsSame( ancestor ) && // not bottom - faceMap.FindIndex( ancestor )) // belongs to the prism + PShapeIteratorPtr fIt = myHelper->GetAncestors( *edge, *mesh, TopAbs_FACE ); + while ( fIt->more() ) { - wallFaces.push_back( TopoDS::Face( ancestor )); - break; + const TopoDS_Shape* face = fIt->next(); + if ( !bottomFace.IsSame( *face ) && // not bottom + faceMap.FindIndex( *face )) // belongs to the prism + { + wallFaces.push_back( TopoDS::Face( *face )); + break; + } } + ++edge; + } + if ( iE == *nbE ) + { + iE = 0; + ++nbE; } } return ( wallFaces.size() == bottomEdges.size() ); @@ -2159,25 +2205,18 @@ TopoDS_Edge StdMeshers_PrismAsBlock::TSideFace::GetEdge(const int iEdge) const TopoDS_Shape V2 = myHelper->GetSubShapeByNode( node, meshDS ); if ( V2.ShapeType() == TopAbs_VERTEX && !V2.IsSame( V1 )) { - TopTools_ListIteratorOfListOfShape ancestIt = - myHelper->GetMesh()->GetAncestors( V1 ); - for ( ; ancestIt.More(); ancestIt.Next() ) - { - const TopoDS_Shape & ancestor = ancestIt.Value(); - if ( ancestor.ShapeType() == TopAbs_EDGE ) - for ( TopExp_Explorer e( ancestor, TopAbs_VERTEX ); e.More(); e.Next() ) - if ( V2.IsSame( e.Current() )) - return TopoDS::Edge( ancestor ); - } + TopoDS_Shape ancestor = myHelper->GetCommonAncestor( V1, V2, *myHelper->GetMesh(), TopAbs_EDGE); + if ( !ancestor.IsNull() ) + return TopoDS::Edge( ancestor ); } return TopoDS_Edge(); } //================================================================================ /*! - * \brief Fill block subshapes + * \brief Fill block sub-shapes * \param shapeMap - map to fill in - * \retval int - nb inserted subshapes + * \retval int - nb inserted sub-shapes */ //================================================================================