Salome HOME
Merge branch 'occ/shaper2smesh'
[modules/smesh.git] / src / SMESH_I / SMESH_Mesh_i.cxx
index c65fc0e25d8f02913f0533c72dc31a44e3dd5d8c..d4e396cbdfacd0556715d974ba7d7b1d655a9077 100644 (file)
@@ -114,6 +114,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;
@@ -270,9 +271,30 @@ void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
     geomClient->RemoveShapeFromBuffer(aIOR);
   }
 
+  // update the reference to theNewGeom (needed for correct execution of a dumped python script)
+  SMESH::SMESH_Mesh_var   me = _this();
+  SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me );
+  CORBA::String_var    entry = theNewGeom->GetStudyEntry();
+  if ( !aSO->_is_nil() )
+  {
+    SALOMEDS::SObject_wrap aShapeRefSO;
+    if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() ))
+    {
+      SALOMEDS::SObject_wrap    aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry );
+      SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
+      builder->Addreference( aShapeRefSO, aShapeSO );
+    }
+  }
+
   // re-assign global hypotheses to the new shape
   _mainShapeTick = -1;
   CheckGeomModif( true );
+
+  TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject("
+                << me <<".GetMesh()), " << entry.in() << ")";
+
+  TPythonDump() <<  me << ".ReplaceShape( " << entry.in() << " )";
+
 }
 
 //================================================================================
@@ -668,6 +690,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();
@@ -676,7 +700,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 );
 
@@ -2002,8 +2029,7 @@ void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
     return;
   // group indices
   GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
-  GEOM::GEOM_IGroupOperations_ptr groupOp =
-    geomGen->GetIGroupOperations();
+  GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations();
   GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
 
   // store data
@@ -2062,6 +2088,8 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
       CORBA::Object_var  geomObj = _gen_i->SObjectToObject( geomSO );
       GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
       newShape = _gen_i->GeomObjectToShape( geom );
+      CORBA::String_var entry = geom->GetStudyEntry();
+      groupData._groupEntry = entry.in();
     }
   }
   else
@@ -2277,7 +2305,9 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
   if ( _preMeshInfo )
     _preMeshInfo->ForgetAllData();
 
-  _impl->Clear();
+  
+  if (isBreakLink)
+    _impl->Clear();
   TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
   if ( newShape.IsNull() )
     return;
@@ -2347,6 +2377,8 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
     ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
   }
 
+  std::map< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
+
   // count shapes excluding compounds corresponding to geom groups
   int oldNbSubShapes = meshDS->MaxShapeIndex();
   for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
@@ -2354,6 +2386,11 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
     const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
     if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
       break;
+    // fill ii2iMap
+    std::set<int> subIds;
+    for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
+      subIds.insert( meshDS->ShapeToIndex( it.Value() ));
+    ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
   }
 
   // check if shape topology changes - save shape type per shape ID
@@ -2374,9 +2411,15 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
   }
 
   // re-add shapes (compounds) of geom groups
+  std::map< int, int > old2newIDs; // group IDs
   std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
   for ( ; data != _geomGroupData.end(); ++data )
   {
+    int oldID = 0;
+    std::map< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
+    if ( ii2i != ii2iMap.end() )
+      oldID = ii2i->second;
+
     TopoDS_Shape newShape = newGroupShape( *data, isBreakLink ? IS_BREAK_LINK : MAIN_TRANSFORMED );
     if ( !newShape.IsNull() )
     {
@@ -2387,7 +2430,9 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
         BRep_Builder().Add( compound, newShape );
         newShape = compound;
       }
-      _impl->GetSubMesh( newShape );
+      int newID = _impl->GetSubMesh( newShape )->GetId();
+      if ( oldID && oldID != newID )
+        old2newIDs.insert( std::make_pair( oldID, newID ));
     }
   }
 
@@ -2396,7 +2441,11 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
   {
     if ( !sameTopology && ids2Hyps[i].first != 1 )
       continue; // assign only global hypos
-    const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
+    int sID = ids2Hyps[i].first;
+    std::map< int, int >::iterator o2n = old2newIDs.find( sID );
+    if ( o2n != old2newIDs.end() )
+      sID = o2n->second;
+    const TopoDS_Shape& s = meshDS->IndexToShape( sID );
     const THypList&  hyps = ids2Hyps[i].second;
     THypList::const_iterator h = hyps.begin();
     for ( ; h != hyps.end(); ++h )
@@ -2430,13 +2479,39 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
         g->GetGroupDS()->SetColor( data._color );
     }
 
+    std::map< int, int >::iterator o2n = old2newIDs.begin();
+    for ( ; o2n != old2newIDs.end(); ++o2n )
+    {
+      int newID = o2n->second, oldID = o2n->first;
+      if ( !_mapSubMesh.count( oldID ))
+        continue;
+      if ( newID > 0 )
+      {
+        _mapSubMesh   [ newID ] = _impl->GetSubMeshContaining( newID );
+        _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
+        _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
+      }
+      _mapSubMesh.   erase(oldID);
+      _mapSubMesh_i. erase(oldID);
+      _mapSubMeshIor.erase(oldID);
+      if ( newID > 0 )
+        _mapSubMesh_i [ newID ]->changeLocalId( newID );
+    }
+
     // update _mapSubMesh
     std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
     for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
       i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
   }
 
-  _gen_i->UpdateIcons( SMESH::SMESH_Mesh_var( _this() ));
+  _gen_i->UpdateIcons( me );
+
+  if ( !isBreakLink )
+  {
+    SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
+    if ( !meshSO->_is_nil() )
+      _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
+  }
 }
 
 //=============================================================================
@@ -3165,40 +3240,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;
   }
 }