Salome HOME
yfr : Merge with v1.2
[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 using namespace std;
30 using namespace std;
31 #include "SMESH_Mesh.hxx"
32 #include "SMESH_subMesh.hxx"
33 #include "SMESH_Gen.hxx"
34 #include "SMESH_Hypothesis.hxx"
35 #include "SMESHDS_Script.hxx"
36 //#include "SMESHDS_ListOfAsciiString.hxx"
37 //#include "SMESHDS_ListIteratorOfListOfAsciiString.hxx"
38 #include "SMESHDS_ListOfPtrHypothesis.hxx"
39 #include "SMESHDS_ListIteratorOfListOfPtrHypothesis.hxx"
40 #include "SMDS_MeshElement.hxx"
41 #include "SMDS_MeshFacesIterator.hxx"
42 #include "SMDS_MeshVolumesIterator.hxx"
43 #include "TCollection_AsciiString.hxx"
44
45 #include "utilities.h"
46
47 #include "Mesh_Writer.h"
48 #include "DriverMED_W_SMESHDS_Mesh.h"
49 #include "DriverDAT_W_SMESHDS_Mesh.h"
50 #include "DriverUNV_W_SMESHDS_Mesh.h"
51
52 //=============================================================================
53 /*!
54  * 
55  */
56 //=============================================================================
57
58 SMESH_Mesh::SMESH_Mesh()
59 {
60   MESSAGE("SMESH_Mesh::SMESH_Mesh");
61   _id = -1;
62   ASSERT(0);
63 }
64
65 //=============================================================================
66 /*!
67  * 
68  */
69 //=============================================================================
70
71 SMESH_Mesh::SMESH_Mesh(int localId,
72                        int studyId,
73                        SMESH_Gen* gen,
74                        const Handle(SMESHDS_Document)& myDocument)
75 {
76   MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)");
77   _id = localId;
78   _studyId = studyId;
79   _gen = gen;
80   _myDocument = myDocument;
81   _idDoc = _myDocument->NewMesh();
82   _myMeshDS = _myDocument->GetMesh(_idDoc);
83   _isShapeToMesh = false;
84 }
85
86 //=============================================================================
87 /*!
88  * 
89  */
90 //=============================================================================
91
92 SMESH_Mesh::~SMESH_Mesh()
93 {
94   MESSAGE("SMESH_Mesh::~SMESH_Mesh");
95 }
96
97 //=============================================================================
98 /*!
99  * 
100  */
101 //=============================================================================
102
103 void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape& aShape)
104   throw (SALOME_Exception)
105 {
106   MESSAGE("SMESH_Mesh::ShapeToMesh");
107   if (_isShapeToMesh)
108     throw SALOME_Exception(LOCALIZED("a shape to mesh as already been defined"));
109   _isShapeToMesh = true;
110   _myMeshDS->ShapeToMesh(aShape);
111
112   // NRI : 24/02/03
113   TopExp::MapShapes(aShape,_subShapes);
114 }
115
116 //=============================================================================
117 /*!
118  * 
119  */
120 //=============================================================================
121
122 bool SMESH_Mesh::AddHypothesis(const TopoDS_Shape& aSubShape,
123                                int anHypId)
124   throw (SALOME_Exception)
125 {
126   MESSAGE("SMESH_Mesh::AddHypothesis");
127
128   StudyContextStruct* sc = _gen->GetStudyContext(_studyId);
129   if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
130     {
131       MESSAGE("Hypothesis ID does not give an hypothesis");
132       SCRUTE(_studyId);
133       SCRUTE(anHypId);
134       throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
135     }
136
137   SMESH_subMesh* subMesh = GetSubMesh(aSubShape);
138   SMESH_Hypothesis* anHyp = sc->mapHypothesis[anHypId];
139   int event;
140
141   // shape 
142
143   if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
144     event = SMESH_subMesh::ADD_HYP;
145   else
146     event = SMESH_subMesh::ADD_ALGO;
147   int ret = subMesh->AlgoStateEngine(event, anHyp);
148
149   // subShapes (only when shape is mainShape)
150   TopoDS_Shape mainShape = _myMeshDS->ShapeToMesh();
151   if (aSubShape.IsSame(mainShape))
152     {
153       if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
154         event = SMESH_subMesh::ADD_FATHER_HYP;
155       else
156         event = SMESH_subMesh::ADD_FATHER_ALGO;
157       subMesh->SubMeshesAlgoStateEngine(event, anHyp);
158     }
159
160   subMesh->DumpAlgoState(true);
161   //SCRUTE(ret);
162   return ret;
163 }
164
165 //=============================================================================
166 /*!
167  * 
168  */
169 //=============================================================================
170
171 bool SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape& aSubShape,
172                                   int anHypId)
173   throw (SALOME_Exception)
174 {
175   MESSAGE("SMESH_Mesh::RemoveHypothesis");
176
177   StudyContextStruct* sc = _gen->GetStudyContext(_studyId);
178   if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
179     throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
180
181   SMESH_subMesh* subMesh = GetSubMesh(aSubShape);
182   SMESH_Hypothesis* anHyp = sc->mapHypothesis[anHypId];
183   int hypType = anHyp->GetType();
184   SCRUTE(hypType);
185   int event;
186
187   // shape 
188
189   if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
190     event = SMESH_subMesh::REMOVE_HYP;
191   else
192     event = SMESH_subMesh::REMOVE_ALGO;
193   int ret = subMesh->AlgoStateEngine(event, anHyp);
194
195   // subShapes (only when shape is mainShape)
196
197   TopoDS_Shape mainShape = _myMeshDS->ShapeToMesh();
198   if (aSubShape.IsSame(mainShape))
199     {
200       if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
201         event = SMESH_subMesh::REMOVE_FATHER_HYP;
202       else
203         event = SMESH_subMesh::REMOVE_FATHER_ALGO;
204       subMesh->SubMeshesAlgoStateEngine(event, anHyp);
205     }
206
207   subMesh->DumpAlgoState(true);
208   SCRUTE(ret);
209   return ret;
210 }
211
212 //=============================================================================
213 /*!
214  * 
215  */
216 //=============================================================================
217
218 const Handle(SMESHDS_Mesh)& SMESH_Mesh::GetMeshDS()
219 {
220   return _myMeshDS;
221 }
222
223
224 //=============================================================================
225 /*!
226  * 
227  */
228 //=============================================================================
229
230 const list<SMESHDS_Hypothesis*>&
231 SMESH_Mesh::GetHypothesisList(const TopoDS_Shape& aSubShape)
232   throw (SALOME_Exception)
233 {
234   MESSAGE("SMESH_Mesh::GetHypothesisList");
235   _subShapeHypothesisList.clear();
236   const SMESHDS_ListOfPtrHypothesis& listHyp
237     = _myMeshDS->GetHypothesis(aSubShape);
238   SMESHDS_ListIteratorOfListOfPtrHypothesis it(listHyp);
239   while (it.More())
240     {
241       SMESHDS_Hypothesis* anHyp = it.Value();
242       _subShapeHypothesisList.push_back(anHyp);
243       it.Next();
244     }
245   return _subShapeHypothesisList;
246 }
247
248 //=============================================================================
249 /*!
250  * 
251  */
252 //=============================================================================
253
254 const SMESHDS_ListOfCommand& SMESH_Mesh::GetLog()
255   throw (SALOME_Exception)
256 {
257   MESSAGE("SMESH_Mesh::GetLog");
258   Handle (SMESHDS_Script) scriptDS = _myMeshDS->GetScript();
259   const SMESHDS_ListOfCommand& logDS = scriptDS->GetCommands();
260 //   SMESHDS_ListIteratorOfListOfCommand its;
261 //   const SMESHDS_ListOfAsciiString& logDS = scriptDS->GetCommands();
262 //   SMESHDS_ListIteratorOfListOfAsciiString its;
263 //   for (its.Initialize(logDS); its.More(); its.Next())
264 //     {
265 //       SCRUTE(its.Value().ToCString());
266 //     }
267   return logDS;
268 }
269
270 //=============================================================================
271 /*!
272  * 
273  */
274 //=============================================================================
275 void SMESH_Mesh::ClearLog()
276   throw (SALOME_Exception)
277 {
278   MESSAGE("SMESH_Mesh::ClearLog");
279   Handle (SMESHDS_Script) scriptDS = _myMeshDS->GetScript();
280   scriptDS->Clear();
281 }
282
283 //=============================================================================
284 /*!
285  * 
286  */
287 //=============================================================================
288
289 int SMESH_Mesh::GetId()
290 {
291   MESSAGE("SMESH_Mesh::GetId");
292   return _id;
293 }
294
295 //=============================================================================
296 /*!
297  * 
298  */
299 //=============================================================================
300
301 SMESH_Gen* SMESH_Mesh::GetGen()
302 {
303   return _gen;
304 }
305
306 //=============================================================================
307 /*!
308  * Get or Create the SMESH_subMesh object implementation
309  */
310 //=============================================================================
311
312 SMESH_subMesh* SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
313   throw (SALOME_Exception)
314 {
315   //MESSAGE("SMESH_Mesh::GetSubMesh");
316   SMESH_subMesh* aSubMesh;
317   int index = _subShapes.FindIndex(aSubShape);
318   if ( _mapSubMesh.find(index) != _mapSubMesh.end() ) {
319     aSubMesh = _mapSubMesh[index];
320   } else {
321     aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
322     _mapSubMesh[index] = aSubMesh;
323   }
324
325   /* NRI 24/02/2003
326   int index = -1;
327   if (_subShapes.Contains(aSubShape))
328     {
329       index = _subShapes.FindIndex(aSubShape);
330       ASSERT(_mapSubMesh.find(index) != _mapSubMesh.end());
331       aSubMesh = _mapSubMesh[index];
332       //MESSAGE("found submesh " << index);
333     }
334   else
335     {
336       index = _subShapes.Add(aSubShape);
337       aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
338       _mapSubMesh[index] = aSubMesh;
339       //MESSAGE("created submesh " << index);
340     }
341   */
342   return aSubMesh;
343 }
344
345 //=============================================================================
346 /*!
347  * Get the SMESH_subMesh object implementation. Dont create it, return null
348  * if it does not exist.
349  */
350 //=============================================================================
351 //
352 //  * Given a subShape, find if there is a subMesh associated to this subShape
353 //  * or to a collection of shapes containing this subShape. Collection =
354 //  * compsolid, shell, wire.
355 //  *
356 //  * WARNING : with arg = compsolid, shell or wire returns always NULL.
357 //  * with a face inside a shell, and submesh created for both, if arg is face,
358 //  * returns first created submesh of the two. 
359 //  * subMesh is not created, return may be NULL.
360
361 SMESH_subMesh* SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape)
362   throw (SALOME_Exception)
363 {
364   //MESSAGE("SMESH_Mesh::GetSubMeshContaining");
365   bool isFound = false;
366   SMESH_subMesh* aSubMesh = NULL;
367
368   int index = _subShapes.FindIndex(aSubShape);
369   if ( _mapSubMesh.find(index) != _mapSubMesh.end() ) {
370     aSubMesh = _mapSubMesh[index];
371     isFound = true;
372   } 
373
374   /* NRI 24/02/2003
375   int index = -1;
376   if (_subShapes.Contains(aSubShape))
377     {
378       index = _subShapes.FindIndex(aSubShape);
379       ASSERT(_mapSubMesh.find(index) != _mapSubMesh.end());
380       aSubMesh = _mapSubMesh[index];
381       isFound = true;
382       //MESSAGE("found submesh " << index);
383     }
384   */
385
386 //   map<int, SMESH_subMesh*>::iterator itsm;
387 //   for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
388 //     {
389 //       aSubMesh = (*itsm).second;
390 //       isFound = aSubMesh->Contains(aSubShape);
391 //       if (isFound) break;
392 //     }
393
394   if (! isFound) aSubMesh = NULL;
395   return aSubMesh;
396 }
397
398 //=============================================================================
399 /*!
400  *
401  */
402 //=============================================================================
403
404 const list <SMESH_subMesh*>&
405 SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis* anHyp)
406   throw (SALOME_Exception)
407 {
408   MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis");
409   map<int, SMESH_subMesh*>::iterator itsm;
410   _subMeshesUsingHypothesisList.clear();
411   for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
412     {
413       SMESH_subMesh* aSubMesh = (*itsm).second;
414       bool usesHyp = false;
415       SMESH_Algo* algo = _gen->GetAlgo(*this, aSubMesh->GetSubShape());
416       if (algo != NULL)
417         {
418           const list<SMESHDS_Hypothesis*>& usedHyps
419             = algo->GetUsedHypothesis(*this, aSubMesh->GetSubShape());
420           list<SMESHDS_Hypothesis*>::const_iterator itl;
421           for(itl=usedHyps.begin(); itl != usedHyps.end(); itl++)
422             if (anHyp == (*itl))
423               {
424                 usesHyp = true;
425                 break;
426               }     
427         }
428       if (usesHyp) _subMeshesUsingHypothesisList.push_back(aSubMesh);
429     }
430   return _subMeshesUsingHypothesisList;
431 }
432
433 //=============================================================================
434 /*!
435  *
436  */
437 //=============================================================================
438
439 void SMESH_Mesh::ExportMED( const char* file )
440   throw (SALOME_Exception)
441 {
442   Mesh_Writer* myWriter = new DriverMED_W_SMESHDS_Mesh;
443   myWriter->SetFile( string(file) );
444   myWriter->SetMesh( _myMeshDS );
445   MESSAGE ( " _idDoc " << _idDoc )
446   myWriter->SetMeshId( _idDoc );
447   myWriter->Add();
448 }
449
450 void SMESH_Mesh::ExportDAT( const char* file )
451   throw (SALOME_Exception)
452 {
453   Mesh_Writer* myWriter = new DriverDAT_W_SMESHDS_Mesh;
454   myWriter->SetFile( string(file) );
455   myWriter->SetMesh( _myMeshDS );
456   myWriter->SetMeshId( _idDoc );
457   myWriter->Add();
458 }
459
460 void SMESH_Mesh::ExportUNV( const char* file )
461   throw (SALOME_Exception)
462 {
463   Mesh_Writer* myWriter = new DriverUNV_W_SMESHDS_Mesh;
464   myWriter->SetFile( string(file) );
465   myWriter->SetMesh( _myMeshDS );
466   myWriter->SetMeshId( _idDoc );
467   myWriter->Add();
468 }
469
470 //=============================================================================
471 /*!
472  *  
473  */
474 //=============================================================================
475 int SMESH_Mesh::NbNodes()
476   throw (SALOME_Exception)
477 {
478   return _myMeshDS->NbNodes();
479 }
480
481 //=============================================================================
482 /*!
483  *  
484  */
485 //=============================================================================
486 int SMESH_Mesh::NbEdges()
487   throw (SALOME_Exception)
488 {
489   return _myMeshDS->NbEdges();
490 }
491
492 //=============================================================================
493 /*!
494  *  
495  */
496 //=============================================================================
497 int SMESH_Mesh::NbFaces()
498   throw (SALOME_Exception)
499 {
500   return _myMeshDS->NbFaces();
501 }
502 int SMESH_Mesh::NbTriangles()
503   throw (SALOME_Exception)
504 {
505   SMDS_MeshFacesIterator itFaces(_myMeshDS);
506   int Nb = 0;
507   for (;itFaces.More();itFaces.Next()) {
508     const Handle(SMDS_MeshElement)& elem = itFaces.Value();
509
510     switch (elem->NbNodes()) {
511     case 3 : {
512       Nb++;
513       break;
514     }
515     }
516   }
517   return Nb;
518 }
519 int SMESH_Mesh::NbQuadrangles()
520   throw (SALOME_Exception)
521 {
522   SMDS_MeshFacesIterator itFaces(_myMeshDS);
523   int Nb = 0;
524   for (;itFaces.More();itFaces.Next()) {
525     const Handle(SMDS_MeshElement)& elem = itFaces.Value();
526     
527     switch (elem->NbNodes()) {
528     case 4 : {
529       Nb++;
530       break;
531     }
532     }
533   }
534   return Nb;
535 }
536
537 //=============================================================================
538 /*!
539  *  
540  */
541 //=============================================================================
542 int SMESH_Mesh::NbVolumes()
543   throw (SALOME_Exception)
544 {
545   return _myMeshDS->NbVolumes();
546 }
547 int SMESH_Mesh::NbTetras()
548   throw (SALOME_Exception)
549 {
550   int Nb = 0;
551   SMDS_MeshVolumesIterator itVolumes(_myMeshDS);
552   for (;itVolumes.More();itVolumes.Next()) {
553     const Handle(SMDS_MeshElement)& elem = itVolumes.Value();
554
555     switch (elem->NbNodes()) {
556     case 4 : {
557       Nb++;
558       break;
559     }
560     }
561   }
562   return Nb;
563 }
564 int SMESH_Mesh::NbHexas()
565   throw (SALOME_Exception)
566 {
567   int Nb = 0;
568   SMDS_MeshVolumesIterator itVolumes(_myMeshDS);
569   for (;itVolumes.More();itVolumes.Next()) {
570     const Handle(SMDS_MeshElement)& elem = itVolumes.Value();
571
572     switch (elem->NbNodes()) {
573     case 8 : {
574       Nb++;
575       break;
576     }
577     }
578   }
579   return Nb;
580 }
581
582 //=============================================================================
583 /*!
584  *  
585  */
586 //=============================================================================
587 int SMESH_Mesh::NbSubMesh()
588   throw (SALOME_Exception)
589 {
590   return _myMeshDS->NbSubMesh();
591 }