Back to index

salome-smesh  6.5.0
SMESH_Mesh.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 
00023 //  SMESH SMESH : implementaion of SMESH idl descriptions
00024 //  File   : SMESH_Mesh.cxx
00025 //  Author : Paul RASCLE, EDF
00026 //  Module : SMESH
00027 //
00028 #include "SMESH_Mesh.hxx"
00029 #include "SMESH_MesherHelper.hxx"
00030 #include "SMESH_subMesh.hxx"
00031 #include "SMESH_Gen.hxx"
00032 #include "SMESH_Hypothesis.hxx"
00033 #include "SMESH_Group.hxx"
00034 #include "SMESH_HypoFilter.hxx"
00035 #include "SMESHDS_Group.hxx"
00036 #include "SMESHDS_Script.hxx"
00037 #include "SMESHDS_GroupOnGeom.hxx"
00038 #include "SMESHDS_Document.hxx"
00039 #include "SMDS_MeshVolume.hxx"
00040 #include "SMDS_SetIterator.hxx"
00041 
00042 #include "utilities.h"
00043 
00044 #include "DriverMED_W_SMESHDS_Mesh.h"
00045 #include "DriverDAT_W_SMDS_Mesh.h"
00046 #include "DriverUNV_W_SMDS_Mesh.h"
00047 #include "DriverSTL_W_SMDS_Mesh.h"
00048 
00049 #include "DriverMED_R_SMESHDS_Mesh.h"
00050 #include "DriverUNV_R_SMDS_Mesh.h"
00051 #include "DriverSTL_R_SMDS_Mesh.h"
00052 #ifdef WITH_CGNS
00053 #include "DriverCGNS_Read.hxx"
00054 #include "DriverCGNS_Write.hxx"
00055 #endif
00056 
00057 #undef _Precision_HeaderFile
00058 #include <BRepBndLib.hxx>
00059 #include <BRepPrimAPI_MakeBox.hxx>
00060 #include <Bnd_Box.hxx>
00061 #include <TopExp.hxx>
00062 #include <TopExp_Explorer.hxx>
00063 #include <TopTools_ListIteratorOfListOfShape.hxx>
00064 #include <TopTools_ListOfShape.hxx>
00065 #include <TopTools_MapOfShape.hxx>
00066 #include <TopoDS_Iterator.hxx>
00067 
00068 #include "Utils_ExceptHandlers.hxx"
00069 
00070 #include <boost/thread/thread.hpp>
00071 #include <boost/bind.hpp>
00072 
00073 using namespace std;
00074 
00075 // maximum stored group name length in MED file
00076 #define MAX_MED_GROUP_NAME_LENGTH 80
00077 
00078 #ifdef _DEBUG_
00079 static int MYDEBUG = 0;
00080 #else
00081 static int MYDEBUG = 0;
00082 #endif
00083 
00084 #define cSMESH_Hyp(h) static_cast<const SMESH_Hypothesis*>(h)
00085 
00086 typedef SMESH_HypoFilter THypType;
00087 
00088 //=============================================================================
00092 //=============================================================================
00093 
00094 SMESH_Mesh::SMESH_Mesh(int               theLocalId, 
00095                        int               theStudyId, 
00096                        SMESH_Gen*        theGen,
00097                        bool              theIsEmbeddedMode,
00098                        SMESHDS_Document* theDocument):
00099   _groupId( 0 ), _nbSubShapes( 0 )
00100 {
00101   MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)");
00102   _id            = theLocalId;
00103   _studyId       = theStudyId;
00104   _gen           = theGen;
00105   _myDocument    = theDocument;
00106   _idDoc         = theDocument->NewMesh(theIsEmbeddedMode);
00107   _myMeshDS      = theDocument->GetMesh(_idDoc);
00108   _isShapeToMesh = false;
00109   _isAutoColor   = false;
00110   _isModified    = false;
00111   _shapeDiagonal = 0.0;
00112   _callUp = 0;
00113   _myMeshDS->ShapeToMesh( PseudoShape() );
00114 }
00115 
00116 //================================================================================
00120 //================================================================================
00121 
00122 SMESH_Mesh::SMESH_Mesh():
00123   _id(-1),
00124   _studyId(-1),
00125   _idDoc(-1),
00126   _groupId( 0 ),
00127   _nbSubShapes( 0 ),
00128   _isShapeToMesh( false ),
00129   _myDocument( 0 ),
00130   _myMeshDS( 0 ),
00131   _gen( 0 ),
00132   _isAutoColor( false ),
00133   _isModified( false ),
00134   _shapeDiagonal( 0.0 ),
00135   _callUp( 0 )
00136 {
00137 }
00138 
00139 namespace
00140 {
00141   void deleteMeshDS(SMESHDS_Mesh* meshDS)
00142   {
00143     //cout << "deleteMeshDS( " << meshDS << endl;
00144     delete meshDS;
00145   }
00146 }
00147 
00148 //=============================================================================
00152 //=============================================================================
00153 
00154 SMESH_Mesh::~SMESH_Mesh()
00155 {
00156   MESSAGE("SMESH_Mesh::~SMESH_Mesh");
00157 
00158   // issue 0020340: EDF 1022 SMESH : Crash with FindNodeClosestTo in a second new study
00159   //   Notify event listeners at least that something happens
00160   if ( SMESH_subMesh * sm = GetSubMeshContaining(1))
00161     sm->ComputeStateEngine( SMESH_subMesh::MESH_ENTITY_REMOVED );
00162 
00163   // delete groups
00164   map < int, SMESH_Group * >::iterator itg;
00165   for (itg = _mapGroup.begin(); itg != _mapGroup.end(); itg++) {
00166     SMESH_Group *aGroup = (*itg).second;
00167     delete aGroup;
00168   }
00169   _mapGroup.clear();
00170 
00171   // delete sub-meshes
00172   map <int, SMESH_subMesh*>::iterator sm = _mapSubMesh.begin();
00173   for ( ; sm != _mapSubMesh.end(); ++sm )
00174   {
00175     delete sm->second;
00176     sm->second = 0;
00177   }
00178   _mapSubMesh.clear();
00179 
00180   if ( _callUp) delete _callUp;
00181   _callUp = 0;
00182 
00183   // remove self from studyContext
00184   if ( _gen )
00185   {
00186     StudyContextStruct * studyContext = _gen->GetStudyContext( _studyId );
00187     studyContext->mapMesh.erase( _id );
00188   }
00189   if ( _myDocument )
00190     _myDocument->RemoveMesh( _id );
00191   _myDocument = 0;
00192 
00193   if ( _myMeshDS )
00194     // delete _myMeshDS, in a thread in order not to block closing a study with large meshes
00195     boost::thread aThread(boost::bind( & deleteMeshDS, _myMeshDS ));
00196 }
00197 
00198 //================================================================================
00202 //================================================================================
00203 
00204 bool SMESH_Mesh::MeshExists( int meshId ) const
00205 {
00206   return _myDocument ? _myDocument->GetMesh( meshId ) : false;
00207 }
00208 
00209 //=============================================================================
00213 //=============================================================================
00214 
00215 void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
00216 {
00217   if(MYDEBUG) MESSAGE("SMESH_Mesh::ShapeToMesh");
00218 
00219   if ( !aShape.IsNull() && _isShapeToMesh ) {
00220     if ( aShape.ShapeType() != TopAbs_COMPOUND && // group contents is allowed to change
00221          _myMeshDS->ShapeToMesh().ShapeType() != TopAbs_COMPOUND )
00222       throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined"));
00223   }
00224   // clear current data
00225   if ( !_myMeshDS->ShapeToMesh().IsNull() )
00226   {
00227     // removal of a shape to mesh, delete objects referring to sub-shapes:
00228     // - sub-meshes
00229     map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.begin();
00230     for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
00231       delete i_sm->second;
00232     _mapSubMesh.clear();
00233     //  - groups on geometry
00234     map <int, SMESH_Group *>::iterator i_gr = _mapGroup.begin();
00235     while ( i_gr != _mapGroup.end() ) {
00236       if ( dynamic_cast<SMESHDS_GroupOnGeom*>( i_gr->second->GetGroupDS() )) {
00237         _myMeshDS->RemoveGroup( i_gr->second->GetGroupDS() );
00238         delete i_gr->second;
00239         _mapGroup.erase( i_gr++ );
00240       }
00241       else
00242         i_gr++;
00243     }
00244     _mapAncestors.Clear();
00245 
00246     // clear SMESHDS
00247     TopoDS_Shape aNullShape;
00248     _myMeshDS->ShapeToMesh( aNullShape );
00249 
00250     _shapeDiagonal = 0.0;
00251   }
00252 
00253   // set a new geometry
00254   if ( !aShape.IsNull() )
00255   {
00256     _myMeshDS->ShapeToMesh(aShape);
00257     _isShapeToMesh = true;
00258     _nbSubShapes = _myMeshDS->MaxShapeIndex();
00259 
00260     // fill map of ancestors
00261     fillAncestorsMap(aShape);
00262   }
00263   else
00264   {
00265     _isShapeToMesh = false;
00266     _shapeDiagonal = 0.0;
00267     _myMeshDS->ShapeToMesh( PseudoShape() );
00268   }
00269   _isModified = false;
00270 }
00271 
00272 //=======================================================================
00276 //=======================================================================
00277 
00278 TopoDS_Shape SMESH_Mesh::GetShapeToMesh() const
00279 {
00280   return _myMeshDS->ShapeToMesh();
00281 }
00282 
00283 //=======================================================================
00288 //=======================================================================
00289 
00290 const TopoDS_Solid& SMESH_Mesh::PseudoShape()
00291 {
00292   static TopoDS_Solid aSolid;
00293   if ( aSolid.IsNull() )
00294   {
00295     aSolid = BRepPrimAPI_MakeBox(1,1,1);
00296   }
00297   return aSolid;
00298 }
00299 
00300 //=======================================================================
00304 //=======================================================================
00305 
00306 double SMESH_Mesh::GetShapeDiagonalSize(const TopoDS_Shape & aShape)
00307 {
00308   if ( !aShape.IsNull() ) {
00309     Bnd_Box Box;
00310     BRepBndLib::Add(aShape, Box);
00311     return sqrt( Box.SquareExtent() );
00312   }
00313   return 0;
00314 }
00315 
00316 //=======================================================================
00320 //=======================================================================
00321 
00322 double SMESH_Mesh::GetShapeDiagonalSize() const
00323 {
00324   if ( _shapeDiagonal == 0. && _isShapeToMesh )
00325     const_cast<SMESH_Mesh*>(this)->_shapeDiagonal = GetShapeDiagonalSize( GetShapeToMesh() );
00326 
00327   return _shapeDiagonal;
00328 }
00329 
00330 //================================================================================
00334 //================================================================================
00335 
00336 void SMESH_Mesh::Load()
00337 {
00338   if (_callUp)
00339     _callUp->Load();
00340 }
00341 
00342 //=======================================================================
00346 //=======================================================================
00347 
00348 void SMESH_Mesh::Clear()
00349 {
00350   // clear mesh data
00351   _myMeshDS->ClearMesh();
00352 
00353   // update compute state of submeshes
00354   if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) )
00355   {
00356     sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
00357     sm->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
00358     sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); // for event listeners (issue 0020918)
00359     sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
00360   }
00361   _isModified = false;
00362 }
00363 
00364 //=======================================================================
00368 //=======================================================================
00369 
00370 void SMESH_Mesh::ClearSubMesh(const int theShapeId)
00371 {
00372   // clear sub-meshes; get ready to re-compute as a side-effect 
00373   if ( SMESH_subMesh *sm = GetSubMeshContaining( theShapeId ) )
00374   {
00375     SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
00376                                                              /*complexShapeFirst=*/false);
00377     while ( smIt->more() )
00378     {
00379       sm = smIt->next();
00380       TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType();      
00381       if ( shapeType == TopAbs_VERTEX || shapeType < TopAbs_SOLID )
00382         // all other shapes depends on vertices so they are already cleaned
00383         sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
00384       // to recompute even if failed
00385       sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
00386     }
00387   }
00388 }
00389 
00390 //=======================================================================
00391 //function : UNVToMesh
00392 //purpose  : 
00393 //=======================================================================
00394 
00395 int SMESH_Mesh::UNVToMesh(const char* theFileName)
00396 {
00397   if(MYDEBUG) MESSAGE("UNVToMesh - theFileName = "<<theFileName);
00398   if(_isShapeToMesh)
00399     throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
00400   _isShapeToMesh = false;
00401   DriverUNV_R_SMDS_Mesh myReader;
00402   myReader.SetMesh(_myMeshDS);
00403   myReader.SetFile(theFileName);
00404   myReader.SetMeshId(-1);
00405   myReader.Perform();
00406   if(MYDEBUG){
00407     MESSAGE("UNVToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
00408     MESSAGE("UNVToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
00409     MESSAGE("UNVToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
00410     MESSAGE("UNVToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
00411   }
00412   SMDS_MeshGroup* aGroup = (SMDS_MeshGroup*) myReader.GetGroup();
00413   if (aGroup != 0) {
00414     TGroupNamesMap aGroupNames = myReader.GetGroupNamesMap();
00415     //const TGroupIdMap& aGroupId = myReader.GetGroupIdMap();
00416     aGroup->InitSubGroupsIterator();
00417     while (aGroup->MoreSubGroups()) {
00418       SMDS_MeshGroup* aSubGroup = (SMDS_MeshGroup*) aGroup->NextSubGroup();
00419       string aName = aGroupNames[aSubGroup];
00420       int aId;
00421 
00422       SMESH_Group* aSMESHGroup = AddGroup( aSubGroup->GetType(), aName.c_str(), aId );
00423       if ( aSMESHGroup ) {
00424         if(MYDEBUG) MESSAGE("UNVToMesh - group added: "<<aName);      
00425         SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( aSMESHGroup->GetGroupDS() );
00426         if ( aGroupDS ) {
00427           aGroupDS->SetStoreName(aName.c_str());
00428           aSubGroup->InitIterator();
00429           const SMDS_MeshElement* aElement = 0;
00430           while (aSubGroup->More()) {
00431             aElement = aSubGroup->Next();
00432             if (aElement) {
00433               aGroupDS->SMDSGroup().Add(aElement);
00434             }
00435           }
00436           if (aElement)
00437             aGroupDS->SetType(aElement->GetType());
00438         }
00439       }
00440     }
00441   }
00442   return 1;
00443 }
00444 
00445 //=======================================================================
00446 //function : MEDToMesh
00447 //purpose  : 
00448 //=======================================================================
00449 
00450 int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName)
00451 {
00452   if(MYDEBUG) MESSAGE("MEDToMesh - theFileName = "<<theFileName<<", mesh name = "<<theMeshName);
00453   if(_isShapeToMesh)
00454     throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
00455   _isShapeToMesh = false;
00456   DriverMED_R_SMESHDS_Mesh myReader;
00457   myReader.SetMesh(_myMeshDS);
00458   myReader.SetMeshId(-1);
00459   myReader.SetFile(theFileName);
00460   myReader.SetMeshName(theMeshName);
00461   Driver_Mesh::Status status = myReader.Perform();
00462   if(MYDEBUG){
00463     MESSAGE("MEDToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
00464     MESSAGE("MEDToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
00465     MESSAGE("MEDToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
00466     MESSAGE("MEDToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
00467   }
00468 
00469   // Reading groups (sub-meshes are out of scope of MED import functionality)
00470   list<TNameAndType> aGroupNames = myReader.GetGroupNamesAndTypes();
00471   if(MYDEBUG) MESSAGE("MEDToMesh - Nb groups = "<<aGroupNames.size()); 
00472   int anId;
00473   list<TNameAndType>::iterator name_type = aGroupNames.begin();
00474   for ( ; name_type != aGroupNames.end(); name_type++ ) {
00475     SMESH_Group* aGroup = AddGroup( name_type->second, name_type->first.c_str(), anId );
00476     if ( aGroup ) {
00477       if(MYDEBUG) MESSAGE("MEDToMesh - group added: "<<name_type->first.c_str());      
00478       SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( aGroup->GetGroupDS() );
00479       if ( aGroupDS ) {
00480         aGroupDS->SetStoreName( name_type->first.c_str() );
00481         myReader.GetGroup( aGroupDS );
00482       }
00483     }
00484   }
00485   return (int) status;
00486 }
00487 
00488 //=======================================================================
00489 //function : STLToMesh
00490 //purpose  : 
00491 //=======================================================================
00492 
00493 int SMESH_Mesh::STLToMesh(const char* theFileName)
00494 {
00495   if(MYDEBUG) MESSAGE("STLToMesh - theFileName = "<<theFileName);
00496   if(_isShapeToMesh)
00497     throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
00498   _isShapeToMesh = false;
00499   DriverSTL_R_SMDS_Mesh myReader;
00500   myReader.SetMesh(_myMeshDS);
00501   myReader.SetFile(theFileName);
00502   myReader.SetMeshId(-1);
00503   myReader.Perform();
00504   if(MYDEBUG){
00505     MESSAGE("STLToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
00506     MESSAGE("STLToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
00507     MESSAGE("STLToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
00508     MESSAGE("STLToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
00509   }
00510   return 1;
00511 }
00512 
00513 //================================================================================
00519 //================================================================================
00520 
00521 int SMESH_Mesh::CGNSToMesh(const char*  theFileName,
00522                            const int    theMeshIndex,
00523                            std::string& theMeshName)
00524 {
00525   int res = Driver_Mesh::DRS_FAIL;
00526 #ifdef WITH_CGNS
00527 
00528   DriverCGNS_Read myReader;
00529   myReader.SetMesh(_myMeshDS);
00530   myReader.SetFile(theFileName);
00531   myReader.SetMeshId(theMeshIndex);
00532   res = myReader.Perform();
00533   theMeshName = myReader.GetMeshName();
00534 
00535   // create groups
00536   SynchronizeGroups();
00537 
00538 #endif
00539   return res;
00540 }
00541 
00542 //=============================================================================
00546 //=============================================================================
00547 
00548 SMESH_Hypothesis::Hypothesis_Status
00549   SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
00550                             int                  anHypId  ) throw(SALOME_Exception)
00551 {
00552   Unexpect aCatch(SalomeException);
00553   if(MYDEBUG) MESSAGE("SMESH_Mesh::AddHypothesis");
00554 
00555   SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
00556   if ( !subMesh || !subMesh->GetId())
00557     return SMESH_Hypothesis::HYP_BAD_SUBSHAPE;
00558 
00559   StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
00560   if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
00561   {
00562     if(MYDEBUG) MESSAGE("Hypothesis ID does not give an hypothesis");
00563     if(MYDEBUG) {
00564       SCRUTE(_studyId);
00565       SCRUTE(anHypId);
00566     }
00567     throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
00568   }
00569 
00570   SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
00571   MESSAGE( "SMESH_Mesh::AddHypothesis " << anHyp->GetName() );
00572 
00573   bool isGlobalHyp = IsMainShape( aSubShape );
00574 
00575   // NotConformAllowed can be only global
00576   if ( !isGlobalHyp )
00577   {
00578     // NOTE: this is not a correct way to check a name of hypothesis,
00579     // there should be an attribute of hypothesis saying that it can/can't
00580     // be global/local
00581     string hypName = anHyp->GetName();
00582     if ( hypName == "NotConformAllowed" )
00583     {
00584       if(MYDEBUG) MESSAGE( "Hypotesis <NotConformAllowed> can be only global" );
00585       return SMESH_Hypothesis::HYP_INCOMPATIBLE;
00586     }
00587   }
00588 
00589   // shape 
00590 
00591   bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
00592   int event = isAlgo ? SMESH_subMesh::ADD_ALGO : SMESH_subMesh::ADD_HYP;
00593 
00594   SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
00595 
00596   // sub-shapes
00597   if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
00598       anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is added on father
00599   {
00600     event = isAlgo ? SMESH_subMesh::ADD_FATHER_ALGO : SMESH_subMesh::ADD_FATHER_HYP;
00601 
00602     SMESH_Hypothesis::Hypothesis_Status ret2 =
00603       subMesh->SubMeshesAlgoStateEngine(event, anHyp);
00604     if (ret2 > ret)
00605       ret = ret2;
00606 
00607     // check concurent hypotheses on ancestors
00608     if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
00609     {
00610       SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
00611       while ( smIt->more() ) {
00612         SMESH_subMesh* sm = smIt->next();
00613         if ( sm->IsApplicableHypotesis( anHyp )) {
00614           ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
00615           if (ret2 > ret) {
00616             ret = ret2;
00617             break;
00618           }
00619         }
00620       }
00621     }
00622   }
00623   HasModificationsToDiscard(); // to reset _isModified flag if a mesh becomes empty
00624 
00625   GetMeshDS()->Modified();
00626 
00627   if(MYDEBUG) subMesh->DumpAlgoState(true);
00628   if(MYDEBUG) SCRUTE(ret);
00629   return ret;
00630 }
00631 
00632 //=============================================================================
00636 //=============================================================================
00637 
00638 SMESH_Hypothesis::Hypothesis_Status
00639   SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
00640                                int anHypId)throw(SALOME_Exception)
00641 {
00642   Unexpect aCatch(SalomeException);
00643   if(MYDEBUG) MESSAGE("SMESH_Mesh::RemoveHypothesis");
00644   
00645   StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
00646   if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
00647     throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
00648   
00649   SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
00650   if(MYDEBUG) {
00651     int hypType = anHyp->GetType();
00652     SCRUTE(hypType);
00653   }
00654   
00655   // shape 
00656   
00657   bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
00658   int event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP;
00659 
00660   SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
00661 
00662   SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
00663 
00664   // there may appear concurrent hyps that were covered by the removed hyp
00665   if (ret < SMESH_Hypothesis::HYP_CONCURENT &&
00666       subMesh->IsApplicableHypotesis( anHyp ) &&
00667       subMesh->CheckConcurentHypothesis( anHyp->GetType() ) != SMESH_Hypothesis::HYP_OK)
00668     ret = SMESH_Hypothesis::HYP_CONCURENT;
00669 
00670   // sub-shapes
00671   if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
00672       anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is removed from father
00673   {
00674     event = isAlgo ? SMESH_subMesh::REMOVE_FATHER_ALGO : SMESH_subMesh::REMOVE_FATHER_HYP;
00675 
00676     SMESH_Hypothesis::Hypothesis_Status ret2 =
00677       subMesh->SubMeshesAlgoStateEngine(event, anHyp);
00678     if (ret2 > ret) // more severe
00679       ret = ret2;
00680 
00681     // check concurent hypotheses on ancestors
00682     if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) )
00683     {
00684       SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
00685       while ( smIt->more() ) {
00686         SMESH_subMesh* sm = smIt->next();
00687         if ( sm->IsApplicableHypotesis( anHyp )) {
00688           ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
00689           if (ret2 > ret) {
00690             ret = ret2;
00691             break;
00692           }
00693         }
00694       }
00695     }
00696   }
00697 
00698   HasModificationsToDiscard(); // to reset _isModified flag if mesh become empty
00699 
00700   GetMeshDS()->Modified();
00701 
00702   if(MYDEBUG) subMesh->DumpAlgoState(true);
00703   if(MYDEBUG) SCRUTE(ret);
00704   return ret;
00705 }
00706 
00707 //=============================================================================
00711 //=============================================================================
00712 
00713 const list<const SMESHDS_Hypothesis*>&
00714 SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const
00715   throw(SALOME_Exception)
00716 {
00717   Unexpect aCatch(SalomeException);
00718   return _myMeshDS->GetHypothesis(aSubShape);
00719 }
00720 
00721 //=======================================================================
00730 //=======================================================================
00731 
00732 const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape &    aSubShape,
00733                                                    const SMESH_HypoFilter& aFilter,
00734                                                    const bool              andAncestors,
00735                                                    TopoDS_Shape*           assignedTo) const
00736 {
00737   {
00738     const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
00739     list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
00740     for ( ; hyp != hypList.end(); hyp++ ) {
00741       const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp );
00742       if ( aFilter.IsOk( h, aSubShape)) {
00743         if ( assignedTo ) *assignedTo = aSubShape;
00744         return h;
00745       }
00746     }
00747   }
00748   if ( andAncestors )
00749   {
00750     // user sorted submeshes of ancestors, according to stored submesh priority
00751     const list<SMESH_subMesh*> smList = getAncestorsSubMeshes( aSubShape );
00752     list<SMESH_subMesh*>::const_iterator smIt = smList.begin(); 
00753     for ( ; smIt != smList.end(); smIt++ )
00754     {
00755       const TopoDS_Shape& curSh = (*smIt)->GetSubShape();
00756       const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(curSh);
00757       list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
00758       for ( ; hyp != hypList.end(); hyp++ ) {
00759         const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp );
00760         if (aFilter.IsOk( h, curSh )) {
00761           if ( assignedTo ) *assignedTo = curSh;
00762           return h;
00763         }
00764       }
00765     }
00766   }
00767   return 0;
00768 }
00769 
00770 //================================================================================
00779 //================================================================================
00780 
00781 int SMESH_Mesh::GetHypotheses(const TopoDS_Shape &                aSubShape,
00782                               const SMESH_HypoFilter&             aFilter,
00783                               list <const SMESHDS_Hypothesis * >& aHypList,
00784                               const bool                          andAncestors) const
00785 {
00786   set<string> hypTypes; // to exclude same type hypos from the result list
00787   int nbHyps = 0;
00788 
00789   // only one main hypothesis is allowed
00790   bool mainHypFound = false;
00791 
00792   // fill in hypTypes
00793   list<const SMESHDS_Hypothesis*>::const_iterator hyp;
00794   for ( hyp = aHypList.begin(); hyp != aHypList.end(); hyp++ ) {
00795     if ( hypTypes.insert( (*hyp)->GetName() ).second )
00796       nbHyps++;
00797     if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
00798       mainHypFound = true;
00799   }
00800 
00801   // get hypos from aSubShape
00802   {
00803     const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
00804     for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
00805       if ( aFilter.IsOk (cSMESH_Hyp( *hyp ), aSubShape) &&
00806            ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
00807            hypTypes.insert( (*hyp)->GetName() ).second )
00808       {
00809         aHypList.push_back( *hyp );
00810         nbHyps++;
00811         if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
00812           mainHypFound = true;
00813       }
00814   }
00815 
00816   // get hypos from ancestors of aSubShape
00817   if ( andAncestors )
00818   {
00819     TopTools_MapOfShape map;
00820 
00821     // user sorted submeshes of ancestors, according to stored submesh priority
00822     const list<SMESH_subMesh*> smList = getAncestorsSubMeshes( aSubShape );
00823     list<SMESH_subMesh*>::const_iterator smIt = smList.begin(); 
00824     for ( ; smIt != smList.end(); smIt++ )
00825     {
00826       const TopoDS_Shape& curSh = (*smIt)->GetSubShape();
00827      if ( !map.Add( curSh ))
00828         continue;
00829       const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(curSh);
00830       for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
00831         if (aFilter.IsOk( cSMESH_Hyp( *hyp ), curSh ) &&
00832             ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
00833             hypTypes.insert( (*hyp)->GetName() ).second )
00834         {
00835           aHypList.push_back( *hyp );
00836           nbHyps++;
00837           if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
00838             mainHypFound = true;
00839         }
00840     }
00841   }
00842   return nbHyps;
00843 }
00844 
00845 //=============================================================================
00849 //=============================================================================
00850 
00851 const list<SMESHDS_Command*> & SMESH_Mesh::GetLog() throw(SALOME_Exception)
00852 {
00853   Unexpect aCatch(SalomeException);
00854   if(MYDEBUG) MESSAGE("SMESH_Mesh::GetLog");
00855   return _myMeshDS->GetScript()->GetCommands();
00856 }
00857 
00858 //=============================================================================
00862 //=============================================================================
00863 void SMESH_Mesh::ClearLog() throw(SALOME_Exception)
00864 {
00865   Unexpect aCatch(SalomeException);
00866   if(MYDEBUG) MESSAGE("SMESH_Mesh::ClearLog");
00867   _myMeshDS->GetScript()->Clear();
00868 }
00869 
00870 //=============================================================================
00874 //=============================================================================
00875 
00876 SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
00877   throw(SALOME_Exception)
00878 {
00879   Unexpect aCatch(SalomeException);
00880   SMESH_subMesh *aSubMesh;
00881   int index = _myMeshDS->ShapeToIndex(aSubShape);
00882 
00883   // for submeshes on GEOM Group
00884   if (( !index || index > _nbSubShapes ) && aSubShape.ShapeType() == TopAbs_COMPOUND ) {
00885     TopoDS_Iterator it( aSubShape );
00886     if ( it.More() )
00887     {
00888       index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() );
00889       if ( index > _nbSubShapes ) _nbSubShapes = index; // not to create sm for this group again
00890 
00891       // fill map of Ancestors
00892       fillAncestorsMap(aSubShape);
00893     }
00894   }
00895 //   if ( !index )
00896 //     return NULL; // neither sub-shape nor a group
00897 
00898   map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.find(index);
00899   if ( i_sm != _mapSubMesh.end())
00900   {
00901     aSubMesh = i_sm->second;
00902   }
00903   else
00904   {
00905     aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
00906     _mapSubMesh[index] = aSubMesh;
00907   }
00908   return aSubMesh;
00909 }
00910 
00911 //=============================================================================
00916 //=============================================================================
00917 
00918 SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape) const
00919   throw(SALOME_Exception)
00920 {
00921   Unexpect aCatch(SalomeException);
00922   SMESH_subMesh *aSubMesh = NULL;
00923   
00924   int index = _myMeshDS->ShapeToIndex(aSubShape);
00925 
00926   map <int, SMESH_subMesh *>::const_iterator i_sm = _mapSubMesh.find(index);
00927   if ( i_sm != _mapSubMesh.end())
00928     aSubMesh = i_sm->second;
00929 
00930   return aSubMesh;
00931 }
00932 //=============================================================================
00937 //=============================================================================
00938 
00939 SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const int aShapeID) const
00940 throw(SALOME_Exception)
00941 {
00942   Unexpect aCatch(SalomeException);
00943   
00944   map <int, SMESH_subMesh *>::const_iterator i_sm = _mapSubMesh.find(aShapeID);
00945   if (i_sm == _mapSubMesh.end())
00946     return NULL;
00947   return i_sm->second;
00948 }
00949 //================================================================================
00953 //================================================================================
00954 
00955 list<SMESH_subMesh*>
00956 SMESH_Mesh::GetGroupSubMeshesContaining(const TopoDS_Shape & aSubShape) const
00957   throw(SALOME_Exception)
00958 {
00959   Unexpect aCatch(SalomeException);
00960   list<SMESH_subMesh*> found;
00961 
00962   SMESH_subMesh * subMesh = GetSubMeshContaining(aSubShape);
00963   if ( !subMesh )
00964     return found;
00965 
00966   // submeshes of groups have max IDs, so search from the map end
00967   map<int, SMESH_subMesh *>::const_reverse_iterator i_sm;
00968   for ( i_sm = _mapSubMesh.rbegin(); i_sm != _mapSubMesh.rend(); ++i_sm) {
00969     SMESHDS_SubMesh * ds = i_sm->second->GetSubMeshDS();
00970     if ( ds && ds->IsComplexSubmesh() ) {
00971       if ( SMESH_MesherHelper::IsSubShape( aSubShape, i_sm->second->GetSubShape() ))
00972       {
00973         found.push_back( i_sm->second );
00974         //break;
00975       }
00976     } else {
00977       break; // the rest sub-meshes are not those of groups
00978     }
00979   }
00980 
00981   if ( found.empty() ) // maybe the main shape is a COMPOUND (issue 0021530)
00982   {
00983     if ( SMESH_subMesh * mainSM = GetSubMeshContaining(1))
00984       if ( mainSM->GetSubShape().ShapeType() == TopAbs_COMPOUND )
00985       {
00986         TopoDS_Iterator it( mainSM->GetSubShape() );
00987         if ( it.Value().ShapeType() == aSubShape.ShapeType() &&
00988              SMESH_MesherHelper::IsSubShape( aSubShape, mainSM->GetSubShape() ))
00989           found.push_back( mainSM );
00990       }
00991   }
00992   return found;
00993 }
00994 //=======================================================================
00995 //function : IsUsedHypothesis
00996 //purpose  : Return True if anHyp is used to mesh aSubShape
00997 //=======================================================================
00998 
00999 bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
01000                                   const SMESH_subMesh* aSubMesh)
01001 {
01002   SMESH_Hypothesis* hyp = static_cast<SMESH_Hypothesis*>(anHyp);
01003 
01004   // check if anHyp can be used to mesh aSubMesh
01005   if ( !aSubMesh || !aSubMesh->IsApplicableHypotesis( hyp ))
01006     return false;
01007 
01008   const TopoDS_Shape & aSubShape = const_cast<SMESH_subMesh*>( aSubMesh )->GetSubShape();
01009 
01010   SMESH_Algo *algo = _gen->GetAlgo(*this, aSubShape );
01011 
01012   // algorithm
01013   if (anHyp->GetType() > SMESHDS_Hypothesis::PARAM_ALGO)
01014     return ( anHyp == algo );
01015 
01016   // algorithm parameter
01017   if (algo)
01018   {
01019     // look trough hypotheses used by algo
01020     SMESH_HypoFilter hypoKind;
01021     if ( algo->InitCompatibleHypoFilter( hypoKind, !hyp->IsAuxiliary() )) {
01022       list <const SMESHDS_Hypothesis * > usedHyps;
01023       if ( GetHypotheses( aSubShape, hypoKind, usedHyps, true ))
01024         return ( find( usedHyps.begin(), usedHyps.end(), anHyp ) != usedHyps.end() );
01025     }
01026   }
01027 
01028   // look through all assigned hypotheses
01029   //SMESH_HypoFilter filter( SMESH_HypoFilter::Is( hyp ));
01030   return false; //GetHypothesis( aSubShape, filter, true );
01031 }
01032 
01033 //=============================================================================
01037 //=============================================================================
01038 
01039 const list < SMESH_subMesh * >&
01040 SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
01041   throw(SALOME_Exception)
01042 {
01043   Unexpect aCatch(SalomeException);
01044   if(MYDEBUG) MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis");
01045   map < int, SMESH_subMesh * >::iterator itsm;
01046   _subMeshesUsingHypothesisList.clear();
01047   for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
01048   {
01049     SMESH_subMesh *aSubMesh = (*itsm).second;
01050     if ( IsUsedHypothesis ( anHyp, aSubMesh ))
01051       _subMeshesUsingHypothesisList.push_back(aSubMesh);
01052   }
01053   return _subMeshesUsingHypothesisList;
01054 }
01055 
01056 //=======================================================================
01057 //function : NotifySubMeshesHypothesisModification
01058 //purpose  : Say all submeshes using theChangedHyp that it has been modified
01059 //=======================================================================
01060 
01061 void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* hyp)
01062 {
01063   Unexpect aCatch(SalomeException);
01064 
01065   if ( !GetMeshDS()->IsUsedHypothesis( hyp ))
01066     return;
01067 
01068   if (_callUp)
01069     _callUp->HypothesisModified();
01070 
01071   const SMESH_Algo *foundAlgo = 0;
01072   SMESH_HypoFilter algoKind, compatibleHypoKind;
01073   list <const SMESHDS_Hypothesis * > usedHyps;
01074 
01075 
01076   map < int, SMESH_subMesh * >::iterator itsm;
01077   for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
01078   {
01079     SMESH_subMesh *aSubMesh = (*itsm).second;
01080     if ( aSubMesh->IsApplicableHypotesis( hyp ))
01081     {
01082       const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
01083 
01084       if ( !foundAlgo ) // init filter for algo search
01085         algoKind.Init( THypType::IsAlgo() ).And( THypType::IsApplicableTo( aSubShape ));
01086       
01087       const SMESH_Algo *algo = static_cast<const SMESH_Algo*>
01088         ( GetHypothesis( aSubShape, algoKind, true ));
01089 
01090       if ( algo )
01091       {
01092         bool sameAlgo = ( algo == foundAlgo );
01093         if ( !sameAlgo && foundAlgo )
01094           sameAlgo = ( strcmp( algo->GetName(), foundAlgo->GetName() ) == 0);
01095 
01096         if ( !sameAlgo ) { // init filter for used hypos search
01097           if ( !algo->InitCompatibleHypoFilter( compatibleHypoKind, !hyp->IsAuxiliary() ))
01098             continue; // algo does not use any hypothesis
01099           foundAlgo = algo;
01100         }
01101 
01102         // check if hyp is used by algo
01103         usedHyps.clear();
01104         if ( GetHypotheses( aSubShape, compatibleHypoKind, usedHyps, true ) &&
01105              find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() )
01106         {
01107           aSubMesh->AlgoStateEngine(SMESH_subMesh::MODIF_HYP,
01108                                     const_cast< SMESH_Hypothesis*>( hyp ));
01109         }
01110       }
01111     }
01112   }
01113   HasModificationsToDiscard(); // to reset _isModified flag if mesh becomes empty
01114   GetMeshDS()->Modified();
01115 }
01116 
01117 //=============================================================================
01121 //=============================================================================
01122 void SMESH_Mesh::SetAutoColor(bool theAutoColor) throw(SALOME_Exception)
01123 {
01124   Unexpect aCatch(SalomeException);
01125   _isAutoColor = theAutoColor;
01126 }
01127 
01128 bool SMESH_Mesh::GetAutoColor() throw(SALOME_Exception)
01129 {
01130   Unexpect aCatch(SalomeException);
01131   return _isAutoColor;
01132 }
01133 
01134 //=======================================================================
01135 //function : SetIsModified
01136 //purpose  : Set the flag meaning that the mesh has been edited "manually"
01137 //=======================================================================
01138 
01139 void SMESH_Mesh::SetIsModified(bool isModified)
01140 {
01141   _isModified = isModified;
01142 
01143   if ( _isModified )
01144     // check if mesh becomes empty as result of modification
01145     HasModificationsToDiscard();
01146 }
01147 
01148 //=======================================================================
01149 //function : HasModificationsToDiscard
01150 //purpose  : Return true if the mesh has been edited since a total re-compute
01151 //           and those modifications may prevent successful partial re-compute.
01152 //           As a side effect reset _isModified flag if mesh is empty
01153 //issue    : 0020693
01154 //=======================================================================
01155 
01156 bool SMESH_Mesh::HasModificationsToDiscard() const
01157 {
01158   if ( ! _isModified )
01159     return false;
01160 
01161   // return true if the next Compute() will be partial and
01162   // existing but changed elements may prevent successful re-compute
01163   bool hasComputed = false, hasNotComputed = false;
01164   map <int, SMESH_subMesh*>::const_iterator i_sm = _mapSubMesh.begin();
01165   for ( ; i_sm != _mapSubMesh.end() ; ++i_sm )
01166     switch ( i_sm->second->GetSubShape().ShapeType() )
01167     {
01168     case TopAbs_EDGE:
01169     case TopAbs_FACE:
01170     case TopAbs_SOLID:
01171       if ( i_sm->second->IsMeshComputed() )
01172         hasComputed = true;
01173       else
01174         hasNotComputed = true;
01175       if ( hasComputed && hasNotComputed)
01176         return true;
01177     }
01178 
01179   if ( NbNodes() < 1 )
01180     const_cast<SMESH_Mesh*>(this)->_isModified = false;
01181 
01182   return false;
01183 }
01184 
01185 //================================================================================
01189 //================================================================================
01190 
01191 bool SMESH_Mesh::HasDuplicatedGroupNamesMED()
01192 {
01193   //set<string> aGroupNames; // Corrected for Mantis issue 0020028
01194   map< SMDSAbs_ElementType, set<string> > aGroupNames;
01195   for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
01196   {
01197     SMESH_Group* aGroup = it->second;
01198     SMDSAbs_ElementType aType = aGroup->GetGroupDS()->GetType();
01199     string aGroupName = aGroup->GetName();
01200     aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH);
01201     if (!aGroupNames[aType].insert(aGroupName).second)
01202       return true;
01203   }
01204 
01205   return false;
01206 }
01207 
01208 //================================================================================
01212 //================================================================================
01213 
01214 void SMESH_Mesh::ExportMED(const char *        file, 
01215                            const char*         theMeshName, 
01216                            bool                theAutoGroups,
01217                            int                 theVersion,
01218                            const SMESHDS_Mesh* meshPart) 
01219   throw(SALOME_Exception)
01220 {
01221   Unexpect aCatch(SalomeException);
01222 
01223   DriverMED_W_SMESHDS_Mesh myWriter;
01224   myWriter.SetFile    ( file, MED::EVersion(theVersion) );
01225   myWriter.SetMesh    ( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS   );
01226   if ( !theMeshName ) 
01227     myWriter.SetMeshId  ( _idDoc      );
01228   else {
01229     myWriter.SetMeshId  ( -1          );
01230     myWriter.SetMeshName( theMeshName );
01231   }
01232 
01233   if ( theAutoGroups ) {
01234     myWriter.AddGroupOfNodes();
01235     myWriter.AddGroupOfEdges();
01236     myWriter.AddGroupOfFaces();
01237     myWriter.AddGroupOfVolumes();
01238   }
01239 
01240   // Pass groups to writer. Provide unique group names.
01241   //set<string> aGroupNames; // Corrected for Mantis issue 0020028
01242   if ( !meshPart )
01243   {
01244     map< SMDSAbs_ElementType, set<string> > aGroupNames;
01245     char aString [256];
01246     int maxNbIter = 10000; // to guarantee cycle finish
01247     for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
01248       SMESH_Group*       aGroup   = it->second;
01249       SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
01250       if ( aGroupDS ) {
01251         SMDSAbs_ElementType aType = aGroupDS->GetType();
01252         string aGroupName0 = aGroup->GetName();
01253         aGroupName0.resize(MAX_MED_GROUP_NAME_LENGTH);
01254         string aGroupName = aGroupName0;
01255         for (int i = 1; !aGroupNames[aType].insert(aGroupName).second && i < maxNbIter; i++) {
01256           sprintf(&aString[0], "GR_%d_%s", i, aGroupName0.c_str());
01257           aGroupName = aString;
01258           aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH);
01259         }
01260         aGroupDS->SetStoreName( aGroupName.c_str() );
01261         myWriter.AddGroup( aGroupDS );
01262       }
01263     }
01264   }
01265   // Perform export
01266   myWriter.Perform();
01267 }
01268 
01269 void SMESH_Mesh::ExportSAUV(const char *file, 
01270                             const char* theMeshName, 
01271                             bool theAutoGroups)
01272   throw(SALOME_Exception)
01273 {
01274   std::string medfilename(file);
01275   medfilename += ".med";
01276   std::string cmd;
01277 #ifdef WNT
01278   cmd = "%PYTHONBIN% ";
01279 #else
01280   cmd = "python ";
01281 #endif
01282   cmd += "-c \"";
01283   cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
01284   cmd += "\"";
01285   system(cmd.c_str());
01286   ExportMED(medfilename.c_str(), theMeshName, theAutoGroups, 1);
01287 #ifdef WNT
01288   cmd = "%PYTHONBIN% ";
01289 #else
01290   cmd = "python ";
01291 #endif
01292   cmd += "-c \"";
01293   cmd += "from medutilities import convert ; convert(r'" + medfilename + "', 'MED', 'GIBI', 1, r'" + file + "')";
01294   cmd += "\"";
01295   system(cmd.c_str());
01296 #ifdef WNT
01297   cmd = "%PYTHONBIN% ";
01298 #else
01299   cmd = "python ";
01300 #endif
01301   cmd += "-c \"";
01302   cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
01303   cmd += "\"";
01304   system(cmd.c_str());
01305 }
01306 
01307 //================================================================================
01311 //================================================================================
01312 
01313 void SMESH_Mesh::ExportDAT(const char *        file,
01314                            const SMESHDS_Mesh* meshPart) throw(SALOME_Exception)
01315 {
01316   Unexpect aCatch(SalomeException);
01317   DriverDAT_W_SMDS_Mesh myWriter;
01318   myWriter.SetFile( file );
01319   myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS );
01320   myWriter.SetMeshId(_idDoc);
01321   myWriter.Perform();
01322 }
01323 
01324 //================================================================================
01328 //================================================================================
01329 
01330 void SMESH_Mesh::ExportUNV(const char *        file,
01331                            const SMESHDS_Mesh* meshPart) throw(SALOME_Exception)
01332 {
01333   Unexpect aCatch(SalomeException);
01334   DriverUNV_W_SMDS_Mesh myWriter;
01335   myWriter.SetFile( file );
01336   myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS );
01337   myWriter.SetMeshId(_idDoc);
01338   //  myWriter.SetGroups(_mapGroup);
01339 
01340   if ( !meshPart )
01341   {
01342     for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
01343       SMESH_Group*       aGroup   = it->second;
01344       SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
01345       if ( aGroupDS ) {
01346         string aGroupName = aGroup->GetName();
01347         aGroupDS->SetStoreName( aGroupName.c_str() );
01348         myWriter.AddGroup( aGroupDS );
01349       }
01350     }
01351   }
01352   myWriter.Perform();
01353 }
01354 
01355 //================================================================================
01359 //================================================================================
01360 
01361 void SMESH_Mesh::ExportSTL(const char *        file,
01362                            const bool          isascii,
01363                            const SMESHDS_Mesh* meshPart) throw(SALOME_Exception)
01364 {
01365   Unexpect aCatch(SalomeException);
01366   DriverSTL_W_SMDS_Mesh myWriter;
01367   myWriter.SetFile( file );
01368   myWriter.SetIsAscii( isascii );
01369   myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS);
01370   myWriter.SetMeshId(_idDoc);
01371   myWriter.Perform();
01372 }
01373 
01374 //================================================================================
01378 //================================================================================
01379 
01380 void SMESH_Mesh::ExportCGNS(const char *        file,
01381                             const SMESHDS_Mesh* meshDS)
01382 {
01383   int res = Driver_Mesh::DRS_FAIL;
01384 #ifdef WITH_CGNS
01385   DriverCGNS_Write myWriter;
01386   myWriter.SetFile( file );
01387   myWriter.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
01388   myWriter.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId());
01389   res = myWriter.Perform();
01390 #endif
01391   if ( res != Driver_Mesh::DRS_OK )
01392     throw SALOME_Exception("Export failed");
01393 }
01394 
01395 //================================================================================
01399 //================================================================================
01400 
01401 int SMESH_Mesh::NbNodes() const throw(SALOME_Exception)
01402 {
01403   Unexpect aCatch(SalomeException);
01404   return _myMeshDS->NbNodes();
01405 }
01406 
01407 //================================================================================
01411 //================================================================================
01412 
01413 int SMESH_Mesh::Nb0DElements() const throw(SALOME_Exception)
01414 {
01415   Unexpect aCatch(SalomeException);
01416   return _myMeshDS->GetMeshInfo().Nb0DElements();
01417 }
01418 
01419 //================================================================================
01423 //================================================================================
01424 
01425 int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
01426 {
01427   Unexpect aCatch(SalomeException);
01428   return _myMeshDS->GetMeshInfo().NbEdges(order);
01429 }
01430 
01431 //================================================================================
01435 //================================================================================
01436 
01437 int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
01438 {
01439   Unexpect aCatch(SalomeException);
01440   return _myMeshDS->GetMeshInfo().NbFaces(order);
01441 }
01442 
01443 //================================================================================
01447 //================================================================================
01448 
01449 int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
01450 {
01451   Unexpect aCatch(SalomeException);
01452   return _myMeshDS->GetMeshInfo().NbTriangles(order);
01453 }
01454 
01455 //================================================================================
01459 //================================================================================
01460 
01461 int SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
01462 {
01463   Unexpect aCatch(SalomeException);
01464   return _myMeshDS->GetMeshInfo().NbQuadrangles(order);
01465 }
01466 
01467 //================================================================================
01471 //================================================================================
01472 
01473 int SMESH_Mesh::NbBiQuadQuadrangles() const throw(SALOME_Exception)
01474 {
01475   Unexpect aCatch(SalomeException);
01476   return _myMeshDS->GetMeshInfo().NbBiQuadQuadrangles();
01477 }
01478 
01479 //================================================================================
01483 //================================================================================
01484 
01485 int SMESH_Mesh::NbPolygons() const throw(SALOME_Exception)
01486 {
01487   Unexpect aCatch(SalomeException);
01488   return _myMeshDS->GetMeshInfo().NbPolygons();
01489 }
01490 
01491 //================================================================================
01495 //================================================================================
01496 
01497 int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
01498 {
01499   Unexpect aCatch(SalomeException);
01500   return _myMeshDS->GetMeshInfo().NbVolumes(order);
01501 }
01502 
01503 //================================================================================
01507 //================================================================================
01508 
01509 int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
01510 {
01511   Unexpect aCatch(SalomeException);
01512   return _myMeshDS->GetMeshInfo().NbTetras(order);
01513 }
01514 
01515 //================================================================================
01519 //================================================================================
01520 
01521 int SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
01522 {
01523   Unexpect aCatch(SalomeException);
01524   return _myMeshDS->GetMeshInfo().NbHexas(order);
01525 }
01526 
01527 //================================================================================
01531 //================================================================================
01532 
01533 int SMESH_Mesh::NbTriQuadraticHexas() const throw(SALOME_Exception)
01534 {
01535   Unexpect aCatch(SalomeException);
01536   return _myMeshDS->GetMeshInfo().NbTriQuadHexas();
01537 }
01538 
01539 //================================================================================
01543 //================================================================================
01544 
01545 int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
01546 {
01547   Unexpect aCatch(SalomeException);
01548   return _myMeshDS->GetMeshInfo().NbPyramids(order);
01549 }
01550 
01551 //================================================================================
01555 //================================================================================
01556 
01557 int SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
01558 {
01559   Unexpect aCatch(SalomeException);
01560   return _myMeshDS->GetMeshInfo().NbPrisms(order);
01561 }
01562 
01563 //================================================================================
01567 //================================================================================
01568 
01569 int SMESH_Mesh::NbHexagonalPrisms() const throw(SALOME_Exception)
01570 {
01571   Unexpect aCatch(SalomeException);
01572   return _myMeshDS->GetMeshInfo().NbHexPrisms();
01573 }
01574 
01575 //================================================================================
01579 //================================================================================
01580 
01581 int SMESH_Mesh::NbPolyhedrons() const throw(SALOME_Exception)
01582 {
01583   Unexpect aCatch(SalomeException);
01584   return _myMeshDS->GetMeshInfo().NbPolyhedrons();
01585 }
01586 
01587 //================================================================================
01591 //================================================================================
01592 
01593 int SMESH_Mesh::NbSubMesh() const throw(SALOME_Exception)
01594 {
01595   Unexpect aCatch(SalomeException);
01596   return _myMeshDS->NbSubMesh();
01597 }
01598 
01599 //=======================================================================
01600 //function : IsNotConformAllowed
01601 //purpose  : check if a hypothesis alowing notconform mesh is present
01602 //=======================================================================
01603 
01604 bool SMESH_Mesh::IsNotConformAllowed() const
01605 {
01606   if(MYDEBUG) MESSAGE("SMESH_Mesh::IsNotConformAllowed");
01607 
01608   static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( "NotConformAllowed" ));
01609   return GetHypothesis( _myMeshDS->ShapeToMesh(), filter, false );
01610 }
01611 
01612 //=======================================================================
01613 //function : IsMainShape
01614 //purpose  : 
01615 //=======================================================================
01616 
01617 bool SMESH_Mesh::IsMainShape(const TopoDS_Shape& theShape) const
01618 {
01619   return theShape.IsSame(_myMeshDS->ShapeToMesh() );
01620 }
01621 
01622 //=============================================================================
01626 //=============================================================================
01627 
01628 SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType,
01629                                    const char*               theName,
01630                                    int&                      theId,
01631                                    const TopoDS_Shape&       theShape,
01632                                    const SMESH_PredicatePtr& thePredicate)
01633 {
01634   if (_mapGroup.count(_groupId))
01635     return NULL;
01636   theId = _groupId;
01637   SMESH_Group* aGroup = new SMESH_Group (theId, this, theType, theName, theShape, thePredicate);
01638   GetMeshDS()->AddGroup( aGroup->GetGroupDS() );
01639   _mapGroup[_groupId++] = aGroup;
01640   return aGroup;
01641 }
01642 
01643 //================================================================================
01649 //================================================================================
01650 
01651 bool SMESH_Mesh::SynchronizeGroups()
01652 {
01653   int nbGroups = _mapGroup.size();
01654   const set<SMESHDS_GroupBase*>& groups = _myMeshDS->GetGroups();
01655   set<SMESHDS_GroupBase*>::const_iterator gIt = groups.begin();
01656   for ( ; gIt != groups.end(); ++gIt )
01657   {
01658     SMESHDS_GroupBase* groupDS = (SMESHDS_GroupBase*) *gIt;
01659     _groupId = groupDS->GetID();
01660     if ( !_mapGroup.count( _groupId ))
01661       _mapGroup[_groupId] = new SMESH_Group( groupDS );
01662   }
01663   if ( !_mapGroup.empty() )
01664     _groupId = _mapGroup.rbegin()->first + 1;
01665 
01666   return nbGroups < _mapGroup.size();
01667 }
01668 
01669 //================================================================================
01673 //================================================================================
01674 
01675 SMESH_Mesh::GroupIteratorPtr SMESH_Mesh::GetGroups() const
01676 {
01677   typedef map <int, SMESH_Group *> TMap;
01678   return GroupIteratorPtr( new SMDS_mapIterator<TMap>( _mapGroup ));
01679 }
01680 
01681 //=============================================================================
01685 //=============================================================================
01686 
01687 SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID)
01688 {
01689   if (_mapGroup.find(theGroupID) == _mapGroup.end())
01690     return NULL;
01691   return _mapGroup[theGroupID];
01692 }
01693 
01694 
01695 //=============================================================================
01699 //=============================================================================
01700 
01701 list<int> SMESH_Mesh::GetGroupIds() const
01702 {
01703   list<int> anIds;
01704   for ( map<int, SMESH_Group*>::const_iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
01705     anIds.push_back( it->first );
01706   
01707   return anIds;
01708 }
01709 
01710 //================================================================================
01715 //================================================================================
01716 
01717 void SMESH_Mesh::SetCallUp( TCallUp* upCaller )
01718 {
01719   if ( _callUp ) delete _callUp;
01720   _callUp = upCaller;
01721 }
01722 
01723 //=============================================================================
01727 //=============================================================================
01728 
01729 bool SMESH_Mesh::RemoveGroup (const int theGroupID)
01730 {
01731   if (_mapGroup.find(theGroupID) == _mapGroup.end())
01732     return false;
01733   GetMeshDS()->RemoveGroup( _mapGroup[theGroupID]->GetGroupDS() );
01734   delete _mapGroup[theGroupID];
01735   _mapGroup.erase (theGroupID);
01736   if (_callUp)
01737     _callUp->RemoveGroup( theGroupID );
01738   return true;
01739 }
01740 
01741 //=======================================================================
01742 //function : GetAncestors
01743 //purpose  : return list of ancestors of theSubShape in the order
01744 //           that lower dimention shapes come first.
01745 //=======================================================================
01746 
01747 const TopTools_ListOfShape& SMESH_Mesh::GetAncestors(const TopoDS_Shape& theS) const
01748 {
01749   if ( _mapAncestors.Contains( theS ) )
01750     return _mapAncestors.FindFromKey( theS );
01751 
01752   static TopTools_ListOfShape emptyList;
01753   return emptyList;
01754 }
01755 
01756 //=======================================================================
01757 //function : Dump
01758 //purpose  : dumps contents of mesh to stream [ debug purposes ]
01759 //=======================================================================
01760 
01761 ostream& SMESH_Mesh::Dump(ostream& save)
01762 {
01763   int clause = 0;
01764   save << "========================== Dump contents of mesh ==========================" << endl << endl;
01765   save << ++clause << ") Total number of nodes:   \t"    << NbNodes() << endl;
01766   save << ++clause << ") Total number of edges:   \t"    << NbEdges() << endl;
01767   save << ++clause << ") Total number of faces:   \t"    << NbFaces() << endl;
01768   save << ++clause << ") Total number of polygons:\t"    << NbPolygons() << endl;
01769   save << ++clause << ") Total number of volumes:\t"     << NbVolumes() << endl;
01770   save << ++clause << ") Total number of polyhedrons:\t" << NbPolyhedrons() << endl << endl;
01771   for ( int isQuadratic = 0; isQuadratic < 2; ++isQuadratic )
01772   {
01773     string orderStr = isQuadratic ? "quadratic" : "linear";
01774     SMDSAbs_ElementOrder order  = isQuadratic ? ORDER_QUADRATIC : ORDER_LINEAR;
01775 
01776     save << ++clause << ") Total number of " << orderStr << " edges:\t" << NbEdges(order) << endl;
01777     save << ++clause << ") Total number of " << orderStr << " faces:\t" << NbFaces(order) << endl;
01778     if ( NbFaces(order) > 0 ) {
01779       int nb3 = NbTriangles(order);
01780       int nb4 = NbQuadrangles(order);
01781       save << clause << ".1) Number of " << orderStr << " triangles:  \t" << nb3 << endl;
01782       save << clause << ".2) Number of " << orderStr << " quadrangles:\t" << nb4 << endl;
01783       if ( nb3 + nb4 !=  NbFaces(order) ) {
01784         map<int,int> myFaceMap;
01785         SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
01786         while( itFaces->more( ) ) {
01787           int nbNodes = itFaces->next()->NbNodes();
01788           if ( myFaceMap.find( nbNodes ) == myFaceMap.end() )
01789             myFaceMap[ nbNodes ] = 0;
01790           myFaceMap[ nbNodes ] = myFaceMap[ nbNodes ] + 1;
01791         }
01792         save << clause << ".3) Faces in detail: " << endl;
01793         map <int,int>::iterator itF;
01794         for (itF = myFaceMap.begin(); itF != myFaceMap.end(); itF++)
01795           save << "--> nb nodes: " << itF->first << " - nb elemens:\t" << itF->second << endl;
01796       }
01797     }
01798     save << ++clause << ") Total number of " << orderStr << " volumes:\t" << NbVolumes(order) << endl;
01799     if ( NbVolumes(order) > 0 ) {
01800       int nb8 = NbHexas(order);
01801       int nb4 = NbTetras(order);
01802       int nb5 = NbPyramids(order);
01803       int nb6 = NbPrisms(order);
01804       save << clause << ".1) Number of " << orderStr << " hexahedrons:\t" << nb8 << endl;
01805       save << clause << ".2) Number of " << orderStr << " tetrahedrons:\t" << nb4 << endl;
01806       save << clause << ".3) Number of " << orderStr << " prisms:      \t" << nb6 << endl;
01807       save << clause << ".4) Number of " << orderStr << " pyramids:\t" << nb5 << endl;
01808       if ( nb8 + nb4 + nb5 + nb6 != NbVolumes(order) ) {
01809         map<int,int> myVolumesMap;
01810         SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
01811         while( itVolumes->more( ) ) {
01812           int nbNodes = itVolumes->next()->NbNodes();
01813           if ( myVolumesMap.find( nbNodes ) == myVolumesMap.end() )
01814             myVolumesMap[ nbNodes ] = 0;
01815           myVolumesMap[ nbNodes ] = myVolumesMap[ nbNodes ] + 1;
01816         }
01817         save << clause << ".5) Volumes in detail: " << endl;
01818         map <int,int>::iterator itV;
01819         for (itV = myVolumesMap.begin(); itV != myVolumesMap.end(); itV++)
01820           save << "--> nb nodes: " << itV->first << " - nb elemens:\t" << itV->second << endl;
01821       }
01822     }
01823     save << endl;
01824   }
01825   save << "===========================================================================" << endl;
01826   return save;
01827 }
01828 
01829 //=======================================================================
01830 //function : GetElementType
01831 //purpose  : Returns type of mesh element with certain id
01832 //=======================================================================
01833 
01834 SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem )
01835 {
01836   return _myMeshDS->GetElementType( id, iselem );
01837 }
01838 
01839 //=============================================================================
01843 //=============================================================================
01844 
01845 SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID )
01846 {
01847   SMESH_Group* aGroup = 0;
01848   map < int, SMESH_Group * >::iterator itg = _mapGroup.find( theGroupID );
01849   if ( itg == _mapGroup.end() )
01850     return aGroup;
01851 
01852   SMESH_Group* anOldGrp = (*itg).second;
01853   SMESHDS_GroupBase* anOldGrpDS = anOldGrp->GetGroupDS();
01854   if ( !anOldGrp || !anOldGrpDS )
01855     return aGroup;
01856 
01857   // create new standalone group
01858   aGroup = new SMESH_Group (theGroupID, this, anOldGrpDS->GetType(), anOldGrp->GetName() );
01859   _mapGroup[theGroupID] = aGroup;
01860 
01861   SMESHDS_Group* aNewGrpDS = dynamic_cast<SMESHDS_Group*>( aGroup->GetGroupDS() );
01862   GetMeshDS()->RemoveGroup( anOldGrpDS );
01863   GetMeshDS()->AddGroup( aNewGrpDS );
01864 
01865   // add elements (or nodes) into new created group
01866   SMDS_ElemIteratorPtr anItr = anOldGrpDS->GetElements();
01867   while ( anItr->more() )
01868     aNewGrpDS->Add( (anItr->next())->GetID() );
01869 
01870   // set color
01871   aNewGrpDS->SetColor( anOldGrpDS->GetColor() );
01872 
01873   // remove old group
01874   delete anOldGrp;
01875 
01876   return aGroup;
01877 }
01878 
01879 //=============================================================================
01883 //=============================================================================
01884 
01885 void SMESH_Mesh::ClearMeshOrder()
01886 {
01887   _mySubMeshOrder.clear();
01888 }
01889 
01890 //=============================================================================
01894 //=============================================================================
01895 
01896 void SMESH_Mesh::SetMeshOrder(const TListOfListOfInt& theOrder )
01897 {
01898   _mySubMeshOrder = theOrder;
01899 }
01900 
01901 //=============================================================================
01905 //=============================================================================
01906 
01907 const TListOfListOfInt& SMESH_Mesh::GetMeshOrder() const
01908 {
01909   return _mySubMeshOrder;
01910 }
01911 
01912 //=============================================================================
01916 //=============================================================================
01917 
01918 void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape)
01919 {
01920 
01921   int desType, ancType;
01922   if ( !theShape.IsSame( GetShapeToMesh()) && theShape.ShapeType() == TopAbs_COMPOUND )
01923   {
01924     // a geom group is added. Insert it into lists of ancestors before
01925     // the first ancestor more complex than group members
01926     int memberType = TopoDS_Iterator( theShape ).Value().ShapeType();
01927     for ( desType = TopAbs_VERTEX; desType >= memberType; desType-- )
01928       for (TopExp_Explorer des( theShape, TopAbs_ShapeEnum( desType )); des.More(); des.Next())
01929       {
01930         if ( !_mapAncestors.Contains( des.Current() )) continue;// issue 0020982
01931         TopTools_ListOfShape& ancList = _mapAncestors.ChangeFromKey( des.Current() );
01932         TopTools_ListIteratorOfListOfShape ancIt (ancList);
01933         while ( ancIt.More() && ancIt.Value().ShapeType() >= memberType )
01934           ancIt.Next();
01935         if ( ancIt.More() )
01936           ancList.InsertBefore( theShape, ancIt );
01937       }
01938   }
01939   {
01940     for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- )
01941       for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
01942         TopExp::MapShapesAndAncestors ( theShape,
01943                                         (TopAbs_ShapeEnum) desType,
01944                                         (TopAbs_ShapeEnum) ancType,
01945                                         _mapAncestors );
01946   }
01947 }
01948 
01949 //=============================================================================
01955 //=============================================================================
01956 
01957 bool SMESH_Mesh::SortByMeshOrder(list<SMESH_subMesh*>& theListToSort) const
01958 {
01959   if ( !_mySubMeshOrder.size() || theListToSort.size() < 2)
01960     return true;
01961   
01962   bool res = false;
01963   list<SMESH_subMesh*> onlyOrderedList;
01964   // collect all ordered submeshes in one list as pointers
01965   // and get their positions within theListToSort
01966   typedef list<SMESH_subMesh*>::iterator TPosInList;
01967   map< int, TPosInList > sortedPos;
01968   TPosInList smBeg = theListToSort.begin(), smEnd = theListToSort.end();
01969   TListOfListOfInt::const_iterator listIddIt = _mySubMeshOrder.begin();
01970   for( ; listIddIt != _mySubMeshOrder.end(); listIddIt++) {
01971     const TListOfInt& listOfId = *listIddIt;
01972     TListOfInt::const_iterator idIt = listOfId.begin();
01973     for ( ; idIt != listOfId.end(); idIt++ ) {
01974       if ( SMESH_subMesh * sm = GetSubMeshContaining( *idIt )) {
01975         TPosInList smPos = find( smBeg, smEnd, sm );
01976         if ( smPos != smEnd ) {
01977           onlyOrderedList.push_back( sm );
01978           sortedPos[ distance( smBeg, smPos )] = smPos;
01979         }
01980       }
01981     }
01982   }
01983   if (onlyOrderedList.size() < 2)
01984     return res;
01985   res = true;
01986 
01987   list<SMESH_subMesh*>::iterator onlyBIt = onlyOrderedList.begin();
01988   list<SMESH_subMesh*>::iterator onlyEIt = onlyOrderedList.end();
01989 
01990   // iterate on ordered submeshes and insert them in detected positions
01991   map< int, TPosInList >::iterator i_pos = sortedPos.begin();
01992   for ( ; onlyBIt != onlyEIt; ++onlyBIt, ++i_pos )
01993     *(i_pos->second) = *onlyBIt;
01994 
01995   return res;
01996 }
01997 
01998 //=============================================================================
02004 //=============================================================================
02005 
02006 list<SMESH_subMesh*> SMESH_Mesh::getAncestorsSubMeshes
02007   (const TopoDS_Shape& theSubShape) const
02008 {
02009   list<SMESH_subMesh*> listOfSubMesh;
02010   TopTools_ListIteratorOfListOfShape it( GetAncestors( theSubShape ));
02011   for (; it.More(); it.Next() )
02012     if ( SMESH_subMesh* sm = GetSubMeshContaining( it.Value() ))
02013       listOfSubMesh.push_back(sm);
02014 
02015   // sort submeshes according to stored mesh order
02016   SortByMeshOrder( listOfSubMesh );
02017 
02018   return listOfSubMesh;
02019 }