Salome HOME
0021897: EDF 1495 SMESH : Problem with groups when building a compound with medballs
[modules/smesh.git] / src / SMESH_I / SMESH_Gen_i.cxx
index 97e4ede843d51f7e5f9849daed8b50e4e15d3f66..00cc36bee86238e73b45f83ae3f43fd5e0f2aeee 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  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
 #include <map>
 #include <fstream>
 #include <cstdio>
+#include <stdlib.h>
 
 using namespace std;
 using SMESH::TPythonDump;
@@ -591,6 +592,12 @@ CORBA::Boolean SMESH_Gen_i::IsEmbeddedMode()
 //=============================================================================
 
 void SMESH_Gen_i::SetCurrentStudy( SALOMEDS::Study_ptr theStudy )
+{
+  setCurrentStudy( theStudy );
+}
+
+void SMESH_Gen_i::setCurrentStudy( SALOMEDS::Study_ptr theStudy,
+                                   bool                theStudyIsBeingClosed)
 {
   int curStudyId = GetCurrentStudyID();
   myCurrentStudy = SALOMEDS::Study::_duplicate( theStudy );
@@ -601,7 +608,7 @@ void SMESH_Gen_i::SetCurrentStudy( SALOMEDS::Study_ptr theStudy )
   }
 
   // myCurrentStudy may be nil
-  if ( !CORBA::is_nil( myCurrentStudy ) ) {
+  if ( !theStudyIsBeingClosed && !CORBA::is_nil( myCurrentStudy ) ) {
     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
     if( !myCurrentStudy->FindComponent( "GEOM" )->_is_nil() )
       aStudyBuilder->LoadWith( myCurrentStudy->FindComponent( "GEOM" ), GetGeomEngine() );
@@ -954,7 +961,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName
     aStudyBuilder->CommitCommand();
     if ( !aSO->_is_nil() ) {
       // Update Python script
-      TPythonDump() << aSO << " = smeshgen.CreateMeshesFromUNV(r'" << theFileName << "')";
+      TPythonDump() << aSO << " = " << this << ".CreateMeshesFromUNV(r'" << theFileName << "')";
     }
   }
 
@@ -1216,6 +1223,47 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* theFileName,
   return aResult._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Create a mesh and import data from a GMF file
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr
+SMESH_Gen_i::CreateMeshesFromGMF( const char*             theFileName,
+                                  SMESH::ComputeError_out theError)
+    throw ( SALOME::SALOME_Exception )
+{
+  Unexpect aCatch(SALOME_SalomeException);
+
+  SMESH::SMESH_Mesh_var aMesh = createMesh();
+#ifdef WIN32
+  char bname[ _MAX_FNAME ];
+  _splitpath( theFileName, NULL, NULL, bname, NULL );
+  string aFileName = bname;
+#else
+  string aFileName = basename( theFileName );
+#endif
+  // publish mesh in the study
+  if ( CanPublishInStudy( aMesh ) ) {
+    SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
+    aStudyBuilder->NewCommand();  // There is a transaction
+    SALOMEDS::SObject_var aSO = PublishInStudy
+      ( myCurrentStudy, SALOMEDS::SObject::_nil(), aMesh.in(), aFileName.c_str() );
+    aStudyBuilder->CommitCommand();
+    if ( !aSO->_is_nil() ) {
+      // Update Python script
+      TPythonDump() << "("<< aSO << ", error) = " << this << ".CreateMeshesFromGMF(r'" << theFileName << "')";
+    }
+  }
+  SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( aMesh ).in() );
+  ASSERT( aServant );
+  theError = aServant->ImportGMFFile( theFileName );
+  aServant->GetImpl().GetMeshDS()->Modified();
+  return aMesh._retn();
+}
+
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::IsReadyToCompute
@@ -2165,6 +2213,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
           SMESH_Mesh_i* anInitImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( anInitMesh ).in() );
           if ( anInitImpl ) {
             ::SMESH_Mesh& aInitLocMesh = anInitImpl->GetImpl();
+            aInitLocMesh.Load();
             SMESHDS_Mesh* anInitMeshDS = aInitLocMesh.GetMeshDS();
 
             TIDsMap nodesMap;
@@ -2180,17 +2229,20 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
             int anNbEdges   = 0;
             int anNbFaces   = 0;
             int anNbVolumes = 0;
+            int aNbBalls    = 0;
 
             SMESH::long_array_var anIDsNodes   = new SMESH::long_array();
             SMESH::long_array_var anIDsEdges   = new SMESH::long_array();
             SMESH::long_array_var anIDsFaces   = new SMESH::long_array();
             SMESH::long_array_var anIDsVolumes = new SMESH::long_array();
+            SMESH::long_array_var anIDsBalls   = new SMESH::long_array();
 
             if( theCommonGroups ) {
               anIDsNodes->length(   anInitMeshDS->NbNodes()   );
               anIDsEdges->length(   anInitMeshDS->NbEdges()   );
               anIDsFaces->length(   anInitMeshDS->NbFaces()   );
               anIDsVolumes->length( anInitMeshDS->NbVolumes() );
+              anIDsBalls->length(   anInitMeshDS->NbBalls() );
             }
 
             for ( int j = 0; itElems->more(); j++) {
@@ -2218,34 +2270,47 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
               }//nodes loop
 
               // creates a corresponding element on existent nodes in new mesh
-              if ( anElem->IsPoly() && anElemType == SMDSAbs_Volume )
+              switch ( anElem->GetEntityType() ) {
+              case SMDSEntity_Polyhedra:
+                if ( const SMDS_VtkVolume* aVolume =
+                     dynamic_cast<const SMDS_VtkVolume*> (anElem))
+                {
+                  aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray,
+                                                             aVolume->GetQuantities());
+                  elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
+                  if( theCommonGroups )
+                    anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
+                }
+                break;
+              case SMDSEntity_Ball:
+                if ( const SMDS_BallElement* aBall =
+                     dynamic_cast<const SMDS_BallElement*> (anElem))
+                {
+                  aNewElem = aNewEditor.AddElement(aNodesArray, SMDSAbs_Ball,
+                                                   /*isPoly=*/false, /*id=*/0,
+                                                   aBall->GetDiameter() );
+                  elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
+                  if( theCommonGroups )
+                    anIDsBalls[aNbBalls++] = aNewElem->GetID();
+                }
+                break;
+              default:
                 {
-                  const SMDS_VtkVolume* aVolume =
-                    dynamic_cast<const SMDS_VtkVolume*> (anElem);
-                  if ( aVolume ) {
-                    aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray,
-                                                               aVolume->GetQuantities());
-                    elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
-                    if( theCommonGroups )
+                  aNewElem = aNewEditor.AddElement(aNodesArray,
+                                                   anElemType,
+                                                   anElem->IsPoly());
+                  elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
+                  if( theCommonGroups ) {
+                    if( anElemType == SMDSAbs_Edge )
+                      anIDsEdges[anNbEdges++] = aNewElem->GetID();
+                    else if( anElemType == SMDSAbs_Face )
+                      anIDsFaces[anNbFaces++] = aNewElem->GetID();
+                    else if( anElemType == SMDSAbs_Volume )
                       anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
                   }
                 }
-              else {
-
-                aNewElem = aNewEditor.AddElement(aNodesArray,
-                                                 anElemType,
-                                                 anElem->IsPoly());
-                elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
-                if( theCommonGroups ) {
-                  if( anElemType == SMDSAbs_Edge )
-                    anIDsEdges[anNbEdges++] = aNewElem->GetID();
-                  else if( anElemType == SMDSAbs_Face )
-                    anIDsFaces[anNbFaces++] = aNewElem->GetID();
-                  else if( anElemType == SMDSAbs_Volume )
-                    anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
-                }
               }
-            }//elems loop
+            } //elems loop
 
             // copy orphan nodes
             SMDS_NodeIteratorPtr  itNodes = anInitMeshDS->nodesIterator();
