Salome HOME
IPAL52557: TC7.5.0: default value in Hypothesis is different in new and saved studies
[modules/smesh.git] / src / SMESH / SMESH_Mesh.cxx
index 3988f2a236eef7e45d55c162a5af6ddcdde42140..8b27cba540b680b93615827cc5839de99b88cd20 100644 (file)
 #include "DriverCGNS_Write.hxx"
 #endif
 
+#include <GEOMUtils.hxx>
+
 #undef _Precision_HeaderFile
-#include <BRepBndLib.hxx>
+//#include <BRepBndLib.hxx>
 #include <BRepPrimAPI_MakeBox.hxx>
 #include <Bnd_Box.hxx>
 #include <TColStd_MapOfInteger.hxx>
@@ -226,7 +228,7 @@ SMESH_Mesh::~SMESH_Mesh()
 
 bool SMESH_Mesh::MeshExists( int meshId ) const
 {
-  return _myDocument ? _myDocument->GetMesh( meshId ) : false;
+  return _myDocument ? bool( _myDocument->GetMesh( meshId )) : false;
 }
 
 //=============================================================================
@@ -327,7 +329,7 @@ double SMESH_Mesh::GetShapeDiagonalSize(const TopoDS_Shape & aShape)
 {
   if ( !aShape.IsNull() ) {
     Bnd_Box Box;
-    BRepBndLib::Add(aShape, Box);
+    GEOMUtils::PreciseBoundingBox(aShape, Box);
     return sqrt( Box.SquareExtent() );
   }
   return 0;
@@ -601,12 +603,16 @@ SMESH_ComputeErrorPtr SMESH_Mesh::GMFToMesh(const char* theFileName,
 //=============================================================================
 
 SMESH_Hypothesis::Hypothesis_Status
-  SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
-                            int                  anHypId  ) throw(SALOME_Exception)
+SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
+                          int                  anHypId,
+                          std::string*         anError  ) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   if(MYDEBUG) MESSAGE("SMESH_Mesh::AddHypothesis");
 
+  if ( anError )
+    anError->clear();
+
   SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
   if ( !subMesh || !subMesh->GetId())
     return SMESH_Hypothesis::HYP_BAD_SUBSHAPE;
@@ -631,23 +637,36 @@ SMESH_Hypothesis::Hypothesis_Status
     }
   }
 
-  // shape 
+  // shape
 
-  bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
-  int event = isAlgo ? SMESH_subMesh::ADD_ALGO : SMESH_subMesh::ADD_HYP;
+  bool isAlgo = ( anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO );
+  int   event = isAlgo ? SMESH_subMesh::ADD_ALGO : SMESH_subMesh::ADD_HYP;
 
   SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
 
+  if ( anError && SMESH_Hypothesis::IsStatusFatal(ret) && subMesh->GetComputeError() )
+    *anError = subMesh->GetComputeError()->myComment;
+
   // sub-shapes
-  if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
-      anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is added on father
+  if ( !SMESH_Hypothesis::IsStatusFatal(ret) &&
+       anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is added on father
   {
     event = isAlgo ? SMESH_subMesh::ADD_FATHER_ALGO : SMESH_subMesh::ADD_FATHER_HYP;
 
     SMESH_Hypothesis::Hypothesis_Status ret2 =
-      subMesh->SubMeshesAlgoStateEngine(event, anHyp);
+      subMesh->SubMeshesAlgoStateEngine(event, anHyp, /*exitOnFatal=*/true);
     if (ret2 > ret)
+    {
       ret = ret2;
+      if ( SMESH_Hypothesis::IsStatusFatal( ret ))
+      {
+        if ( anError && subMesh->GetComputeError() )
+          *anError = subMesh->GetComputeError()->myComment;
+        // remove anHyp
+        event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP;
+        subMesh->AlgoStateEngine(event, anHyp);
+      }
+    }
 
     // check concurent hypotheses on ancestors
     if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
@@ -892,16 +911,19 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh *               aSubMesh,
     const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
     const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
     for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
-      if ( aFilter.IsOk (cSMESH_Hyp( *hyp ), aSubShape) &&
-           ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
-           hypTypes.insert( (*hyp)->GetName() ).second )
+    {
+      const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp );
+      if (( aFilter.IsOk( h, aSubShape )) &&
+          ( h->IsAuxiliary() || !mainHypFound ) &&
+          ( h->IsAuxiliary() || hypTypes.insert( h->GetName() ).second ))
       {
         aHypList.push_back( *hyp );
         nbHyps++;
-        if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
+        if ( !h->IsAuxiliary() )
           mainHypFound = true;
         if ( assignedTo ) assignedTo->push_back( aSubShape );
       }
+    }
   }
 
   // get hypos from ancestors of aSubShape
