Salome HOME
0021803: EDF 2351 : Available versions of MED in TUI function ExportMED aren't consis...
[modules/smesh.git] / src / SMESH / SMESH_Mesh.cxx
index ba8715cb48d61964eaae41b8fb7ef7cf1ceef974..8344f7de45b1a739eb932136b91fef03e97ae85e 100644 (file)
@@ -438,6 +438,7 @@ void SMESH_Mesh::Clear()
       sm->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
     }
   }
+  GetMeshDS()->Modified();
   _isModified = false;
 }
 
@@ -713,6 +714,7 @@ SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
     }
   }
   HasModificationsToDiscard(); // to reset _isModified flag if a mesh becomes empty
+  GetMeshDS()->Modified();
 
   if(MYDEBUG) subMesh->DumpAlgoState(true);
   if(MYDEBUG) SCRUTE(ret);
@@ -783,6 +785,7 @@ SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
   }
 
   HasModificationsToDiscard(); // to reset _isModified flag if mesh become empty
+  GetMeshDS()->Modified();
 
   if(MYDEBUG) subMesh->DumpAlgoState(true);
   if(MYDEBUG) SCRUTE(ret);
@@ -1208,49 +1211,67 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h
   SMESH_Algo *algo;
   const SMESH_HypoFilter* compatibleHypoKind;
   list <const SMESHDS_Hypothesis * > usedHyps;
-
-  // keep sub-meshes not to miss ones whose state can change due to notifying others
   vector< SMESH_subMesh* > smToNotify;
+  bool allMeshedEdgesNotified = true;
 
   SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() );
   while ( smIt->more() )
   {
     SMESH_subMesh* aSubMesh = smIt->next();
+    bool toNotify = false;
 
     // if aSubMesh meshing depends on hyp,
     // we call aSubMesh->AlgoStateEngine( MODIF_HYP, hyp ) that causes either
     // 1) clearing already computed aSubMesh or
     // 2) changing algo_state from MISSING_HYP to HYP_OK when parameters of hyp becomes valid,
     // other possible changes are not interesting. (IPAL0052457 - assigning hyp performance pb)
-    if ( aSubMesh->GetComputeState() != SMESH_subMesh::COMPUTE_OK &&
-         aSubMesh->GetComputeState() != SMESH_subMesh::FAILED_TO_COMPUTE &&
-         aSubMesh->GetAlgoState()    != SMESH_subMesh::MISSING_HYP &&
-         !hyp->DataDependOnParams() )
-      continue;
-
-    const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
-
-    if (( aSubMesh->IsApplicableHypotesis( hyp )) &&
-        ( algo = aSubMesh->GetAlgo() )            &&
-        ( compatibleHypoKind = algo->GetCompatibleHypoFilter( !hyp->IsAuxiliary() )) &&
-        ( compatibleHypoKind->IsOk( hyp, aSubShape )))
+    if ( aSubMesh->GetComputeState() == SMESH_subMesh::COMPUTE_OK ||
+         aSubMesh->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE ||
+         aSubMesh->GetAlgoState()    == SMESH_subMesh::MISSING_HYP ||
+         hyp->DataDependOnParams() )
     {
-      // check if hyp is used by algo
-      usedHyps.clear();
-      if ( GetHypotheses( aSubMesh, *compatibleHypoKind, usedHyps, true ) &&
-           find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() )
+      const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
+
+      if (( aSubMesh->IsApplicableHypotesis( hyp )) &&
+          ( algo = aSubMesh->GetAlgo() )            &&
+          ( compatibleHypoKind = algo->GetCompatibleHypoFilter( !hyp->IsAuxiliary() )) &&
+          ( compatibleHypoKind->IsOk( hyp, aSubShape )))
       {
-        smToNotify.push_back( aSubMesh );
+        // check if hyp is used by algo
+        usedHyps.clear();
+        toNotify = ( GetHypotheses( aSubMesh, *compatibleHypoKind, usedHyps, true ) &&
+                     std::find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() );
       }
     }
+    if ( toNotify )
+    {
+      smToNotify.push_back( aSubMesh );
+      if ( aSubMesh->GetAlgoState() == SMESH_subMesh::MISSING_HYP )
+        allMeshedEdgesNotified = false; //  update of algo state needed, not mesh clearing
+    }
+    else
+    {
+      if ( !aSubMesh->IsEmpty() &&
+           aSubMesh->GetSubShape().ShapeType() == TopAbs_EDGE )
+        allMeshedEdgesNotified = false;
+    }
   }
+  if ( smToNotify.empty() )
+    return;
 
