Salome HOME
22611: EDF 8409 SMESH: Bad dump of CutListOfGroups
[modules/smesh.git] / src / SMESH_I / SMESH_Mesh_i.cxx
index d3e504e163f9e1e4311f207441cd18110ceecfc9..311e1377de03680480ba070b33923581a35ba940 100644 (file)
 #include "SMESHDS_Group.hxx"
 #include "SMESHDS_GroupOnGeom.hxx"
 #include "SMESH_Controls.hxx"
+#include "SMESH_File.hxx"
 #include "SMESH_Filter_i.hxx"
 #include "SMESH_Gen_i.hxx"
 #include "SMESH_Group.hxx"
 #include "SMESH_Group_i.hxx"
+#include "SMESH_Mesh.hxx"
 #include "SMESH_MeshAlgos.hxx"
 #include "SMESH_MeshEditor.hxx"
 #include "SMESH_MeshEditor_i.hxx"
 #include "SMESH_PythonDump.hxx"
 #include "SMESH_subMesh_i.hxx"
 
-#include <OpUtil.hxx>
 #include <SALOMEDS_Attributes_wrap.hxx>
 #include <SALOMEDS_wrap.hxx>
-#include <SALOME_NamingService.hxx>
 #include <Utils_ExceptHandlers.hxx>
-#include <Utils_SINGLETON.hxx>
 #include <utilities.h>
 
 #include <GEOMImpl_Types.hxx>
 
 // OCCT Includes
 #include <BRep_Builder.hxx>
-#include <OSD_Directory.hxx>
-#include <OSD_File.hxx>
-#include <OSD_Path.hxx>
-#include <OSD_Protection.hxx>
-#include <Standard_OutOfMemory.hxx>
-#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+#include <Standard_ErrorHandler.hxx>
 #include <TColStd_MapOfInteger.hxx>
-#include <TColStd_SequenceOfInteger.hxx>
-#include <TCollection_AsciiString.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_MapIteratorOfMapOfShape.hxx>
 
 // STL Includes
 #include <algorithm>
-#include <string>
 #include <iostream>
 #include <sstream>
 
-#include <sys/stat.h>
-
 // to pass CORBA exception through SMESH_TRY
 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
 
@@ -199,7 +188,8 @@ void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
   // to track changes of GEOM groups
   SMESH::SMESH_Mesh_var mesh = _this();
   addGeomGroupData( theShapeObject, mesh );
-  _mainShapeTick = theShapeObject->GetTick();
+  if ( !CORBA::is_nil( theShapeObject ))
+    _mainShapeTick = theShapeObject->GetTick();
 }
 
 //================================================================================
@@ -403,14 +393,7 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
   _medFileInfo->major    = major;
   _medFileInfo->minor    = minor;
   _medFileInfo->release  = release;
-#ifdef WIN32
-  struct _stati64 d;
-  if ( ::_stati64( theFileName, &d ) != -1 )
-#else
-  struct stat64 d;
-  if ( ::stat64( theFileName, &d ) != -1 )
-#endif
-    _medFileInfo->fileSize = d.st_size;
+  _medFileInfo->fileSize = SMESH_File( theFileName ).size();
 
   return ConvertDriverMEDReadStatus(status);
 }
@@ -1564,7 +1547,7 @@ SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
 
   // Update Python script
   pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
-         << ".CutListOfGroups( " << theMainGroups
+         << ".CutListOfGroups( " << theMainGroups << ", "
          << theToolGroups << ", '" << theName << "' )";
 
   SMESH_CATCH( SMESH::throwCorbaException );
@@ -1709,6 +1692,9 @@ void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
     groupData._indices.insert( ids[i] );
   // SMESH object
   groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
+  // shape index in SMESHDS
+  // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
+  // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
 }
 
 //================================================================================
@@ -1824,13 +1810,12 @@ void SMESH_Mesh_i::CheckGeomModif()
   GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
   if ( mainGO->_is_nil() ) return;
 
