Salome HOME
23418: [OCC] Mesh: Minimization of memory usage of SMESH
[modules/smesh.git] / src / StdMeshers / StdMeshers_Prism_3D.cxx
index 939679f95828254332543c5c7c129903dda568c1..f5807f09a192f848a28904cad3c1cbd6514297fe 100644 (file)
@@ -111,6 +111,7 @@ namespace {
         algo->myProxyMesh.reset( new SMESH_ProxyMesh( *helper->GetMesh() ));
 
       algo->myQuadList.clear();
+      algo->myHelper = 0;
 
       if ( helper )
         algo->_quadraticMesh = helper->GetIsQuadratic();
@@ -1200,8 +1201,8 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism)
         sweeper.myBndColumns.push_back( & u2colIt->second );
     }
     // load node columns inside the bottom FACE
-    TNode2ColumnMap::iterator bot_column = myBotToColumnMap.begin();
     sweeper.myIntColumns.reserve( myBotToColumnMap.size() );
+    TNode2ColumnMap::iterator bot_column = myBotToColumnMap.begin();
     for ( ; bot_column != myBotToColumnMap.end(); ++bot_column )
       sweeper.myIntColumns.push_back( & bot_column->second );
 
@@ -1242,6 +1243,14 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism)
       // column nodes; middle part of the column are zero pointers
       TNodeColumn& column = bot_column->second;
 
+      // check if a column is already computed using non-block approach
+      size_t i;
+      for ( i = 0; i < column.size(); ++i )
+        if ( !column[ i ])
+          break;
+      if ( i == column.size() )
+        continue; // all nodes created
+
       gp_XYZ botParams, topParams;
       if ( !tBotNode.HasParams() )
       {
@@ -1789,9 +1798,8 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism)
       if ( myHelper->GetIsQuadratic() )
       {
         // fill myHelper with medium nodes built by quadAlgo
-        SMDS_ElemIteratorPtr fIt = fSM->GetSubMeshDS()->GetElements();
-        while ( fIt->more() )
-          myHelper->AddTLinks( dynamic_cast<const SMDS_MeshFace*>( fIt->next() ));
+        for ( SMDS_ElemIteratorPtr fIt = fSM->GetSubMeshDS()->GetElements(); fIt->more(); )
+          myHelper->AddTLinks( SMDS_Mesh::DownCast<SMDS_MeshFace>( fIt->next() ));
       }
     }
   }
@@ -2282,7 +2290,7 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top( const gp_Trsf & bottomToTopTrsf
     TNode2ColumnMap::iterator bN_col =
       myBotToColumnMap.insert( make_pair ( bN, TNodeColumn() )).first;
     TNodeColumn & column = bN_col->second;
-    column.resize( zSize );
+    column.resize( zSize, 0 );
     column.front() = botNode;
     column.back()  = topNode;
   }
