Salome HOME
23437: EDF 14551 - mesh groups missing
[modules/smesh.git] / src / SMESH_I / SMESH_Gen_i_1.cxx
index 65ee1e31d21d00f6a6a50600a17e51d6809166fc..b08b7e3e6d35d8b09a536a17ca8b5b5e75a68af5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -26,6 +26,7 @@
 
 #include "SMESH_Gen_i.hxx"
 
+#include "SMESHDS_Mesh.hxx"
 #include "SMESH_Algo_i.hxx"
 #include "SMESH_Comment.hxx"
 #include "SMESH_Group_i.hxx"
 
 #ifdef _DEBUG_
 static int MYDEBUG = 0;
-//static int VARIABLE_DEBUG = 0;
 #else
 static int MYDEBUG = 0;
-//static int VARIABLE_DEBUG = 0;
 #endif
 
+using namespace std;
+
 //=============================================================================
 /*!
  *  Get...Tag [ static ]
@@ -264,68 +265,90 @@ static SALOMEDS::SObject_ptr publish(SALOMEDS::Study_ptr   theStudy,
   SALOMEDS::SObject_wrap SO = SMESH_Gen_i::ObjectToSObject( theStudy, theIOR );
   SALOMEDS::StudyBuilder_var     aStudyBuilder = theStudy->NewBuilder();
   SALOMEDS::UseCaseBuilder_wrap useCaseBuilder = theStudy->GetUseCaseBuilder();
-  SALOMEDS::SObject_wrap objAfter;
+  bool isNewSO = false, isInUseCaseTree = false;
   if ( SO->_is_nil() )
   {
     if ( theTag == 0 ) {
       SO = aStudyBuilder->NewObject( theFatherObject );
+      isNewSO = true;
     }
     else if ( !theFatherObject->FindSubObject( theTag, SO.inout() ))
     {
       SO = aStudyBuilder->NewObjectToTag( theFatherObject, theTag );
-
-      // define the next tag after given one in the data tree to insert SObject
-      SALOMEDS::SObject_wrap curObj;
-      if ( theFatherObject->GetLastChildTag() > theTag )
-      {
-        SALOMEDS::UseCaseIterator_wrap anUseCaseIter = useCaseBuilder->GetUseCaseIterator(theFatherObject);
-        for ( ; anUseCaseIter->More(); anUseCaseIter->Next() ) {
-          curObj = anUseCaseIter->Value();
-          if ( curObj->Tag() > theTag  ) {
-            objAfter = curObj;
-            break;
-          }
-        }
-      }
+      isNewSO = true;
+    }
+    else
+    {
+      isInUseCaseTree = useCaseBuilder->IsUseCaseNode( SO );
     }
   }
+  else
+  {
+    isInUseCaseTree = useCaseBuilder->IsUseCaseNode( SO );
+  }
 
   SALOMEDS::GenericAttribute_wrap anAttr;
-  if ( !CORBA::is_nil( theIOR )) {
+  if ( !CORBA::is_nil( theIOR ))
+  {
     anAttr = aStudyBuilder->FindOrCreateAttribute( SO, "AttributeIOR" );
     CORBA::String_var objStr = SMESH_Gen_i::GetORB()->object_to_string( theIOR );
     SALOMEDS::AttributeIOR_wrap iorAttr = anAttr;
-    iorAttr->SetValue( objStr.in() );
-    // UnRegister() !!!
-    SALOME::GenericObj_var genObj = SALOME::GenericObj::_narrow( theIOR );
-    if ( !genObj->_is_nil() )
-      genObj->UnRegister();
+    CORBA::String_var objStrCur = iorAttr->Value();
+    bool sameIOR = ( objStrCur.in() && strcmp( objStr.in(), objStrCur.in() ) == 0 );
+    if ( !sameIOR )
+    {
+      iorAttr->SetValue( objStr.in() );
+      // UnRegister() !!!
+      SALOME::GenericObj_var genObj = SALOME::GenericObj::_narrow( theIOR );
+      if ( !genObj->_is_nil() )
+        genObj->UnRegister();
+    }
   }
+
   if ( thePixMap ) {
     anAttr  = aStudyBuilder->FindOrCreateAttribute( SO, "AttributePixMap" );
     SALOMEDS::AttributePixMap_wrap pm = anAttr;
     pm->SetPixMap( thePixMap );
   }
+
   if ( !theSelectable ) {
     anAttr = aStudyBuilder->FindOrCreateAttribute( SO, "AttributeSelectable" );
     SALOMEDS::AttributeSelectable_wrap selAttr = anAttr;
     selAttr->SetSelectable( false );
   }
 
+  if ( !isNewSO )
+    aStudyBuilder->RemoveReference( SO );// remove garbage reference (23336)
+
   // add object to the use case tree
   // (to support tree representation customization and drag-n-drop)
-  if ( !CORBA::is_nil( objAfter ) ) {
-    useCaseBuilder->InsertBefore( SO, objAfter );    // insert at given tag
-  } else if ( !useCaseBuilder->IsUseCaseNode( SO ) ) {
-    useCaseBuilder->AppendTo( theFatherObject, SO ); // append to the end of list
+  if ( isNewSO || !isInUseCaseTree )
+  {
+    // define the next tag after given one in the data tree to insert SObject
+    SALOMEDS::SObject_wrap curObj, objAfter;
+    if ( theFatherObject->GetLastChildTag() > theTag && theTag > 0 )
+    {
+      SALOMEDS::UseCaseIterator_wrap
+        anUseCaseIter = useCaseBuilder->GetUseCaseIterator(theFatherObject);
+      for ( ; anUseCaseIter->More(); anUseCaseIter->Next() ) {
+        curObj = anUseCaseIter->Value();
+        if ( curObj->Tag() > theTag  ) {
+          objAfter = curObj;
+          break;
+        }
+      }
+    }
+    if ( !CORBA::is_nil( objAfter ))
+      useCaseBuilder->InsertBefore( SO, objAfter );    // insert at given tag
+    else if ( !isInUseCaseTree )
+      useCaseBuilder->AppendTo( theFatherObject, SO ); // append to the end of list
   }
-
   return SO._retn();
 }
 
 //=======================================================================
 //function : setName
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMESH_Gen_i::SetName(SALOMEDS::SObject_ptr theSObject,
@@ -415,14 +438,21 @@ static void addReference (SALOMEDS::Study_ptr   theStudy,
         theTag = tag;
     }
     if ( !theSObject->FindSubObject( theTag, aReferenceSO.inout() ))
-    {
       aReferenceSO = aStudyBuilder->NewObjectToTag( theSObject, theTag );
-      // add reference to the use case tree
-      // (to support tree representation customization and drag-n-drop)
-      SALOMEDS::UseCaseBuilder_wrap useCaseBuilder = theStudy->GetUseCaseBuilder();
-      useCaseBuilder->AppendTo( aReferenceSO->GetFather(), aReferenceSO );
-    }
+
     aStudyBuilder->Addreference( aReferenceSO, aToObjSO );
+
+    // add reference to the use case tree
+    // (to support tree representation customization and drag-n-drop)
+    SALOMEDS::UseCaseBuilder_wrap  useCaseBuilder = theStudy->GetUseCaseBuilder();
+    SALOMEDS::UseCaseIterator_wrap    useCaseIter = useCaseBuilder->GetUseCaseIterator(theSObject);
+    for ( ; useCaseIter->More(); useCaseIter->Next() )
+    {
+      SALOMEDS::SObject_wrap curSO = useCaseIter->Value();
+      if ( curSO->Tag() == theTag )
+        return;
+    }
+    useCaseBuilder->AppendTo( theSObject, aReferenceSO );
   }
 }
 
@@ -574,7 +604,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishMesh (SALOMEDS::Study_ptr   theStudy,
     // Publish global hypotheses
 
     SMESH::ListOfHypothesis_var hypList = theMesh->GetHypothesisList( aShapeObject );
-    for ( int i = 0; i < hypList->length(); i++ )
+    for ( CORBA::ULong i = 0; i < hypList->length(); i++ )
     {
       SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( hypList[ i ]);
       SALOMEDS::SObject_wrap so = PublishHypothesis( theStudy, aHyp );
@@ -699,7 +729,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SALOMEDS::Study_ptr      theS
   // Publish hypothesis
 
   SMESH::ListOfHypothesis_var hypList = theMesh->GetHypothesisList( theShapeObject );
-  for ( int i = 0; i < hypList->length(); i++ ) {
+  for ( CORBA::ULong i = 0; i < hypList->length(); i++ ) {
     SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( hypList[ i ]);
     SALOMEDS::SObject_wrap so = PublishHypothesis( theStudy, aHyp );
     AddHypothesisToShape( theStudy, theMesh, theShapeObject, aHyp );
@@ -731,13 +761,13 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishGroup (SALOMEDS::Study_ptr    theStudy
       if ( aMeshSO->_is_nil())
         return SALOMEDS::SObject::_nil();
     }
-    int aType = (int)theGroup->GetType();
+    size_t aType = (int)theGroup->GetType();
     const char* aRootNames[] = {
       "Compound Groups", "Groups of Nodes", "Groups of Edges",
       "Groups of Faces", "Groups of Volumes", "Groups of 0D Elements",
       "Groups of Balls" };
 
-    // Currently, groups with heterogenous content are not supported
+    // Currently, groups with heterogeneous content are not supported
     if ( aType != SMESH::ALL )
     {
       long aRootTag = GetNodeGroupsTag() + aType - 1;
@@ -751,8 +781,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishGroup (SALOMEDS::Study_ptr    theStudy
         SetName( aRootSO, aRootNames[aType] );
 
       // Add new group to corresponding sub-tree
-      SMESH::array_of_ElementType_var elemTypes = theGroup->GetTypes();
-      int isEmpty = ( elemTypes->length() == 0 );
+      int isEmpty = false;
       std::string pm[2] = { "ICON_SMESH_TREE_GROUP", "ICON_SMESH_TREE_MESH_WARN" };
       if ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ))
       {
@@ -760,9 +789,14 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishGroup (SALOMEDS::Study_ptr    theStudy
       }
       else if ( SMESH::DownCast< SMESH_Group_i* > ( theGroup ))
       {
-        SMESH::array_of_ElementType_var allElemTypes = theMesh->GetTypes();
-        for ( size_t i =0; i < allElemTypes->length() && isEmpty; ++i )
-          isEmpty = ( allElemTypes[i] != theGroup->GetType() );
+        if ( theGroup->GetType() == SMESH::NODE )
+          isEmpty = ( theMesh->NbNodes() == 0 );
+        else
+        {
+          SMESH::array_of_ElementType_var allElemTypes = theMesh->GetTypes();
+          for ( size_t i =0; i < allElemTypes->length() && isEmpty; ++i )
+            isEmpty = ( allElemTypes[i] != theGroup->GetType() );
+        }
       }
       aGroupSO = publish (theStudy, theGroup, aRootSO, 0, pm[isEmpty].c_str() );
     }
@@ -887,7 +921,7 @@ bool SMESH_Gen_i::AddHypothesisToShape(SALOMEDS::Study_ptr         theStudy,
   if ( aMeshSO->_is_nil() || aHypSO->_is_nil())
     return false;
 
-  // Find a mesh or submesh refering to theShape
+  // Find a mesh or submesh referring to theShape
   SALOMEDS::SObject_wrap aMeshOrSubMesh =
     GetMeshOrSubmeshByShape( theStudy, theMesh, theShape );
   if ( aMeshOrSubMesh->_is_nil() )
@@ -940,7 +974,7 @@ bool SMESH_Gen_i::RemoveHypothesisFromShape(SALOMEDS::Study_ptr         theStudy
 
   CORBA::String_var hypEntry = aHypSO->GetID();
 
-  // Find a mesh or submesh refering to theShape
+  // Find a mesh or sub-mesh referring to theShape
   SALOMEDS::SObject_wrap aMeshOrSubMesh =
     GetMeshOrSubmeshByShape( theStudy, theMesh, theShape );
   if ( aMeshOrSubMesh->_is_nil() )
@@ -1063,7 +1097,7 @@ void SMESH_Gen_i::UpdateParameters(CORBA::Object_ptr theObject, const char* theP
         if ( pos < varStr.size() )
         {
           varFound = ( varStr.compare( pos, myLastParameters[i].size(), myLastParameters[i] ) == 0 &&
-                       // same string begining but is length same?
+                       // same string beginning but is length same?
                        ( pos + myLastParameters[i].size() >= varStr.size() ||
                          separators.find( varStr[ pos+1 ]) != std::string::npos ));
           if ( varFound )