Salome HOME
DCQ : Merge with Ecole_Ete_a6.
[modules/smesh.git] / src / SMESH / SMESH_Mesh.cxx
1 //  SMESH SMESH : implementaion of SMESH idl descriptions
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMESH_Mesh.cxx
25 //  Author : Paul RASCLE, EDF
26 //  Module : SMESH
27 //  $Header$
28
29 #include "SMESH_Mesh.hxx"
30 #include "SMESH_subMesh.hxx"
31 #include "SMESH_Gen.hxx"
32 #include "SMESH_Hypothesis.hxx"
33 #include "SMESH_Group.hxx"
34 #include "SMESHDS_Group.hxx"
35 #include "SMESHDS_Script.hxx"
36 #include "SMDS_MeshVolume.hxx"
37
38 #include "utilities.h"
39
40 #include "Mesh_Writer.h"
41 #include "DriverMED_W_SMESHDS_Mesh.h"
42 #include "DriverDAT_W_SMESHDS_Mesh.h"
43 #include "DriverUNV_W_SMESHDS_Mesh.h"
44
45 #include "DriverMED_R_SMESHDS_Mesh.h"
46
47 #include <TCollection_AsciiString.hxx>
48 #include <memory>
49 #include <TopTools_ListOfShape.hxx>
50 #include <TopExp.hxx>
51 #include <TopTools_ListIteratorOfListOfShape.hxx>
52 #include "Utils_ExceptHandlers.hxx"
53
54
55 //=============================================================================
56 /*!
57  * 
58  */
59 //=============================================================================
60
61 SMESH_Mesh::SMESH_Mesh()
62 {
63         MESSAGE("SMESH_Mesh::SMESH_Mesh");
64         _id = -1;
65         ASSERT(0);
66 }
67
68 //=============================================================================
69 /*!
70  * 
71  */
72 //=============================================================================
73
74 SMESH_Mesh::SMESH_Mesh(int localId, int studyId, SMESH_Gen * gen, SMESHDS_Document * myDocument)
75 : _groupId( 0 )
76 {
77         MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)");
78         _id = localId;
79         _studyId = studyId;
80         _gen = gen;
81         _myDocument = myDocument;
82         _idDoc = _myDocument->NewMesh();
83         _myMeshDS = _myDocument->GetMesh(_idDoc);
84         _isShapeToMesh = false;
85 }
86
87 //=============================================================================
88 /*!
89  * 
90  */
91 //=============================================================================
92
93 SMESH_Mesh::~SMESH_Mesh()
94 {
95   MESSAGE("SMESH_Mesh::~SMESH_Mesh");
96
97   // delete groups
98   map < int, SMESH_Group * >::iterator itg;
99   for (itg = _mapGroup.begin(); itg != _mapGroup.end(); itg++) {
100     SMESH_Group *aGroup = (*itg).second;
101     delete aGroup;
102   }
103 }
104
105 //=============================================================================
106 /*!
107  * 
108  */
109 //=============================================================================
110
111 void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape){
112         MESSAGE("SMESH_Mesh::ShapeToMesh");
113         if (_isShapeToMesh)
114                 throw
115                         SALOME_Exception(LOCALIZED
116                 ("a shape to mesh as already been defined"));
117         _isShapeToMesh = true;
118         _myMeshDS->ShapeToMesh(aShape);
119
120         // NRI : 24/02/03
121         TopExp::MapShapes(aShape, _subShapes);
122 }
123
124 //=======================================================================
125 //function : MEDToMesh
126 //purpose  : 
127 //=======================================================================
128
129 int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName)
130 {
131   MESSAGE("MEDToMesh - theFileName = "<<theFileName<<", mesh name = "<<theMeshName);
132   if(_isShapeToMesh)
133     throw SALOME_Exception(LOCALIZED("a shape to mesh as already been defined"));
134   _isShapeToMesh = true;
135   std::auto_ptr<DriverMED_R_SMESHDS_Mesh> myReader(new DriverMED_R_SMESHDS_Mesh);
136   myReader->SetMesh(_myMeshDS);
137   myReader->SetMeshId(-1);
138   myReader->SetFile(theFileName);
139   myReader->SetMeshName(theMeshName);
140   DriverMED_R_SMESHDS_Mesh::ReadStatus status = myReader->ReadMySelf();
141   MESSAGE("MEDToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
142   MESSAGE("MEDToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
143   MESSAGE("MEDToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
144   MESSAGE("MEDToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
145
146   // Reading groups (sub-meshes are out of scope of MED import functionality)
147   list<string> aGroupNames = myReader->GetGroupNames();
148   MESSAGE("MEDToMesh - Nb groups = "<<aGroupNames.size()); 
149   int anId;
150   for ( list<string>::iterator it = aGroupNames.begin(); it != aGroupNames.end(); it++ ) {
151     SMESH_Group* aGroup = AddGroup( SMDSAbs_All, it->c_str(), anId );
152     if ( aGroup ) {
153       MESSAGE("MEDToMesh - group added: "<<it->c_str());      
154       SMESHDS_Group* aGroupDS = aGroup->GetGroupDS();
155       aGroupDS->SetStoreName( it->c_str() );
156       myReader->GetGroup( aGroupDS );
157     }
158   }
159   return (int) status;
160 }
161
162 //=============================================================================
163 /*!
164  * 
165  */
166 //=============================================================================
167
168 SMESH_Hypothesis::Hypothesis_Status
169   SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
170                             int anHypId) throw(SALOME_Exception)
171 {
172   Unexpect aCatch(SalomeException);
173   MESSAGE("SMESH_Mesh::AddHypothesis");
174
175   StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
176   if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
177   {
178     MESSAGE("Hypothesis ID does not give an hypothesis");
179     SCRUTE(_studyId);
180     SCRUTE(anHypId);
181     throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
182   }
183
184   SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
185   SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
186   SCRUTE( anHyp->GetName() );
187   int event;
188
189   bool isGlobalHyp = IsMainShape( aSubShape );
190
191   // NotConformAllowed can be only global
192   if ( !isGlobalHyp )
193   {
194     string hypName = anHyp->GetName();
195     if ( hypName == "NotConformAllowed" )
196     {
197       MESSAGE( "Hypotesis <NotConformAllowed> can be only global" );
198       return SMESH_Hypothesis::HYP_INCOMPATIBLE;
199     }
200   }
201
202   // shape 
203
204   if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
205     event = SMESH_subMesh::ADD_HYP;
206   else
207     event = SMESH_subMesh::ADD_ALGO;
208   SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
209
210   // subShapes
211   if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
212       !subMesh->IsApplicableHypotesis( anHyp )) // is added on father
213   {
214     if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
215       event = SMESH_subMesh::ADD_FATHER_HYP;
216     else
217       event = SMESH_subMesh::ADD_FATHER_ALGO;
218     SMESH_Hypothesis::Hypothesis_Status ret2 =
219       subMesh->SubMeshesAlgoStateEngine(event, anHyp);
220     if (ret2 > ret)
221       ret = ret2;
222   }
223
224   subMesh->DumpAlgoState(true);
225   SCRUTE(ret);
226   return ret;
227 }
228
229 //=============================================================================
230 /*!
231  * 
232  */
233 //=============================================================================
234
235 SMESH_Hypothesis::Hypothesis_Status
236   SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
237                                int anHypId)throw(SALOME_Exception)
238 {
239   Unexpect aCatch(SalomeException);
240         MESSAGE("SMESH_Mesh::RemoveHypothesis");
241
242         StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
243         if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
244                 throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
245
246         SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
247         SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
248         int hypType = anHyp->GetType();
249         SCRUTE(hypType);
250         int event;
251
252         // shape 
253
254         if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
255                 event = SMESH_subMesh::REMOVE_HYP;
256         else
257                 event = SMESH_subMesh::REMOVE_ALGO;
258         SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
259
260         // subShapes
261         if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
262             !subMesh->IsApplicableHypotesis( anHyp )) // is removed from father
263         {
264                 if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
265                         event = SMESH_subMesh::REMOVE_FATHER_HYP;
266                 else
267                         event = SMESH_subMesh::REMOVE_FATHER_ALGO;
268                 SMESH_Hypothesis::Hypothesis_Status ret2 =
269                   subMesh->SubMeshesAlgoStateEngine(event, anHyp);
270                 if (ret2 > ret) // more severe
271                   ret = ret2;
272         }
273
274         subMesh->DumpAlgoState(true);
275         SCRUTE(ret);
276         return ret;
277 }
278
279 //=============================================================================
280 /*!
281  * 
282  */
283 //=============================================================================
284
285 SMESHDS_Mesh * SMESH_Mesh::GetMeshDS()
286 {
287         return _myMeshDS;
288 }
289
290 //=============================================================================
291 /*!
292  * 
293  */
294 //=============================================================================
295
296 const list<const SMESHDS_Hypothesis*>&
297         SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const
298         throw(SALOME_Exception)
299 {
300   Unexpect aCatch(SalomeException);
301 //      MESSAGE("SMESH_Mesh::GetHypothesisList");
302 //      _subShapeHypothesisList.clear();
303 //      const list<const SMESHDS_Hypothesis*>& listHyp =
304 //              _myMeshDS->GetHypothesis(aSubShape);
305
306 //      list<const SMESHDS_Hypothesis*>::const_iterator it=listHyp.begin();
307 //      while (it!=listHyp.end())
308 //      {
309 //              const SMESHDS_Hypothesis *anHyp = *it;
310 //              _subShapeHypothesisList.push_back(anHyp);
311 //              it++;
312 //      }
313 //      return _subShapeHypothesisList;
314   return _myMeshDS->GetHypothesis(aSubShape);
315 }
316
317 //=============================================================================
318 /*!
319  * 
320  */
321 //=============================================================================
322
323 const list<SMESHDS_Command*> & SMESH_Mesh::GetLog() throw(SALOME_Exception)
324 {
325   Unexpect aCatch(SalomeException);
326         MESSAGE("SMESH_Mesh::GetLog");
327         return _myMeshDS->GetScript()->GetCommands();
328 }
329
330 //=============================================================================
331 /*!
332  * 
333  */
334 //=============================================================================
335 void SMESH_Mesh::ClearLog() throw(SALOME_Exception)
336 {
337   Unexpect aCatch(SalomeException);
338         MESSAGE("SMESH_Mesh::ClearLog");
339         _myMeshDS->GetScript()->Clear();
340 }
341
342 //=============================================================================
343 /*!
344  * 
345  */
346 //=============================================================================
347
348 int SMESH_Mesh::GetId()
349 {
350         MESSAGE("SMESH_Mesh::GetId");
351         return _id;
352 }
353
354 //=============================================================================
355 /*!
356  * 
357  */
358 //=============================================================================
359
360 SMESH_Gen *SMESH_Mesh::GetGen()
361 {
362         return _gen;
363 }
364
365 //=============================================================================
366 /*!
367  * Get or Create the SMESH_subMesh object implementation
368  */
369 //=============================================================================
370
371 SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
372 throw(SALOME_Exception)
373 {
374   Unexpect aCatch(SalomeException);
375         //MESSAGE("SMESH_Mesh::GetSubMesh");
376         SMESH_subMesh *aSubMesh;
377         int index = _subShapes.FindIndex(aSubShape);
378
379         if (_mapSubMesh.find(index) != _mapSubMesh.end())
380         {
381                 aSubMesh = _mapSubMesh[index];
382         }
383         else
384         {
385                 aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
386                 _mapSubMesh[index] = aSubMesh;
387         }
388
389         /* NRI 24/02/2003
390          * int index = -1;
391          * if (_subShapes.Contains(aSubShape))
392          * {
393          * index = _subShapes.FindIndex(aSubShape);
394          * ASSERT(_mapSubMesh.find(index) != _mapSubMesh.end());
395          * aSubMesh = _mapSubMesh[index];
396          * //MESSAGE("found submesh " << index);
397          * }
398          * else
399          * {
400          * index = _subShapes.Add(aSubShape);
401          * aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
402          * _mapSubMesh[index] = aSubMesh;
403          * //MESSAGE("created submesh " << index);
404          * }
405          */
406         return aSubMesh;
407 }
408
409 //=============================================================================
410 /*!
411  * Get the SMESH_subMesh object implementation. Dont create it, return null
412  * if it does not exist.
413  */
414 //=============================================================================
415 //
416 //  * Given a subShape, find if there is a subMesh associated to this subShape
417 //  * or to a collection of shapes containing this subShape. Collection =
418 //  * compsolid, shell, wire.
419 //  *
420 //  * WARNING : with arg = compsolid, shell or wire returns always NULL.
421 //  * with a face inside a shell, and submesh created for both, if arg is face,
422 //  * returns first created submesh of the two. 
423 //  * subMesh is not created, return may be NULL.
424
425 SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape)
426 throw(SALOME_Exception)
427 {
428   Unexpect aCatch(SalomeException);
429         //MESSAGE("SMESH_Mesh::GetSubMeshContaining");
430         bool isFound = false;
431         SMESH_subMesh *aSubMesh = NULL;
432
433         int index = _subShapes.FindIndex(aSubShape);
434         if (_mapSubMesh.find(index) != _mapSubMesh.end())
435         {
436                 aSubMesh = _mapSubMesh[index];
437                 isFound = true;
438         }
439
440         /* NRI 24/02/2003
441          * int index = -1;
442          * if (_subShapes.Contains(aSubShape))
443          * {
444          * index = _subShapes.FindIndex(aSubShape);
445          * ASSERT(_mapSubMesh.find(index) != _mapSubMesh.end());
446          * aSubMesh = _mapSubMesh[index];
447          * isFound = true;
448          * //MESSAGE("found submesh " << index);
449          * }
450          */
451
452 //   map<int, SMESH_subMesh*>::iterator itsm;
453 //   for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
454 //     {
455 //       aSubMesh = (*itsm).second;
456 //       isFound = aSubMesh->Contains(aSubShape);
457 //       if (isFound) break;
458 //     }
459
460         if (!isFound)
461                 aSubMesh = NULL;
462         return aSubMesh;
463 }
464
465 //=======================================================================
466 //function : IsUsedHypothesis
467 //purpose  : Return True if anHyp is used to mesh aSubShape
468 //=======================================================================
469
470 bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
471                                   const TopoDS_Shape & aSubShape)
472 {
473   //MESSAGE( "SMESH_Mesh::IsUsedHypothesis" );
474
475   // check if anHyp is applicable to aSubShape
476   SMESH_subMesh * subMesh = GetSubMeshContaining( aSubShape );
477   if (!subMesh ||
478       !subMesh->IsApplicableHypotesis(static_cast<SMESH_Hypothesis*>(anHyp)))
479     return false;
480
481   SMESH_Algo *algo = _gen->GetAlgo(*this, aSubShape);
482
483   // algorithm
484   if (anHyp->GetType() > SMESHDS_Hypothesis::PARAM_ALGO)
485     return ( anHyp == algo );
486
487   // algorithm parameter
488   if (algo)
489   {
490     // look trough hypotheses used by algo
491     const list <const SMESHDS_Hypothesis * >&usedHyps =
492       algo->GetUsedHypothesis(*this, aSubShape);
493     list <const SMESHDS_Hypothesis * >::const_iterator itl;
494     for (itl = usedHyps.begin(); itl != usedHyps.end(); itl++)
495       if (anHyp == (*itl))
496         return true;
497   }
498   else
499   {
500     // look through all assigned hypotheses
501     {
502       const list <const SMESHDS_Hypothesis * >&usedHyps =
503         _myMeshDS->GetHypothesis( aSubShape );
504       list <const SMESHDS_Hypothesis * >::const_iterator itl;
505       for (itl = usedHyps.begin(); itl != usedHyps.end(); itl++)
506         if (anHyp == (*itl))
507           return true;
508     }
509
510     // on ancestors
511     TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape ));
512     for (; it.More(); it.Next())
513     {
514       const list <const SMESHDS_Hypothesis * >&usedHyps =
515         _myMeshDS->GetHypothesis( aSubShape );
516       list <const SMESHDS_Hypothesis * >::const_iterator itl;
517       for (itl = usedHyps.begin(); itl != usedHyps.end(); itl++)
518         if (anHyp == (*itl))
519           return true;
520     }
521   }
522     
523   return false;
524 }
525
526
527 //=============================================================================
528 /*!
529  *
530  */
531 //=============================================================================
532
533 const list < SMESH_subMesh * >&
534         SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
535 throw(SALOME_Exception)
536 {
537   Unexpect aCatch(SalomeException);
538         MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis");
539         map < int, SMESH_subMesh * >::iterator itsm;
540         _subMeshesUsingHypothesisList.clear();
541         for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
542         {
543                 SMESH_subMesh *aSubMesh = (*itsm).second;
544                 if ( IsUsedHypothesis ( anHyp, aSubMesh->GetSubShape() ))
545                         _subMeshesUsingHypothesisList.push_back(aSubMesh);
546         }
547         return _subMeshesUsingHypothesisList;
548 }
549
550 //=============================================================================
551 /*!
552  *
553  */
554 //=============================================================================
555
556 void SMESH_Mesh::ExportMED(const char *file, const char* theMeshName, bool theAutoGroups) throw(SALOME_Exception)
557 {
558   Unexpect aCatch(SalomeException);
559   std::auto_ptr<DriverMED_W_SMESHDS_Mesh> myWriter(new DriverMED_W_SMESHDS_Mesh);
560   myWriter  ->SetFile    ( file        );
561   myWriter  ->SetMesh    ( _myMeshDS   );
562   if ( !theMeshName ) 
563     myWriter->SetMeshId  ( _idDoc      );
564   else {
565     myWriter->SetMeshId  ( -1          );
566     myWriter->SetMeshName( theMeshName );
567   }
568
569   if ( theAutoGroups ) {
570     myWriter->AddGroupOfNodes();
571     myWriter->AddGroupOfEdges();
572     myWriter->AddGroupOfFaces();
573     myWriter->AddGroupOfVolumes();
574   }
575
576   for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
577     SMESH_Group*     aGroup = it->second;
578     SMESHDS_Group* aGroupDS = aGroup->GetGroupDS();
579     aGroupDS->SetStoreName( aGroup->GetName() );
580     myWriter->AddGroup( aGroupDS );
581   }
582
583   myWriter->Add();
584 }
585
586 void SMESH_Mesh::ExportDAT(const char *file) throw(SALOME_Exception)
587 {
588   Unexpect aCatch(SalomeException);
589         Mesh_Writer *myWriter = new DriverDAT_W_SMESHDS_Mesh;
590         myWriter->SetFile(string(file));
591         myWriter->SetMesh(_myMeshDS);
592         myWriter->SetMeshId(_idDoc);
593         myWriter->Add();
594 }
595
596 void SMESH_Mesh::ExportUNV(const char *file) throw(SALOME_Exception)
597 {
598   Unexpect aCatch(SalomeException);
599         Mesh_Writer *myWriter = new DriverUNV_W_SMESHDS_Mesh;
600         myWriter->SetFile(string(file));
601         myWriter->SetMesh(_myMeshDS);
602         myWriter->SetMeshId(_idDoc);
603         myWriter->Add();
604 }
605
606 //=============================================================================
607 /*!
608  *  
609  */
610 //=============================================================================
611 int SMESH_Mesh::NbNodes() throw(SALOME_Exception)
612 {
613   Unexpect aCatch(SalomeException);
614         return _myMeshDS->NbNodes();
615 }
616
617 //=============================================================================
618 /*!
619  *  
620  */
621 //=============================================================================
622 int SMESH_Mesh::NbEdges() throw(SALOME_Exception)
623 {
624   Unexpect aCatch(SalomeException);
625         return _myMeshDS->NbEdges();
626 }
627
628 //=============================================================================
629 /*!
630  *  
631  */
632 //=============================================================================
633 int SMESH_Mesh::NbFaces() throw(SALOME_Exception)
634 {
635   Unexpect aCatch(SalomeException);
636         return _myMeshDS->NbFaces();
637 }
638
639 ///////////////////////////////////////////////////////////////////////////////
640 /// Return the number of 3 nodes faces in the mesh. This method run in O(n)
641 ///////////////////////////////////////////////////////////////////////////////
642 int SMESH_Mesh::NbTriangles() throw(SALOME_Exception)
643 {
644   Unexpect aCatch(SalomeException);
645         int Nb = 0;
646
647         SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
648         while(itFaces->more()) if(itFaces->next()->NbNodes()==3) Nb++;
649         return Nb;
650 }
651
652 ///////////////////////////////////////////////////////////////////////////////
653 /// Return the number of 4 nodes faces in the mesh. This method run in O(n)
654 ///////////////////////////////////////////////////////////////////////////////
655 int SMESH_Mesh::NbQuadrangles() throw(SALOME_Exception)
656 {
657   Unexpect aCatch(SalomeException);
658         int Nb = 0;
659
660         SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
661         while(itFaces->more()) if(itFaces->next()->NbNodes()==4) Nb++;
662         return Nb;
663 }
664
665 //=============================================================================
666 /*!
667  *  
668  */
669 //=============================================================================
670 int SMESH_Mesh::NbVolumes() throw(SALOME_Exception)
671 {
672   Unexpect aCatch(SalomeException);
673         return _myMeshDS->NbVolumes();
674 }
675
676 int SMESH_Mesh::NbTetras() throw(SALOME_Exception)
677 {
678   Unexpect aCatch(SalomeException);
679         int Nb = 0;
680         SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
681         while(itVolumes->more()) if(itVolumes->next()->NbNodes()==4) Nb++;
682         return Nb;
683 }
684
685 int SMESH_Mesh::NbHexas() throw(SALOME_Exception)
686 {
687   Unexpect aCatch(SalomeException);
688         int Nb = 0;
689         SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
690         while(itVolumes->more()) if(itVolumes->next()->NbNodes()==8) Nb++;
691         return Nb;
692 }
693
694 int SMESH_Mesh::NbPyramids() throw(SALOME_Exception)
695 {
696   Unexpect aCatch(SalomeException);
697         int Nb = 0;
698         SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
699         while(itVolumes->more()) if(itVolumes->next()->NbNodes()==5) Nb++;
700         return Nb;
701 }
702
703 int SMESH_Mesh::NbPrisms() throw(SALOME_Exception)
704 {
705   Unexpect aCatch(SalomeException);
706         int Nb = 0;
707         SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
708         while(itVolumes->more()) if(itVolumes->next()->NbNodes()==6) Nb++;
709         return Nb;
710 }
711
712 //=============================================================================
713 /*!
714  *  
715  */
716 //=============================================================================
717 int SMESH_Mesh::NbSubMesh() throw(SALOME_Exception)
718 {
719   Unexpect aCatch(SalomeException);
720         return _myMeshDS->NbSubMesh();
721 }
722
723 //=======================================================================
724 //function : IsNotConformAllowed
725 //purpose  : check if a hypothesis alowing notconform mesh is present
726 //=======================================================================
727
728 bool SMESH_Mesh::IsNotConformAllowed() const
729 {
730   MESSAGE("SMESH_Mesh::IsNotConformAllowed");
731
732   const list<const SMESHDS_Hypothesis*>& listHyp =
733     _myMeshDS->GetHypothesis( _myMeshDS->ShapeToMesh() );
734   list<const SMESHDS_Hypothesis*>::const_iterator it=listHyp.begin();
735   while (it!=listHyp.end())
736   {
737     const SMESHDS_Hypothesis *aHyp = *it;
738     string hypName = aHyp->GetName();
739     if ( hypName == "NotConformAllowed" )
740       return true;
741     it++;
742   }
743   return false;
744 }
745
746 //=======================================================================
747 //function : IsMainShape
748 //purpose  : 
749 //=======================================================================
750
751 bool SMESH_Mesh::IsMainShape(const TopoDS_Shape& theShape) const
752 {
753   return theShape.IsSame(_myMeshDS->ShapeToMesh() );
754 }
755
756 //=============================================================================
757 /*!
758  *  
759  */
760 //=============================================================================
761
762 SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType,
763                                    const char*               theName,
764                                    int&                      theId)
765 {
766   if (_mapGroup.find(_groupId) != _mapGroup.end())
767     return NULL;
768   SMESH_Group* aGroup = new SMESH_Group (this, theType, theName);
769   theId = _groupId;
770   _mapGroup[_groupId++] = aGroup;
771   return aGroup;
772 }
773
774 //=============================================================================
775 /*!
776  *  
777  */
778 //=============================================================================
779
780 SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID)
781 {
782   if (_mapGroup.find(theGroupID) == _mapGroup.end())
783     return NULL;
784   return _mapGroup[theGroupID];
785 }
786
787
788 //=============================================================================
789 /*!
790  *  
791  */
792 //=============================================================================
793
794 list<int> SMESH_Mesh::GetGroupIds()
795 {
796   list<int> anIds;
797   for ( map<int, SMESH_Group*>::const_iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
798     anIds.push_back( it->first );
799   
800   return anIds;
801 }
802
803
804 //=============================================================================
805 /*!
806  *  
807  */
808 //=============================================================================
809
810 void SMESH_Mesh::RemoveGroup (const int theGroupID)
811 {
812   if (_mapGroup.find(theGroupID) == _mapGroup.end())
813     return;
814   delete _mapGroup[theGroupID];
815   _mapGroup.erase (theGroupID);
816 }
817
818 //=======================================================================
819 //function : GetAncestors
820 //purpose  : return list of ancestors of theSubShape in the order
821 //           that lower dimention shapes come first.
822 //=======================================================================
823
824 const TopTools_ListOfShape& SMESH_Mesh::GetAncestors(const TopoDS_Shape& theS)
825 {
826   if ( _mapAncestors.IsEmpty() )
827   {
828     // fill _mapAncestors
829     int desType, ancType;
830     for ( desType = TopAbs_EDGE; desType > TopAbs_COMPOUND; desType-- )
831       for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
832         TopExp::MapShapesAndAncestors (_myMeshDS->ShapeToMesh(),
833                                        (TopAbs_ShapeEnum) desType,
834                                        (TopAbs_ShapeEnum) ancType,
835                                        _mapAncestors );
836   }
837
838   if ( _mapAncestors.Contains( theS ) )
839     return _mapAncestors.FindFromKey( theS );
840
841   static TopTools_ListOfShape emptyList;
842   return emptyList;
843 }
844
845 //=======================================================================
846 //function : Dump
847 //purpose  : dumps contents of mesh to stream [ debug purposes ]
848 //=======================================================================
849 ostream& SMESH_Mesh::Dump(ostream& save)
850 {
851   save << "========================== Dump contents of mesh ==========================" << endl;
852   save << "1) Total number of nodes:     " << NbNodes() << endl;
853   save << "2) Total number of edges:     " << NbEdges() << endl;
854   save << "3) Total number of faces:     " << NbFaces() << endl;
855   if ( NbFaces() > 0 ) {
856     int nb3 = NbTriangles();
857     int nb4 = NbQuadrangles();
858     save << "3.1.) Number of triangles:    " << nb3 << endl;
859     save << "3.2.) Number of quadrangles:  " << nb4 << endl;
860     if ( nb3 + nb4 !=  NbFaces() ) {
861       map<int,int> myFaceMap;
862       SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
863       while( itFaces->more( ) ) {
864         int nbNodes = itFaces->next()->NbNodes();
865         if ( myFaceMap.find( nbNodes ) == myFaceMap.end() )
866           myFaceMap[ nbNodes ] = 0;
867         myFaceMap[ nbNodes ] = myFaceMap[ nbNodes ] + 1;
868       }
869       save << "3.3.) Faces in detail: " << endl;
870       map <int,int>::iterator itF;
871       for (itF = myFaceMap.begin(); itF != myFaceMap.end(); itF++)
872         save << "--> nb nodes: " << itF->first << " - nb elemens: " << itF->second << endl;
873     }
874   }
875   save << "4) Total number of volumes:   " << NbVolumes() << endl;
876   if ( NbVolumes() > 0 ) {
877     int nb8 = NbHexas();
878     int nb4 = NbTetras();
879     int nb5 = NbPyramids();
880     int nb6 = NbPrisms();
881     save << "4.1.) Number of hexahedrons:  " << nb8 << endl;
882     save << "4.2.) Number of tetrahedrons: " << nb4 << endl;
883     save << "4.3.) Number of prisms:       " << nb6 << endl;
884     save << "4.4.) Number of pyramides:    " << nb5 << endl;
885     if ( nb8 + nb4 + nb5 + nb6 != NbVolumes() ) {
886       map<int,int> myVolumesMap;
887       SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
888       while( itVolumes->more( ) ) {
889         int nbNodes = itVolumes->next()->NbNodes();
890         if ( myVolumesMap.find( nbNodes ) == myVolumesMap.end() )
891           myVolumesMap[ nbNodes ] = 0;
892         myVolumesMap[ nbNodes ] = myVolumesMap[ nbNodes ] + 1;
893       }
894       save << "4.5.) Volumes in detail: " << endl;
895       map <int,int>::iterator itV;
896       for (itV = myVolumesMap.begin(); itV != myVolumesMap.end(); itV++)
897         save << "--> nb nodes: " << itV->first << " - nb elemens: " << itV->second << endl;
898     }
899   }
900   save << "===========================================================================" << endl;
901   return save;
902 }