-  if ( mainGO->GetType() == GEOM_GROUP )
+  if ( mainGO->GetType() == GEOM_GROUP ||
+       mainGO->GetTick() == _mainShapeTick )
   {
     CheckGeomGroupModif();
     return;
   }
-  if ( mainGO->GetTick() == _mainShapeTick )
-    return;
 
   GEOM_Client* geomClient = _gen_i->GetShapeReader();
   if ( !geomClient ) return;
@@ -1841,7 +1826,7 @@ void SMESH_Mesh_i::CheckGeomModif()
   geomClient->RemoveShapeFromBuffer( ior.in() );
 
   // Update data taking into account that
-  // all sub-shapes change but IDs of sub-shapes remain
+  // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
 
   _impl->Clear();
   TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
@@ -1879,9 +1864,31 @@ void SMESH_Mesh_i::CheckGeomModif()
   }
 
   // change shape to mesh
+  int oldNbSubShapes = meshDS->MaxShapeIndex();
   _impl->ShapeToMesh( TopoDS_Shape() );
   _impl->ShapeToMesh( newShape );
 
+  // re-add shapes of geom groups
+  list<TGeomGroupData>::iterator data = _geomGroupData.begin();
+  for ( ; data != _geomGroupData.end(); ++data )
+  {
+    TopoDS_Shape newShape = newGroupShape( *data );
+    if ( !newShape.IsNull() )
+    {
+      if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
+      {
+        TopoDS_Compound compound;
+        BRep_Builder().MakeCompound( compound );
+        BRep_Builder().Add( compound, newShape );
+        newShape = compound;
+      }
+      _impl->GetSubMesh( newShape );
+    }
+  }
+  if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
+    THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
+                                  SALOME::INTERNAL_ERROR );
+
   // re-assign hypotheses
   for ( size_t i = 0; i < ids2Hyps.size(); ++i )
   {
@@ -2748,44 +2755,36 @@ CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
 
 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
 {
-  TCollection_AsciiString aFullName ((char*)file);
-  OSD_Path aPath (aFullName);
-  OSD_File aFile (aPath);
-  if (aFile.Exists()) {
+  SMESH_File aFile( file );
+  SMESH_Comment msg;
+  if (aFile.exists()) {
     // existing filesystem node
-    if (aFile.KindOfFile() == OSD_FILE) {
-      if (aFile.IsWriteable()) {
-        if (overwrite) {
-          aFile.Reset();
-          aFile.Remove();
-        }
-        if (aFile.Failed()) {
-          TCollection_AsciiString msg ("File ");
-          msg += aFullName + " cannot be replaced.";
-          THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
+    if ( !aFile.isDirectory() ) {
+      if ( aFile.openForWriting() ) {
+        if ( overwrite && ! aFile.remove()) {
+          msg << "Can't replace " << aFile.getName();
         }
       } else {
-        TCollection_AsciiString msg ("File ");
-        msg += aFullName + " cannot be overwritten.";
-        THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
+        msg << "Can't write into " << aFile.getName();
       }
     } else {
-      TCollection_AsciiString msg ("Location ");
-      msg += aFullName + " is not a file.";
-      THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
+      msg << "Location " << aFile.getName() << " is not a file";
     }
-  } else {
+  }
+  else {
     // nonexisting file; check if it can be created
-    aFile.Reset();
-    aFile.Build(OSD_WriteOnly, OSD_Protection());
-    if (aFile.Failed()) {
-      TCollection_AsciiString msg ("You cannot create the file ");
-      msg += aFullName + ". Check the directory existance and access rights.";
-      THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
-    } else {
-      aFile.Close();
-      aFile.Remove();
+    if ( !aFile.openForWriting() ) {
+      msg << "You cannot create the file "
+          << aFile.getName()
+          << ". Check the directory existance and access rights";
     }
+    aFile.remove();
+  }
+
+  if ( !msg.empty() )
+  {
+    msg << ".";
+    THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
   }
 }
 
@@ -3046,7 +3045,7 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
   {
     aMeshName = prepareMeshNameAndGroups(file, overwrite);
     _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
-                      version, 0, autoDimension, have0dField);
+                      version, 0, autoDimension, /*addODOnVertices=*/have0dField);
     meshDS = _impl->GetMeshDS();
   }
   else
@@ -3066,7 +3065,7 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
     }
     SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
     _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
-                      version, partDS, autoDimension, have0dField);
+                      version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
     meshDS = tmpDSDeleter._obj = partDS;
   }
 
@@ -3152,7 +3151,7 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field&        fieldWriter,
                            name.in(),
                            elemType,
                            comps->length(),
-                           ( dataType == GEOM::FDT_Int )))
+                           /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
       continue;
 
     for ( size_t iC = 0; iC < comps->length(); ++iC )