@@ -918,16 +940,19 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh *               aSubMesh,
       const TopoDS_Shape& curSh = (*smIt)->GetSubShape();
       const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(curSh);
       for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
-        if (( aFilter.IsOk( cSMESH_Hyp( *hyp ), curSh ))         &&
-            ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
-            ( hypTypes.insert( (*hyp)->GetName() ).second          ))
+      {
+        const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp );
+        if (( aFilter.IsOk( h, curSh )) &&
+            ( h->IsAuxiliary() || !mainHypFound ) &&
+            ( h->IsAuxiliary() || hypTypes.insert( h->GetName() ).second ))
         {
           aHypList.push_back( *hyp );
           nbHyps++;
-          if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
+          if ( !h->IsAuxiliary() )
             mainHypFound = true;
           if ( assignedTo ) assignedTo->push_back( curSh );
         }
+      }
     }
   }
   return nbHyps;
@@ -984,6 +1009,8 @@ SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
   throw(SALOME_Exception)
 {
   int index = _myMeshDS->ShapeToIndex(aSubShape);
+  if ( !index && aSubShape.IsNull() )
+    return 0;
 
   // for submeshes on GEOM Group
   if (( !index || index > _nbSubShapes ) && aSubShape.ShapeType() == TopAbs_COMPOUND ) {
@@ -996,14 +1023,29 @@ SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
         fillAncestorsMap( _myMeshDS->IndexToShape( ++_nbSubShapes ));
     }
   }
-//   if ( !index )
-//     return NULL; // neither sub-shape nor a group
+  // if ( !index )
+  //   return NULL; // neither sub-shape nor a group
 
   SMESH_subMesh* aSubMesh = _subMeshHolder->Get( index );
   if ( !aSubMesh )
   {
     aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
     _subMeshHolder->Add( index, aSubMesh );
+
+    // include non-computable sub-meshes in SMESH_subMesh::_ancestors of sub-submeshes
+    switch ( aSubShape.ShapeType() ) {
+    case TopAbs_COMPOUND:
+    case TopAbs_WIRE:
+    case TopAbs_SHELL:
+      for ( TopoDS_Iterator subIt( aSubShape ); subIt.More(); subIt.Next() )
+      {
+        SMESH_subMesh* sm = GetSubMesh( subIt.Value() );
+        SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*inclideSelf=*/true);
+        while ( smIt->more() )
+          smIt->next()->ClearAncestors();
+      }
+    default:;
+    }
   }
   return aSubMesh;
 }
@@ -1157,6 +1199,9 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h
   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;
+
   SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() );
   while ( smIt->more() )
   {
@@ -1184,11 +1229,17 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h
       if ( GetHypotheses( aSubMesh, *compatibleHypoKind, usedHyps, true ) &&
            find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() )
       {
-        aSubMesh->AlgoStateEngine(SMESH_subMesh::MODIF_HYP,
-                                  const_cast< SMESH_Hypothesis*>( hyp ));
+        smToNotify.push_back( aSubMesh );
       }
     }
   }
+
+  for ( size_t i = 0; i < smToNotify.size(); ++i )
+  {
+    smToNotify[i]->AlgoStateEngine(SMESH_subMesh::MODIF_HYP,
+                                   const_cast< SMESH_Hypothesis*>( hyp ));
+  }
+
   HasModificationsToDiscard(); // to reset _isModified flag if mesh becomes empty
   GetMeshDS()->Modified();
 }
@@ -2185,12 +2236,10 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape)
         while ( ancIt.More() && ancIt.Value().ShapeType() >= memberType )
           ancIt.Next();
         if ( ancIt.More() )
-        {
           ancList.InsertBefore( theShape, ancIt );
-          GetSubMesh( des.Current() )->ClearAncestors(); // to re-fill _ancestors
-        }
       }
   }
+  else // else added for 52457: Addition of hypotheses is 8 time longer than meshing
   {
     for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- )
       for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
@@ -2202,9 +2251,11 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape)
   // visit COMPOUNDs inside a COMPOUND that are not reachable by TopExp_Explorer
   if ( theShape.ShapeType() == TopAbs_COMPOUND )
   {
-    for ( TopoDS_Iterator sIt(theShape); sIt.More(); sIt.Next() )
-      if ( sIt.Value().ShapeType() == TopAbs_COMPOUND )
-        fillAncestorsMap( sIt.Value() );
+    TopoDS_Iterator sIt(theShape);
+    if ( sIt.More() && sIt.Value().ShapeType() == TopAbs_COMPOUND )
+      for ( ; sIt.More(); sIt.Next() )
+        if ( sIt.Value().ShapeType() == TopAbs_COMPOUND )
+          fillAncestorsMap( sIt.Value() );
   }
 }