-  for ( size_t i = 0; i < smToNotify.size(); ++i )
+  // if all meshed EDGEs will be notified then the notification is equivalent
+  // to the whole mesh clearing, which is usually faster
+  if ( allMeshedEdgesNotified && NbNodes() > 0 )
   {
-    smToNotify[i]->AlgoStateEngine(SMESH_subMesh::MODIF_HYP,
-                                   const_cast< SMESH_Hypothesis*>( hyp ));
+    Clear();
+  }
+  else
+  {
+    // notify in reverse order to avoid filling the pool of IDs
+    for ( int i = smToNotify.size()-1; i >= 0; --i )
+      smToNotify[i]->AlgoStateEngine(SMESH_subMesh::MODIF_HYP,
+                                     const_cast< SMESH_Hypothesis*>( hyp ));
   }
-
   HasModificationsToDiscard(); // to reset _isModified flag if mesh becomes empty
   GetMeshDS()->Modified();
 }
@@ -1358,7 +1379,6 @@ bool SMESH_Mesh::HasDuplicatedGroupNamesMED()
  *  \param [in] theAutoGroups - boolean parameter for creating/not creating
  *              the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
  *              the typical use is auto_groups=false.
- *  \param [in] theVersion - defines the version of format of MED file, that will be created
  *  \param [in] meshPart - mesh data to export
  *  \param [in] theAutoDimension - if \c true, a space dimension of a MED mesh can be either
      *         - 1D if all mesh nodes lie on OX coordinate axis, or
@@ -1372,7 +1392,6 @@ bool SMESH_Mesh::HasDuplicatedGroupNamesMED()
 void SMESH_Mesh::ExportMED(const char *        file, 
                            const char*         theMeshName, 
                            bool                theAutoGroups,
-                           int                 theVersion,
                            const SMESHDS_Mesh* meshPart,
                            bool                theAutoDimension,
                            bool                theAddODOnVertices)
@@ -1381,7 +1400,7 @@ void SMESH_Mesh::ExportMED(const char *        file,
   SMESH_TRY;
 
   DriverMED_W_SMESHDS_Mesh myWriter;
-  myWriter.SetFile         ( file, MED::EVersion(theVersion) );
+  myWriter.SetFile         ( file );
   myWriter.SetMesh         ( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS   );
   myWriter.SetAutoDimension( theAutoDimension );
   myWriter.AddODOnVertices ( theAddODOnVertices );
@@ -1453,7 +1472,7 @@ void SMESH_Mesh::ExportSAUV(const char *file,
   cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
   cmd += "\"";
   system(cmd.c_str());
-  ExportMED(medfilename.c_str(), theMeshName, theAutoGroups, 1);
+  ExportMED(medfilename.c_str(), theMeshName, theAutoGroups);
 #ifdef WIN32
   cmd = "%PYTHONBIN% ";
 #else
@@ -2349,7 +2368,7 @@ bool SMESH_Mesh::SortByMeshOrder(std::vector<SMESH_subMesh*>& theListToSort) con
   vector<SMESH_subMesh*>::iterator onlyBIt = onlyOrderedList.begin();
   vector<SMESH_subMesh*>::iterator onlyEIt = onlyOrderedList.end();
 
-  // iterate on ordered submeshes and insert them in detected positions
+  // iterate on ordered sub-meshes and insert them in detected positions
   map< int, TPosInList >::iterator i_pos = sortedPos.begin();
   for ( ; onlyBIt != onlyEIt; ++onlyBIt, ++i_pos )
     *(i_pos->second) = *onlyBIt;
@@ -2367,18 +2386,27 @@ bool SMESH_Mesh::IsOrderOK( const SMESH_subMesh* smBefore,
                             const SMESH_subMesh* smAfter ) const
 {
   TListOfListOfInt::const_iterator listIdsIt = _mySubMeshOrder.begin();
-  TListOfInt::const_iterator idBef, idAft;
   for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++)
   {
     const TListOfInt& listOfId = *listIdsIt;
-    idBef = std::find( listOfId.begin(), listOfId.end(), smBefore->GetId() );
-    if ( idBef != listOfId.end() )
-      idAft = std::find( listOfId.begin(), listOfId.end(), smAfter->GetId() );
-    if ( idAft != listOfId.end () )
-      return ( std::distance( listOfId.begin(), idBef ) <
-               std::distance( listOfId.begin(), idAft )   );
+    int iB = -1, iA = -1, i = 0;
+    for ( TListOfInt::const_iterator id = listOfId.begin(); id != listOfId.end(); ++id, ++i )
+    {
+      if ( *id == smBefore->GetId() )
+      {
+        iB = i;
+        if ( iA > -1 )
+          return iB < iA;
+      }
+      else if ( *id == smAfter->GetId() )
+      {
+        iA = i;
+        if ( iB > -1 )
+          return iB < iA;
+      }
+    }
   }
-  return true; // no order imposed to given submeshes
+  return true; // no order imposed to given sub-meshes
 } 
 
 //=============================================================================