Salome HOME
0021370: EDF SMESH: Hexahedron + Composite Side Disretization generate a bad mesh
authoreap <eap@opencascade.com>
Thu, 6 Oct 2011 09:42:51 +0000 (09:42 +0000)
committereap <eap@opencascade.com>
Thu, 6 Oct 2011 09:42:51 +0000 (09:42 +0000)
    Redesign LoadNodeColumns() to work with a composite base side

src/SMESH/SMESH_MesherHelper.cxx
src/SMESH/SMESH_MesherHelper.hxx

index 6b00df0583518b3f85dcf6b4bc4ff318fb26d266..65ff6c65772e9dbab173f37cb457866e509ffbbd 100644 (file)
@@ -1576,6 +1576,26 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
                                          SMESHDS_Mesh*      theMesh,
                                          SMESH_ProxyMesh*   theProxyMesh)
 {
                                          SMESHDS_Mesh*      theMesh,
                                          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;
   if ( theProxyMesh )
   {
   const SMESHDS_SubMesh* faceSubMesh = 0;
   if ( theProxyMesh )
   {
@@ -1594,22 +1614,41 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
   if ( !faceSubMesh || faceSubMesh->NbElements() == 0 )
     return false;
 
   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<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 );
+    }
+  }
 
 
-  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<const SMDS_MeshNode*>& 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 )
   }
   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
 
   // 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<const SMDS_MeshNode*>& nCol1 = par_nVec_1->second;
     vector<const SMDS_MeshNode*>& nCol2 = par_nVec_2->second;
   {
     vector<const SMDS_MeshNode*>& nCol1 = par_nVec_1->second;
     vector<const SMDS_MeshNode*>& 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];
 
     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 );
     }
       }
       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;
 }
   }
   return theParam2ColumnMap.size() > 1 && theParam2ColumnMap.begin()->second.size() > 1;
 }
index b8a679ed86bbed692cc76aa0a3f09465b4f15aa4..b8dc4cec9daaa6c19c7b36b7a3a706af08455bda 100644 (file)
@@ -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
    * \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
     * \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
    */
    * 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<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,
                               const TopoDS_Face& theFace,
                               const TopoDS_Edge& theBaseEdge,
   static bool LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
                               const TopoDS_Face& theFace,
                               const TopoDS_Edge& theBaseEdge,