@@ -2581,7 +2589,7 @@ double StdMeshers_Prism_3D::getSweepTolerance( const Prism_3D::TPrismTopo& thePr
 
 //=======================================================================
 //function : isSimpleQuad
-//purpose  : check if the bottom FACE is meshable with nice qudrangles,
+//purpose  : check if the bottom FACE is meshable with nice quadrangles,
 //           if so the block aproach can work rather fast.
 //           This is a temporary mean caused by problems in StdMeshers_Sweeper
 //=======================================================================
@@ -3054,7 +3062,7 @@ bool StdMeshers_Prism_3D::IsApplicable(const TopoDS_Shape & shape, bool toCheckA
 
           if ( side._topEdge.IsNull() )
           {
-            // find vertical EDGEs --- EGDEs shared with neighbor side FACEs
+            // find vertical EDGEs --- EDGEs shared with neighbor side FACEs
             for ( int is2nd = 0; is2nd < 2 && isOK; ++is2nd ) // 2 adjacent neighbors
             {
               int di = is2nd ? 1 : -1;
@@ -3415,7 +3423,7 @@ bool StdMeshers_Prism_3D::initPrism(Prism_3D::TPrismTopo& thePrism,
   if ( !botSM ) // find a proper bottom
   {
     bool savedSetErrorToSM = mySetErrorToSM;
-    mySetErrorToSM = false; // ingore errors in initPrism()
+    mySetErrorToSM = false; // ignore errors in initPrism()
 
     // search among meshed FACEs
     list< SMESH_subMesh* >::iterator sm = meshedSubMesh.begin();
@@ -4838,7 +4846,7 @@ TPCurveOnHorFaceAdaptor::TPCurveOnHorFaceAdaptor( const TSideFace*   sideFace,
         }
         if ( !C2d.IsNull() )
         {
-          double u = static_cast< const SMDS_EdgePosition* >( n->GetPosition() )->GetUParameter();
+          double u = SMDS_EdgePositionPtr( n->GetPosition() )->GetUParameter();
           if ( f <= u && u <= l )
           {
             uv = C2d->Value( u ).XY();
@@ -4950,7 +4958,7 @@ bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol,
   const size_t zSrc = 0, zTgt = zSize-1;
   if ( zSize < 3 ) return true;
 
-  vector< vector< gp_XYZ > > intPntsOfLayer( zSize ); // node coodinates to compute
+  vector< vector< gp_XYZ > > intPntsOfLayer( zSize ); // node coordinates to compute
   // set coordinates of src and tgt nodes
   for ( size_t z = 0; z < intPntsOfLayer.size(); ++z )
     intPntsOfLayer[ z ].resize( myIntColumns.size() );
@@ -4962,9 +4970,9 @@ bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol,
 
   // for each internal column find boundary nodes whose error to use for correction
   prepareTopBotDelaunay();
-  findDelaunayTriangles();
+  bool isErrorCorrectable = findDelaunayTriangles();
 
-  // compute coordinates of internal nodes by projecting (transfroming) src and tgt
+  // compute coordinates of internal nodes by projecting (transforming) src and tgt
   // nodes towards the central layer
 
   vector< NSProjUtils::TrsfFinder3D > trsfOfLayer( zSize );
@@ -5020,6 +5028,22 @@ bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol,
     fromSrcBndPnts.swap( toSrcBndPnts );
   }
 
+  // Evaluate an error of boundary points
+
+  if ( !isErrorCorrectable && !allowHighBndError )
+  {
+    for ( size_t iP = 0; iP < myBndColumns.size(); ++iP )
+    {
+      double sumError = 0;
+      for ( size_t z = 1; z < zS; ++z ) // loop on layers
+        sumError += ( bndError[ z-1     ][ iP ].Modulus() +
+                      bndError[ zSize-z ][ iP ].Modulus() );
+
+      if ( sumError > tol )
+        return false;
+    }
+  }
+
   // Compute two projections of internal points to the central layer
   // in order to evaluate an error of internal points
 
@@ -5079,7 +5103,6 @@ bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol,
     }
   }
 
-  //centerIntErrorIsSmall = true; // 3D_mesh_Extrusion_00/A3
   if ( !centerIntErrorIsSmall )
   {
     // Compensate the central error; continue adding projection
@@ -5288,7 +5311,7 @@ bool StdMeshers_Sweeper::ComputeNodesOnStraight()
       return false;
 
     // create nodes along a line
-    SMESH_NodeXYZ botP( botNode ), topP( topNode);
+    SMESH_NodeXYZ botP( botNode ), topP( topNode );
     for ( size_t iZ = 0; iZ < myZColumns[0].size(); ++iZ )
     {
       // use barycentric coordinates as weight of Z of boundary columns
@@ -5390,11 +5413,11 @@ void StdMeshers_Sweeper::prepareTopBotDelaunay()
 //================================================================================
 /*!
  * \brief For each internal node column, find Delaunay triangles including it
- *        and Barycentric Coordinates withing the triangles. Fill in myTopBotTriangles
+ *        and Barycentric Coordinates within the triangles. Fill in myTopBotTriangles
  */
 //================================================================================
 
-void StdMeshers_Sweeper::findDelaunayTriangles()
+bool StdMeshers_Sweeper::findDelaunayTriangles()
 {
   const SMDS_MeshNode     *botNode, *topNode;
   const BRepMesh_Triangle *topTria;
@@ -5424,14 +5447,17 @@ void StdMeshers_Sweeper::findDelaunayTriangles()
     myTopBotTriangles[ colID ] = tbTrias;
   }
 
-#ifdef _DEBUG_
   if ( myBotDelaunay->NbVisitedNodes() < nbInternalNodes )
-    throw SALOME_Exception(LOCALIZED("Not all internal nodes found by Delaunay"));
-#endif
+  {
+    myTopBotTriangles.clear();
+    return false;
+  }
 
   myBotDelaunay.reset();
   myTopDelaunay.reset();
   myNodeID2ColID.Clear();
+
+  return true;
 }
 
 //================================================================================