@@ -3239,9 +3238,9 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field&        fieldWriter,
           const SMDS_MeshElement* e = elemIt->next();
           const int shapeID = e->getshapeId();
           if ( shapeID < 1 || shapeID >= intVals.size() )
-            fieldWriter.AddValue( noneIntValue );
+            fieldWriter.AddValue( (double) noneIntValue );
           else
-            fieldWriter.AddValue( intVals[ shapeID ]);
+            fieldWriter.AddValue( (double) intVals[ shapeID ]);
         }
 
       // write a step
@@ -3279,17 +3278,17 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field&        fieldWriter,
     std::vector< std::string > compNames;
     switch ( geomAssocFields[ iF ]) {
     case 'v': case 'V':
-      fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/true );
+      fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
       compNames.push_back( "dim" );
       break;
     case 'e': case 'E':
-      fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/true );
+      fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
       break;
     case 'f': case 'F':
-      fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/true );
+      fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
       break;
     case 's': case 'S':
-      fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/true );
+      fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
       break;
     default: continue;
     }
@@ -3310,14 +3309,14 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field&        fieldWriter,
         const int shapeID = e->getshapeId();
         if ( shapeID < 1 )
         {
-          fieldWriter.AddValue( -1 );
-          fieldWriter.AddValue( -1 );
+          fieldWriter.AddValue( (double) -1 );
+          fieldWriter.AddValue( (double) -1 );
         }
         else
         {
           const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
-          fieldWriter.AddValue( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]);
-          fieldWriter.AddValue( shapeID );
+          fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
+          fieldWriter.AddValue( (double) shapeID );
         }
       }
     else
@@ -3326,9 +3325,9 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field&        fieldWriter,
         const SMDS_MeshElement* e = elemIt->next();
         const int shapeID = e->getshapeId();
         if ( shapeID < 1 )
-          fieldWriter.AddValue( -1 );
+          fieldWriter.AddValue( (double) -1 );
         else
-          fieldWriter.AddValue( shapeID );
+          fieldWriter.AddValue( (double) shapeID );
       }
 
     // write a step
@@ -4139,17 +4138,11 @@ SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
 
   // find inverse elements
   SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
-  TColStd_SequenceOfInteger IDs;
-  while(eIt->more()) {
+  aResult->length( aNode->NbInverseElements() );  
+  for( int i = 0; eIt->more(); ++i )
+  {
     const SMDS_MeshElement* elem = eIt->next();
-    IDs.Append(elem->GetID());
-  }
-  if(IDs.Length()>0) {
-    aResult->length(IDs.Length());
-    int i = 1;
-    for(; i<=IDs.Length(); i++) {
-      aResult[i-1] = IDs.Value(i);
-    }
+    aResult[ i ] = elem->GetID();
   }
   return aResult._retn();
 }
@@ -5730,6 +5723,8 @@ TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
   {
     const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
     TListOfInt subMeshIds;
+    if ( i > 0 )
+      aPythonDump << ", ";
     aPythonDump << "[ ";
     // Collect subMeshes which should be clear
     //  do it list-by-list, because modification of submesh order