0021370: EDF SMESH: Hexahedron + Composite Side Disretization generate a bad mesh

Redesign LoadNodeColumns() to work with a composite base side
This commit is contained in:
eap 2011-10-06 09:42:51 +00:00
parent d36c35f9a2
commit 9ff48e7e76
2 changed files with 70 additions and 18 deletions

View File

@ -1576,6 +1576,26 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
SMESHDS_Mesh* theMesh, SMESHDS_Mesh* theMesh,
SMESH_ProxyMesh* theProxyMesh) SMESH_ProxyMesh* theProxyMesh)
{ {
return LoadNodeColumns(theParam2ColumnMap,
theFace,
std::list<TopoDS_Edge>(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<TopoDS_Edge>& theBaseSide,
SMESHDS_Mesh* theMesh,
SMESH_ProxyMesh* theProxyMesh)
{
// get a right submesh of theFace
const SMESHDS_SubMesh* faceSubMesh = 0; const SMESHDS_SubMesh* faceSubMesh = 0;
if ( theProxyMesh ) if ( theProxyMesh )
{ {
@ -1594,22 +1614,41 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
if ( !faceSubMesh || faceSubMesh->NbElements() == 0 ) if ( !faceSubMesh || faceSubMesh->NbElements() == 0 )
return false; return false;
// get data of edges for normalization of params
vector< double > length;
double fullLen = 0;
list<TopoDS_Edge>::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 );
}
}
// get nodes on theBaseEdge sorted by param on edge and initialize theParam2ColumnMap with them // 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 )
{
map< double, const SMDS_MeshNode*> sortedBaseNodes; map< double, const SMDS_MeshNode*> sortedBaseNodes;
if ( !SMESH_Algo::GetSortedNodesOnEdge( theMesh, theBaseEdge,/*noMedium=*/true, sortedBaseNodes) SMESH_Algo::GetSortedNodesOnEdge( theMesh, *edge,/*noMedium=*/true, sortedBaseNodes);
|| sortedBaseNodes.size() < 2 ) if ( sortedBaseNodes.empty() ) continue;
return false;
int nbRows = faceSubMesh->NbElements() / ( sortedBaseNodes.size()-1 ) + 1; 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(); 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++ ) for ( ; u_n != sortedBaseNodes.end(); u_n++ )
{ {
double par = ( u_n->first - f ) / range; double par = prevPar + coeff * ( u_n->first - f );
vector<const SMDS_MeshNode*>& nCol = theParam2ColumnMap[ par ]; TParam2ColumnMap::iterator u2nn =
nCol.resize( nbRows ); theParam2ColumnMap.insert( theParam2ColumnMap.end(), make_pair( par, TNodeColumn()));
nCol[0] = u_n->second; u2nn->second.push_back( u_n->second );
}
} }
TParam2ColumnMap::iterator par_nVec_2, par_nVec_1 = theParam2ColumnMap.begin(); TParam2ColumnMap::iterator par_nVec_2, par_nVec_1 = theParam2ColumnMap.begin();
if ( theProxyMesh ) 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 // fill theParam2ColumnMap column by column by passing from nodes on
// theBaseEdge up via mesh faces on theFace // theBaseEdge up via mesh faces on theFace
@ -1631,6 +1672,8 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
{ {
vector<const SMDS_MeshNode*>& nCol1 = par_nVec_1->second; vector<const SMDS_MeshNode*>& nCol1 = par_nVec_1->second;
vector<const SMDS_MeshNode*>& nCol2 = par_nVec_2->second; vector<const SMDS_MeshNode*>& nCol2 = par_nVec_2->second;
nCol1.resize( nbRows );
nCol2.resize( nbRows );
int i1, i2, iRow = 0; int i1, i2, iRow = 0;
const SMDS_MeshNode *n1 = nCol1[0], *n2 = nCol2[0]; const SMDS_MeshNode *n1 = nCol1[0], *n2 = nCol2[0];
@ -1653,8 +1696,9 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
} }
avoidSet.insert( face ); avoidSet.insert( face );
} }
if ( iRow + 1 < nbRows ) // compact if necessary // set a real height
nCol1.resize( iRow + 1 ), nCol2.resize( iRow + 1 ); nCol1.resize( iRow + 1 );
nCol2.resize( iRow + 1 );
} }
return theParam2ColumnMap.size() > 1 && theParam2ColumnMap.begin()->second.size() > 1; return theParam2ColumnMap.size() > 1 && theParam2ColumnMap.begin()->second.size() > 1;
} }

View File

@ -85,15 +85,23 @@ public:
* \brief Load nodes bound to face into a map of node columns * \brief Load nodes bound to face into a map of node columns
* \param theParam2ColumnMap - map of node columns to fill * \param theParam2ColumnMap - map of node columns to fill
* \param theFace - the face on which nodes are searched for * \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 * \param theMesh - the mesh containing nodes
* \retval bool - false if something is wrong * \retval bool - false if something is wrong
* *
* The key of the map is a normalized parameter of each * 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 * This method works in supposition that nodes on the face
* forms a rectangular grid and elements can be quardrangles or triangles * forms a rectangular grid and elements can be quardrangles or triangles
*/ */
static bool LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
const TopoDS_Face& theFace,
const std::list<TopoDS_Edge>& theBaseSide,
SMESHDS_Mesh* theMesh,
SMESH_ProxyMesh* theProxyMesh=0);
/*!
* \brief Variant of LoadNodeColumns() above with theBaseSide given by one edge
*/
static bool LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap, static bool LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
const TopoDS_Face& theFace, const TopoDS_Face& theFace,
const TopoDS_Edge& theBaseEdge, const TopoDS_Edge& theBaseEdge,