Back to index

salome-smesh  6.5.0
SMESH_Mesh_i.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 //  File   : SMESH_Mesh_i.cxx
00023 //  Author : Paul RASCLE, EDF
00024 //  Module : SMESH
00025 
00026 #include "SMESH_Mesh_i.hxx"
00027 
00028 #include "DriverMED_R_SMESHDS_Mesh.h"
00029 #include "DriverMED_W_SMESHDS_Mesh.h"
00030 #include "SMDS_EdgePosition.hxx"
00031 #include "SMDS_ElemIterator.hxx"
00032 #include "SMDS_FacePosition.hxx"
00033 #include "SMDS_IteratorOnIterators.hxx"
00034 #include "SMDS_SetIterator.hxx"
00035 #include "SMDS_VolumeTool.hxx"
00036 #include "SMESHDS_Command.hxx"
00037 #include "SMESHDS_CommandType.hxx"
00038 #include "SMESHDS_GroupOnGeom.hxx"
00039 #include "SMESH_Filter_i.hxx"
00040 #include "SMESH_Gen_i.hxx"
00041 #include "SMESH_Group.hxx"
00042 #include "SMESH_Group_i.hxx"
00043 #include "SMESH_MEDMesh_i.hxx"
00044 #include "SMESH_MeshEditor.hxx"
00045 #include "SMESH_MeshEditor_i.hxx"
00046 #include "SMESH_MesherHelper.hxx"
00047 #include "SMESH_PreMeshInfo.hxx"
00048 #include "SMESH_PythonDump.hxx"
00049 #include "SMESH_subMesh_i.hxx"
00050 
00051 #include <OpUtil.hxx>
00052 #include <SALOME_NamingService.hxx>
00053 #include <Utils_CorbaException.hxx>
00054 #include <Utils_ExceptHandlers.hxx>
00055 #include <Utils_SINGLETON.hxx>
00056 #include <utilities.h>
00057 #include <GEOMImpl_Types.hxx>
00058 
00059 // OCCT Includes
00060 #include <BRep_Builder.hxx>
00061 #include <OSD_Directory.hxx>
00062 #include <OSD_File.hxx>
00063 #include <OSD_Path.hxx>
00064 #include <OSD_Protection.hxx>
00065 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
00066 #include <TColStd_MapOfInteger.hxx>
00067 #include <TColStd_SequenceOfInteger.hxx>
00068 #include <TCollection_AsciiString.hxx>
00069 #include <TopExp.hxx>
00070 #include <TopExp_Explorer.hxx>
00071 #include <TopoDS_Compound.hxx>
00072 #include <TopTools_MapOfShape.hxx>
00073 #include <TopTools_MapIteratorOfMapOfShape.hxx>
00074 
00075 // STL Includes
00076 #include <algorithm>
00077 #include <string>
00078 #include <iostream>
00079 #include <sstream>
00080 #include <sys/stat.h>
00081 
00082 #ifdef _DEBUG_
00083 static int MYDEBUG = 0;
00084 #else
00085 static int MYDEBUG = 0;
00086 #endif
00087 
00088 using namespace std;
00089 using SMESH::TPythonDump;
00090 
00091 int SMESH_Mesh_i::_idGenerator = 0;
00092 
00093 //To disable automatic genericobj management, the following line should be commented.
00094 //Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
00095 #define WITHGENERICOBJ
00096 
00097 //=============================================================================
00101 //=============================================================================
00102 
00103 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
00104                             SMESH_Gen_i*            gen_i,
00105                             CORBA::Long studyId )
00106 : SALOME::GenericObj_i( thePOA )
00107 {
00108   MESSAGE("SMESH_Mesh_i");
00109   _impl = NULL;
00110   _gen_i = gen_i;
00111   _id = _idGenerator++;
00112   _studyId = studyId;
00113   _preMeshInfo = NULL;
00114 }
00115 
00116 //=============================================================================
00120 //=============================================================================
00121 
00122 SMESH_Mesh_i::~SMESH_Mesh_i()
00123 {
00124   MESSAGE("~SMESH_Mesh_i");
00125 
00126 #ifdef WITHGENERICOBJ
00127   // destroy groups
00128   map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
00129   for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) {
00130     if ( CORBA::is_nil( itGr->second ))
00131       continue;
00132     SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>(SMESH_Gen_i::GetServant(itGr->second).in());
00133     if (aGroup) {
00134       // this method is called from destructor of group (PAL6331)
00135       //_impl->RemoveGroup( aGroup->GetLocalID() );
00136       aGroup->myMeshServant = 0;
00137       aGroup->UnRegister();
00138     }
00139   }
00140   _mapGroups.clear();
00141 
00142   // destroy submeshes
00143   map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
00144   for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) {
00145     if ( CORBA::is_nil( itSM->second ))
00146       continue;
00147     SMESH_subMesh_i* aSubMesh = dynamic_cast<SMESH_subMesh_i*>(SMESH_Gen_i::GetServant(itSM->second).in());
00148     if (aSubMesh) {
00149       aSubMesh->UnRegister();
00150     }
00151   }
00152   _mapSubMeshIor.clear();
00153 
00154   // destroy hypotheses
00155   map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
00156   for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
00157     if ( CORBA::is_nil( itH->second ))
00158       continue;
00159     SMESH_Hypothesis_i* aHypo = dynamic_cast<SMESH_Hypothesis_i*>(SMESH_Gen_i::GetServant(itH->second).in());
00160     if (aHypo) {
00161       aHypo->UnRegister();
00162     }
00163   }
00164   _mapHypo.clear();
00165 #endif
00166 
00167   delete _impl; _impl = NULL;
00168 
00169   if ( _preMeshInfo ) delete _preMeshInfo; _preMeshInfo = NULL;
00170 }
00171 
00172 //=============================================================================
00180 //=============================================================================
00181 
00182 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
00183     throw (SALOME::SALOME_Exception)
00184 {
00185   Unexpect aCatch(SALOME_SalomeException);
00186   try {
00187     _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
00188   }
00189   catch(SALOME_Exception & S_ex) {
00190     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
00191   }
00192   // to track changes of GEOM groups
00193   addGeomGroupData( theShapeObject, _this() );
00194 }
00195 
00196 //================================================================================
00200 //================================================================================
00201 
00202 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
00203   throw (SALOME::SALOME_Exception)
00204 {
00205   Unexpect aCatch(SALOME_SalomeException);
00206   bool res = false;
00207   try {
00208     res = _impl->HasShapeToMesh();
00209   }
00210   catch(SALOME_Exception & S_ex) {
00211     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
00212   }
00213   return res;
00214 }
00215 
00216 //=======================================================================
00217 //function : GetShapeToMesh
00218 //purpose  :
00219 //=======================================================================
00220 
00221 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
00222   throw (SALOME::SALOME_Exception)
00223 {
00224   Unexpect aCatch(SALOME_SalomeException);
00225   GEOM::GEOM_Object_var aShapeObj;
00226   try {
00227     TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
00228     if ( !S.IsNull() )
00229       aShapeObj = _gen_i->ShapeToGeomObject( S );
00230   }
00231   catch(SALOME_Exception & S_ex) {
00232     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
00233   }
00234   return aShapeObj._retn();
00235 }
00236 
00237 //================================================================================
00241 //================================================================================
00242 
00243 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
00244 {
00245   Unexpect aCatch(SALOME_SalomeException);
00246   return !_preMeshInfo;
00247 }
00248 
00249 //================================================================================
00253 //================================================================================
00254 
00255 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
00256 {
00257   Unexpect aCatch(SALOME_SalomeException);
00258   if ( _preMeshInfo )
00259     _preMeshInfo->FullLoadFromFile();
00260 }
00261 
00262 //================================================================================
00266 //================================================================================
00267 
00268 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
00269 {
00270   Unexpect aCatch(SALOME_SalomeException);
00271   if ( _preMeshInfo )
00272     _preMeshInfo->ForgetAllData();
00273 
00274   try {
00275     _impl->Clear();
00276     CheckGeomGroupModif(); // issue 20145
00277   }
00278   catch(SALOME_Exception & S_ex) {
00279     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
00280   }
00281   TPythonDump() <<  _this() << ".Clear()";
00282 }
00283 
00284 //================================================================================
00288 //================================================================================
00289 
00290 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
00291   throw (SALOME::SALOME_Exception)
00292 {
00293   Unexpect aCatch(SALOME_SalomeException);
00294   if ( _preMeshInfo )
00295     _preMeshInfo->FullLoadFromFile();
00296 
00297   try {
00298     _impl->ClearSubMesh( ShapeID );
00299   }
00300   catch(SALOME_Exception & S_ex) {
00301     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
00302   }
00303 }
00304 
00305 //=============================================================================
00309 //=============================================================================
00310 
00311 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
00312 {
00313   SMESH::DriverMED_ReadStatus res;
00314   switch (theStatus)
00315   {
00316   case DriverMED_R_SMESHDS_Mesh::DRS_OK:
00317     res = SMESH::DRS_OK; break;
00318   case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
00319     res = SMESH::DRS_EMPTY; break;
00320   case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
00321     res = SMESH::DRS_WARN_RENUMBER; break;
00322   case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
00323     res = SMESH::DRS_WARN_SKIP_ELEM; break;
00324   case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
00325   default:
00326     res = SMESH::DRS_FAIL; break;
00327   }
00328   return res;
00329 }
00330 
00331 //=============================================================================
00337 //=============================================================================
00338 
00339 SMESH::DriverMED_ReadStatus
00340 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
00341   throw ( SALOME::SALOME_Exception )
00342 {
00343   Unexpect aCatch(SALOME_SalomeException);
00344   int status;
00345   try {
00346     status = _impl->MEDToMesh( theFileName, theMeshName );
00347   }
00348   catch( SALOME_Exception& S_ex ) {
00349     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
00350   }
00351   catch ( ... ) {
00352     THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
00353   }
00354 
00355   CreateGroupServants();
00356 
00357   int major, minor, release;
00358   if( !MED::getMEDVersion( theFileName, major, minor, release ) )
00359     major = minor = release = -1;
00360   _medFileInfo           = new SALOME_MED::MedFileInfo();
00361   _medFileInfo->fileName = theFileName;
00362   _medFileInfo->fileSize = 0;
00363 #ifdef WIN32
00364   struct _stati64 d;
00365   if ( ::_stati64( theFileName, &d ) != -1 )
00366 #else
00367   struct stat64 d;
00368   if ( ::stat64( theFileName, &d ) != -1 )
00369 #endif
00370     _medFileInfo->fileSize = d.st_size;
00371   _medFileInfo->major    = major;
00372   _medFileInfo->minor    = minor;
00373   _medFileInfo->release  = release;
00374 
00375   return ConvertDriverMEDReadStatus(status);
00376 }
00377 
00378 //================================================================================
00382 //================================================================================
00383 
00384 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char*  theFileName,
00385                                                           const int    theMeshIndex,
00386                                                           std::string& theMeshName )
00387   throw ( SALOME::SALOME_Exception )
00388 {
00389   Unexpect aCatch(SALOME_SalomeException);
00390   int status;
00391   try {
00392     status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
00393   }
00394   catch( SALOME_Exception& S_ex ) {
00395     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
00396   }
00397   catch ( ... ) {
00398     THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
00399   }
00400 
00401   CreateGroupServants();
00402 
00403   return ConvertDriverMEDReadStatus(status);
00404 }
00405 
00406 //================================================================================
00410 //================================================================================
00411 
00412 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
00413 {
00414   string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
00415                                                                nbDigits);
00416   return CORBA::string_dup( ver.c_str() );
00417 }
00418 
00419 //=============================================================================
00425 //=============================================================================
00426 
00427 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
00428   throw ( SALOME::SALOME_Exception )
00429 {
00430   // Read mesh with name = <theMeshName> into SMESH_Mesh
00431   _impl->UNVToMesh( theFileName );
00432 
00433   CreateGroupServants();
00434 
00435   return 1;
00436 }
00437 
00438 //=============================================================================
00444 //=============================================================================
00445 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
00446   throw ( SALOME::SALOME_Exception )
00447 {
00448   // Read mesh with name = <theMeshName> into SMESH_Mesh
00449   _impl->STLToMesh( theFileName );
00450 
00451   return 1;
00452 }
00453 
00454 //=============================================================================
00458 //=============================================================================
00459 
00460 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
00461 
00462 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
00463                          (SMESH_Hypothesis::Hypothesis_Status theStatus)
00464 {
00465   switch (theStatus) {
00466   RETURNCASE( HYP_OK            );
00467   RETURNCASE( HYP_MISSING       );
00468   RETURNCASE( HYP_CONCURENT     );
00469   RETURNCASE( HYP_BAD_PARAMETER );
00470   RETURNCASE( HYP_HIDDEN_ALGO   );
00471   RETURNCASE( HYP_HIDING_ALGO   );
00472   RETURNCASE( HYP_UNKNOWN_FATAL );
00473   RETURNCASE( HYP_INCOMPATIBLE  );
00474   RETURNCASE( HYP_NOTCONFORM    );
00475   RETURNCASE( HYP_ALREADY_EXIST );
00476   RETURNCASE( HYP_BAD_DIM       );
00477   RETURNCASE( HYP_BAD_SUBSHAPE  );
00478   RETURNCASE( HYP_BAD_GEOMETRY  );
00479   RETURNCASE( HYP_NEED_SHAPE    );
00480   default:;
00481   }
00482   return SMESH::HYP_UNKNOWN_FATAL;
00483 }
00484 
00485 //=============================================================================
00493 //=============================================================================
00494 
00495 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr       aSubShapeObject,
00496                                                      SMESH::SMESH_Hypothesis_ptr anHyp)
00497   throw(SALOME::SALOME_Exception)
00498 {
00499   Unexpect aCatch(SALOME_SalomeException);
00500   if ( _preMeshInfo )
00501     _preMeshInfo->ForgetOrLoad();
00502 
00503   SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
00504 
00505   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
00506     _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
00507                                  aSubShapeObject, anHyp );
00508 
00509   if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
00510 
00511   // Update Python script
00512   if(_impl->HasShapeToMesh()) {
00513     TPythonDump() << "status = " << _this() << ".AddHypothesis( "
00514                   << aSubShapeObject << ", " << anHyp << " )";
00515   }
00516   else {
00517     TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
00518   }
00519   
00520   return ConvertHypothesisStatus(status);
00521 }
00522 
00523 //=============================================================================
00527 //=============================================================================
00528 
00529 SMESH_Hypothesis::Hypothesis_Status
00530   SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr       aSubShapeObject,
00531                               SMESH::SMESH_Hypothesis_ptr anHyp)
00532 {
00533   if(MYDEBUG) MESSAGE("addHypothesis");
00534 
00535   if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
00536     THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
00537                                  SALOME::BAD_PARAM);
00538 
00539   SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
00540   if (CORBA::is_nil(myHyp))
00541     THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
00542                                  SALOME::BAD_PARAM);
00543 
00544   SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
00545   try
00546   {
00547     TopoDS_Shape myLocSubShape;
00548     //use PseudoShape in case if mesh has no shape
00549     if(HasShapeToMesh())
00550       myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
00551     else              
00552       myLocSubShape = _impl->GetShapeToMesh();
00553     
00554     int hypId = myHyp->GetId();
00555     status = _impl->AddHypothesis(myLocSubShape, hypId);
00556     if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
00557       _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
00558 #ifdef WITHGENERICOBJ
00559       _mapHypo[hypId]->Register();
00560 #endif
00561       // assure there is a corresponding submesh
00562       if ( !_impl->IsMainShape( myLocSubShape )) {
00563         int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
00564         if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
00565           createSubMesh( aSubShapeObject );
00566       }
00567     }
00568   }
00569   catch(SALOME_Exception & S_ex)
00570   {
00571     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
00572   }
00573   return status;
00574 }
00575 
00576 //=============================================================================
00580 //=============================================================================
00581 
00582 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
00583                                                         SMESH::SMESH_Hypothesis_ptr anHyp)
00584      throw(SALOME::SALOME_Exception)
00585 {
00586   Unexpect aCatch(SALOME_SalomeException);
00587   if ( _preMeshInfo )
00588     _preMeshInfo->ForgetOrLoad();
00589 
00590   SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
00591 
00592   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
00593     _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
00594                                       aSubShapeObject, anHyp );
00595 
00596   // Update Python script
00597     // Update Python script
00598   if(_impl->HasShapeToMesh()) {
00599   TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
00600                 << aSubShapeObject << ", " << anHyp << " )";
00601   }
00602   else {
00603     TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
00604                   << anHyp << " )";
00605   }
00606 
00607   return ConvertHypothesisStatus(status);
00608 }
00609 
00610 //=============================================================================
00614 //=============================================================================
00615 
00616 SMESH_Hypothesis::Hypothesis_Status
00617 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr       aSubShapeObject,
00618                                SMESH::SMESH_Hypothesis_ptr anHyp)
00619 {
00620   if(MYDEBUG) MESSAGE("removeHypothesis()");
00621   // **** proposer liste de sub-shape (selection multiple)
00622 
00623   if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
00624     THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
00625 
00626   SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
00627   if (CORBA::is_nil(myHyp))
00628     THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
00629 
00630   SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
00631   try
00632   {
00633     TopoDS_Shape myLocSubShape;
00634     //use PseudoShape in case if mesh has no shape
00635     if(HasShapeToMesh())
00636       myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
00637     else
00638       myLocSubShape = _impl->GetShapeToMesh();
00639 
00640     int hypId = myHyp->GetId();
00641     status = _impl->RemoveHypothesis(myLocSubShape, hypId);
00642 //     if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many sub-shapes
00643 //       _mapHypo.erase( hypId );
00644   }
00645   catch(SALOME_Exception & S_ex)
00646   {
00647     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
00648   }
00649   return status;
00650 }
00651 
00652 //=============================================================================
00656 //=============================================================================
00657 
00658 SMESH::ListOfHypothesis *
00659         SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
00660 throw(SALOME::SALOME_Exception)
00661 {
00662   Unexpect aCatch(SALOME_SalomeException);
00663   if (MYDEBUG) MESSAGE("GetHypothesisList");
00664   if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
00665     THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
00666 
00667   SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
00668 
00669   try {
00670     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
00671     if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
00672       myLocSubShape = _impl->GetShapeToMesh();
00673     const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
00674     int i = 0, n = aLocalList.size();
00675     aList->length( n );
00676 
00677     for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
00678       SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
00679       if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
00680         aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
00681     }
00682 
00683     aList->length( i );
00684   }
00685   catch(SALOME_Exception & S_ex) {
00686     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
00687   }
00688 
00689   return aList._retn();
00690 }
00691 
00692 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
00693 {
00694   Unexpect aCatch(SALOME_SalomeException);
00695   if (MYDEBUG) MESSAGE("GetSubMeshes");
00696 
00697   SMESH::submesh_array_var aList = new SMESH::submesh_array();
00698 
00699   // Python Dump
00700   TPythonDump aPythonDump;
00701   if ( !_mapSubMeshIor.empty() )
00702     aPythonDump << "[ ";
00703 
00704   try {
00705     aList->length( _mapSubMeshIor.size() );
00706     int i = 0;
00707     map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
00708     for ( ; it != _mapSubMeshIor.end(); it++ ) {
00709       if ( CORBA::is_nil( it->second )) continue;
00710       aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
00711       // Python Dump
00712       if (i > 1) aPythonDump << ", ";
00713       aPythonDump << it->second;
00714     }
00715     aList->length( i );
00716   }
00717   catch(SALOME_Exception & S_ex) {
00718     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
00719   }
00720 
00721   // Update Python script
00722   if ( !_mapSubMeshIor.empty() )
00723     aPythonDump << " ] = " << _this() << ".GetSubMeshes()";
00724 
00725   return aList._retn();
00726 }
00727 
00728 //=============================================================================
00732 //=============================================================================
00733 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
00734                                                   const char*           theName )
00735      throw(SALOME::SALOME_Exception)
00736 {
00737   Unexpect aCatch(SALOME_SalomeException);
00738   MESSAGE("SMESH_Mesh_i::GetSubMesh");
00739   if (CORBA::is_nil(aSubShapeObject))
00740     THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
00741                                  SALOME::BAD_PARAM);
00742 
00743   SMESH::SMESH_subMesh_var subMesh;
00744   SMESH::SMESH_Mesh_var    aMesh = SMESH::SMESH_Mesh::_narrow(_this());
00745   try {
00746     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
00747 
00748     //Get or Create the SMESH_subMesh object implementation
00749 
00750     int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
00751 
00752     if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
00753     {
00754       TopoDS_Iterator it( myLocSubShape );
00755       if ( it.More() )
00756         THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
00757     }
00758     subMesh = getSubMesh( subMeshId );
00759 
00760     // create a new subMesh object servant if there is none for the shape
00761     if ( subMesh->_is_nil() )
00762       subMesh = createSubMesh( aSubShapeObject );
00763     if ( _gen_i->CanPublishInStudy( subMesh )) {
00764       SALOMEDS::SObject_var aSO =
00765         _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
00766                                subMesh, aSubShapeObject, theName );
00767       if ( !aSO->_is_nil()) {
00768         // Update Python script
00769         TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
00770                       << aSubShapeObject << ", '" << theName << "' )";
00771       }
00772     }
00773   }
00774   catch(SALOME_Exception & S_ex) {
00775     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
00776   }
00777   return subMesh._retn();
00778 }
00779 
00780 //=============================================================================
00784 //=============================================================================
00785 
00786 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
00787      throw (SALOME::SALOME_Exception)
00788 {
00789   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
00790   if ( theSubMesh->_is_nil() )
00791     return;
00792 
00793   GEOM::GEOM_Object_var aSubShapeObject;
00794   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
00795   if ( !aStudy->_is_nil() )  {
00796     // Remove submesh's SObject
00797     SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
00798     if ( !anSO->_is_nil() ) {
00799       long aTag = SMESH_Gen_i::GetRefOnShapeTag();
00800       SALOMEDS::SObject_var anObj, aRef;
00801       if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
00802         aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
00803 
00804 //       if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
00805 //         aSubShapeObject = theSubMesh->GetSubShape();
00806 
00807       aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
00808 
00809       // Update Python script
00810       TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
00811     }
00812   }
00813 
00814   if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
00815     if ( _preMeshInfo )
00816       _preMeshInfo->ForgetOrLoad();
00817 }
00818 
00819 //=============================================================================
00823 //=============================================================================
00824 
00825 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
00826                                                   const char*        theName )
00827      throw(SALOME::SALOME_Exception)
00828 {
00829   Unexpect aCatch(SALOME_SalomeException);
00830   if ( _preMeshInfo )
00831     _preMeshInfo->FullLoadFromFile();
00832 
00833   SMESH::SMESH_Group_var aNewGroup =
00834     SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
00835 
00836   if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
00837     SALOMEDS::SObject_var aSO =
00838       _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
00839                            aNewGroup, GEOM::GEOM_Object::_nil(), theName);
00840     if ( !aSO->_is_nil()) {
00841       // Update Python script
00842       TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
00843                     << theElemType << ", '" << theName << "' )";
00844     }
00845   }
00846   return aNewGroup._retn();
00847 }
00848 
00849 
00850 //=============================================================================
00854 //=============================================================================
00855 SMESH::SMESH_GroupOnGeom_ptr
00856 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType    theElemType,
00857                                    const char*           theName,
00858                                    GEOM::GEOM_Object_ptr theGeomObj)
00859      throw(SALOME::SALOME_Exception)
00860 {
00861   Unexpect aCatch(SALOME_SalomeException);
00862   if ( _preMeshInfo )
00863     _preMeshInfo->FullLoadFromFile();
00864 
00865   SMESH::SMESH_GroupOnGeom_var aNewGroup;
00866 
00867   TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
00868   if ( !aShape.IsNull() )
00869   {
00870     aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
00871       ( createGroup( theElemType, theName, aShape ));
00872 
00873     if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
00874       SALOMEDS::SObject_var aSO =
00875         _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
00876                              aNewGroup, theGeomObj, theName);
00877       if ( !aSO->_is_nil()) {
00878         // Update Python script
00879         TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
00880                       << theElemType << ", '" << theName << "', " << theGeomObj << " )";
00881       }
00882     }
00883   }
00884 
00885   return aNewGroup._retn();
00886 }
00887 
00888 //================================================================================
00896 //================================================================================
00897 
00898 SMESH::SMESH_GroupOnFilter_ptr
00899 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
00900                                     const char*        theName,
00901                                     SMESH::Filter_ptr  theFilter )
00902     throw (SALOME::SALOME_Exception)
00903 {
00904   Unexpect aCatch(SALOME_SalomeException);
00905   if ( _preMeshInfo )
00906     _preMeshInfo->FullLoadFromFile();
00907 
00908   if ( CORBA::is_nil( theFilter ))
00909     THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
00910 
00911   SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
00912   if ( !predicate )
00913     THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
00914 
00915   SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
00916     ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
00917 
00918   TPythonDump pd;
00919   if ( !aNewGroup->_is_nil() )
00920     aNewGroup->SetFilter( theFilter );
00921 
00922   if ( _gen_i->CanPublishInStudy( aNewGroup ) )
00923   {
00924     SALOMEDS::SObject_var aSO =
00925       _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
00926                            GEOM::GEOM_Object::_nil(), theName);
00927     if ( !aSO->_is_nil()) {
00928       // Update Python script
00929       pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
00930          << theElemType << ", '" << theName << "', " << theFilter << " )";
00931     }
00932   }
00933 
00934   return aNewGroup._retn();
00935 }
00936 
00937 //=============================================================================
00941 //=============================================================================
00942 
00943 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
00944      throw (SALOME::SALOME_Exception)
00945 {
00946   if ( theGroup->_is_nil() )
00947     return;
00948 
00949   SMESH_GroupBase_i* aGroup =
00950     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
00951   if ( !aGroup )
00952     return;
00953 
00954   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
00955   if ( !aStudy->_is_nil() )  {
00956     SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
00957 
00958     if ( !aGroupSO->_is_nil() ) {
00959       // Update Python script
00960       TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
00961 
00962       // Remove group's SObject
00963       aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
00964     }
00965   }
00966 
00967   // Remove the group from SMESH data structures
00968   removeGroup( aGroup->GetLocalID() );
00969 }
00970 
00971 //=============================================================================
00975 //=============================================================================
00976 
00977 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
00978   throw (SALOME::SALOME_Exception)
00979 {
00980   if ( _preMeshInfo )
00981     _preMeshInfo->FullLoadFromFile();
00982 
00983   if ( theGroup->_is_nil() )
00984     return;
00985 
00986   SMESH_GroupBase_i* aGroup =
00987     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
00988   if ( !aGroup )
00989     return;
00990 
00991   SMESH::long_array_var anIds = aGroup->GetListOfID();
00992   SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
00993 
00994   TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
00995 
00996   // Remove contents
00997   if ( aGroup->GetType() == SMESH::NODE )
00998     aMeshEditor->RemoveNodes( anIds );
00999   else
01000     aMeshEditor->RemoveElements( anIds );
01001 
01002   // Remove group
01003   RemoveGroup( theGroup );
01004 
01005   // Update Python script
01006   pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
01007 }
01008 
01009 //================================================================================
01014 //================================================================================
01015 
01016 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
01017 {
01018   Unexpect aCatch(SALOME_SalomeException);
01019   if (MYDEBUG) MESSAGE("GetGroups");
01020 
01021   SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
01022 
01023   // Python Dump
01024   TPythonDump aPythonDump;
01025   if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
01026     aPythonDump << "[ ";
01027 
01028   try {
01029     aList->length( _mapGroups.size() );
01030     int i = 0;
01031     map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
01032     for ( ; it != _mapGroups.end(); it++ ) {
01033       if ( CORBA::is_nil( it->second )) continue;
01034       aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
01035       // Python Dump
01036       if (i > 1) aPythonDump << ", ";
01037       aPythonDump << it->second;
01038     }
01039     aList->length( i );
01040   }
01041   catch(SALOME_Exception & S_ex) {
01042     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
01043   }
01044 
01045   // Update Python script
01046   if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
01047     aPythonDump << " ] = " << _this() << ".GetGroups()";
01048 
01049   return aList._retn();
01050 }
01051 
01052 //=============================================================================
01056 //=============================================================================
01057 
01058 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
01059 {
01060   Unexpect aCatch(SALOME_SalomeException);
01061   return _mapGroups.size();
01062 }
01063 
01064 //=============================================================================
01069 //=============================================================================
01070 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
01071                                                   SMESH::SMESH_GroupBase_ptr theGroup2,
01072                                                   const char* theName )
01073   throw (SALOME::SALOME_Exception)
01074 {
01075   if ( _preMeshInfo )
01076     _preMeshInfo->FullLoadFromFile();
01077 
01078   try
01079   {
01080     if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
01081          theGroup1->GetType() != theGroup2->GetType() )
01082       return SMESH::SMESH_Group::_nil();
01083 
01084     // Create Union
01085     SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
01086     if ( aResGrp->_is_nil() )
01087       return SMESH::SMESH_Group::_nil();
01088 
01089     SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
01090     SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
01091 
01092     TColStd_MapOfInteger aResMap;
01093 
01094     for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
01095       aResMap.Add( anIds1[ i1 ] );
01096 
01097     for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
01098       aResMap.Add( anIds2[ i2 ] );
01099 
01100     SMESH::long_array_var aResIds = new SMESH::long_array;
01101     aResIds->length( aResMap.Extent() );
01102 
01103     int resI = 0;
01104     TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
01105     for( ; anIter.More(); anIter.Next() )
01106       aResIds[ resI++ ] = anIter.Key();
01107 
01108     aResGrp->Add( aResIds );
01109 
01110     // Clear python lines, created by CreateGroup() and Add()
01111     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
01112     _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
01113     _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
01114 
01115     // Update Python script
01116     TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
01117                   << theGroup1 << ", " << theGroup2 << ", '"
01118                   << theName << "' )";
01119 
01120     return aResGrp._retn();
01121   }
01122   catch( ... )
01123   {
01124     return SMESH::SMESH_Group::_nil();
01125   }
01126 }
01127 
01128 //=============================================================================
01136 //=============================================================================
01137 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
01138                                                        const char*                theName )
01139 throw (SALOME::SALOME_Exception)
01140 {
01141   if ( _preMeshInfo )
01142     _preMeshInfo->FullLoadFromFile();
01143 
01144   if ( !theName )
01145     return SMESH::SMESH_Group::_nil();
01146 
01147   try
01148   {
01149     vector< int > anIds;
01150     SMESH::ElementType aType = SMESH::ALL;
01151     for ( int g = 0, n = theGroups.length(); g < n; g++ )
01152     {
01153       SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
01154       if ( CORBA::is_nil( aGrp ) )
01155         continue;
01156 
01157       // check type
01158       SMESH::ElementType aCurrType = aGrp->GetType();
01159       if ( aType == SMESH::ALL )
01160         aType = aCurrType;
01161       else 
01162       {
01163         if ( aType != aCurrType )
01164           return SMESH::SMESH_Group::_nil();
01165       }
01166 
01167       // unite ids
01168       SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
01169       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
01170       {
01171         int aCurrId = aCurrIds[ i ];
01172         anIds.push_back( aCurrId );
01173       }
01174     }
01175 
01176     // Create group
01177     SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
01178     if ( aResGrp->_is_nil() )
01179       return SMESH::SMESH_Group::_nil();
01180     
01181     // Create array of identifiers
01182     SMESH::long_array_var aResIds = new SMESH::long_array;
01183     aResIds->length( anIds.size() );
01184     
01185     //NCollection_Map< int >::Iterator anIter( anIds );
01186     for ( int i = 0; i<anIds.size(); i++ )
01187     {
01188       aResIds[ i ] = anIds[i];
01189     }
01190     aResGrp->Add( aResIds );
01191 
01192     // Clear python lines, created by CreateGroup() and Add()
01193     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
01194     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
01195     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
01196 
01197     // Update Python script
01198     
01199     TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
01200                   << &theGroups << ", '" << theName << "' )";
01201 
01202     return aResGrp._retn();
01203   }
01204   catch( ... )
01205   {
01206     return SMESH::SMESH_Group::_nil();
01207   }
01208 }
01209 
01210 //=============================================================================
01215 //=============================================================================
01216 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
01217                                                       SMESH::SMESH_GroupBase_ptr theGroup2,
01218                                                       const char* theName )
01219   throw (SALOME::SALOME_Exception)
01220 {
01221   if ( _preMeshInfo )
01222     _preMeshInfo->FullLoadFromFile();
01223 
01224   if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
01225        theGroup1->GetType() != theGroup2->GetType() )
01226     return SMESH::SMESH_Group::_nil();
01227 
01228   // Create Intersection
01229   SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
01230   if ( aResGrp->_is_nil() )
01231     return aResGrp;
01232 
01233   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
01234   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
01235 
01236   TColStd_MapOfInteger aMap1;
01237 
01238   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
01239     aMap1.Add( anIds1[ i1 ] );
01240 
01241   TColStd_SequenceOfInteger aSeq;
01242 
01243   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
01244     if ( aMap1.Contains( anIds2[ i2 ] ) )
01245       aSeq.Append( anIds2[ i2 ] );
01246 
01247   SMESH::long_array_var aResIds = new SMESH::long_array;
01248   aResIds->length( aSeq.Length() );
01249 
01250   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
01251     aResIds[ resI ] = aSeq( resI + 1 );
01252 
01253   aResGrp->Add( aResIds );
01254 
01255   // Clear python lines, created by CreateGroup() and Add()
01256   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
01257   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
01258   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
01259 
01260   // Update Python script
01261   TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
01262                 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
01263 
01264   return aResGrp._retn();
01265 }
01266 
01267 //=============================================================================
01275 //=============================================================================
01276 SMESH::SMESH_Group_ptr
01277 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
01278                                     const char*                theName )
01279   throw (SALOME::SALOME_Exception)
01280 {
01281   if ( _preMeshInfo )
01282     _preMeshInfo->FullLoadFromFile();
01283 
01284   if ( !theName )
01285     return SMESH::SMESH_Group::_nil();
01286 
01287   try
01288   {
01289     NCollection_DataMap< int, int > anIdToCount;
01290     SMESH::ElementType aType = SMESH::ALL;
01291     for ( int g = 0, n = theGroups.length(); g < n; g++ )
01292     {
01293       SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
01294       if ( CORBA::is_nil( aGrp ) )
01295         continue;
01296 
01297       // check type
01298       SMESH::ElementType aCurrType = aGrp->GetType();
01299       if ( aType == SMESH::ALL )
01300         aType = aCurrType;
01301       else 
01302       {
01303         if ( aType != aCurrType )
01304           return SMESH::SMESH_Group::_nil();
01305       }
01306 
01307       // calculates number of occurance ids in groups
01308       SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
01309       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
01310       {
01311         int aCurrId = aCurrIds[ i ];
01312         if ( !anIdToCount.IsBound( aCurrId ) )
01313           anIdToCount.Bind( aCurrId, 1 );
01314         else 
01315           anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
01316       }
01317     }
01318     
01319     // create map of ids
01320     int nbGrp = theGroups.length();
01321     vector< int > anIds;
01322     NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
01323     for ( ; anIter.More(); anIter.Next() )
01324     {
01325       int aCurrId = anIter.Key();
01326       int aCurrNb = anIter.Value();
01327       if ( aCurrNb == nbGrp )
01328         anIds.push_back( aCurrId );
01329     }
01330 
01331     // Create group
01332     SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
01333     if ( aResGrp->_is_nil() )
01334       return SMESH::SMESH_Group::_nil();
01335     
01336     // Create array of identifiers
01337     SMESH::long_array_var aResIds = new SMESH::long_array;
01338     aResIds->length( anIds.size() );
01339     
01340     //NCollection_Map< int >::Iterator aListIter( anIds );
01341     for ( int i = 0; i<anIds.size(); i++ )
01342     {
01343       aResIds[ i ] = anIds[i];
01344     }
01345     aResGrp->Add( aResIds );
01346 
01347     // Clear python lines, created by CreateGroup() and Add()
01348     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
01349     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
01350     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
01351 
01352     // Update Python script
01353     
01354     TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
01355                   << &theGroups << ", '" << theName << "' )";
01356 
01357     return aResGrp._retn();
01358   }
01359   catch( ... )
01360   {
01361     return SMESH::SMESH_Group::_nil();
01362   }
01363 }
01364 
01365 //=============================================================================
01370 //=============================================================================
01371 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
01372                                                 SMESH::SMESH_GroupBase_ptr theGroup2,
01373                                                 const char*                theName )
01374   throw (SALOME::SALOME_Exception)
01375 {
01376   if ( _preMeshInfo )
01377     _preMeshInfo->FullLoadFromFile();
01378 
01379   if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
01380        theGroup1->GetType() != theGroup2->GetType() )
01381     return SMESH::SMESH_Group::_nil();
01382 
01383   // Perform Cutting
01384   SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
01385   if ( aResGrp->_is_nil() )
01386     return aResGrp;
01387 
01388   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
01389   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
01390 
01391   TColStd_MapOfInteger aMap2;
01392 
01393   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
01394     aMap2.Add( anIds2[ i2 ] );
01395 
01396   TColStd_SequenceOfInteger aSeq;
01397   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
01398     if ( !aMap2.Contains( anIds1[ i1 ] ) )
01399       aSeq.Append( anIds1[ i1 ] );
01400 
01401   SMESH::long_array_var aResIds = new SMESH::long_array;
01402   aResIds->length( aSeq.Length() );
01403 
01404   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
01405     aResIds[ resI ] = aSeq( resI + 1 );
01406 
01407   aResGrp->Add( aResIds );
01408 
01409   // Clear python lines, created by CreateGroup() and Add()
01410   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
01411   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
01412   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
01413 
01414   // Update Python script
01415   TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
01416                 << theGroup1 << ", " << theGroup2 << ", '"
01417                 << theName << "' )";
01418 
01419   return aResGrp._retn();
01420 }
01421 
01422 //=============================================================================
01431 //=============================================================================
01432 SMESH::SMESH_Group_ptr
01433 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups, 
01434                               const SMESH::ListOfGroups& theToolGroups, 
01435                               const char*                theName )
01436   throw (SALOME::SALOME_Exception)
01437 {
01438   if ( _preMeshInfo )
01439     _preMeshInfo->FullLoadFromFile();
01440 
01441   if ( !theName )
01442     return SMESH::SMESH_Group::_nil();
01443 
01444   try
01445   {
01446     set< int > aToolIds;
01447     SMESH::ElementType aType = SMESH::ALL;
01448     int g, n;
01449     // iterate through tool groups
01450     for ( g = 0, n = theToolGroups.length(); g < n; g++ )
01451     {
01452       SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
01453       if ( CORBA::is_nil( aGrp ) )
01454         continue;
01455 
01456       // check type
01457       SMESH::ElementType aCurrType = aGrp->GetType();
01458       if ( aType == SMESH::ALL )
01459         aType = aCurrType;
01460       else 
01461       {
01462         if ( aType != aCurrType )
01463           return SMESH::SMESH_Group::_nil();
01464       }
01465 
01466       // unite tool ids
01467       SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
01468       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
01469       {
01470         int aCurrId = aCurrIds[ i ];
01471         aToolIds.insert( aCurrId );
01472       }
01473     }
01474 
01475     vector< int > anIds; // result
01476 
01477     // Iterate through main group 
01478     for ( g = 0, n = theMainGroups.length(); g < n; g++ )
01479     {
01480       SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
01481       if ( CORBA::is_nil( aGrp ) )
01482         continue;
01483 
01484       // check type
01485       SMESH::ElementType aCurrType = aGrp->GetType();
01486       if ( aType == SMESH::ALL )
01487         aType = aCurrType;
01488       else 
01489       {
01490         if ( aType != aCurrType )
01491           return SMESH::SMESH_Group::_nil();
01492       }
01493 
01494       // unite tool ids
01495       SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
01496       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
01497       {
01498         int aCurrId = aCurrIds[ i ];
01499         if ( !aToolIds.count( aCurrId ) )
01500           anIds.push_back( aCurrId );
01501       }
01502     }
01503 
01504     // Create group
01505     SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
01506     if ( aResGrp->_is_nil() )
01507       return SMESH::SMESH_Group::_nil();
01508     
01509     // Create array of identifiers
01510     SMESH::long_array_var aResIds = new SMESH::long_array;
01511     aResIds->length( anIds.size() );
01512     
01513     for (int i=0; i<anIds.size(); i++ )
01514     {
01515       aResIds[ i ] = anIds[i];
01516     }
01517     aResGrp->Add( aResIds );
01518 
01519     // Clear python lines, created by CreateGroup() and Add()
01520     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
01521     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
01522     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
01523 
01524     // Update Python script
01525 
01526     TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
01527                   << &theMainGroups << ", " << &theToolGroups << ", '"
01528                   << theName << "' )";
01529     
01530     return aResGrp._retn();
01531   }
01532   catch( ... )
01533   {
01534     return SMESH::SMESH_Group::_nil();
01535   }
01536 }
01537 
01538 //=============================================================================
01549 //=============================================================================
01550 SMESH::SMESH_Group_ptr
01551 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, 
01552                              SMESH::ElementType         theElemType, 
01553                              const char*                theName )
01554   throw (SALOME::SALOME_Exception)
01555 {
01556   if ( _preMeshInfo )
01557     _preMeshInfo->FullLoadFromFile();
01558 
01559   SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
01560 
01561   if ( !theName || !aMeshDS )
01562     return SMESH::SMESH_Group::_nil();
01563 
01564   SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
01565 
01566   try
01567   {
01568     // Create map of nodes from all groups 
01569 
01570     set< int > aNodeMap;
01571     
01572     for ( int g = 0, n = theGroups.length(); g < n; g++ )
01573     {
01574       SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
01575       if ( CORBA::is_nil( aGrp ) )
01576         continue;
01577 
01578       SMESH::ElementType aType = aGrp->GetType();
01579       if ( aType == SMESH::ALL )
01580         continue;
01581       else if ( aType == SMESH::NODE )
01582       {
01583         SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
01584         for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
01585         {
01586           int aCurrId = aCurrIds[ i ];
01587           const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
01588           if ( aNode )
01589             aNodeMap.insert( aNode->GetID() );
01590         }
01591       }
01592       else 
01593       {
01594         SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
01595         for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
01596         {
01597           int aCurrId = aCurrIds[ i ];
01598           const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
01599           if ( !anElem )
01600             continue;
01601           SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
01602           while( aNodeIter->more() )
01603           {
01604             const SMDS_MeshNode* aNode = 
01605               dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
01606             if ( aNode )
01607               aNodeMap.insert( aNode->GetID() );
01608           }
01609         }
01610       }
01611     }
01612 
01613     // Get result identifiers 
01614 
01615     vector< int > aResultIds;
01616     if ( theElemType == SMESH::NODE )
01617     {
01618       //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
01619       set<int>::iterator iter = aNodeMap.begin();
01620       for ( ; iter != aNodeMap.end(); iter++ )
01621         aResultIds.push_back( *iter);
01622     }
01623     else
01624     {
01625       // Create list of elements of given dimension constructed on the nodes
01626       vector< int > anElemList;
01627       //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
01628       //for ( ; aNodeIter.More(); aNodeIter.Next() )
01629       set<int>::iterator iter = aNodeMap.begin();
01630       for ( ; iter != aNodeMap.end(); iter++ )
01631       {
01632         const SMDS_MeshElement* aNode = 
01633           dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
01634         if ( !aNode )
01635           continue;
01636 
01637          SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
01638         while( anElemIter->more() )
01639         {
01640           const SMDS_MeshElement* anElem = 
01641             dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
01642           if ( anElem && anElem->GetType() == anElemType )
01643             anElemList.push_back( anElem->GetID() );
01644         }
01645       }
01646 
01647       // check whether all nodes of elements are present in nodes map
01648       for (int i=0; i< anElemList.size(); i++)
01649       {
01650         const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
01651         if ( !anElem )
01652           continue;
01653 
01654         bool isOk = true;
01655         SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
01656         while( aNodeIter->more() )
01657         {
01658           const SMDS_MeshNode* aNode = 
01659             dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
01660           if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
01661           {
01662             isOk = false;
01663             break;
01664           }
01665         } 
01666         if ( isOk )
01667           aResultIds.push_back( anElem->GetID() );
01668       }
01669     }
01670 
01671     // Create group
01672 
01673     SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
01674     if ( aResGrp->_is_nil() )
01675       return SMESH::SMESH_Group::_nil();
01676     
01677     // Create array of identifiers
01678     SMESH::long_array_var aResIds = new SMESH::long_array;
01679     aResIds->length( aResultIds.size() );
01680     
01681     for (int i=0; i< aResultIds.size(); i++)
01682       aResIds[ i ] = aResultIds[i];
01683     aResGrp->Add( aResIds );
01684 
01685     // Remove strings corresponding to group creation
01686     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
01687     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
01688     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
01689 
01690     // Update Python script
01691     
01692     TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
01693                   << &theGroups << ", " << theElemType << ", '" << theName << "' )";
01694 
01695     return aResGrp._retn();
01696   }
01697   catch( ... )
01698   {
01699     return SMESH::SMESH_Group::_nil();
01700   }
01701 }
01702 
01703 //================================================================================
01707 //================================================================================
01708 
01709 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
01710                                     CORBA::Object_ptr     theSmeshObj)
01711 {
01712   if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
01713     return;
01714   // group SO
01715   SALOMEDS::Study_var   study  = _gen_i->GetCurrentStudy();
01716   SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
01717   if ( groupSO->_is_nil() )
01718     return;
01719   // group indices
01720   GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
01721   GEOM::GEOM_IGroupOperations_var groupOp =
01722     geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
01723   GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
01724 
01725   // store data
01726   _geomGroupData.push_back( TGeomGroupData() );
01727   TGeomGroupData & groupData = _geomGroupData.back();
01728   // entry
01729   CORBA::String_var entry = groupSO->GetID();
01730   groupData._groupEntry = entry.in();
01731   // indices
01732   for ( int i = 0; i < ids->length(); ++i )
01733     groupData._indices.insert( ids[i] );
01734   // SMESH object
01735   groupData._smeshObject = theSmeshObj;
01736 }
01737 
01738 //================================================================================
01742 //================================================================================
01743 
01744 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
01745 {
01746   list<TGeomGroupData>::iterator
01747     data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
01748   for ( ; data != dataEnd; ++data ) {
01749     if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
01750       _geomGroupData.erase( data );
01751       return;
01752     }
01753   }
01754 }
01755 
01756 //================================================================================
01760 //================================================================================
01761 
01762 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
01763 {
01764   TopoDS_Shape newShape;
01765 
01766   // get geom group
01767   SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
01768   if ( study->_is_nil() ) return newShape; // means "not changed"
01769   SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
01770   if ( !groupSO->_is_nil() )
01771   {
01772     CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
01773     if ( CORBA::is_nil( groupObj )) return newShape;
01774     GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
01775 
01776     // get indices of group items
01777     set<int> curIndices;
01778     GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
01779     GEOM::GEOM_IGroupOperations_var groupOp =
01780       geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
01781     GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
01782     for ( int i = 0; i < ids->length(); ++i )
01783       curIndices.insert( ids[i] );
01784 
01785     if ( groupData._indices == curIndices )
01786       return newShape; // group not changed
01787 
01788     // update data
01789     groupData._indices = curIndices;
01790 
01791     GEOM_Client* geomClient = _gen_i->GetShapeReader();
01792     if ( !geomClient ) return newShape;
01793     TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
01794     geomClient->RemoveShapeFromBuffer( groupIOR );
01795     newShape = _gen_i->GeomObjectToShape( geomGroup );
01796   }    
01797 
01798   if ( newShape.IsNull() ) {
01799     // geom group becomes empty - return empty compound
01800     TopoDS_Compound compound;
01801     BRep_Builder().MakeCompound(compound);
01802     newShape = compound;
01803   }
01804   return newShape;
01805 }
01806 
01807 namespace
01808 {
01809   //=============================================================================
01813   //=============================================================================
01814   struct TIndexedShape
01815   {
01816     int          _index;
01817     TopoDS_Shape _shape;
01818     TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
01819   };
01820 }
01821 //=============================================================================
01828 //=============================================================================
01829 
01830 void SMESH_Mesh_i::CheckGeomGroupModif()
01831 {
01832   if ( !_impl->HasShapeToMesh() ) return;
01833 
01834   SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
01835   if ( study->_is_nil() ) return;
01836 
01837   CORBA::Long nbEntities = NbNodes() + NbElements();
01838 
01839   // Check if group contents changed
01840 
01841   typedef map< string, TopoDS_Shape > TEntry2Geom;
01842   TEntry2Geom newGroupContents;
01843 
01844   list<TGeomGroupData>::iterator
01845     data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
01846   for ( ; data != dataEnd; ++data )
01847   {
01848     pair< TEntry2Geom::iterator, bool > it_new =
01849       newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
01850     bool processedGroup    = !it_new.second;
01851     TopoDS_Shape& newShape = it_new.first->second;
01852     if ( !processedGroup )
01853       newShape = newGroupShape( *data );
01854     if ( newShape.IsNull() )
01855       continue; // no changes
01856 
01857     if ( _preMeshInfo )
01858       _preMeshInfo->ForgetOrLoad();
01859 
01860     if ( processedGroup ) { // update group indices
01861       list<TGeomGroupData>::iterator data2 = data;
01862       for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
01863       data->_indices = data2->_indices;
01864     }
01865 
01866     // Update SMESH objects according to new GEOM group contents
01867 
01868     SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
01869     if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
01870     {
01871       int oldID = submesh->GetId();
01872       if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
01873         continue;
01874       TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
01875 
01876       // update hypotheses
01877       list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
01878       list <const SMESHDS_Hypothesis * >::iterator hypIt;
01879       for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
01880       {
01881         _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
01882         _impl->AddHypothesis   ( newShape, (*hypIt)->GetID());
01883       }
01884       // care of submeshes
01885       SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
01886       int newID = newSubmesh->GetId();
01887       if ( newID != oldID ) {
01888         _mapSubMesh   [ newID ] = newSubmesh;
01889         _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
01890         _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
01891         _mapSubMesh.   erase(oldID);
01892         _mapSubMesh_i. erase(oldID);
01893         _mapSubMeshIor.erase(oldID);
01894         _mapSubMesh_i [ newID ]->changeLocalId( newID );
01895       }
01896       continue;
01897     }
01898 
01899     SMESH::SMESH_GroupOnGeom_var smeshGroup =
01900       SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
01901     if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
01902     {
01903       SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
01904       if ( group_i ) {
01905         ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
01906         SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
01907         ds->SetShape( newShape );
01908       }
01909       continue;
01910     }
01911 
01912     SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
01913     if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
01914     {
01915       // Remove groups and submeshes basing on removed sub-shapes
01916 
01917       TopTools_MapOfShape newShapeMap;
01918       TopoDS_Iterator shapeIt( newShape );
01919       for ( ; shapeIt.More(); shapeIt.Next() )
01920         newShapeMap.Add( shapeIt.Value() );
01921 
01922       SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
01923       for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
01924       {
01925         if ( newShapeMap.Contains( shapeIt.Value() ))
01926           continue;
01927         TopTools_IndexedMapOfShape oldShapeMap;
01928         TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
01929         for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
01930         {
01931           const TopoDS_Shape& oldShape = oldShapeMap(i);
01932           int oldInd = meshDS->ShapeToIndex( oldShape );
01933           // -- submeshes --
01934           map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
01935           if ( i_smIor != _mapSubMeshIor.end() ) {
01936             RemoveSubMesh( i_smIor->second ); // one submesh per shape index
01937           }
01938           // --- groups ---
01939           map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
01940           for ( ; i_grp != _mapGroups.end(); ++i_grp )
01941           {
01942             // check if a group bases on oldInd shape
01943             SMESHDS_GroupOnGeom* grpOnGeom = 0;
01944             if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
01945               grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
01946             if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
01947             { // remove
01948               RemoveGroup( i_grp->second ); // several groups can base on same shape
01949               i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
01950             }
01951           }
01952         }
01953       }
01954       // Reassign hypotheses and update groups after setting the new shape to mesh
01955 
01956       // collect anassigned hypotheses
01957       typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
01958       list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
01959       TShapeHypList assignedHyps;
01960       for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
01961       {
01962         const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
01963         list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
01964         if ( !hyps.empty() ) {
01965           assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
01966           for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
01967             _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
01968         }
01969       }
01970       // collect shapes supporting groups
01971       typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
01972       TShapeTypeList groupData;
01973       const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
01974       set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
01975       for ( ; grIt != groups.end(); ++grIt )
01976       {
01977         if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
01978           groupData.push_back
01979             ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
01980       }
01981       // set new shape to mesh -> DS of submeshes and geom groups is deleted
01982       _impl->ShapeToMesh( newShape );
01983       
01984       // reassign hypotheses
01985       TShapeHypList::iterator indS_hyps = assignedHyps.begin();
01986       for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
01987       {
01988         TIndexedShape&                   geom = indS_hyps->first;
01989         list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
01990         int oldID = geom._index;
01991         int newID = meshDS->ShapeToIndex( geom._shape );
01992         if ( !newID )
01993           continue;
01994         if ( oldID == 1 ) { // main shape
01995           newID = 1;
01996           geom._shape = newShape;
01997         }
01998         for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
01999           _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
02000         // care of submeshes
02001         SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
02002         if ( newID != oldID ) {
02003           _mapSubMesh   [ newID ] = newSubmesh;
02004           _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
02005           _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
02006           _mapSubMesh.   erase(oldID);
02007           _mapSubMesh_i. erase(oldID);
02008           _mapSubMeshIor.erase(oldID);
02009           _mapSubMesh_i [ newID ]->changeLocalId( newID );
02010         }
02011       }
02012       // recreate groups
02013       TShapeTypeList::iterator geomType = groupData.begin();
02014       for ( ; geomType != groupData.end(); ++geomType )
02015       {
02016         const TIndexedShape& geom = geomType->first;
02017         int oldID = geom._index;
02018         if ( _mapGroups.find( oldID ) == _mapGroups.end() )
02019           continue;
02020         // get group name
02021         SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
02022         CORBA::String_var     name    = groupSO->GetName();
02023         // update
02024         SMESH_GroupBase_i* group_i    = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
02025         int newID;
02026         if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
02027           group_i->changeLocalId( newID );
02028       }
02029 
02030       break; // everything has been updated
02031 
02032     } // update mesh
02033   } // loop on group data
02034 
02035   // Update icons
02036 
02037   CORBA::Long newNbEntities = NbNodes() + NbElements();
02038   list< SALOMEDS::SObject_var > soToUpdateIcons;
02039   if ( newNbEntities != nbEntities )
02040   {
02041     // Add all SObjects with icons to soToUpdateIcons
02042     soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
02043 
02044     for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
02045          i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
02046       soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
02047 
02048     for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
02049           i_gr != _mapGroups.end(); ++i_gr ) // groups
02050       soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
02051   }
02052 
02053   list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
02054   for ( ; so != soToUpdateIcons.end(); ++so )
02055     _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
02056 }
02057 
02058 //=============================================================================
02062 //=============================================================================
02063 
02064 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
02065 {
02066   if ( _preMeshInfo )
02067     _preMeshInfo->FullLoadFromFile();
02068 
02069   SMESH::SMESH_Group_var aGroup;
02070   if ( theGroup->_is_nil() )
02071     return aGroup._retn();
02072 
02073   Unexpect aCatch(SALOME_SalomeException);
02074 
02075   SMESH_GroupBase_i* aGroupToRem =
02076     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
02077   if ( !aGroupToRem )
02078     return aGroup._retn();
02079 
02080   const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
02081 
02082   int anId = aGroupToRem->GetLocalID();
02083   if ( !_impl->ConvertToStandalone( anId ) )
02084     return aGroup._retn();
02085   removeGeomGroupData( theGroup );
02086 
02087   SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
02088 
02089   // remove old instance of group from own map
02090   _mapGroups.erase( anId );
02091 
02092   SALOMEDS::StudyBuilder_var builder;
02093   SALOMEDS::SObject_var aGroupSO;
02094   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
02095   if ( !aStudy->_is_nil() )  {
02096     builder = aStudy->NewBuilder();
02097     aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
02098     if ( !aGroupSO->_is_nil() ) {
02099 
02100       // remove reference to geometry
02101       SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
02102       for ( ; chItr->More(); chItr->Next() )
02103         // Remove group's child SObject
02104         builder->RemoveObject( chItr->Value() );
02105 
02106       // Update Python script
02107       TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
02108                     << aGroupSO << " )";
02109 
02110       // change icon of Group on Filter
02111       if ( isOnFilter )
02112       {
02113         SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
02114         const int isEmpty = ( elemTypes->length() == 0 );
02115         if ( !isEmpty )
02116         {
02117           SALOMEDS::GenericAttribute_var anAttr =
02118             builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
02119           SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr );
02120           pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
02121         }
02122       }
02123     }
02124   }
02125 
02126   // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
02127   SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
02128   aGroupImpl->Register();
02129   // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
02130 
02131   // remember new group in own map
02132   aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
02133   _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
02134 
02135   // register CORBA object for persistence
02136   /*int nextId =*/ _gen_i->RegisterObject( aGroup );
02137 
02138   builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
02139 
02140   return aGroup._retn();
02141 }
02142 
02143 //=============================================================================
02147 //=============================================================================
02148 
02149 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
02150 {
02151   if(MYDEBUG) MESSAGE( "createSubMesh" );
02152   TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
02153 
02154   ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
02155   int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
02156   SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
02157   SMESH::SMESH_subMesh_var subMesh
02158     = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
02159 
02160   _mapSubMesh[subMeshId] = mySubMesh;
02161   _mapSubMesh_i[subMeshId] = subMeshServant;
02162   _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
02163 
02164   // register CORBA object for persistence
02165   int nextId = _gen_i->RegisterObject( subMesh );
02166   if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
02167 
02168   // to track changes of GEOM groups
02169   addGeomGroupData( theSubShapeObject, subMesh );
02170 
02171   return subMesh._retn();
02172 }
02173 
02174 //=======================================================================
02175 //function : getSubMesh
02176 //purpose  :
02177 //=======================================================================
02178 
02179 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
02180 {
02181   map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
02182   if ( it == _mapSubMeshIor.end() )
02183     return SMESH::SMESH_subMesh::_nil();
02184 
02185   return SMESH::SMESH_subMesh::_duplicate( (*it).second );
02186 }
02187 
02188 
02189 //=============================================================================
02193 //=============================================================================
02194 
02195 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
02196                                   GEOM::GEOM_Object_ptr    theSubShapeObject )
02197 {
02198   bool isHypChanged = false;
02199   if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
02200     return isHypChanged;
02201 
02202   if ( theSubShapeObject->_is_nil() )  // not published shape (IPAL13617)
02203   {
02204     CORBA::Long shapeId = theSubMesh->GetId();
02205     if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
02206     {
02207       TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
02208       if ( !S.IsNull() )
02209       {
02210         list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
02211         isHypChanged = !hyps.empty();
02212         list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
02213         for ( ; hyp != hyps.end(); ++hyp )
02214           _impl->RemoveHypothesis(S, (*hyp)->GetID());
02215       }
02216     }
02217   }
02218   else
02219   {
02220     try {
02221       SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
02222       isHypChanged = ( aHypList->length() > 0 );
02223       for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
02224         removeHypothesis( theSubShapeObject, aHypList[i] );
02225       }
02226     }
02227     catch( const SALOME::SALOME_Exception& ) {
02228       INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
02229     }
02230     removeGeomGroupData( theSubShapeObject );
02231   }
02232   int subMeshId = theSubMesh->GetId();
02233 
02234   _mapSubMesh.erase(subMeshId);
02235   _mapSubMesh_i.erase(subMeshId);
02236   _mapSubMeshIor.erase(subMeshId);
02237 
02238   return isHypChanged;
02239 }
02240 
02241 //=============================================================================
02245 //=============================================================================
02246 
02247 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType        theElemType,
02248                                                       const char*               theName,
02249                                                       const TopoDS_Shape&       theShape,
02250                                                       const SMESH_PredicatePtr& thePredicate )
02251 {
02252   std::string newName;
02253   if ( !theName || strlen( theName ) == 0 )
02254   {
02255     std::set< std::string > presentNames;
02256     std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
02257     for ( ; i_gr != _mapGroups.end(); ++i_gr )
02258       presentNames.insert( i_gr->second->GetName() );
02259     do {
02260       newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
02261     } while ( !presentNames.insert( newName ).second );
02262     theName = newName.c_str();
02263   }
02264   int anId;
02265   SMESH::SMESH_GroupBase_var aGroup;
02266   if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
02267   {
02268     SMESH_GroupBase_i* aGroupImpl;
02269     if ( !theShape.IsNull() )
02270       aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
02271     else if ( thePredicate )
02272       aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
02273     else
02274       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
02275 
02276     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
02277     SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
02278     aGroupImpl->Register();
02279     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
02280 
02281     aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
02282     _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
02283 
02284     // register CORBA object for persistence
02285     int nextId = _gen_i->RegisterObject( aGroup );
02286     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
02287 
02288     // to track changes of GEOM groups
02289     if ( !theShape.IsNull() ) {
02290       GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
02291       addGeomGroupData( geom, aGroup );
02292     }
02293   }
02294   return aGroup._retn();
02295 }
02296 
02297 //=============================================================================
02303 //=============================================================================
02304 
02305 void SMESH_Mesh_i::removeGroup( const int theId )
02306 {
02307   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
02308   if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
02309     SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
02310     _mapGroups.erase( theId );
02311     removeGeomGroupData( group );
02312     if (! _impl->RemoveGroup( theId ))
02313     {
02314       // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
02315       RemoveGroup( group );
02316     }
02317   }
02318 }
02319 
02320 //=============================================================================
02324 //=============================================================================
02325 
02326 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
02327 throw(SALOME::SALOME_Exception)
02328 {
02329   if ( _preMeshInfo )
02330     _preMeshInfo->FullLoadFromFile();
02331 
02332   SMESH::log_array_var aLog;
02333   try{
02334     list < SMESHDS_Command * >logDS = _impl->GetLog();
02335     aLog = new SMESH::log_array;
02336     int indexLog = 0;
02337     int lg = logDS.size();
02338     SCRUTE(lg);
02339     aLog->length(lg);
02340     list < SMESHDS_Command * >::iterator its = logDS.begin();
02341     while(its != logDS.end()){
02342       SMESHDS_Command *com = *its;
02343       int comType = com->GetType();
02344       //SCRUTE(comType);
02345       int lgcom = com->GetNumber();
02346       //SCRUTE(lgcom);
02347       const list < int >&intList = com->GetIndexes();
02348       int inum = intList.size();
02349       //SCRUTE(inum);
02350       list < int >::const_iterator ii = intList.begin();
02351       const list < double >&coordList = com->GetCoords();
02352       int rnum = coordList.size();
02353       //SCRUTE(rnum);
02354       list < double >::const_iterator ir = coordList.begin();
02355       aLog[indexLog].commandType = comType;
02356       aLog[indexLog].number = lgcom;
02357       aLog[indexLog].coords.length(rnum);
02358       aLog[indexLog].indexes.length(inum);
02359       for(int i = 0; i < rnum; i++){
02360         aLog[indexLog].coords[i] = *ir;
02361         //MESSAGE(" "<<i<<" "<<ir.Value());
02362         ir++;
02363       }
02364       for(int i = 0; i < inum; i++){
02365         aLog[indexLog].indexes[i] = *ii;
02366         //MESSAGE(" "<<i<<" "<<ii.Value());
02367         ii++;
02368       }
02369       indexLog++;
02370       its++;
02371     }
02372     if(clearAfterGet)
02373       _impl->ClearLog();
02374   }
02375   catch(SALOME_Exception & S_ex){
02376     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
02377   }
02378   return aLog._retn();
02379 }
02380 
02381 
02382 //=============================================================================
02386 //=============================================================================
02387 
02388 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
02389 {
02390   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
02391   _impl->ClearLog();
02392 }
02393 
02394 //=============================================================================
02398 //=============================================================================
02399 
02400 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
02401 {
02402   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
02403   return _id;
02404 }
02405 
02406 //=============================================================================
02410 //=============================================================================
02411 
02412 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
02413 {
02414   return _studyId;
02415 }
02416 
02417 //=============================================================================
02418 namespace
02419 {
02421   // issue 0020918: groups removal is caused by hyp modification
02422   // issue 0021208: to forget not loaded mesh data at hyp modification
02423   struct TCallUp_i : public SMESH_Mesh::TCallUp
02424   {
02425     SMESH_Mesh_i* _mesh;
02426     TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
02427     virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
02428     virtual void HypothesisModified ()              { _mesh->onHypothesisModified(); }
02429     virtual void Load ()                            { _mesh->Load(); }
02430   };
02431 }
02432 
02433 //================================================================================
02437 //================================================================================
02438 
02439 void SMESH_Mesh_i::onHypothesisModified()
02440 {
02441   if ( _preMeshInfo )
02442     _preMeshInfo->ForgetOrLoad();
02443 }
02444 
02445 //=============================================================================
02449 //=============================================================================
02450 
02451 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
02452 {
02453   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
02454   _impl = impl;
02455   if ( _impl )
02456     _impl->SetCallUp( new TCallUp_i(this));
02457 }
02458 
02459 //=============================================================================
02463 //=============================================================================
02464 
02465 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
02466 {
02467   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
02468   return *_impl;
02469 }
02470 
02471 //=============================================================================
02475 //=============================================================================
02476 
02477 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
02478 {
02479   if ( _preMeshInfo )
02480     _preMeshInfo->FullLoadFromFile();
02481 
02482   // Create MeshEditor
02483   SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
02484   SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
02485 
02486   // Update Python script
02487   TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
02488 
02489   return aMesh._retn();
02490 }
02491 
02492 //=============================================================================
02496 //=============================================================================
02497 
02498 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
02499 {
02500   if ( _preMeshInfo )
02501     _preMeshInfo->FullLoadFromFile();
02502 
02503   SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
02504   SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
02505   return aMesh._retn();
02506 }
02507 
02508 //================================================================================
02513 //================================================================================
02514 
02515 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
02516 {
02517   Unexpect aCatch(SALOME_SalomeException);
02518   return _impl->HasModificationsToDiscard();
02519 }
02520 
02521 //================================================================================
02525 //================================================================================
02526 
02527 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
02528 {
02529   const int MAX_ATTEMPTS = 100;
02530   int cnt = 0;
02531   double tolerance = 0.5;
02532   SALOMEDS::Color col;
02533 
02534   bool ok = false;
02535   while ( !ok ) {
02536     // generate random color
02537     double red    = (double)rand() / RAND_MAX;
02538     double green  = (double)rand() / RAND_MAX;
02539     double blue   = (double)rand() / RAND_MAX;
02540     // check existence in the list of the existing colors
02541     bool matched = false;
02542     std::list<SALOMEDS::Color>::const_iterator it;
02543     for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
02544       SALOMEDS::Color color = *it;
02545       double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B  - blue  );
02546       matched = tol < tolerance;
02547     }
02548     if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
02549     ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
02550     col.R = red;
02551     col.G = green;
02552     col.B = blue;
02553   }
02554   return col;
02555 }
02556 
02557 //=============================================================================
02561 //=============================================================================
02562 
02563 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
02564 {
02565   Unexpect aCatch(SALOME_SalomeException);
02566   _impl->SetAutoColor(theAutoColor);
02567 
02568   TPythonDump pyDump; // not to dump group->SetColor() from below code
02569   pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
02570 
02571   std::list<SALOMEDS::Color> aReservedColors;
02572   map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
02573   for ( ; it != _mapGroups.end(); it++ ) {
02574     if ( CORBA::is_nil( it->second )) continue;
02575     SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
02576     it->second->SetColor( aColor );
02577     aReservedColors.push_back( aColor );
02578   }
02579 }
02580 
02581 //=============================================================================
02585 //=============================================================================
02586 
02587 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
02588 {
02589   Unexpect aCatch(SALOME_SalomeException);
02590   return _impl->GetAutoColor();
02591 }
02592 
02593 //=============================================================================
02597 //=============================================================================
02598 
02599 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
02600 {
02601   return _impl->HasDuplicatedGroupNamesMED();
02602 }
02603 
02604 //================================================================================
02608 //================================================================================
02609 
02610 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
02611 {
02612   TCollection_AsciiString aFullName ((char*)file);
02613   OSD_Path aPath (aFullName);
02614   OSD_File aFile (aPath);
02615   if (aFile.Exists()) {
02616     // existing filesystem node
02617     if (aFile.KindOfFile() == OSD_FILE) {
02618       if (aFile.IsWriteable()) {
02619         if (overwrite) {
02620           aFile.Reset();
02621           aFile.Remove();
02622         }
02623         if (aFile.Failed()) {
02624           TCollection_AsciiString msg ("File ");
02625           msg += aFullName + " cannot be replaced.";
02626           THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
02627         }
02628       } else {
02629         TCollection_AsciiString msg ("File ");
02630         msg += aFullName + " cannot be overwritten.";
02631         THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
02632       }
02633     } else {
02634       TCollection_AsciiString msg ("Location ");
02635       msg += aFullName + " is not a file.";
02636       THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
02637     }
02638   } else {
02639     // nonexisting file; check if it can be created
02640     aFile.Reset();
02641     aFile.Build(OSD_WriteOnly, OSD_Protection());
02642     if (aFile.Failed()) {
02643       TCollection_AsciiString msg ("You cannot create the file ");
02644       msg += aFullName + ". Check the directory existance and access rights.";
02645       THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
02646     } else {
02647       aFile.Close();
02648       aFile.Remove();
02649     }
02650   }
02651 }
02652 
02653 //================================================================================
02660 //================================================================================
02661 
02662 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char*    file,
02663                                               CORBA::Boolean overwrite)
02664 {
02665   // Perform Export
02666   PrepareForWriting(file, overwrite);
02667   string aMeshName = "Mesh";
02668   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
02669   if ( !aStudy->_is_nil() ) {
02670     SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
02671     if ( !aMeshSO->_is_nil() ) {
02672       CORBA::String_var name = aMeshSO->GetName();
02673       aMeshName = name;
02674       // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
02675       if ( !aStudy->GetProperties()->IsLocked() )
02676       {
02677         SALOMEDS::GenericAttribute_var anAttr;
02678         SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
02679         SALOMEDS::AttributeExternalFileDef_var aFileName;
02680         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
02681         aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
02682         ASSERT(!aFileName->_is_nil());
02683         aFileName->SetValue(file);
02684         SALOMEDS::AttributeFileType_var aFileType;
02685         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
02686         aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
02687         ASSERT(!aFileType->_is_nil());
02688         aFileType->SetValue("FICHIERMED");
02689       }
02690     }
02691   }
02692   // Update Python script
02693   // set name of mesh before export
02694   TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
02695 
02696   // check names of groups
02697   checkGroupNames();
02698 
02699   return aMeshName;
02700 }
02701 
02702 //================================================================================
02706 //================================================================================
02707 
02708 void SMESH_Mesh_i::ExportToMEDX (const char*        file,
02709                                  CORBA::Boolean     auto_groups,
02710                                  SMESH::MED_VERSION theVersion,
02711                                  CORBA::Boolean     overwrite)
02712   throw(SALOME::SALOME_Exception)
02713 {
02714   Unexpect aCatch(SALOME_SalomeException);
02715   if ( _preMeshInfo )
02716     _preMeshInfo->FullLoadFromFile();
02717 
02718   string aMeshName = prepareMeshNameAndGroups(file, overwrite);
02719   TPythonDump() << _this() << ".ExportToMEDX( r'"
02720                 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
02721 
02722   _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
02723 }
02724 
02725 //================================================================================
02729 //================================================================================
02730 
02731 void SMESH_Mesh_i::ExportToMED (const char*        file,
02732                                 CORBA::Boolean     auto_groups,
02733                                 SMESH::MED_VERSION theVersion)
02734   throw(SALOME::SALOME_Exception)
02735 {
02736   ExportToMEDX(file,auto_groups,theVersion,true);
02737 }
02738 
02739 //================================================================================
02743 //================================================================================
02744 
02745 void SMESH_Mesh_i::ExportMED (const char* file,
02746                               CORBA::Boolean auto_groups)
02747   throw(SALOME::SALOME_Exception)
02748 {
02749   ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
02750 }
02751 
02752 //================================================================================
02756 //================================================================================
02757 
02758 void SMESH_Mesh_i::ExportSAUV (const char* file,
02759                                CORBA::Boolean auto_groups)
02760   throw(SALOME::SALOME_Exception)
02761 {
02762   Unexpect aCatch(SALOME_SalomeException);
02763   if ( _preMeshInfo )
02764     _preMeshInfo->FullLoadFromFile();
02765 
02766   string aMeshName = prepareMeshNameAndGroups(file, true);
02767   TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
02768   _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
02769 }
02770 
02771 
02772 //================================================================================
02776 //================================================================================
02777 
02778 void SMESH_Mesh_i::ExportDAT (const char *file)
02779   throw(SALOME::SALOME_Exception)
02780 {
02781   Unexpect aCatch(SALOME_SalomeException);
02782   if ( _preMeshInfo )
02783     _preMeshInfo->FullLoadFromFile();
02784 
02785   // Update Python script
02786   // check names of groups
02787   checkGroupNames();
02788   TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
02789 
02790   // Perform Export
02791   PrepareForWriting(file);
02792   _impl->ExportDAT(file);
02793 }
02794 
02795 //================================================================================
02799 //================================================================================
02800 
02801 void SMESH_Mesh_i::ExportUNV (const char *file)
02802   throw(SALOME::SALOME_Exception)
02803 {
02804   Unexpect aCatch(SALOME_SalomeException);
02805   if ( _preMeshInfo )
02806     _preMeshInfo->FullLoadFromFile();
02807 
02808   // Update Python script
02809   // check names of groups
02810   checkGroupNames();
02811   TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
02812 
02813   // Perform Export
02814   PrepareForWriting(file);
02815   _impl->ExportUNV(file);
02816 }
02817 
02818 //================================================================================
02822 //================================================================================
02823 
02824 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
02825   throw(SALOME::SALOME_Exception)
02826 {
02827   Unexpect aCatch(SALOME_SalomeException);
02828   if ( _preMeshInfo )
02829     _preMeshInfo->FullLoadFromFile();
02830 
02831   // Update Python script
02832   // check names of groups
02833   checkGroupNames();
02834   TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
02835 
02836   // Perform Export
02837   PrepareForWriting(file);
02838   _impl->ExportSTL(file, isascii);
02839 }
02840 
02841 //=============================================================================
02846 class SMESH_MeshPartDS : public SMESHDS_Mesh
02847 {
02848 public:
02849   SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart);
02850 
02851   virtual SMDS_NodeIteratorPtr      nodesIterator     (bool idInceasingOrder=false) const;
02852   virtual SMDS_0DElementIteratorPtr elements0dIterator(bool idInceasingOrder=false) const;
02853   virtual SMDS_EdgeIteratorPtr      edgesIterator     (bool idInceasingOrder=false) const;
02854   virtual SMDS_FaceIteratorPtr      facesIterator     (bool idInceasingOrder=false) const;
02855   virtual SMDS_VolumeIteratorPtr    volumesIterator   (bool idInceasingOrder=false) const;
02856 
02857   virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
02858 
02859 private:
02860   TIDSortedElemSet _elements[ SMDSAbs_NbElementTypes ];
02861   SMESHDS_Mesh*    _meshDS;
02865   struct TMeshInfo : public SMDS_MeshInfo
02866   {
02867     void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
02868   };
02869 };
02870 
02871 //================================================================================
02875 //================================================================================
02876 
02877 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
02878                                    const char*                 file,
02879                                    CORBA::Boolean              auto_groups,
02880                                    ::SMESH::MED_VERSION        version,
02881                                    ::CORBA::Boolean            overwrite)
02882   throw (SALOME::SALOME_Exception)
02883 {
02884   Unexpect aCatch(SALOME_SalomeException);
02885   if ( _preMeshInfo )
02886     _preMeshInfo->FullLoadFromFile();
02887 
02888   PrepareForWriting(file, overwrite);
02889 
02890   string aMeshName = "Mesh";
02891   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
02892   if ( !aStudy->_is_nil() ) {
02893     SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart );
02894     if ( !SO->_is_nil() ) {
02895       CORBA::String_var name = SO->GetName();
02896       aMeshName = name;
02897     }
02898   }
02899   SMESH_MeshPartDS partDS( meshPart );
02900   _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
02901 
02902   TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
02903                 << auto_groups << ", " << version << ", " << overwrite << " )";
02904 }
02905 
02906 //================================================================================
02910 //================================================================================
02911 
02912 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
02913                                    const char*                 file)
02914   throw (SALOME::SALOME_Exception)
02915 {
02916   Unexpect aCatch(SALOME_SalomeException);
02917   if ( _preMeshInfo )
02918     _preMeshInfo->FullLoadFromFile();
02919 
02920   PrepareForWriting(file);
02921 
02922   SMESH_MeshPartDS partDS( meshPart );
02923   _impl->ExportDAT(file,&partDS);
02924 
02925   TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
02926 }
02927 //================================================================================
02931 //================================================================================
02932 
02933 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
02934                                    const char*                 file)
02935   throw (SALOME::SALOME_Exception)
02936 {
02937   Unexpect aCatch(SALOME_SalomeException);
02938   if ( _preMeshInfo )
02939     _preMeshInfo->FullLoadFromFile();
02940 
02941   PrepareForWriting(file);
02942 
02943   SMESH_MeshPartDS partDS( meshPart );
02944   _impl->ExportUNV(file, &partDS);
02945 
02946   TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
02947 }
02948 //================================================================================
02952 //================================================================================
02953 
02954 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
02955                                    const char*                 file,
02956                                    ::CORBA::Boolean            isascii)
02957   throw (SALOME::SALOME_Exception)
02958 {
02959   Unexpect aCatch(SALOME_SalomeException);
02960   if ( _preMeshInfo )
02961     _preMeshInfo->FullLoadFromFile();
02962 
02963   PrepareForWriting(file);
02964 
02965   SMESH_MeshPartDS partDS( meshPart );
02966   _impl->ExportSTL(file, isascii, &partDS);
02967 
02968   TPythonDump() << _this() << ".ExportPartToSTL( "
02969                 << meshPart<< ", r'" << file << "', " << isascii << ")";
02970 }
02971 
02972 //================================================================================
02976 //================================================================================
02977 
02978 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
02979                               const char*                 file,
02980                               CORBA::Boolean              overwrite)
02981   throw (SALOME::SALOME_Exception)
02982 {
02983 #ifdef WITH_CGNS
02984   Unexpect aCatch(SALOME_SalomeException);
02985   if ( _preMeshInfo )
02986     _preMeshInfo->FullLoadFromFile();
02987 
02988   PrepareForWriting(file,overwrite);
02989 
02990   SMESH_MeshPartDS partDS( meshPart );
02991   _impl->ExportCGNS(file, &partDS);
02992 
02993   TPythonDump() << _this() << ".ExportCGNS( "
02994                 << meshPart<< ", r'" << file << "', " << overwrite << ")";
02995 #else
02996   THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
02997 #endif
02998 }
02999 
03000 //=============================================================================
03004 //=============================================================================
03005 
03006 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
03007 {
03008   Unexpect aCatch(SALOME_SalomeException);
03009   if ( _preMeshInfo )
03010     _preMeshInfo->FullLoadFromFile();
03011 
03012   SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
03013   SALOME_MED::MESH_var aMesh = aMedMesh->_this();
03014   return aMesh._retn();
03015 }
03016 
03017 //=============================================================================
03018 
03019 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
03020 {
03021   Unexpect aCatch(SALOME_SalomeException);
03022   if ( _preMeshInfo )
03023     return _preMeshInfo->NbNodes();
03024 
03025   return _impl->NbNodes();
03026 }
03027 
03028 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
03029 {
03030   Unexpect aCatch(SALOME_SalomeException);
03031   if ( _preMeshInfo )
03032     return _preMeshInfo->NbElements();
03033 
03034   return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
03035 }
03036 
03037 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
03038 {
03039   Unexpect aCatch(SALOME_SalomeException);
03040   if ( _preMeshInfo )
03041     return _preMeshInfo->Nb0DElements();
03042 
03043   return _impl->Nb0DElements();
03044 }
03045 
03046 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
03047 {
03048   Unexpect aCatch(SALOME_SalomeException);
03049   if ( _preMeshInfo )
03050     return _preMeshInfo->NbEdges();
03051 
03052   return _impl->NbEdges();
03053 }
03054 
03055 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
03056   throw(SALOME::SALOME_Exception)
03057 {
03058   Unexpect aCatch(SALOME_SalomeException);
03059   if ( _preMeshInfo )
03060     return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
03061 
03062   return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
03063 }
03064 
03065 //=============================================================================
03066 
03067 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
03068 {
03069   Unexpect aCatch(SALOME_SalomeException);
03070   if ( _preMeshInfo )
03071     return _preMeshInfo->NbFaces();
03072 
03073   return _impl->NbFaces();
03074 }
03075 
03076 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
03077 {
03078   Unexpect aCatch(SALOME_SalomeException);
03079   if ( _preMeshInfo )
03080     return _preMeshInfo->NbTriangles();
03081 
03082   return _impl->NbTriangles();
03083 }
03084 
03085 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
03086 {
03087   Unexpect aCatch(SALOME_SalomeException);
03088   if ( _preMeshInfo )
03089     return _preMeshInfo->NbQuadrangles();
03090 
03091   return _impl->NbQuadrangles();
03092 }
03093 
03094 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
03095 {
03096   Unexpect aCatch(SALOME_SalomeException);
03097   if ( _preMeshInfo )
03098     return _preMeshInfo->NbBiQuadQuadrangles();
03099 
03100   return _impl->NbBiQuadQuadrangles();
03101 }
03102 
03103 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
03104 {
03105   Unexpect aCatch(SALOME_SalomeException);
03106   if ( _preMeshInfo )
03107     return _preMeshInfo->NbPolygons();
03108 
03109   return _impl->NbPolygons();
03110 }
03111 
03112 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
03113   throw(SALOME::SALOME_Exception)
03114 {
03115   Unexpect aCatch(SALOME_SalomeException);
03116   if ( _preMeshInfo )
03117     return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
03118 
03119   return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
03120 }
03121 
03122 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
03123   throw(SALOME::SALOME_Exception)
03124 {
03125   Unexpect aCatch(SALOME_SalomeException);
03126   if ( _preMeshInfo )
03127     return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
03128 
03129   return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
03130 }
03131 
03132 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
03133   throw(SALOME::SALOME_Exception)
03134 {
03135   Unexpect aCatch(SALOME_SalomeException);
03136   if ( _preMeshInfo )
03137     return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
03138 
03139   return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
03140 }
03141 
03142 //=============================================================================
03143 
03144 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
03145 {
03146   Unexpect aCatch(SALOME_SalomeException);
03147   if ( _preMeshInfo )
03148     return _preMeshInfo->NbVolumes();
03149 
03150   return _impl->NbVolumes();
03151 }
03152 
03153 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
03154 {
03155   Unexpect aCatch(SALOME_SalomeException);
03156   if ( _preMeshInfo )
03157     return _preMeshInfo->NbTetras();
03158 
03159   return _impl->NbTetras();
03160 }
03161 
03162 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
03163 {
03164   Unexpect aCatch(SALOME_SalomeException);
03165   if ( _preMeshInfo )
03166     return _preMeshInfo->NbHexas();
03167 
03168   return _impl->NbHexas();
03169 }
03170 
03171 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
03172 {
03173   Unexpect aCatch(SALOME_SalomeException);
03174   if ( _preMeshInfo )
03175     return _preMeshInfo->NbTriQuadHexas();
03176 
03177   return _impl->NbTriQuadraticHexas();
03178 }
03179 
03180 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
03181 {
03182   Unexpect aCatch(SALOME_SalomeException);
03183   if ( _preMeshInfo )
03184     return _preMeshInfo->NbPyramids();
03185 
03186   return _impl->NbPyramids();
03187 }
03188 
03189 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
03190 {
03191   Unexpect aCatch(SALOME_SalomeException);
03192   if ( _preMeshInfo )
03193     return _preMeshInfo->NbPrisms();
03194 
03195   return _impl->NbPrisms();
03196 }
03197 
03198 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
03199 {
03200   Unexpect aCatch(SALOME_SalomeException);
03201   if ( _preMeshInfo )
03202     return _preMeshInfo->NbHexPrisms();
03203 
03204   return _impl->NbHexagonalPrisms();
03205 }
03206 
03207 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
03208 {
03209   Unexpect aCatch(SALOME_SalomeException);
03210   if ( _preMeshInfo )
03211     return _preMeshInfo->NbPolyhedrons();
03212 
03213   return _impl->NbPolyhedrons();
03214 }
03215 
03216 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
03217   throw(SALOME::SALOME_Exception)
03218 {
03219   Unexpect aCatch(SALOME_SalomeException);
03220   if ( _preMeshInfo )
03221     return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
03222 
03223   return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
03224 }
03225 
03226 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
03227   throw(SALOME::SALOME_Exception)
03228 {
03229   Unexpect aCatch(SALOME_SalomeException);
03230   if ( _preMeshInfo )
03231     return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
03232 
03233   return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
03234 }
03235 
03236 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
03237   throw(SALOME::SALOME_Exception)
03238 {
03239   Unexpect aCatch(SALOME_SalomeException);
03240   if ( _preMeshInfo )
03241     return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
03242 
03243   return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
03244 }
03245 
03246 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
03247   throw(SALOME::SALOME_Exception)
03248 {
03249   Unexpect aCatch(SALOME_SalomeException);
03250   if ( _preMeshInfo )
03251     return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
03252 
03253   return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
03254 }
03255 
03256 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
03257   throw(SALOME::SALOME_Exception)
03258 {
03259   Unexpect aCatch(SALOME_SalomeException);
03260   if ( _preMeshInfo )
03261     return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
03262 
03263   return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
03264 }
03265 
03266 //=============================================================================
03270 //=============================================================================
03271 
03272 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
03273 {
03274   Unexpect aCatch(SALOME_SalomeException);
03275   return _mapSubMesh_i.size();
03276 }
03277 
03278 //=============================================================================
03282 //=============================================================================
03283 
03284 char* SMESH_Mesh_i::Dump()
03285 {
03286   ostringstream os;
03287   _impl->Dump( os );
03288   return CORBA::string_dup( os.str().c_str() );
03289 }
03290 
03291 //=============================================================================
03295 //=============================================================================
03296 
03297 SMESH::long_array* SMESH_Mesh_i::GetIDs()
03298 {
03299   return GetElementsId();
03300 }
03301 
03302 //=============================================================================
03306 //=============================================================================
03307 
03308 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
03309      throw (SALOME::SALOME_Exception)
03310 {
03311   Unexpect aCatch(SALOME_SalomeException);
03312   if ( _preMeshInfo )
03313     _preMeshInfo->FullLoadFromFile();
03314 
03315   SMESH::long_array_var aResult = new SMESH::long_array();
03316   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
03317 
03318   if ( aSMESHDS_Mesh == NULL )
03319     return aResult._retn();
03320 
03321   long nbElements = NbElements();
03322   aResult->length( nbElements );
03323   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
03324   for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
03325     aResult[i] = anIt->next()->GetID();
03326 
03327   return aResult._retn();
03328 }
03329 
03330 
03331 //=============================================================================
03335 //=============================================================================
03336 
03337 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
03338     throw (SALOME::SALOME_Exception)
03339 {
03340   Unexpect aCatch(SALOME_SalomeException);
03341   if ( _preMeshInfo )
03342     _preMeshInfo->FullLoadFromFile();
03343 
03344   SMESH::long_array_var aResult = new SMESH::long_array();
03345   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
03346 
03347   if ( aSMESHDS_Mesh == NULL )
03348     return aResult._retn();
03349 
03350   long nbElements = NbElements();
03351 
03352   // No sense in returning ids of elements along with ids of nodes:
03353   // when theElemType == SMESH::ALL, return node ids only if
03354   // there are no elements
03355   if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
03356     return GetNodesId();
03357 
03358   aResult->length( nbElements );
03359 
03360   int i = 0;
03361 
03362   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
03363   while ( i < nbElements && anIt->more() ) {
03364     const SMDS_MeshElement* anElem = anIt->next();
03365     if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
03366       aResult[i++] = anElem->GetID();
03367   }
03368 
03369   aResult->length( i );
03370 
03371   return aResult._retn();
03372 }
03373 
03374 //=============================================================================
03378 //=============================================================================
03379 
03380 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
03381   throw (SALOME::SALOME_Exception)
03382 {
03383   Unexpect aCatch(SALOME_SalomeException);
03384   if ( _preMeshInfo )
03385     _preMeshInfo->FullLoadFromFile();
03386 
03387   SMESH::long_array_var aResult = new SMESH::long_array();
03388   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
03389 
03390   if ( aSMESHDS_Mesh == NULL )
03391     return aResult._retn();
03392 
03393   long nbNodes = NbNodes();
03394   aResult->length( nbNodes );
03395   SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
03396   for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
03397     aResult[i] = anIt->next()->GetID();
03398 
03399   return aResult._retn();
03400 }
03401 
03402 //=============================================================================
03406 //=============================================================================
03407 
03408 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
03409   throw (SALOME::SALOME_Exception)
03410 {
03411   if ( _preMeshInfo )
03412     _preMeshInfo->FullLoadFromFile();
03413 
03414   return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
03415 }
03416 
03417 //=============================================================================
03421 //=============================================================================
03422 
03423 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
03424   throw (SALOME::SALOME_Exception)
03425 {
03426   if ( _preMeshInfo )
03427     _preMeshInfo->FullLoadFromFile();
03428 
03429   const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
03430   if ( !e )
03431     THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
03432 
03433   return ( SMESH::EntityType ) e->GetEntityType();
03434 }
03435 
03436 //=============================================================================
03440 //=============================================================================
03441 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
03442      throw (SALOME::SALOME_Exception)
03443 {
03444   if ( _preMeshInfo )
03445     _preMeshInfo->FullLoadFromFile();
03446 
03447   SMESH::long_array_var aResult = new SMESH::long_array();
03448 
03449   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
03450   if(!SM) return aResult._retn();
03451 
03452   SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
03453   if(!SDSM) return aResult._retn();
03454 
03455   aResult->length(SDSM->NbElements());
03456 
03457   SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
03458   int i = 0;
03459   while ( eIt->more() ) {
03460     aResult[i++] = eIt->next()->GetID();
03461   }
03462 
03463   return aResult._retn();
03464 }
03465 
03466 
03467 //=============================================================================
03473 //=============================================================================
03474 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
03475                                                    CORBA::Boolean    all)
03476   throw (SALOME::SALOME_Exception)
03477 {
03478   if ( _preMeshInfo )
03479     _preMeshInfo->FullLoadFromFile();
03480 
03481   SMESH::long_array_var aResult = new SMESH::long_array();
03482 
03483   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
03484   if(!SM) return aResult._retn();
03485 
03486   SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
03487   if(!SDSM) return aResult._retn();
03488 
03489   set<int> theElems;
03490   if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
03491     SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
03492     while ( nIt->more() ) {
03493       const SMDS_MeshNode* elem = nIt->next();
03494       theElems.insert( elem->GetID() );
03495     }
03496   }
03497   else { // all nodes of submesh elements
03498     SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
03499     while ( eIt->more() ) {
03500       const SMDS_MeshElement* anElem = eIt->next();
03501       SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
03502       while ( nIt->more() ) {
03503         const SMDS_MeshElement* elem = nIt->next();
03504         theElems.insert( elem->GetID() );
03505       }
03506     }
03507   }
03508 
03509   aResult->length(theElems.size());
03510   set<int>::iterator itElem;
03511   int i = 0;
03512   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
03513     aResult[i++] = *itElem;
03514 
03515   return aResult._retn();
03516 }
03517   
03518 //=============================================================================
03522 //=============================================================================
03523 
03524 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
03525   throw (SALOME::SALOME_Exception)
03526 {
03527   if ( _preMeshInfo )
03528     _preMeshInfo->FullLoadFromFile();
03529 
03530   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
03531   if(!SM) return SMESH::ALL;
03532 
03533   SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
03534   if(!SDSM) return SMESH::ALL;
03535 
03536   if(SDSM->NbElements()==0)
03537     return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
03538 
03539   SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
03540   const SMDS_MeshElement* anElem = eIt->next();
03541   return ( SMESH::ElementType ) anElem->GetType();
03542 }
03543   
03544 
03545 //=============================================================================
03549 //=============================================================================
03550 
03551 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
03552 {
03553   if ( _preMeshInfo )
03554     _preMeshInfo->FullLoadFromFile();
03555 
03556   CORBA::LongLong pointeur = CORBA::LongLong(_impl);
03557   if ( MYDEBUG )
03558     MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
03559   return pointeur;
03560 }
03561 
03562 
03563 //=============================================================================
03568 //=============================================================================
03569 
03570 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
03571 {
03572   if ( _preMeshInfo )
03573     _preMeshInfo->FullLoadFromFile();
03574 
03575   SMESH::double_array_var aResult = new SMESH::double_array();
03576   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
03577   if ( aSMESHDS_Mesh == NULL )
03578     return aResult._retn();
03579 
03580   // find node
03581   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
03582   if(!aNode)
03583     return aResult._retn();
03584 
03585   // add coordinates
03586   aResult->length(3);
03587   aResult[0] = aNode->X();
03588   aResult[1] = aNode->Y();
03589   aResult[2] = aNode->Z();
03590   return aResult._retn();
03591 }
03592 
03593 
03594 //=============================================================================
03599 //=============================================================================
03600 
03601 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
03602 {
03603   if ( _preMeshInfo )
03604     _preMeshInfo->FullLoadFromFile();
03605 
03606   SMESH::long_array_var aResult = new SMESH::long_array();
03607   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
03608   if ( aSMESHDS_Mesh == NULL )
03609     return aResult._retn();
03610 
03611   // find node
03612   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
03613   if(!aNode)
03614     return aResult._retn();
03615 
03616   // find inverse elements
03617   SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
03618   TColStd_SequenceOfInteger IDs;
03619   while(eIt->more()) {
03620     const SMDS_MeshElement* elem = eIt->next();
03621     IDs.Append(elem->GetID());
03622   }
03623   if(IDs.Length()>0) {
03624     aResult->length(IDs.Length());
03625     int i = 1;
03626     for(; i<=IDs.Length(); i++) {
03627       aResult[i-1] = IDs.Value(i);
03628     }
03629   }
03630   return aResult._retn();
03631 }
03632 
03633 //=============================================================================
03637 //=============================================================================
03638 
03639 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
03640 {
03641   if ( _preMeshInfo )
03642     _preMeshInfo->FullLoadFromFile();
03643 
03644   SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
03645   aNodePosition->shapeID = 0;
03646   aNodePosition->shapeType = GEOM::SHAPE;
03647 
03648   SMESHDS_Mesh* mesh = _impl->GetMeshDS();
03649   if ( !mesh ) return aNodePosition;
03650 
03651   if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
03652   {
03653     if ( SMDS_PositionPtr pos = aNode->GetPosition() )
03654     {
03655       aNodePosition->shapeID = aNode->getshapeId();
03656       switch ( pos->GetTypeOfPosition() ) {
03657       case SMDS_TOP_EDGE:
03658         aNodePosition->shapeType = GEOM::EDGE;
03659         aNodePosition->params.length(1);
03660         aNodePosition->params[0] =
03661           static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
03662         break;
03663       case SMDS_TOP_FACE:
03664         aNodePosition->shapeType = GEOM::FACE;
03665         aNodePosition->params.length(2);
03666         aNodePosition->params[0] =
03667           static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
03668         aNodePosition->params[1] =
03669           static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
03670         break;
03671       case SMDS_TOP_VERTEX:
03672         aNodePosition->shapeType = GEOM::VERTEX;
03673         break;
03674       case SMDS_TOP_3DSPACE:
03675         if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
03676           aNodePosition->shapeType = GEOM::SOLID;
03677         else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
03678           aNodePosition->shapeType = GEOM::SHELL;
03679         break;
03680       default:;
03681       }
03682     }
03683   }
03684   return aNodePosition;
03685 }
03686 
03687 //=============================================================================
03692 //=============================================================================
03693 
03694 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
03695 {
03696   if ( _preMeshInfo )
03697     _preMeshInfo->FullLoadFromFile();
03698 
03699   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
03700   if ( aSMESHDS_Mesh == NULL )
03701     return -1;
03702 
03703   // try to find node
03704   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
03705   if(aNode) {
03706     return aNode->getshapeId();
03707   }
03708 
03709   return -1;
03710 }
03711 
03712 
03713 //=============================================================================
03719 //=============================================================================
03720 
03721 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
03722 {
03723   if ( _preMeshInfo )
03724     _preMeshInfo->FullLoadFromFile();
03725 
03726   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
03727   if ( aSMESHDS_Mesh == NULL )
03728     return -1;
03729 
03730   // try to find element
03731   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
03732   if(!elem)
03733     return -1;
03734 
03735   //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
03736   ::SMESH_MeshEditor aMeshEditor(_impl);
03737   int index = aMeshEditor.FindShape( elem );
03738   if(index>0)
03739     return index;
03740 
03741   return -1;
03742 }
03743 
03744 
03745 //=============================================================================
03750 //=============================================================================
03751 
03752 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
03753 {
03754   if ( _preMeshInfo )
03755     _preMeshInfo->FullLoadFromFile();
03756 
03757   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
03758   if ( aSMESHDS_Mesh == NULL ) return -1;
03759   // try to find element
03760   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
03761   if(!elem) return -1;
03762   return elem->NbNodes();
03763 }
03764 
03765 
03766 //=============================================================================
03772 //=============================================================================
03773 
03774 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
03775 {
03776   if ( _preMeshInfo )
03777     _preMeshInfo->FullLoadFromFile();
03778 
03779   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
03780   if ( aSMESHDS_Mesh == NULL ) return -1;
03781   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
03782   if(!elem) return -1;
03783   if( index>=elem->NbNodes() || index<0 ) return -1;
03784   return elem->GetNode(index)->GetID();
03785 }
03786 
03787 //=============================================================================
03791 //=============================================================================
03792 
03793 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
03794 {
03795   if ( _preMeshInfo )
03796     _preMeshInfo->FullLoadFromFile();
03797 
03798   SMESH::long_array_var aResult = new SMESH::long_array();
03799   if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
03800   {
03801     if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
03802     {
03803       aResult->length( elem->NbNodes() );
03804       for ( int i = 0; i < elem->NbNodes(); ++i )
03805         aResult[ i ] = elem->GetNode( i )->GetID();
03806     }
03807   }
03808   return aResult._retn();
03809 }
03810 
03811 //=============================================================================
03816 //=============================================================================
03817 
03818 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
03819 {
03820   if ( _preMeshInfo )
03821     _preMeshInfo->FullLoadFromFile();
03822 
03823   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
03824   if ( aSMESHDS_Mesh == NULL ) return false;
03825   // try to find node
03826   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
03827   if(!aNode) return false;
03828   // try to find element
03829   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
03830   if(!elem) return false;
03831 
03832   return elem->IsMediumNode(aNode);
03833 }
03834 
03835 
03836 //=============================================================================
03841 //=============================================================================
03842 
03843 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
03844                                                    SMESH::ElementType theElemType)
03845 {
03846   if ( _preMeshInfo )
03847     _preMeshInfo->FullLoadFromFile();
03848 
03849   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
03850   if ( aSMESHDS_Mesh == NULL ) return false;
03851 
03852   // try to find node
03853   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
03854   if(!aNode) return false;
03855 
03856   SMESH_MesherHelper aHelper( *(_impl) );
03857 
03858   SMDSAbs_ElementType aType;
03859   if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
03860   else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
03861   else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
03862   else aType = SMDSAbs_All;
03863 
03864   return aHelper.IsMedium(aNode,aType);
03865 }
03866 
03867 
03868 //=============================================================================
03872 //=============================================================================
03873 
03874 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
03875 {
03876   if ( _preMeshInfo )
03877     _preMeshInfo->FullLoadFromFile();
03878 
03879   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
03880   if ( aSMESHDS_Mesh == NULL ) return -1;
03881   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
03882   if(!elem) return -1;
03883   return elem->NbEdges();
03884 }
03885 
03886 
03887 //=============================================================================
03891 //=============================================================================
03892 
03893 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
03894 {
03895   if ( _preMeshInfo )
03896     _preMeshInfo->FullLoadFromFile();
03897 
03898   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
03899   if ( aSMESHDS_Mesh == NULL ) return -1;
03900   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
03901   if(!elem) return -1;
03902   return elem->NbFaces();
03903 }
03904 
03905 //=======================================================================
03906 //function : GetElemFaceNodes
03907 //purpose  : Returns nodes of given face (counted from zero) for given element.
03908 //=======================================================================
03909 
03910 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long  elemId,
03911                                                   CORBA::Short faceIndex)
03912 {
03913   if ( _preMeshInfo )
03914     _preMeshInfo->FullLoadFromFile();
03915 
03916   SMESH::long_array_var aResult = new SMESH::long_array();
03917   if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
03918   {
03919     if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
03920     {
03921       SMDS_VolumeTool vtool( elem );
03922       if ( faceIndex < vtool.NbFaces() )
03923       {
03924         aResult->length( vtool.NbFaceNodes( faceIndex ));
03925         const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
03926         for ( int i = 0; i < aResult->length(); ++i )
03927           aResult[ i ] = nn[ i ]->GetID();
03928       }
03929     }
03930   }
03931   return aResult._retn();
03932 }
03933 
03934 //=======================================================================
03935 //function : FindElementByNodes
03936 //purpose  : Returns an element based on all given nodes.
03937 //=======================================================================
03938 
03939 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
03940 {
03941   if ( _preMeshInfo )
03942     _preMeshInfo->FullLoadFromFile();
03943 
03944   CORBA::Long elemID(0);
03945   if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
03946   {
03947     vector< const SMDS_MeshNode * > nn( nodes.length() );
03948     for ( int i = 0; i < nodes.length(); ++i )
03949       if ( !( nn[i] = mesh->FindNode( nodes[i] )))
03950         return elemID;
03951 
03952     const SMDS_MeshElement* elem = mesh->FindElement( nn );
03953     if ( !elem && ( _impl->NbEdges  ( ORDER_QUADRATIC ) ||
03954                     _impl->NbFaces  ( ORDER_QUADRATIC ) ||
03955                     _impl->NbVolumes( ORDER_QUADRATIC )))
03956       elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
03957 
03958     if ( elem ) elemID = CORBA::Long( elem->GetID() );
03959   }
03960   return elemID;
03961 }
03962 
03963 //=============================================================================
03967 //=============================================================================
03968 
03969 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
03970 {
03971   if ( _preMeshInfo )
03972     _preMeshInfo->FullLoadFromFile();
03973 
03974   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
03975   if ( aSMESHDS_Mesh == NULL ) return false;
03976   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
03977   if(!elem) return false;
03978   return elem->IsPoly();
03979 }
03980 
03981 
03982 //=============================================================================
03986 //=============================================================================
03987 
03988 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
03989 {
03990   if ( _preMeshInfo )
03991     _preMeshInfo->FullLoadFromFile();
03992 
03993   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
03994   if ( aSMESHDS_Mesh == NULL ) return false;
03995   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
03996   if(!elem) return false;
03997   return elem->IsQuadratic();
03998 }
03999 
04000 
04001 //=============================================================================
04005 //=============================================================================
04006 
04007 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
04008 {
04009   if ( _preMeshInfo )
04010     _preMeshInfo->FullLoadFromFile();
04011 
04012   SMESH::double_array_var aResult = new SMESH::double_array();
04013   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
04014   if ( aSMESHDS_Mesh == NULL )
04015     return aResult._retn();
04016 
04017   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
04018   if(!elem)
04019     return aResult._retn();
04020 
04021   if(elem->GetType()==SMDSAbs_Volume) {
04022     SMDS_VolumeTool aTool;
04023     if(aTool.Set(elem)) {
04024       aResult->length(3);
04025       if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
04026         aResult->length(0);
04027     }
04028   }
04029   else {
04030     SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
04031     int nbn = 0;
04032     double x=0., y=0., z=0.;
04033     for(; anIt->more(); ) {
04034       nbn++;
04035       const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
04036       x += aNode->X();
04037       y += aNode->Y();
04038       z += aNode->Z();
04039     }
04040     if(nbn>0) {
04041       // add coordinates
04042       aResult->length(3);
04043       aResult[0] = x/nbn;
04044       aResult[1] = y/nbn;
04045       aResult[2] = z/nbn;
04046     }
04047   }
04048 
04049   return aResult._retn();
04050 }
04051 
04052 
04053 //=============================================================================
04057 //=============================================================================
04058 
04059 void SMESH_Mesh_i::CreateGroupServants() 
04060 {
04061   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
04062 
04063   set<int> addedIDs;
04064   ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
04065   while ( groupIt->more() )
04066   {
04067     ::SMESH_Group* group = groupIt->next();
04068     int            anId = group->GetGroupDS()->GetID();
04069 
04070     map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
04071     if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
04072       continue;
04073     addedIDs.insert( anId );
04074 
04075     SMESH_GroupBase_i* aGroupImpl;
04076     TopoDS_Shape       shape;
04077     if ( SMESHDS_GroupOnGeom* groupOnGeom =
04078          dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
04079     {
04080       aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
04081       shape      = groupOnGeom->GetShape();
04082     }
04083     else {
04084       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
04085     }
04086 
04087     // To ensure correct mapping of servant and correct reference counting in GenericObj_i
04088     SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
04089     aGroupImpl->Register();
04090 
04091     SMESH::SMESH_GroupBase_var groupVar =
04092       SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
04093     _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
04094 
04095     // register CORBA object for persistence
04096     int nextId = _gen_i->RegisterObject( groupVar );
04097     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
04098 
04099     // publishing the groups in the study
04100     if ( !aStudy->_is_nil() ) {
04101       GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
04102       _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
04103     }
04104   }
04105   if ( !addedIDs.empty() )
04106   {
04107     // python dump
04108     set<int>::iterator id = addedIDs.begin();
04109     for ( ; id != addedIDs.end(); ++id )
04110     {
04111       map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
04112       int i = std::distance( _mapGroups.begin(), it );
04113       TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
04114     }
04115   }
04116 }
04117 
04118 //=============================================================================
04122 //=============================================================================
04123 
04124 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
04125 {
04126   int nbGroups = groupIDs.size();
04127   SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
04128   aList->length( nbGroups );
04129 
04130   list<int>::const_iterator ids = groupIDs.begin();
04131   for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
04132   {
04133     map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
04134     if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
04135       aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
04136   }
04137   aList->length( nbGroups );
04138   return aList._retn();
04139 }
04140 
04141 //=============================================================================
04145 //=============================================================================
04146 
04147 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
04148 {
04149   SALOME_MED::MedFileInfo_var res( _medFileInfo );
04150   if ( !res.operator->() ) {
04151     res = new SALOME_MED::MedFileInfo;
04152     res->fileName = "";
04153     res->fileSize = res->major = res->minor = res->release = -1;
04154   }
04155   return res._retn();
04156 }
04157 
04158 //=============================================================================
04162 //=============================================================================
04163 
04164 void SMESH_Mesh_i::checkGroupNames()
04165 {
04166   int nbGrp = NbGroups();
04167   if ( !nbGrp )
04168     return;
04169 
04170   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
04171   if ( aStudy->_is_nil() )
04172     return; // nothing to do
04173   
04174   SMESH::ListOfGroups* grpList = 0;
04175   // avoid dump of "GetGroups"
04176   {
04177     // store python dump into a local variable inside local scope
04178     SMESH::TPythonDump pDump; // do not delete this line of code
04179     grpList = GetGroups();
04180   }
04181 
04182   for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
04183     SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
04184     if ( !aGrp )
04185       continue;
04186     SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
04187     if ( aGrpSO->_is_nil() )
04188       continue;
04189     // correct name of the mesh group if necessary
04190     const char* guiName = aGrpSO->GetName();
04191     if ( strcmp(guiName, aGrp->GetName()) )
04192       aGrp->SetName( guiName );
04193   }
04194 }
04195 
04196 //=============================================================================
04200 //=============================================================================
04201 void SMESH_Mesh_i::SetParameters(const char* theParameters)
04202 {
04203   // SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
04204   //                                              CORBA::string_dup(theParameters));
04205   SMESH_Gen_i::GetSMESHGen()->UpdateParameters(theParameters);
04206 }
04207 
04208 //=============================================================================
04212 //=============================================================================
04213 char* SMESH_Mesh_i::GetParameters()
04214 {
04215   SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
04216   return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
04217 }
04218 
04219 //=============================================================================
04223 //=============================================================================
04224 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
04225 {
04226   SMESH::string_array_var aResult = new SMESH::string_array();
04227   SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
04228   if(gen) {
04229     char *aParameters = GetParameters();
04230     SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
04231     if(!aStudy->_is_nil()) {
04232       SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters); 
04233       if(aSections->length() > 0) {
04234         SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
04235         aResult->length(aVars.length());
04236         for(int i = 0;i < aVars.length();i++)
04237           aResult[i] = CORBA::string_dup( aVars[i]);
04238       }
04239     }
04240   }
04241   return aResult._retn();
04242 }
04243 
04244 //=======================================================================
04245 //function : GetTypes
04246 //purpose  : Returns types of elements it contains
04247 //=======================================================================
04248 
04249 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
04250 {
04251   if ( _preMeshInfo )
04252     return _preMeshInfo->GetTypes();
04253 
04254   SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
04255 
04256   types->length( 4 );
04257   int nbTypes = 0;
04258   if (_impl->NbEdges())
04259     types[nbTypes++] = SMESH::EDGE;
04260   if (_impl->NbFaces())
04261     types[nbTypes++] = SMESH::FACE;
04262   if (_impl->NbVolumes())
04263     types[nbTypes++] = SMESH::VOLUME;
04264   if (_impl->Nb0DElements())
04265     types[nbTypes++] = SMESH::ELEM0D;
04266   types->length( nbTypes );
04267 
04268   return types._retn();
04269 }
04270 
04271 //=======================================================================
04272 //function : GetMesh
04273 //purpose  : Returns self
04274 //=======================================================================
04275 
04276 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
04277 {
04278   return SMESH::SMESH_Mesh::_duplicate( _this() );
04279 }
04280 
04281 //=======================================================================
04282 //function : IsMeshInfoCorrect
04283 //purpose  : * Returns false if GetMeshInfo() returns incorrect information that may
04284 //           * happen if mesh data is not yet fully loaded from the file of study.
04285 //=======================================================================
04286 
04287 bool SMESH_Mesh_i::IsMeshInfoCorrect()
04288 {
04289   return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
04290 }
04291 
04292 //=============================================================================
04296 //=============================================================================
04297 
04298 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
04299 {
04300   if ( _preMeshInfo )
04301     return _preMeshInfo->GetMeshInfo();
04302 
04303   SMESH::long_array_var aRes = new SMESH::long_array();
04304   aRes->length(SMESH::Entity_Last);
04305   for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
04306     aRes[i] = 0;
04307   SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
04308   if (!aMeshDS)
04309     return aRes._retn();
04310   const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
04311   for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
04312     aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
04313   return aRes._retn();
04314 }
04315 
04316 //=============================================================================
04320 //=============================================================================
04321 
04322 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
04323                                    SMESH::long_array&         theInfo)
04324 {
04325   if (!theItr) return;
04326   while (theItr->more())
04327     theInfo[ theItr->next()->GetEntityType() ]++;
04328 }
04329 
04330 //=============================================================================
04334 //=============================================================================
04335 
04336 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
04337 {
04338   TopAbs_ShapeEnum aType = TopAbs_SOLID;
04339   switch ( theDim ) {
04340   case 0: aType = TopAbs_VERTEX; break;
04341   case 1: aType = TopAbs_EDGE; break;
04342   case 2: aType = TopAbs_FACE; break;
04343   case 3:
04344   default:aType = TopAbs_SOLID; break;
04345   }
04346   return aType;
04347 }
04348 
04349 //=============================================================================
04358 //=============================================================================
04359 
04360 class SMESH_DimHyp
04361 {
04362  public:
04364   int _dim;    
04365   int _ownDim; 
04366   TopTools_MapOfShape _shapeMap;
04367   SMESH_subMesh*      _subMesh;
04368   list<const SMESHDS_Hypothesis*> _hypothesises; 
04369 
04371   SMESH_DimHyp(const SMESH_subMesh*  theSubMesh,
04372                const int             theDim,
04373                const TopoDS_Shape&   theShape)
04374   {
04375     _subMesh = (SMESH_subMesh*)theSubMesh;
04376     SetShape( theDim, theShape );
04377   }
04378 
04380   void SetShape(const int           theDim,
04381                 const TopoDS_Shape& theShape)
04382   {
04383     _dim = theDim;
04384     _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
04385     if (_dim >= _ownDim)
04386       _shapeMap.Add( theShape );
04387     else {
04388       TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
04389       for( ; anExp.More(); anExp.Next() )
04390         _shapeMap.Add( anExp.Current() );
04391     }
04392   }
04393 
04395   static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
04396                                const TopTools_MapOfShape& theToFind,
04397                                const TopAbs_ShapeEnum     theType)
04398   {
04399     bool isShared = false;
04400     TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
04401     for (; !isShared && anItr.More(); anItr.Next() )
04402     {
04403       const TopoDS_Shape aSubSh = anItr.Key();
04404       // check for case when concurrent dimensions are same
04405       isShared = theToFind.Contains( aSubSh );
04406       // check for sub-shape with concurrent dimension
04407       TopExp_Explorer anExp( aSubSh, theType );
04408       for ( ; !isShared && anExp.More(); anExp.Next() )
04409         isShared = theToFind.Contains( anExp.Current() );
04410     }
04411     return isShared;
04412   }
04413   
04415   static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
04416                         const SMESHDS_Hypothesis* theA2)
04417   {
04418     if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
04419          theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
04420       return false; // one of the hypothesis is not algorithm
04421     // check algorithm names (should be equal)
04422     return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
04423   }
04424 
04425   
04427   bool IsConcurrent(const SMESH_DimHyp* theOther) const
04428   {
04429     if ( _subMesh == theOther->_subMesh )
04430       return false; // same sub-shape - should not be
04431 
04432     // if ( <own dim of either of submeshes> == <concurrent dim> &&
04433     //      any of the two submeshes is not on COMPOUND shape )
04434     //  -> no concurrency
04435     bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
04436     bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
04437     if ( (_ownDim == _dim  || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
04438       return false;
04439 
04440 //     bool checkSubShape = ( _dim >= theOther->_dim )
04441 //       ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
04442 //       : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
04443     bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
04444     if ( !checkSubShape )
04445         return false;
04446 
04447     // check algorithms to be same
04448     if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
04449       return true; // different algorithms
04450     
04451     // check hypothesises for concurrence (skip first as algorithm)
04452     int nbSame = 0;
04453     // pointers should be same, becase it is referenes from mesh hypothesis partition
04454     list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
04455     list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
04456     for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
04457       if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
04458         nbSame++;
04459     // the submeshes are concurrent if their algorithms has different parameters
04460     return nbSame != theOther->_hypothesises.size() - 1;
04461   }
04462   
04463 }; // end of SMESH_DimHyp
04464 
04465 typedef list<SMESH_DimHyp*> TDimHypList;
04466 
04467 static void addDimHypInstance(const int               theDim, 
04468                               const TopoDS_Shape&     theShape,
04469                               const SMESH_Algo*       theAlgo,
04470                               const SMESH_subMesh*    theSubMesh,
04471                               const list <const SMESHDS_Hypothesis*>& theHypList,
04472                               TDimHypList*            theDimHypListArr )
04473 {
04474   TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
04475   if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
04476     SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
04477     listOfdimHyp.push_back( dimHyp );
04478   }
04479   
04480   SMESH_DimHyp* dimHyp = listOfdimHyp.back();
04481   dimHyp->_hypothesises.push_front(theAlgo);
04482   list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
04483   for( ; hypIt != theHypList.end(); hypIt++ )
04484     dimHyp->_hypothesises.push_back( *hypIt );
04485 }
04486 
04487 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
04488                             const TDimHypList&  theListOfDimHyp,
04489                             TListOfInt&         theListOfConcurr )
04490 {
04491   TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
04492   for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
04493     const SMESH_DimHyp* curDimHyp = *rIt;
04494     if ( curDimHyp == theDimHyp )
04495       break; // meet own dimHyp pointer in same dimension
04496     else if ( theDimHyp->IsConcurrent( curDimHyp ) )
04497       if ( find( theListOfConcurr.begin(),
04498                  theListOfConcurr.end(),
04499                  curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
04500         theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
04501   }
04502 }
04503 
04504 static void unionLists(TListOfInt&       theListOfId,
04505                        TListOfListOfInt& theListOfListOfId,
04506                        const int         theIndx )
04507 {
04508   TListOfListOfInt::iterator it = theListOfListOfId.begin();
04509   for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
04510     if ( i < theIndx )
04511       continue; //skip already treated lists
04512     // check if other list has any same submesh object
04513     TListOfInt& otherListOfId = *it;
04514     if ( find_first_of( theListOfId.begin(), theListOfId.end(),
04515                         otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
04516       continue;
04517          
04518     // union two lists (from source into target)
04519     TListOfInt::iterator it2 = otherListOfId.begin();
04520     for ( ; it2 != otherListOfId.end(); it2++ ) {
04521       if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
04522         theListOfId.push_back(*it2);
04523     }
04524     // clear source list
04525     otherListOfId.clear();
04526   }
04527 }
04528 
04530 static void removeDimHyps( TDimHypList* theArrOfList )
04531 {
04532   for (int i = 0; i < 4; i++ ) {
04533     TDimHypList& listOfdimHyp = theArrOfList[i];
04534     TDimHypList::const_iterator it = listOfdimHyp.begin();
04535     for ( ; it != listOfdimHyp.end(); it++ )
04536       delete (*it);
04537   }
04538 }
04539 
04540 //=============================================================================
04544 //=============================================================================
04545 
04546 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
04547 {
04548   SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
04549 
04550   SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
04551   if ( !aMeshDS )
04552     return aResult._retn();
04553   
04554   ::SMESH_Mesh& mesh = GetImpl();
04555   TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
04556   if ( !anOrder.size() ) {
04557 
04558     // collect submeshes detecting concurrent algorithms and hypothesises
04559     TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
04560     
04561     map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
04562     for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
04563       ::SMESH_subMesh* sm = (*i_sm).second;
04564       // shape of submesh
04565       const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
04566       
04567       // list of assigned hypothesises
04568       const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
04569       // Find out dimensions where the submesh can be concurrent.
04570       // We define the dimensions by algo of each of hypotheses in hypList
04571       list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
04572       for( ; hypIt != hypList.end(); hypIt++ ) {
04573         SMESH_Algo* anAlgo = 0;
04574         const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
04575         if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
04576           // hyp it-self is algo
04577           anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
04578         else {
04579           // try to find algorithm with help of sub-shapes
04580           TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
04581           for ( ; !anAlgo && anExp.More(); anExp.Next() )
04582             anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
04583         }
04584         if (!anAlgo)
04585           continue; // no assigned algorithm to current submesh
04586 
04587         int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
04588         // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
04589 
04590         // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
04591         for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
04592           addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
04593       }
04594     } // end iterations on submesh
04595     
04596     // iterate on created dimension-hypotheses and check for concurrents
04597     for ( int i = 0; i < 4; i++ ) {
04598       const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
04599       // check for concurrents in own and other dimensions (step-by-step)
04600       TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
04601       for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
04602         const SMESH_DimHyp* dimHyp = *dhIt;
04603         TListOfInt listOfConcurr;
04604         // looking for concurrents and collect into own list
04605         for ( int j = i; j < 4; j++ )
04606           findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
04607         // check if any concurrents found
04608         if ( listOfConcurr.size() > 0 ) {
04609           // add own submesh to list of concurrent
04610           listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
04611           anOrder.push_back( listOfConcurr );
04612         }
04613       }
04614     }
04615     
04616     removeDimHyps(dimHypListArr);
04617     
04618     // now, minimise the number of concurrent groups
04619     // Here we assume that lists of submeshes can have same submesh
04620     // in case of multi-dimension algorithms, as result
04621     //  list with common submesh has to be united into one list
04622     int listIndx = 0;
04623     TListOfListOfInt::iterator listIt = anOrder.begin();
04624     for(; listIt != anOrder.end(); listIt++, listIndx++ )
04625       unionLists( *listIt,  anOrder, listIndx + 1 );
04626   }
04627   // convert submesh ids into interface instances
04628   //  and dump command into python
04629   convertMeshOrder( anOrder, aResult, false );
04630 
04631   return aResult._retn();
04632 }
04633 
04634 //=============================================================================
04641 //=============================================================================
04642 
04643 static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
04644                                const SMESH_subMesh*        theSubMesh,
04645                                set<const SMESH_subMesh*>&  theCommon )
04646 {
04647   if ( !theSubMesh )
04648     return;
04649   list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
04650   for ( ; it != theSubMeshList.end(); it++ )
04651     theSubMesh->FindIntersection( *it, theCommon );
04652   theSubMeshList.push_back( theSubMesh );
04653   //theCommon.insert( theSubMesh );
04654 }
04655 
04656 //=============================================================================
04661 //=============================================================================
04662 
04663 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
04664 {
04665   if ( _preMeshInfo )
04666     _preMeshInfo->ForgetOrLoad();
04667 
04668   bool res = false;
04669   ::SMESH_Mesh& mesh = GetImpl();
04670 
04671   TPythonDump aPythonDump; // prevent dump of called methods
04672   aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
04673 
04674   TListOfListOfInt subMeshOrder;
04675   for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
04676   {
04677     const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
04678     TListOfInt subMeshIds;
04679     aPythonDump << "[ ";
04680     // Collect subMeshes which should be clear
04681     //  do it list-by-list, because modification of submesh order
04682     //  take effect between concurrent submeshes only
04683     set<const SMESH_subMesh*> subMeshToClear;
04684     list<const SMESH_subMesh*> subMeshList;
04685     for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
04686     {
04687       const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
04688       if ( j > 0 )
04689         aPythonDump << ", ";
04690       aPythonDump << subMesh;
04691       subMeshIds.push_back( subMesh->GetId() );
04692       // detect common parts of submeshes
04693       if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
04694         findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
04695     }
04696     aPythonDump << " ]";
04697     subMeshOrder.push_back( subMeshIds );
04698 
04699     // clear collected submeshes
04700     set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
04701     for ( ; clrIt != subMeshToClear.end(); clrIt++ )
04702       if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
04703         sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
04704   }
04705   aPythonDump << " ])";
04706 
04707   mesh.SetMeshOrder( subMeshOrder );
04708   res = true;
04709   
04710   return res;
04711 }
04712 
04713 //=============================================================================
04717 //=============================================================================
04718 
04719 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt&     theIdsOrder,
04720                                      SMESH::submesh_array_array& theResOrder,
04721                                      const bool                  theIsDump)
04722 {
04723   int nbSet = theIdsOrder.size();
04724   TPythonDump aPythonDump; // prevent dump of called methods
04725   if ( theIsDump )
04726     aPythonDump << "[ ";
04727   theResOrder.length(nbSet);
04728   TListOfListOfInt::const_iterator it = theIdsOrder.begin();
04729   int listIndx = 0;
04730   for( ; it != theIdsOrder.end(); it++ ) {
04731     // translate submesh identificators into submesh objects
04732     //  takeing into account real number of concurrent lists
04733     const TListOfInt& aSubOrder = (*it);
04734     if (!aSubOrder.size())
04735       continue;
04736     if ( theIsDump )
04737       aPythonDump << "[ ";
04738     // convert shape indeces into interfaces
04739     SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
04740     aResSubSet->length(aSubOrder.size());
04741     TListOfInt::const_iterator subIt = aSubOrder.begin();
04742     for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
04743       if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
04744         continue;
04745       SMESH::SMESH_subMesh_var subMesh =
04746         SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
04747       if ( theIsDump ) {
04748         if ( j > 0 )
04749           aPythonDump << ", ";
04750         aPythonDump << subMesh;
04751       }
04752       aResSubSet[ j++ ] = subMesh;
04753     }
04754     if ( theIsDump )
04755       aPythonDump << " ]";
04756     theResOrder[ listIndx++ ] = aResSubSet;
04757   }
04758   // correct number of lists
04759   theResOrder.length( listIndx );
04760 
04761   if ( theIsDump ) {
04762     // finilise python dump
04763     aPythonDump << " ]";
04764     aPythonDump << " = " << _this() << ".GetMeshOrder()";
04765   }
04766 }
04767 
04768 //================================================================================
04769 //
04770 // Implementation of SMESH_MeshPartDS
04771 //
04772 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
04773   SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
04774 {
04775   SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
04776   SMESH_Mesh_i*       mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
04777 
04778   _meshDS = mesh_i->GetImpl().GetMeshDS();
04779 
04780   SetPersistentId( _meshDS->GetPersistentId() );
04781 
04782   if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
04783   {
04784     // <meshPart> is the whole mesh
04785     myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
04786     // copy groups
04787     set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
04788     myGroupSet = _meshDS->GetGroups();
04789   }
04790   else
04791   {
04792     TMeshInfo tmpInfo;
04793     SMESH::long_array_var           anIDs = meshPart->GetIDs();
04794     SMESH::array_of_ElementType_var types = meshPart->GetTypes();
04795     if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
04796     {
04797       for (int i=0; i < anIDs->length(); i++)
04798         if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
04799           if ( _elements[ SMDSAbs_Node ].insert( n ).second )
04800             tmpInfo.Add( n );
04801     }
04802     else
04803     {
04804       for (int i=0; i < anIDs->length(); i++)
04805         if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
04806           if ( _elements[ e->GetType() ].insert( e ).second )
04807           {
04808             tmpInfo.Add( e );
04809             SMDS_ElemIteratorPtr nIt = e->nodesIterator();
04810             while ( nIt->more() )
04811             {
04812               const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
04813               if ( _elements[ SMDSAbs_Node ].insert( n ).second )
04814                 tmpInfo.Add( n );
04815             }
04816           }
04817     }
04818     myInfo = tmpInfo;
04819 
04820     _meshDS = 0; // to enforce iteration on _elements and _nodes
04821   }
04822 }
04823 // -------------------------------------------------------------------------------------
04824 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
04825 {
04826   typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
04827   if ( type == SMDSAbs_All && !_meshDS )
04828   {
04829     typedef vector< SMDS_ElemIteratorPtr > TIterVec;
04830     TIterVec iterVec;
04831     for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
04832       if ( !_elements[i].empty() && i != SMDSAbs_Node )
04833         iterVec.push_back
04834           ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
04835 
04836     typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
04837     return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
04838   }
04839   return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
04840       ( new TIter( _elements[type].begin(), _elements[type].end() ));
04841 }
04842 // -------------------------------------------------------------------------------------
04843 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType)                       \
04844   iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const                 \
04845   {                                                                                 \
04846     typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
04847     return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType                 \
04848       ( new TIter( _elements[elemType].begin(), _elements[elemType].end() ));       \
04849   }
04850 // -------------------------------------------------------------------------------------
04851 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
04852 _GET_ITER_DEFINE( SMDS_0DElementIteratorPtr, elements0dIterator, SMDS_Mesh0DElement, SMDSAbs_0DElement)
04853 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
04854 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
04855 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
04856 #undef _GET_ITER_DEFINE
04857 //
04858 // END Implementation of SMESH_MeshPartDS
04859 //
04860 //================================================================================