@@ -2274,7 +2339,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
             SMESH::ElementType aGroupType;
             CORBA::String_var aGroupName;
             if ( theCommonGroups ) {
-              for(aGroupType=SMESH::NODE;aGroupType<=SMESH::VOLUME;aGroupType=(SMESH::ElementType)(aGroupType+1)) {
+              for(aGroupType=SMESH::NODE;aGroupType<=SMESH::BALL;aGroupType=(SMESH::ElementType)(aGroupType+1)) {
                 string str = "Gr";
                 SALOMEDS::SObject_var aMeshSObj = ObjectToSObject( myCurrentStudy, anInitMesh );
                 if(aMeshSObj)
@@ -2304,6 +2369,11 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
                   anIDsVolumes->length(anNbVolumes);
                   anLen = anNbVolumes;
                   break;
+                case SMESH::BALL:
+                  str += "Balls";
+                  anIDsBalls->length(aNbBalls);
+                  anLen = aNbBalls;
+                  break;
                 default:
                   break;
                 }
@@ -2327,6 +2397,9 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
                   case SMESH::VOLUME:
                     aNewGroup->Add( anIDsVolumes );
                     break;
+                  case SMESH::BALL:
+                    aNewGroup->Add( anIDsBalls );
+                    break;
                   default:
                     break;
                   }
@@ -2339,8 +2412,8 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
             }
 
             // check that current group name and type don't have identical ones in union mesh
