Salome HOME
Fix regression of Extrusion 3D caused by OCCT changes
[modules/smesh.git] / src / SMESH_I / SMESH_Mesh_i.cxx
index c5a4ecd6e3d016b28e8dbe42b0604b93c1e63af1..8329b0cc28be3b2eca9dccd42cf22c3be7d2f3fb 100644 (file)
@@ -113,6 +113,7 @@ SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
   _impl          = NULL;
   _gen_i         = gen_i;
   _id            = _idGenerator++;
+  _nbInvalidHypos= -1;
   _editor        = NULL;
   _previewEditor = NULL;
   _preMeshInfo   = NULL;
@@ -647,6 +648,8 @@ SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr       aSubShape,
   if ( _preMeshInfo )
     _preMeshInfo->ForgetOrLoad();
 
+  const int prevNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
+
   std::string error;
   SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
   anErrorText = error.c_str();
@@ -655,7 +658,10 @@ SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr       aSubShape,
   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
   {
     _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
-    _gen_i->UpdateIcons( mesh );
+
+    int newNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
+    if ( newNbMeshEnt != prevNbMeshEnt )
+      _gen_i->UpdateIcons( mesh );
   }
   if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
 
@@ -3072,40 +3078,55 @@ namespace
     SMESH_Mesh_i* _mesh;
     TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
     virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
-    virtual void HypothesisModified (int theHypID)  { _mesh->onHypothesisModified( theHypID ); }
+    virtual void HypothesisModified( int hypID,
+                                     bool updIcons) { _mesh->onHypothesisModified( hypID,
+                                                                                   updIcons ); }
     virtual void Load ()                            { _mesh->Load(); }
+    virtual bool IsLoaded()                         { return _mesh->IsLoaded(); }
   };
 }
 
 //================================================================================
 /*!
- * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
+ * \brief callback from _impl to
+ *     1) forget not loaded mesh data (issue 0021208)
+ *     2) mark hypothesis as valid
  */
 //================================================================================
 
-void SMESH_Mesh_i::onHypothesisModified(int theHypID)
+void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
 {
   if ( _preMeshInfo )
     _preMeshInfo->ForgetOrLoad();
 
-  SMESH::SMESH_Mesh_var mesh = _this();
-  _gen_i->UpdateIcons( mesh );
+  if ( theUpdateIcons )
+  {
+    SMESH::SMESH_Mesh_var mesh = _this();
+    _gen_i->UpdateIcons( mesh );
+  }
 
-  // mark a hypothesis as valid after edition
-  SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
-  SALOMEDS::SObject_wrap hypRoot;
-  if ( !smeshComp->_is_nil() && 
-       smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
+  if ( _nbInvalidHypos != 0 )
   {
-    SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
-    for ( ; anIter->More(); anIter->Next() )
+    // mark a hypothesis as valid after edition
+    int nbInvalid = 0;
+    SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
+    SALOMEDS::SObject_wrap hypRoot;
+    if ( !smeshComp->_is_nil() &&
+         smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
     {
-      SALOMEDS::SObject_wrap    hypSO = anIter->Value();
-      CORBA::Object_var           obj = _gen_i->SObjectToObject( hypSO );
-      SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
-      if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
-        _gen_i->HighLightInvalid( hyp, false );
+      SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
+      for ( ; anIter->More(); anIter->Next() )
+      {
+        SALOMEDS::SObject_wrap    hypSO = anIter->Value();
+        CORBA::Object_var           obj = _gen_i->SObjectToObject( hypSO );
+        SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
+        if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
+          _gen_i->HighLightInvalid( hyp, false );
+        else
+          nbInvalid += _gen_i->IsInvalid( hypSO );
+      }
     }
+    _nbInvalidHypos = nbInvalid;
   }
 }
 
@@ -5068,7 +5089,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long  elemId,
 }
 
 //=======================================================================
-//function : GetElemFaceNodes
+//function : GetFaceNormal
 //purpose  : Returns three components of normal of given mesh face.
 //=======================================================================
 
@@ -6083,19 +6104,23 @@ class SMESH_DimHyp
     if ( (_ownDim == _dim  || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
       return false;
 
-//     bool checkSubShape = ( _dim >= theOther->_dim )
-//       ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
-//       : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
     bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
     if ( !checkSubShape )
-        return false;
+      return false;
 
     // check algorithms to be same
-    if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
-      return true; // different algorithms -> concurrency !
+    const SMESH_Algo* a1 = this->GetAlgo();
+    const SMESH_Algo* a2 = theOther->GetAlgo();
+    bool isSame = checkAlgo( a1, a2 );
+    if ( !isSame )
+    {
+      if ( !a1 || !a2 )
+        return false; // pb?
+      return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
+    }
 
     // check hypothesises for concurrence (skip first as algorithm)
-    int nbSame = 0;
+    size_t nbSame = 0;
     // pointers should be same, because it is referened from mesh hypothesis partition
     list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
     list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
@@ -6103,7 +6128,7 @@ class SMESH_DimHyp
       if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
         nbSame++;
     // the submeshes are concurrent if their algorithms has different parameters
-    return nbSame != (int)theOther->_hypotheses.size() - 1;
+    return nbSame != theOther->_hypotheses.size() - 1;
   }
 
   // Return true if algorithm of this SMESH_DimHyp is used if no
@@ -6627,6 +6652,48 @@ const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
   return 0;
 }
 // -------------------------------------------------------------------------------------
+bool SMESH_MeshPartDS::HasNumerationHoles()
+{
+  if ( _meshDS ) return _meshDS->HasNumerationHoles();
+
+  return ( MinNodeID() != 1 ||
+           MaxNodeID() != NbNodes() ||
+           MinElementID() != 1 ||
+           MaxElementID() != NbElements() );
+}
+// -------------------------------------------------------------------------------------
+int SMESH_MeshPartDS::MaxNodeID() const
+{
+  if ( _meshDS ) return _meshDS->MaxNodeID();
+  return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
+}
+// -------------------------------------------------------------------------------------
+int SMESH_MeshPartDS::MinNodeID() const
+{
+  if ( _meshDS ) return _meshDS->MinNodeID();
+  return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
+}  
+// -------------------------------------------------------------------------------------
+int SMESH_MeshPartDS::MaxElementID() const
+{
+  if ( _meshDS ) return _meshDS->MaxElementID();
+  int maxID = 0;
+  for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
+    if ( !_elements[ iType ].empty() )
+      maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
+  return maxID;
+}
+// -------------------------------------------------------------------------------------
+int SMESH_MeshPartDS::MinElementID() const
+{
+  if ( _meshDS ) return _meshDS->MinElementID();
+  int minID = 0;
+  for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
+    if ( !_elements[ iType ].empty() )
+      minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
+  return minID;
+}
+// -------------------------------------------------------------------------------------
 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
 {
   if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );