Salome HOME
Merge from BR_WIN_INDUS_514 04/10/2010
[modules/smesh.git] / src / SMESH_I / SMESH_Mesh_i.cxx
index 9c44e29d2e49609bd17c86cd05acf714e4f73258..bb8c8b4971c2b3dd79466ff4a500ca73d7717dd2 100644 (file)
@@ -1,4 +1,4 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//  Copyright (C) 2007-2010  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
@@ -23,7 +23,7 @@
 //  File   : SMESH_Mesh_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//
+
 #include "SMESH_Mesh_i.hxx"
 
 #include "SMESH_Filter_i.hxx"
@@ -89,7 +89,9 @@ using SMESH::TPythonDump;
 
 int SMESH_Mesh_i::myIdGenerator = 0;
 
-
+//To disable automatic genericobj management, the following line should be commented.
+//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+#define WITHGENERICOBJ
 
 //=============================================================================
 /*!
@@ -118,17 +120,48 @@ SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
 SMESH_Mesh_i::~SMESH_Mesh_i()
 {
   INFOS("~SMESH_Mesh_i");
-  map<int, SMESH::SMESH_GroupBase_ptr>::iterator it;
-  for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) {
-    SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( it->second ).in() );
-    if ( aGroup ) {
-      // this method is colled from destructor of group (PAL6331)
+
+#ifdef WITHGENERICOBJ
+  // destroy groups
+  map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
+  for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) {
+    if ( CORBA::is_nil( itGr->second ))
+      continue;
+    SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>(SMESH_Gen_i::GetServant(itGr->second).in());
+    if (aGroup) {
+      // this method is called from destructor of group (PAL6331)
       //_impl->RemoveGroup( aGroup->GetLocalID() );
-      
+      aGroup->myMeshServant = 0;
       aGroup->Destroy();
     }
   }
   _mapGroups.clear();
+
+  // destroy submeshes
+  map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
+  for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) {
+    if ( CORBA::is_nil( itSM->second ))
+      continue;
+    SMESH_subMesh_i* aSubMesh = dynamic_cast<SMESH_subMesh_i*>(SMESH_Gen_i::GetServant(itSM->second).in());
+    if (aSubMesh) {
+      aSubMesh->Destroy();
+    }
+  }
+  _mapSubMeshIor.clear();
+
+  // destroy hypotheses
+  map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
+  for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
+    if ( CORBA::is_nil( itH->second ))
+      continue;
+    SMESH_Hypothesis_i* aHypo = dynamic_cast<SMESH_Hypothesis_i*>(SMESH_Gen_i::GetServant(itH->second).in());
+    if (aHypo) {
+      aHypo->Destroy();
+    }
+  }
+  _mapHypo.clear();
+#endif
+
   delete _impl;
 }
 
@@ -473,6 +506,9 @@ SMESH_Hypothesis::Hypothesis_Status
     status = _impl->AddHypothesis(myLocSubShape, hypId);
     if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
       _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
+#ifdef WITHGENERICOBJ
+      _mapHypo[hypId]->Register();
+#endif
       // assure there is a corresponding submesh
       if ( !_impl->IsMainShape( myLocSubShape )) {
         int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
@@ -624,6 +660,9 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShap
     //Get or Create the SMESH_subMesh object implementation
 
     int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
+    if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
+      THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
+
     subMesh = getSubMesh( subMeshId );
 
     // create a new subMesh object servant if there is none for the shape
@@ -697,6 +736,7 @@ inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType
     CASE2STRING( EDGE );
     CASE2STRING( FACE );
     CASE2STRING( VOLUME );
+    CASE2STRING( ELEM0D );
   default:;
   }
   return "";
@@ -1860,7 +1900,6 @@ void SMESH_Mesh_i::CheckGeomGroupModif()
 //=============================================================================
 /*!
  * \brief Create standalone group instead if group on geometry
- * 
  */
 //=============================================================================
 
@@ -1917,8 +1956,8 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGe
   _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
 
   // register CORBA object for persistence
-  //int nextId = _gen_i->RegisterObject( aGroup );
-  //if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
+  /*int nextId =*/ _gen_i->RegisterObject( aGroup );
+
   builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
 
   return aGroup._retn();
@@ -2229,6 +2268,19 @@ SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
   return aMesh._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Return true if the mesh has been edited since a last total re-compute
