From 9ff48e7e76c5a6e9be6dced7dee62858b0f8ea6b Mon Sep 17 00:00:00 2001 From: eap Date: Thu, 6 Oct 2011 09:42:51 +0000 Subject: [PATCH] 0021370: EDF SMESH: Hexahedron + Composite Side Disretization generate a bad mesh Redesign LoadNodeColumns() to work with a composite base side --- src/SMESH/SMESH_MesherHelper.cxx | 74 +++++++++++++++++++++++++------- src/SMESH/SMESH_MesherHelper.hxx | 12 +++++- 2 files changed, 69 insertions(+), 17 deletions(-) diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index 6b00df058..65ff6c657 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -1576,6 +1576,26 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap, SMESHDS_Mesh* theMesh, SMESH_ProxyMesh* theProxyMesh) { + return LoadNodeColumns(theParam2ColumnMap, + theFace, + std::list(1,theBaseEdge), + theMesh, + theProxyMesh); +} + +//======================================================================= +//function : LoadNodeColumns +//purpose : Load nodes bound to face into a map of node columns +//======================================================================= + +bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap, + const TopoDS_Face& theFace, + const std::list& theBaseSide, + SMESHDS_Mesh* theMesh, + SMESH_ProxyMesh* theProxyMesh) +{ + // get a right submesh of theFace + const SMESHDS_SubMesh* faceSubMesh = 0; if ( theProxyMesh ) { @@ -1594,22 +1614,41 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap, if ( !faceSubMesh || faceSubMesh->NbElements() == 0 ) return false; - // get nodes on theBaseEdge sorted by param on edge and initialize theParam2ColumnMap with them + // get data of edges for normalization of params - map< double, const SMDS_MeshNode*> sortedBaseNodes; - if ( !SMESH_Algo::GetSortedNodesOnEdge( theMesh, theBaseEdge,/*noMedium=*/true, sortedBaseNodes) - || sortedBaseNodes.size() < 2 ) - return false; + vector< double > length; + double fullLen = 0; + list::const_iterator edge; + { + for ( edge = theBaseSide.begin(); edge != theBaseSide.end(); ++edge ) + { + double len = std::max( 1e-10, SMESH_Algo::EdgeLength( *edge )); + fullLen += len; + length.push_back( len ); + } + } - int nbRows = faceSubMesh->NbElements() / ( sortedBaseNodes.size()-1 ) + 1; - map< double, const SMDS_MeshNode*>::iterator u_n = sortedBaseNodes.begin(); - double f = u_n->first, range = sortedBaseNodes.rbegin()->first - f; - for ( ; u_n != sortedBaseNodes.end(); u_n++ ) + // get nodes on theBaseEdge sorted by param on edge and initialize theParam2ColumnMap with them + edge = theBaseSide.begin(); + for ( int iE = 0; edge != theBaseSide.end(); ++edge, ++iE ) { - double par = ( u_n->first - f ) / range; - vector& nCol = theParam2ColumnMap[ par ]; - nCol.resize( nbRows ); - nCol[0] = u_n->second; + map< double, const SMDS_MeshNode*> sortedBaseNodes; + SMESH_Algo::GetSortedNodesOnEdge( theMesh, *edge,/*noMedium=*/true, sortedBaseNodes); + if ( sortedBaseNodes.empty() ) continue; + + double f, l; + BRep_Tool::Range( *edge, f, l ); + if ( edge->Orientation() == TopAbs_REVERSED ) std::swap( f, l ); + const double coeff = 1. / ( l - f ) / length[iE] / fullLen; + const double prevPar = theParam2ColumnMap.empty() ? 0 : theParam2ColumnMap.rbegin()->first; + map< double, const SMDS_MeshNode*>::iterator u_n = sortedBaseNodes.begin(); + for ( ; u_n != sortedBaseNodes.end(); u_n++ ) + { + double par = prevPar + coeff * ( u_n->first - f ); + TParam2ColumnMap::iterator u2nn = + theParam2ColumnMap.insert( theParam2ColumnMap.end(), make_pair( par, TNodeColumn())); + u2nn->second.push_back( u_n->second ); + } } TParam2ColumnMap::iterator par_nVec_2, par_nVec_1 = theParam2ColumnMap.begin(); if ( theProxyMesh ) @@ -1621,6 +1660,8 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap, } } + int nbRows = 1 + faceSubMesh->NbElements() / ( theParam2ColumnMap.size()-1 ); + // fill theParam2ColumnMap column by column by passing from nodes on // theBaseEdge up via mesh faces on theFace @@ -1631,6 +1672,8 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap, { vector& nCol1 = par_nVec_1->second; vector& nCol2 = par_nVec_2->second; + nCol1.resize( nbRows ); + nCol2.resize( nbRows ); int i1, i2, iRow = 0; const SMDS_MeshNode *n1 = nCol1[0], *n2 = nCol2[0]; @@ -1653,8 +1696,9 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap, } avoidSet.insert( face ); } - if ( iRow + 1 < nbRows ) // compact if necessary - nCol1.resize( iRow + 1 ), nCol2.resize( iRow + 1 ); + // set a real height + nCol1.resize( iRow + 1 ); + nCol2.resize( iRow + 1 ); } return theParam2ColumnMap.size() > 1 && theParam2ColumnMap.begin()->second.size() > 1; } diff --git a/src/SMESH/SMESH_MesherHelper.hxx b/src/SMESH/SMESH_MesherHelper.hxx index b8a679ed8..b8dc4cec9 100644 --- a/src/SMESH/SMESH_MesherHelper.hxx +++ b/src/SMESH/SMESH_MesherHelper.hxx @@ -85,15 +85,23 @@ public: * \brief Load nodes bound to face into a map of node columns * \param theParam2ColumnMap - map of node columns to fill * \param theFace - the face on which nodes are searched for - * \param theBaseEdge - the edge nodes of which are columns' bases + * \param theBaseSide - the edges holding nodes on which columns' bases * \param theMesh - the mesh containing nodes * \retval bool - false if something is wrong * * The key of the map is a normalized parameter of each - * base node on theBaseEdge. + * base node on theBaseSide. Edges in theBaseSide must be sequenced. * This method works in supposition that nodes on the face * forms a rectangular grid and elements can be quardrangles or triangles */ + static bool LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap, + const TopoDS_Face& theFace, + const std::list& theBaseSide, + SMESHDS_Mesh* theMesh, + SMESH_ProxyMesh* theProxyMesh=0); + /*! + * \brief Variant of LoadNodeColumns() above with theBaseSide given by one edge + */ static bool LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap, const TopoDS_Face& theFace, const TopoDS_Edge& theBaseEdge, -- 2.39.2