-            for (int i = 0; i < aListOfGroups->length(); i++) {
-              aGroup = aListOfGroups[i];
+            for (int iG = 0; iG < aListOfGroups->length(); iG++) {
+              aGroup = aListOfGroups[iG];
               aListOfNewGroups.clear();
               aGroupType = aGroup->GetType();
               aGroupName = aGroup->GetName();
@@ -2436,13 +2509,8 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
 
   // IPAL21468 Change icon of compound because it need not be computed.
   SALOMEDS::SObject_var aMeshSObj = ObjectToSObject( myCurrentStudy, aNewMesh );
-  if( !aMeshSObj->_is_nil() ) {
-    SALOMEDS::GenericAttribute_var anAttr;
-    SALOMEDS::StudyBuilder_var aBuilder = myCurrentStudy->NewBuilder();
-    anAttr = aBuilder->FindOrCreateAttribute( aMeshSObj,"AttributePixMap" );
-    SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
-    aPixmap->SetPixMap("ICON_SMESH_TREE_MESH");
-  }
+  SetPixMap( aMeshSObj, "ICON_SMESH_TREE_MESH" );
+
   if (aNewMeshDS)
     aNewMeshDS->Modified();
   return aNewMesh._retn();
@@ -2538,6 +2606,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
   while ( srcElemIt->more() )
   {
     const SMDS_MeshElement * elem = srcElemIt->next();
+    // find / add nodes
     nodes.resize( elem->NbNodes());
     SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
     if ( toKeepIDs ) {
@@ -2560,22 +2629,30 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
         nodes[ iN ] = (const SMDS_MeshNode*) n2n->second;
       }
     }
+    // add elements
     if ( elem->GetType() != SMDSAbs_Node )
     {
       int ID = toKeepIDs ? elem->GetID() : 0;
       const SMDS_MeshElement * newElem;
-      if ( elem->GetEntityType() == SMDSEntity_Polyhedra )
+      switch ( elem->GetEntityType() ) {
+      case SMDSEntity_Polyhedra:
         newElem = editor.GetMeshDS()->
           AddPolyhedralVolumeWithID( nodes,
                                      static_cast<const SMDS_VtkVolume*>(elem)->GetQuantities(),
-                                     elem->GetID());
-      else
+                                     ID);
+        break;
+      case SMDSEntity_Ball:
+        newElem = editor.AddElement( nodes, SMDSAbs_Ball, false, ID,
+                                     static_cast<const SMDS_BallElement*>(elem)->GetDiameter());
+        break;
+      default:
         newElem = editor.AddElement( nodes,elem->GetType(),elem->IsPoly(),ID);
 
       if ( toCopyGroups && !toKeepIDs )
         e2eMapByType[ elem->GetType() ].insert( make_pair( elem, newElem ));
+      }
     }
-  }
+  } // while ( srcElemIt->more() )
 
   // 4(b). Copy free nodes
 
@@ -3362,7 +3439,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
 
             // groups root sub-branch
             SALOMEDS::SObject_var myGroupsBranch;
-            for ( int i = GetNodeGroupsTag(); i <= Get0DElementsGroupsTag(); i++ ) {
+            for ( int i = GetNodeGroupsTag(); i <= GetBallElementsGroupsTag(); i++ ) {
               found = gotBranch->FindSubObject( i, myGroupsBranch );
               if ( found ) {
                 char name_group[ 30 ];
@@ -3376,6 +3453,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                   strcpy( name_group, "Groups of Volumes" );
                 else if ( i == Get0DElementsGroupsTag() )
                   strcpy( name_group, "Groups of 0D Elements" );
+                else if ( i == GetBallElementsGroupsTag() )
+                  strcpy( name_group, "Groups of Balls" );
 
                 aGroup = new HDFgroup( name_group, aTopGroup );
                 aGroup->CreateOnDisk();
@@ -4122,18 +4201,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             }
           }
 
-          // issue 0020693. Restore _isModified flag
-          if( aTopGroup->ExistInternalObject( "_isModified" ) )
-          {
-            aDataset = new HDFdataset( "_isModified", aTopGroup );
-            aDataset->OpenOnDisk();
-            size = aDataset->GetSize();
-            int* isModified = new int[ size ];
-            aDataset->ReadFromDisk( isModified );
-            aDataset->CloseOnDisk();
-            myNewMeshImpl->GetImpl().SetIsModified( bool(*isModified));
-          }
-
           // issue 20918. Restore Persistent Id of SMESHDS_Mesh
           if( aTopGroup->ExistInternalObject( "meshPersistentId" ) )
           {
@@ -4421,7 +4488,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
       }
 
       // try to get GROUPS
-      for ( int ii = GetNodeGroupsTag(); ii <= Get0DElementsGroupsTag(); ii++ ) {
+      for ( int ii = GetNodeGroupsTag(); ii <= GetBallElementsGroupsTag(); ii++ ) {
         char name_group[ 30 ];
         if ( ii == GetNodeGroupsTag() )
           strcpy( name_group, "Groups of Nodes" );
@@ -4433,6 +4500,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
           strcpy( name_group, "Groups of Volumes" );
         else if ( ii == Get0DElementsGroupsTag() )
           strcpy( name_group, "Groups of 0D Elements" );
+        else if ( ii == GetBallElementsGroupsTag() )
+          strcpy( name_group, "Groups of Balls" );
 
         if ( aTopGroup->ExistInternalObject( name_group ) ) {
           aGroup = new HDFgroup( name_group, aTopGroup );
@@ -4688,7 +4757,7 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent )
   // set correct current study
   SALOMEDS::Study_var study = theComponent->GetStudy();
   if ( study->StudyId() != GetCurrentStudyID())
-    SetCurrentStudy( study );
+    setCurrentStudy( study, /*IsBeingClosed=*/true );
 
   // Clear study contexts data
   int studyId = GetCurrentStudyID();