+ *        and those modifications may prevent successful partial re-compute
+ */
+//================================================================================
+
+CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->HasModificationsToDiscard();
+}
+
 //=============================================================================
 /*!
  *
@@ -2347,7 +2399,7 @@ void SMESH_Mesh_i::ExportToMEDX (const char* file,
   // check names of groups
   checkGroupNames();
 
-  TPythonDump() << _this() << ".ExportToMEDX( '"
+  TPythonDump() << _this() << ".ExportToMEDX( r'"
                 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
 
   _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
@@ -2376,7 +2428,7 @@ void SMESH_Mesh_i::ExportDAT (const char *file)
   // Update Python script
   // check names of groups
   checkGroupNames();
-  TPythonDump() << _this() << ".ExportDAT( '" << file << "' )";
+  TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
 
   // Perform Export
   PrepareForWriting(file);
@@ -2391,7 +2443,7 @@ void SMESH_Mesh_i::ExportUNV (const char *file)
   // Update Python script
   // check names of groups
   checkGroupNames();
-  TPythonDump() << _this() << ".ExportUNV( '" << file << "' )";
+  TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
 
   // Perform Export
   PrepareForWriting(file);
@@ -2406,7 +2458,7 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
   // Update Python script
   // check names of groups
   checkGroupNames();
-  TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )";
+  TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
 
   // Perform Export
   PrepareForWriting(file);
@@ -2755,6 +2807,21 @@ SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const boo
   return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
 }
 
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
+  throw (SALOME::SALOME_Exception)
+{
+  const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
+  if ( !e )
+    THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
+
+  return ( SMESH::EntityType ) e->GetEntityType();
+}
 
 //=============================================================================
 /*!
@@ -3180,6 +3247,57 @@ CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
   return elem->NbFaces();
 }
 
+//=======================================================================
+//function : GetElemFaceNodes
+//purpose  : Returns nodes of given face (counted from zero) for given element.
+//=======================================================================
+
+SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long  elemId,
+                                                  CORBA::Short faceIndex)
+{
+  SMESH::long_array_var aResult = new SMESH::long_array();
+  if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
+  {
+    if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
+    {
+      SMDS_VolumeTool vtool( elem );
+      if ( faceIndex < vtool.NbFaces() )
+      {
+        aResult->length( vtool.NbFaceNodes( faceIndex ));
+        const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
+        for ( int i = 0; i < aResult->length(); ++i )
+          aResult[ i ] = nn[ i ]->GetID();
+      }
+    }
+  }
+  return aResult._retn();
+}
+
+//=======================================================================
+//function : FindElementByNodes
+//purpose  : Returns an element based on all given nodes.
+//=======================================================================
+
+CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
+{
+  CORBA::Long elemID(0);
+  if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
+  {
+    vector< const SMDS_MeshNode * > nn( nodes.length() );
+    for ( int i = 0; i < nodes.length(); ++i )
+      if ( !( nn[i] = mesh->FindNode( nodes[i] )))
+        return elemID;
+
+    const SMDS_MeshElement* elem = mesh->FindElement( nn );
+    if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
+                    _impl->NbFaces( ORDER_QUADRATIC ) ||
+                    _impl->NbVolumes( ORDER_QUADRATIC )))
+      elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
+
+    if ( elem ) elemID = CORBA::Long( elem->GetID() );
+  }
+  return elemID;
+}
 
 //=============================================================================
 /*!
@@ -3439,6 +3557,30 @@ SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
   return aResult._retn();
 }
 
+//=======================================================================
+//function : GetTypes
+//purpose  : Returns types of elements it contains
+//=======================================================================
+
+SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
+{
+  SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
+
+  types->length( 4 );
+  int nbTypes = 0;
+  if (_impl->NbEdges())
+    types[nbTypes++] = SMESH::EDGE;
+  if (_impl->NbFaces())
+    types[nbTypes++] = SMESH::FACE;
+  if (_impl->NbVolumes())
+    types[nbTypes++] = SMESH::VOLUME;
+  if (_impl->Nb0DElements())
+    types[nbTypes++] = SMESH::ELEM0D;
+  types->length( nbTypes );
+
+  return types._retn();
+}
+
 //=============================================================================
 /*!
  * \brief Returns statistic of mesh elements